]> git.mxchange.org Git - flightgear.git/blob - src/Navaids/navrecord.cxx
Merge branch 'maint' into next
[flightgear.git] / src / Navaids / navrecord.cxx
1 // navrecord.cxx -- generic vor/dme/ndb class
2 //
3 // Written by Curtis Olson, started May 2004.
4 //
5 // Copyright (C) 2004  Curtis L. Olson - http://www.flightgear.org/~curt
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 //
21 // $Id$
22
23 #ifdef HAVE_CONFIG_H
24   #include "config.h"
25 #endif
26
27 #include <istream>
28
29 #include <simgear/misc/sgstream.hxx>
30 #include <simgear/structure/exception.hxx>
31 #include <simgear/debug/logstream.hxx>
32
33 #include "Navaids/navrecord.hxx"
34 #include "Navaids/navdb.hxx"
35 #include "Airports/runways.hxx"
36 #include "Main/fg_props.hxx"
37
38 FGNavRecord::FGNavRecord(Type aTy, const std::string& aIdent, 
39   const std::string& aName, const SGGeod& aPos,
40   int aFreq, int aRange, double aMultiuse) :
41   FGPositioned(aTy, aIdent, aPos),
42   freq(aFreq),
43   range(aRange),
44   multiuse(aMultiuse),
45   _name(aName),
46   serviceable(true),
47   trans_ident(aIdent)
48
49   initAirportRelation();
50
51   // Ranges are included with the latest data format, no need to
52   // assign our own defaults, unless the range is not set for some
53   // reason.
54   if (range < 0.1) {
55     SG_LOG(SG_GENERAL, SG_WARN, "navaid " << ident() << " has no range set, using defaults");
56     switch (type()) {
57     case NDB:
58     case VOR:
59       range = FG_NAV_DEFAULT_RANGE;
60       break;
61     
62     case LOC:
63     case ILS:
64     case GS:
65       range = FG_LOC_DEFAULT_RANGE;
66       break;
67       
68     case DME:
69       range = FG_DME_DEFAULT_RANGE;
70       break;
71     
72     default:
73       range = FG_LOC_DEFAULT_RANGE;
74     }
75   }
76   
77 }
78
79 void FGNavRecord::initAirportRelation()
80 {
81   if ((type() < ILS) || (type() > GS)) {
82     return; // not airport-located
83   }
84   
85   FGRunway* runway = getRunwayFromName(_name);    
86   // fudge elevation to the runway elevation if it's not specified
87   if (fabs(elevation()) < 0.01) {
88     mPosition.setElevationFt(runway->elevation());
89   }
90   
91   // align localizers with their runway
92   if ((type() == ILS) || (type() == LOC)) {
93     if (!fgGetBool("/sim/navdb/localizers/auto-align", true)) {
94       return;
95     }
96     
97    double threshold 
98      = fgGetDouble( "/sim/navdb/localizers/auto-align-threshold-deg", 5.0 );
99     alignLocaliserWithRunway(runway, threshold);
100   }
101 }
102
103 void FGNavRecord::alignLocaliserWithRunway(FGRunway* aRunway, double aThreshold)
104 {
105 // find the distance from the threshold to the localizer
106   SGGeod runwayThreshold(aRunway->threshold());
107   double dist, az1, az2;
108   SGGeodesy::inverse(mPosition, runwayThreshold, az1, az2, dist);
109
110 // back project that distance along the runway center line
111   SGGeod newPos = aRunway->pointOnCenterline(dist);
112
113   double hdg_diff = get_multiuse() - aRunway->headingDeg();
114
115   // clamp to [-180.0 ... 180.0]
116   if ( hdg_diff < -180.0 ) {
117       hdg_diff += 360.0;
118   } else if ( hdg_diff > 180.0 ) {
119       hdg_diff -= 360.0;
120   }
121
122   if ( fabs(hdg_diff) <= aThreshold ) {
123     mPosition = newPos;
124     set_multiuse( aRunway->headingDeg() );
125   } else {
126     SG_LOG(SG_GENERAL, SG_WARN, "localizer:" << ident() << ", aligning with runway " 
127       << aRunway->ident() << " exceeded heading threshold");
128   }
129 }
130
131 FGTACANRecord::FGTACANRecord(void) :
132     channel(""),
133     freq(0)
134     
135 {
136 }
137
138 std::istream&
139 operator >> ( std::istream& in, FGTACANRecord& n )
140 {
141     in >> n.channel >> n.freq ;
142     //getline( in, n.name );
143
144     return in;
145 }