1 // gps.hxx - distance-measuring equipment.
2 // Written by David Megginson, started 2003.
4 // This file is in the Public Domain and comes with no warranty.
7 #ifndef __INSTRUMENTS_GPS_HXX
8 #define __INSTRUMENTS_GPS_HXX 1
10 #include <simgear/props/props.hxx>
11 #include <simgear/structure/subsystem_mgr.hxx>
12 #include <simgear/math/SGMath.hxx>
14 #include "Navaids/positioned.hxx"
29 void init(SGPropertyNode* base, const char* lonStr, const char* latStr, const char* altStr = NULL);
30 void init(const char* lonStr, const char* latStr, const char* altStr = NULL);
32 void operator=(const SGGeod& geod);
35 SGPropertyNode_ptr _lon, _lat, _alt;
43 * /position/longitude-deg
44 * /position/latitude-deg
45 * /position/altitude-ft
46 * /environment/magnetic-variation-deg
47 * /systems/electrical/outputs/gps
48 * /instrumentation/gps/serviceable
53 * /instrumentation/gps/indicated-longitude-deg
54 * /instrumentation/gps/indicated-latitude-deg
55 * /instrumentation/gps/indicated-altitude-ft
56 * /instrumentation/gps/indicated-vertical-speed-fpm
57 * /instrumentation/gps/indicated-track-true-deg
58 * /instrumentation/gps/indicated-track-magnetic-deg
59 * /instrumentation/gps/indicated-ground-speed-kt
61 * /instrumentation/gps/wp-distance-nm
62 * /instrumentation/gps/wp-bearing-deg
63 * /instrumentation/gps/wp-bearing-mag-deg
64 * /instrumentation/gps/TTW
65 * /instrumentation/gps/course-deviation-deg
66 * /instrumentation/gps/course-error-nm
67 * /instrumentation/gps/to-flag
68 * /instrumentation/gps/odometer
69 * /instrumentation/gps/trip-odometer
70 * /instrumentation/gps/true-bug-error-deg
71 * /instrumentation/gps/magnetic-bug-error-deg
74 class GPS : public SGSubsystem
79 GPS (SGPropertyNode *node);
84 virtual void update (double delta_time_sec);
87 friend class GPSListener;
88 friend class SearchFilter;
91 * Configuration manager, track data relating to aircraft installation
98 void init(SGPropertyNode*);
100 bool turnAnticipationEnabled() const
101 { return _enableTurnAnticipation; }
104 * Desired turn rate in degrees/second. From this we derive the turn
105 * radius and hence how early we need to anticipate it.
107 double turnRateDegSec() const
108 { return _turnRate; }
111 * Distance at which we arm overflight sequencing. Once inside this
112 * distance, a change of the wp1 'TO' flag to false will be considered
113 * overlight of the wp.
115 double overflightArmDistanceNm() const
116 { return _overflightArmDistance; }
119 * Time before the next WP to activate an external annunciator
121 double waypointAlertTime() const
122 { return _waypointAlertTime; }
124 bool tuneNavRadioToRefVor() const
125 { return _tuneRadio1ToRefVor; }
127 bool requireHardSurface() const
128 { return _requireHardSurface; }
130 double minRunwayLengthFt() const
131 { return _minRunwayLengthFt; }
133 double getOBSCourse() const;
135 bool cdiDeflectionIsAngular() const
136 { return (_cdiMaxDeflectionNm <= 0.0); }
138 double cdiDeflectionLinearPeg() const
140 assert(_cdiMaxDeflectionNm > 0.0);
141 return _cdiMaxDeflectionNm;
144 bool _enableTurnAnticipation;
146 // desired turn rate in degrees per second
149 // distance from waypoint to arm overflight sequencing (in nm)
150 double _overflightArmDistance;
152 // time before reaching a waypoint to trigger annunicator light/sound
154 double _waypointAlertTime;
156 // should GPS automatically tune NAV1 to the reference VOR?
157 bool _tuneRadio1ToRefVor;
159 // minimum runway length to require when filtering
160 double _minRunwayLengthFt;
162 // should we require a hard-surfaced runway when filtering?
163 bool _requireHardSurface;
165 // helpers to tie obs-course-source property
166 const char* getOBSCourseSource() const;
167 void setOBSCourseSource(const char* aPropPath);
169 // property to retrieve the OBS course from
170 SGPropertyNode_ptr _obsCourseSource;
172 double _cdiMaxDeflectionNm;
175 class SearchFilter : public FGPositioned::Filter
178 virtual bool pass(FGPositioned* aPos) const;
180 virtual FGPositioned::Type minType() const;
181 virtual FGPositioned::Type maxType() const;
185 * reset all output properties to default / non-service values
189 void updateWithValid(double dt);
190 void updateBasicData(double dt);
191 void updateWaypoints();
193 void updateTrackingBug();
194 void updateReferenceNavaid(double dt);
195 void referenceNavaidSet(const std::string& aNavaid);
196 void tuneNavRadios();
197 void updateRouteData();
199 void routeActivated();
200 void routeManagerSequenced();
203 void updateOverflight();
207 double computeTurnProgress(double aBearing) const;
208 void computeTurnData();
209 void updateTurnData();
210 double computeTurnRadiusNm(double aGroundSpeedKts) const;
213 // scratch maintenence utilities
214 void setScratchFromPositioned(FGPositioned* aPos, int aIndex);
215 void setScratchFromCachedSearchResult();
216 void setScratchFromRouteWaypoint(int aIndex);
219 * Add airport-specific information to a scratch result
221 void addAirportToScratch(FGAirport* aAirport);
226 * Predicate, determine if the lon/lat position in the scratch is
229 bool isScratchPositionValid() const;
231 FGPositioned::Filter* createFilter(FGPositioned::Type aTy);
234 * Search kernel - called each time we step through a result
236 void performSearch();
239 void selectLegMode();
240 void selectOBSMode();
242 void loadRouteWaypoint();
246 void previousResult();
247 void defineWaypoint();
249 // tied-property getter/setters
250 void setCommand(const char* aCmd);
251 const char* getCommand() const { return ""; }
253 const char* getMode() const { return _mode.c_str(); }
255 bool getScratchValid() const { return _scratchValid; }
256 double getScratchDistance() const;
257 double getScratchMagBearing() const;
258 double getScratchTrueBearing() const;
259 bool getScratchHasNext() const { return _searchHasNext; }
261 double getSelectedCourse() const { return _selectedCourse; }
262 double getCDIDeflection() const;
264 double getLegDistance() const;
265 double getLegCourse() const;
266 double getLegMagCourse() const;
267 double getAltDistanceRatio() const;
269 double getTrueTrack() const { return _last_true_track; }
270 double getMagTrack() const;
271 double getGroundspeedKts() const { return _last_speed_kts; }
272 double getVerticalSpeed() const { return _last_vertical_speed; }
274 //bool getLegMode() const { return _mode == "leg"; }
275 //bool getObsMode() const { return _mode == "obs"; }
277 const char* getWP0Ident() const;
278 const char* getWP0Name() const;
280 const char* getWP1Ident() const;
281 const char* getWP1Name() const;
283 double getWP1Distance() const;
284 double getWP1TTW() const;
285 const char* getWP1TTWString() const;
286 double getWP1Bearing() const;
287 double getWP1MagBearing() const;
288 double getWP1CourseDeviation() const;
289 double getWP1CourseErrorNm() const;
290 bool getWP1ToFlag() const;
291 // true-bearing-error and mag-bearing-error
296 SGPropertyNode_ptr _magvar_node;
297 SGPropertyNode_ptr _serviceable_node;
298 SGPropertyNode_ptr _electrical_node;
299 SGPropertyNode_ptr _tracking_bug_node;
300 SGPropertyNode_ptr _raim_node;
302 SGPropertyNode_ptr _odometer_node;
303 SGPropertyNode_ptr _trip_odometer_node;
304 SGPropertyNode_ptr _true_bug_error_node;
305 SGPropertyNode_ptr _magnetic_bug_error_node;
307 SGPropertyNode_ptr _ref_navaid_id_node;
308 SGPropertyNode_ptr _ref_navaid_bearing_node;
309 SGPropertyNode_ptr _ref_navaid_distance_node;
310 SGPropertyNode_ptr _ref_navaid_mag_bearing_node;
311 SGPropertyNode_ptr _ref_navaid_frequency_node;
312 SGPropertyNode_ptr _ref_navaid_name_node;
314 SGPropertyNode_ptr _route_active_node;
315 SGPropertyNode_ptr _route_current_wp_node;
316 SGPropertyNode_ptr _routeDistanceNm;
317 SGPropertyNode_ptr _routeETE;
319 SGPropertyNode_ptr _fromFlagNode;
321 double _selectedCourse;
325 double _last_speed_kts;
326 double _last_true_track;
327 double _last_vertical_speed;
330 GPSListener* _listener;
332 FGRouteMgr* _routeMgr;
334 bool _ref_navaid_set;
335 double _ref_navaid_elapsed;
336 FGPositionedRef _ref_navaid;
341 SGGeodProperty _position;
342 SGGeod _wp0_position;
343 SGGeod _wp1_position;
344 SGGeod _indicated_pos;
345 std::string _wp0Ident, _wp0Name, _wp1Ident, _wp1Name;
346 double _wp1DistanceM, _wp1TrueBearing;
350 SGPropertyNode_ptr _scratchNode;
354 int _searchResultIndex;
355 std::string _searchQuery;
356 FGPositioned::Type _searchType;
358 bool _searchOrderByRange;
359 bool _searchResultsCached;
360 FGPositioned::List _searchResults;
361 bool _searchIsRoute; ///< set if 'search' is actually the current route
362 bool _searchHasNext; ///< is there a result after this one?
363 bool _searchNames; ///< set if we're searching names instead of idents
366 bool _computeTurnData; ///< do we need to update the turn data?
367 bool _anticipateTurn; ///< are we anticipating the next turn or not?
368 bool _inTurn; // is a turn in progress?
369 bool _turnSequenced; // have we sequenced the new leg?
370 double _turnAngle; // angle to turn through, in degrees
371 double _turnStartBearing; // bearing of inbound leg
372 double _turnRadius; // radius of turn in nm
378 #endif // __INSTRUMENTS_GPS_HXX