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
12 #include <simgear/props/props.hxx>
13 #include <simgear/structure/subsystem_mgr.hxx>
14 #include <simgear/math/SGMath.hxx>
16 #include "Navaids/positioned.hxx"
31 void init(SGPropertyNode* base, const char* lonStr, const char* latStr, const char* altStr = NULL);
32 void init(const char* lonStr, const char* latStr, const char* altStr = NULL);
34 void operator=(const SGGeod& geod);
37 SGPropertyNode_ptr _lon, _lat, _alt;
45 * /position/longitude-deg
46 * /position/latitude-deg
47 * /position/altitude-ft
48 * /environment/magnetic-variation-deg
49 * /systems/electrical/outputs/gps
50 * /instrumentation/gps/serviceable
55 * /instrumentation/gps/indicated-longitude-deg
56 * /instrumentation/gps/indicated-latitude-deg
57 * /instrumentation/gps/indicated-altitude-ft
58 * /instrumentation/gps/indicated-vertical-speed-fpm
59 * /instrumentation/gps/indicated-track-true-deg
60 * /instrumentation/gps/indicated-track-magnetic-deg
61 * /instrumentation/gps/indicated-ground-speed-kt
63 * /instrumentation/gps/wp-distance-nm
64 * /instrumentation/gps/wp-bearing-deg
65 * /instrumentation/gps/wp-bearing-mag-deg
66 * /instrumentation/gps/TTW
67 * /instrumentation/gps/course-deviation-deg
68 * /instrumentation/gps/course-error-nm
69 * /instrumentation/gps/to-flag
70 * /instrumentation/gps/odometer
71 * /instrumentation/gps/trip-odometer
72 * /instrumentation/gps/true-bug-error-deg
73 * /instrumentation/gps/magnetic-bug-error-deg
76 class GPS : public SGSubsystem
81 GPS (SGPropertyNode *node);
86 virtual void update (double delta_time_sec);
89 virtual void unbind();
91 friend class GPSListener;
92 friend class SearchFilter;
95 * Configuration manager, track data relating to aircraft installation
102 void bind(GPS* aOwner, SGPropertyNode* aCfg);
104 bool turnAnticipationEnabled() const
105 { return _enableTurnAnticipation; }
108 * Desired turn rate in degrees/second. From this we derive the turn
109 * radius and hence how early we need to anticipate it.
111 double turnRateDegSec() const
112 { return _turnRate; }
115 * Distance at which we arm overflight sequencing. Once inside this
116 * distance, a change of the wp1 'TO' flag to false will be considered
117 * overlight of the wp.
119 double overflightArmDistanceNm() const
120 { return _overflightArmDistance; }
123 * Time before the next WP to activate an external annunciator
125 double waypointAlertTime() const
126 { return _waypointAlertTime; }
128 bool requireHardSurface() const
129 { return _requireHardSurface; }
131 double minRunwayLengthFt() const
132 { return _minRunwayLengthFt; }
134 bool cdiDeflectionIsAngular() const
135 { return (_cdiMaxDeflectionNm <= 0.0); }
137 double cdiDeflectionLinearPeg() const
139 assert(_cdiMaxDeflectionNm > 0.0);
140 return _cdiMaxDeflectionNm;
143 bool driveAutopilot() const
144 { return _driveAutopilot; }
146 bool courseSelectable() const
147 { return _courseSelectable; }
149 bool _enableTurnAnticipation;
151 // desired turn rate in degrees per second
154 // distance from waypoint to arm overflight sequencing (in nm)
155 double _overflightArmDistance;
157 // time before reaching a waypoint to trigger annunicator light/sound
159 double _waypointAlertTime;
161 // minimum runway length to require when filtering
162 double _minRunwayLengthFt;
164 // should we require a hard-surfaced runway when filtering?
165 bool _requireHardSurface;
167 double _cdiMaxDeflectionNm;
169 // should we drive the autopilot directly or not?
170 bool _driveAutopilot;
172 // is selected-course-deg read to set desired-course or not?
173 bool _courseSelectable;
176 class SearchFilter : public FGPositioned::Filter
179 virtual bool pass(FGPositioned* aPos) const;
181 virtual FGPositioned::Type minType() const;
182 virtual FGPositioned::Type maxType() const;
186 * reset all output properties to default / non-service values
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 updateRouteData();
197 void driveAutopilot();
199 void routeActivated();
200 void routeManagerSequenced();
202 void routeFinished();
205 void updateOverflight();
209 double computeTurnProgress(double aBearing) const;
210 void computeTurnData();
211 void updateTurnData();
212 double computeTurnRadiusNm(double aGroundSpeedKts) const;
215 * Update one-shot things when WP1 / leg data change
219 // scratch maintenence utilities
220 void setScratchFromPositioned(FGPositioned* aPos, int aIndex);
221 void setScratchFromCachedSearchResult();
222 void setScratchFromRouteWaypoint(int aIndex);
225 * Add airport-specific information to a scratch result
227 void addAirportToScratch(FGAirport* aAirport);
232 * Predicate, determine if the lon/lat position in the scratch is
235 bool isScratchPositionValid() const;
237 FGPositioned::Filter* createFilter(FGPositioned::Type aTy);
240 * Search kernel - called each time we step through a result
242 void performSearch();
245 void selectLegMode();
246 void selectOBSMode();
248 void loadRouteWaypoint();
252 void previousResult();
253 void defineWaypoint();
254 void insertWaypointAtIndex(int aIndex);
255 void removeWaypointAtIndex(int aIndex);
257 // tied-property getter/setters
258 void setCommand(const char* aCmd);
259 const char* getCommand() const { return ""; }
261 const char* getMode() const { return _mode.c_str(); }
263 bool getScratchValid() const { return _scratchValid; }
264 double getScratchDistance() const;
265 double getScratchMagBearing() const;
266 double getScratchTrueBearing() const;
267 bool getScratchHasNext() const;
269 double getSelectedCourse() const { return _selectedCourse; }
270 void setSelectedCourse(double crs);
271 double getDesiredCourse() const { return _desiredCourse; }
273 double getCDIDeflection() const;
275 double getLegDistance() const;
276 double getLegCourse() const;
277 double getLegMagCourse() const;
278 double getAltDistanceRatio() const;
280 double getTrueTrack() const { return _last_true_track; }
281 double getMagTrack() const;
282 double getGroundspeedKts() const { return _last_speed_kts; }
283 double getVerticalSpeed() const { return _last_vertical_speed; }
285 //bool getLegMode() const { return _mode == "leg"; }
286 //bool getObsMode() const { return _mode == "obs"; }
288 const char* getWP0Ident() const;
289 const char* getWP0Name() const;
291 const char* getWP1Ident() const;
292 const char* getWP1Name() const;
294 double getWP1Distance() const;
295 double getWP1TTW() const;
296 const char* getWP1TTWString() const;
297 double getWP1Bearing() const;
298 double getWP1MagBearing() const;
299 double getWP1CourseDeviation() const;
300 double getWP1CourseErrorNm() const;
301 bool getWP1ToFlag() const;
302 bool getWP1FromFlag() const;
304 // true-bearing-error and mag-bearing-error
308 * Tied-properties helper, record nodes which are tied for easy un-tie-ing
310 template <typename T>
311 void tie(SGPropertyNode* aNode, const char* aRelPath, const SGRawValue<T>& aRawValue)
313 SGPropertyNode* nd = aNode->getNode(aRelPath, true);
314 _tiedNodes.push_back(nd);
318 /// helper, tie the lat/lon/elev of a SGGeod to the named children of aNode
319 void tieSGGeod(SGPropertyNode* aNode, SGGeod& aRef,
320 const char* lonStr, const char* latStr, const char* altStr);
322 /// helper, tie a SGGeod to proeprties, but read-only
323 void tieSGGeodReadOnly(SGPropertyNode* aNode, SGGeod& aRef,
324 const char* lonStr, const char* latStr, const char* altStr);
327 SGPropertyNode_ptr _gpsNode;
328 SGPropertyNode_ptr _magvar_node;
329 SGPropertyNode_ptr _serviceable_node;
330 SGPropertyNode_ptr _electrical_node;
331 SGPropertyNode_ptr _tracking_bug_node;
332 SGPropertyNode_ptr _raim_node;
334 SGPropertyNode_ptr _odometer_node;
335 SGPropertyNode_ptr _trip_odometer_node;
336 SGPropertyNode_ptr _true_bug_error_node;
337 SGPropertyNode_ptr _magnetic_bug_error_node;
338 SGPropertyNode_ptr _eastWestVelocity;
339 SGPropertyNode_ptr _northSouthVelocity;
341 SGPropertyNode_ptr _ref_navaid_id_node;
342 SGPropertyNode_ptr _ref_navaid_bearing_node;
343 SGPropertyNode_ptr _ref_navaid_distance_node;
344 SGPropertyNode_ptr _ref_navaid_mag_bearing_node;
345 SGPropertyNode_ptr _ref_navaid_frequency_node;
346 SGPropertyNode_ptr _ref_navaid_name_node;
348 SGPropertyNode_ptr _route_active_node;
349 SGPropertyNode_ptr _route_current_wp_node;
350 SGPropertyNode_ptr _routeDistanceNm;
351 SGPropertyNode_ptr _routeETE;
352 SGPropertyNode_ptr _routeEditedSignal;
353 SGPropertyNode_ptr _routeFinishedSignal;
354 SGPropertyNode_ptr _desiredCourseNode;
356 double _selectedCourse;
357 double _desiredCourse;
362 double _last_speed_kts;
363 double _last_true_track;
364 double _last_vertical_speed;
365 double _lastEWVelocity;
366 double _lastNSVelocity;
369 GPSListener* _listener;
371 FGRouteMgr* _routeMgr;
373 bool _ref_navaid_set;
374 double _ref_navaid_elapsed;
375 FGPositionedRef _ref_navaid;
380 SGGeodProperty _position;
381 SGGeod _wp0_position;
382 SGGeod _wp1_position;
383 SGGeod _indicated_pos;
384 std::string _wp0Ident, _wp0Name, _wp1Ident, _wp1Name;
385 double _wp1DistanceM, _wp1TrueBearing;
389 SGPropertyNode_ptr _scratchNode;
393 int _searchResultIndex;
394 std::string _searchQuery;
395 FGPositioned::Type _searchType;
397 FGPositioned::List _searchResults;
398 bool _searchIsRoute; ///< set if 'search' is actually the current route
399 bool _searchHasNext; ///< is there a result after this one?
400 bool _searchNames; ///< set if we're searching names instead of idents
403 bool _computeTurnData; ///< do we need to update the turn data?
404 bool _anticipateTurn; ///< are we anticipating the next turn or not?
405 bool _inTurn; // is a turn in progress?
406 bool _turnSequenced; // have we sequenced the new leg?
407 double _turnAngle; // angle to turn through, in degrees
408 double _turnStartBearing; // bearing of inbound leg
409 double _turnRadius; // radius of turn in nm
413 SGPropertyNode_ptr _realismSimpleGps; ///< should the GPS be simple or realistic?
415 // autopilot drive properties
416 SGPropertyNode_ptr _apDrivingFlag;
417 SGPropertyNode_ptr _apTrueHeading;
418 SGPropertyNode_ptr _apTargetAltitudeFt;
419 SGPropertyNode_ptr _apAltitudeLock;
421 std::vector<SGPropertyNode_ptr> _tiedNodes;
425 #endif // __INSTRUMENTS_GPS_HXX