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
13 #include <simgear/props/props.hxx>
14 #include <simgear/structure/subsystem_mgr.hxx>
15 #include <simgear/props/tiedpropertylist.hxx>
17 #include <Navaids/positioned.hxx>
18 #include <Navaids/FlightPlan.hxx>
19 #include <Instrumentation/rnav_waypt_controller.hxx>
27 * /position/longitude-deg
28 * /position/latitude-deg
29 * /position/altitude-ft
30 * /environment/magnetic-variation-deg
31 * /systems/electrical/outputs/gps
32 * /instrumentation/gps/serviceable
37 * /instrumentation/gps/indicated-longitude-deg
38 * /instrumentation/gps/indicated-latitude-deg
39 * /instrumentation/gps/indicated-altitude-ft
40 * /instrumentation/gps/indicated-vertical-speed-fpm
41 * /instrumentation/gps/indicated-track-true-deg
42 * /instrumentation/gps/indicated-track-magnetic-deg
43 * /instrumentation/gps/indicated-ground-speed-kt
45 * /instrumentation/gps/wp-distance-nm
46 * /instrumentation/gps/wp-bearing-deg
47 * /instrumentation/gps/wp-bearing-mag-deg
48 * /instrumentation/gps/TTW
49 * /instrumentation/gps/course-deviation-deg
50 * /instrumentation/gps/course-error-nm
51 * /instrumentation/gps/to-flag
52 * /instrumentation/gps/odometer
53 * /instrumentation/gps/trip-odometer
54 * /instrumentation/gps/true-bug-error-deg
55 * /instrumentation/gps/magnetic-bug-error-deg
57 class GPS : public SGSubsystem,
58 public flightgear::RNAV,
59 public flightgear::FlightPlan::Delegate
62 GPS (SGPropertyNode *node, bool defaultGPSMode = false);
66 // SGSubsystem interface
68 virtual void reinit ();
69 virtual void update (double delta_time_sec);
72 virtual void unbind();
75 virtual SGGeod position();
76 virtual double trackDeg();
77 virtual double groundSpeedKts();
78 virtual double vspeedFPM();
79 virtual double magvarDeg();
80 virtual double selectedMagCourse();
81 virtual double overflightArmDistanceM();
84 friend class SearchFilter;
87 * Configuration manager, track data relating to aircraft installation
94 void bind(GPS* aOwner, SGPropertyNode* aCfg);
96 bool turnAnticipationEnabled() const { return _enableTurnAnticipation; }
99 * Desired turn rate in degrees/second. From this we derive the turn
100 * radius and hence how early we need to anticipate it.
102 double turnRateDegSec() const { return _turnRate; }
105 * Distance at which we arm overflight sequencing. Once inside this
106 * distance, a change of the wp1 'TO' flag to false will be considered
107 * overlight of the wp.
109 double overflightArmDistanceNm() const { return _overflightArmDistance; }
112 * Time before the next WP to activate an external annunciator
114 double waypointAlertTime() const { return _waypointAlertTime; }
116 bool requireHardSurface() const { return _requireHardSurface; }
118 bool cdiDeflectionIsAngular() const { return (_cdiMaxDeflectionNm <= 0.0); }
120 double cdiDeflectionLinearPeg() const
122 assert(_cdiMaxDeflectionNm > 0.0);
123 return _cdiMaxDeflectionNm;
126 bool driveAutopilot() const { return _driveAutopilot; }
128 bool courseSelectable() const { return _courseSelectable; }
131 bool _enableTurnAnticipation;
133 // desired turn rate in degrees per second
136 // distance from waypoint to arm overflight sequencing (in nm)
137 double _overflightArmDistance;
139 // time before reaching a waypoint to trigger annunciator light/sound
141 double _waypointAlertTime;
143 // should we require a hard-surfaced runway when filtering?
144 bool _requireHardSurface;
146 double _cdiMaxDeflectionNm;
148 // should we drive the autopilot directly or not?
149 bool _driveAutopilot;
151 // is selected-course-deg read to set desired-course or not?
152 bool _courseSelectable;
155 class SearchFilter : public FGPositioned::Filter
158 virtual bool pass(FGPositioned* aPos) const;
160 virtual FGPositioned::Type minType() const;
161 virtual FGPositioned::Type maxType() const;
164 /** reset all output properties to default / non-service values */
167 void updateBasicData(double dt);
169 void updateTrackingBug();
170 void updateRouteData();
171 void driveAutopilot();
174 void updateOverflight();
178 double computeTurnProgress(double aBearing) const;
179 void computeTurnData();
180 void updateTurnData();
181 double computeTurnRadiusNm(double aGroundSpeedKts) const;
183 /** Update one-shot things when WP1 / leg data change */
188 /** Predicate, determine if the lon/lat position in the scratch is
190 bool isScratchPositionValid() const;
194 void selectLegMode();
195 void selectOBSMode(flightgear::Waypt* waypt);
198 // tied-property getter/setters
199 void setCommand(const char* aCmd);
200 const char* getCommand() const { return ""; }
202 const char* getMode() const { return _mode.c_str(); }
203 bool getScratchValid() const { return _scratchValid; }
205 double getSelectedCourse() const { return _selectedCourse; }
206 void setSelectedCourse(double crs);
207 double getDesiredCourse() const { return _desiredCourse; }
209 double getCDIDeflection() const;
211 double getLegDistance() const;
212 double getLegCourse() const;
213 double getLegMagCourse() const;
215 double getTrueTrack() const { return _last_true_track; }
216 double getMagTrack() const;
217 double getGroundspeedKts() const { return _last_speed_kts; }
218 double getVerticalSpeed() const { return _last_vertical_speed; }
220 const char* getWP0Ident() const;
221 const char* getWP0Name() const;
223 const char* getWP1Ident() const;
224 const char* getWP1Name() const;
226 double getWP1Distance() const;
227 double getWP1TTW() const;
228 const char* getWP1TTWString() const;
229 double getWP1Bearing() const;
230 double getWP1MagBearing() const;
231 double getWP1CourseDeviation() const;
232 double getWP1CourseErrorNm() const;
233 bool getWP1ToFlag() const;
234 bool getWP1FromFlag() const;
236 // true-bearing-error and mag-bearing-error
240 * Tied-properties helper, record nodes which are tied for easy un-tie-ing
242 template <typename T>
243 void tie(SGPropertyNode* aNode, const char* aRelPath, const SGRawValue<T>& aRawValue)
245 _tiedProperties.Tie(aNode->getNode(aRelPath, true), aRawValue);
248 /** helper, tie the lat/lon/elev of a SGGeod to the named children of aNode */
249 void tieSGGeod(SGPropertyNode* aNode, SGGeod& aRef,
250 const char* lonStr, const char* latStr, const char* altStr);
252 /** helper, tie a SGGeod to proeprties, but read-only */
253 void tieSGGeodReadOnly(SGPropertyNode* aNode, SGGeod& aRef,
254 const char* lonStr, const char* latStr, const char* altStr);
256 // FlightPlan::Delegate
257 virtual void currentWaypointChanged();
258 virtual void waypointsChanged();
259 virtual void cleared();
260 virtual void endOfFlightPlan();
263 void routeManagerFlightPlanChanged(SGPropertyNode*);
264 void routeActivated(SGPropertyNode*);
267 SGPropertyNode_ptr _gpsNode;
268 SGPropertyNode_ptr _currentWayptNode;
269 SGPropertyNode_ptr _magvar_node;
270 SGPropertyNode_ptr _serviceable_node;
271 SGPropertyNode_ptr _electrical_node;
272 SGPropertyNode_ptr _tracking_bug_node;
273 SGPropertyNode_ptr _raim_node;
275 SGPropertyNode_ptr _odometer_node;
276 SGPropertyNode_ptr _trip_odometer_node;
277 SGPropertyNode_ptr _true_bug_error_node;
278 SGPropertyNode_ptr _magnetic_bug_error_node;
279 SGPropertyNode_ptr _eastWestVelocity;
280 SGPropertyNode_ptr _northSouthVelocity;
282 // SGPropertyNode_ptr _route_active_node;
283 SGPropertyNode_ptr _route_current_wp_node;
284 SGPropertyNode_ptr _routeDistanceNm;
285 SGPropertyNode_ptr _routeETE;
286 SGPropertyNode_ptr _desiredCourseNode;
288 double _selectedCourse;
289 double _desiredCourse;
294 double _last_speed_kts;
295 double _last_true_track;
296 double _last_vertical_speed;
297 double _lastEWVelocity;
298 double _lastNSVelocity;
301 * the instrument manager creates a default instance of us,
302 * if no explicit GPS is specific in the aircraft's instruments.xml file.
303 * This allows default route-following to work with the generic autopilot.
304 * This flat is set in that case, to inform us we're a 'fake' installation,
305 * and not to worry about electrical power or similar.
307 bool _defaultGPSMode;
314 SGGeod _wp0_position;
315 SGGeod _indicated_pos;
316 double _legDistanceNm;
320 SGPropertyNode_ptr _scratchNode;
324 bool _computeTurnData; ///< do we need to update the turn data?
325 bool _anticipateTurn; ///< are we anticipating the next turn or not?
326 bool _inTurn; // is a turn in progress?
327 bool _turnSequenced; // have we sequenced the new leg?
328 double _turnAngle; // angle to turn through, in degrees
329 double _turnStartBearing; // bearing of inbound leg
330 double _turnRadius; // radius of turn in nm
334 std::auto_ptr<flightgear::WayptController> _wayptController;
336 flightgear::WayptRef _prevWaypt;
337 flightgear::WayptRef _currentWaypt;
339 // autopilot drive properties
340 SGPropertyNode_ptr _apDrivingFlag;
341 SGPropertyNode_ptr _apTrueHeading;
343 simgear::TiedPropertyList _tiedProperties;
345 SGSharedPtr<flightgear::FlightPlan> _route;
347 SGPropertyChangeCallback<GPS> _callbackFlightPlanChanged;
348 SGPropertyChangeCallback<GPS> _callbackRouteActivated;
351 #endif // __INSTRUMENTS_GPS_HXX