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 <Instrumentation/rnav_waypt_controller.hxx>
31 * /position/longitude-deg
32 * /position/latitude-deg
33 * /position/altitude-ft
34 * /environment/magnetic-variation-deg
35 * /systems/electrical/outputs/gps
36 * /instrumentation/gps/serviceable
41 * /instrumentation/gps/indicated-longitude-deg
42 * /instrumentation/gps/indicated-latitude-deg
43 * /instrumentation/gps/indicated-altitude-ft
44 * /instrumentation/gps/indicated-vertical-speed-fpm
45 * /instrumentation/gps/indicated-track-true-deg
46 * /instrumentation/gps/indicated-track-magnetic-deg
47 * /instrumentation/gps/indicated-ground-speed-kt
49 * /instrumentation/gps/wp-distance-nm
50 * /instrumentation/gps/wp-bearing-deg
51 * /instrumentation/gps/wp-bearing-mag-deg
52 * /instrumentation/gps/TTW
53 * /instrumentation/gps/course-deviation-deg
54 * /instrumentation/gps/course-error-nm
55 * /instrumentation/gps/to-flag
56 * /instrumentation/gps/odometer
57 * /instrumentation/gps/trip-odometer
58 * /instrumentation/gps/true-bug-error-deg
59 * /instrumentation/gps/magnetic-bug-error-deg
61 class GPS : public SGSubsystem, public flightgear::RNAV
64 GPS (SGPropertyNode *node);
68 // SGSubsystem interface
70 virtual void reinit ();
71 virtual void update (double delta_time_sec);
74 virtual void unbind();
77 virtual SGGeod position();
78 virtual double trackDeg();
79 virtual double groundSpeedKts();
80 virtual double vspeedFPM();
81 virtual double magvarDeg();
82 virtual double selectedMagCourse();
83 virtual double overflightArmDistanceM();
86 friend class GPSListener;
87 friend class SearchFilter;
90 * Configuration manager, track data relating to aircraft installation
97 void bind(GPS* aOwner, SGPropertyNode* aCfg);
99 bool turnAnticipationEnabled() const { return _enableTurnAnticipation; }
102 * Desired turn rate in degrees/second. From this we derive the turn
103 * radius and hence how early we need to anticipate it.
105 double turnRateDegSec() const { return _turnRate; }
108 * Distance at which we arm overflight sequencing. Once inside this
109 * distance, a change of the wp1 'TO' flag to false will be considered
110 * overlight of the wp.
112 double overflightArmDistanceNm() const { return _overflightArmDistance; }
115 * Time before the next WP to activate an external annunciator
117 double waypointAlertTime() const { return _waypointAlertTime; }
119 bool requireHardSurface() const { return _requireHardSurface; }
121 bool cdiDeflectionIsAngular() const { return (_cdiMaxDeflectionNm <= 0.0); }
123 double cdiDeflectionLinearPeg() const
125 assert(_cdiMaxDeflectionNm > 0.0);
126 return _cdiMaxDeflectionNm;
129 bool driveAutopilot() const { return _driveAutopilot; }
131 bool courseSelectable() const { return _courseSelectable; }
134 bool _enableTurnAnticipation;
136 // desired turn rate in degrees per second
139 // distance from waypoint to arm overflight sequencing (in nm)
140 double _overflightArmDistance;
142 // time before reaching a waypoint to trigger annunciator light/sound
144 double _waypointAlertTime;
146 // minimum runway length to require when filtering
147 double _minRunwayLengthFt;
149 // should we require a hard-surfaced runway when filtering?
150 bool _requireHardSurface;
152 double _cdiMaxDeflectionNm;
154 // should we drive the autopilot directly or not?
155 bool _driveAutopilot;
157 // is selected-course-deg read to set desired-course or not?
158 bool _courseSelectable;
161 class SearchFilter : public FGPositioned::Filter
164 virtual bool pass(FGPositioned* aPos) const;
166 virtual FGPositioned::Type minType() const;
167 virtual FGPositioned::Type maxType() const;
170 /** reset all output properties to default / non-service values */
173 void updateBasicData(double dt);
175 void updateTrackingBug();
176 void updateReferenceNavaid(double dt);
177 void referenceNavaidSet(const std::string& aNavaid);
178 void updateRouteData();
179 void driveAutopilot();
181 void routeActivated();
182 void routeManagerSequenced();
184 void routeFinished();
187 void updateOverflight();
191 double computeTurnProgress(double aBearing) const;
192 void computeTurnData();
193 void updateTurnData();
194 double computeTurnRadiusNm(double aGroundSpeedKts) const;
196 /** Update one-shot things when WP1 / leg data change */
199 // scratch maintenance utilities
200 void setScratchFromPositioned(FGPositioned* aPos, int aIndex);
201 void setScratchFromCachedSearchResult();
202 void setScratchFromRouteWaypoint(int aIndex);
204 /** Add airport-specific information to a scratch result */
205 void addAirportToScratch(FGAirport* aAirport);
209 /** Predicate, determine if the lon/lat position in the scratch is
211 bool isScratchPositionValid() const;
213 FGPositioned::Filter* createFilter(FGPositioned::Type aTy);
215 /** Search kernel - called each time we step through a result */
216 void performSearch();
219 void selectLegMode();
220 void selectOBSMode();
222 void loadRouteWaypoint();
226 void previousResult();
227 void defineWaypoint();
228 void insertWaypointAtIndex(int aIndex);
229 void removeWaypointAtIndex(int aIndex);
231 // tied-property getter/setters
232 void setCommand(const char* aCmd);
233 const char* getCommand() const { return ""; }
235 const char* getMode() const { return _mode.c_str(); }
237 bool getScratchValid() const { return _scratchValid; }
238 double getScratchDistance() const;
239 double getScratchMagBearing() const;
240 double getScratchTrueBearing() const;
241 bool getScratchHasNext() const;
243 double getSelectedCourse() const { return _selectedCourse; }
244 void setSelectedCourse(double crs);
245 double getDesiredCourse() const { return _desiredCourse; }
247 double getCDIDeflection() const;
249 double getLegDistance() const;
250 double getLegCourse() const;
251 double getLegMagCourse() const;
253 double getTrueTrack() const { return _last_true_track; }
254 double getMagTrack() const;
255 double getGroundspeedKts() const { return _last_speed_kts; }
256 double getVerticalSpeed() const { return _last_vertical_speed; }
258 //bool getLegMode() const { return _mode == "leg"; }
259 //bool getObsMode() const { return _mode == "obs"; }
261 const char* getWP0Ident() const;
262 const char* getWP0Name() const;
264 const char* getWP1Ident() const;
265 const char* getWP1Name() const;
267 double getWP1Distance() const;
268 double getWP1TTW() const;
269 const char* getWP1TTWString() const;
270 double getWP1Bearing() const;
271 double getWP1MagBearing() const;
272 double getWP1CourseDeviation() const;
273 double getWP1CourseErrorNm() const;
274 bool getWP1ToFlag() const;
275 bool getWP1FromFlag() const;
277 // true-bearing-error and mag-bearing-error
281 * Tied-properties helper, record nodes which are tied for easy un-tie-ing
283 template <typename T>
284 void tie(SGPropertyNode* aNode, const char* aRelPath, const SGRawValue<T>& aRawValue)
286 _tiedProperties.Tie(aNode->getNode(aRelPath, true), aRawValue);
289 /** helper, tie the lat/lon/elev of a SGGeod to the named children of aNode */
290 void tieSGGeod(SGPropertyNode* aNode, SGGeod& aRef,
291 const char* lonStr, const char* latStr, const char* altStr);
293 /** helper, tie a SGGeod to proeprties, but read-only */
294 void tieSGGeodReadOnly(SGPropertyNode* aNode, SGGeod& aRef,
295 const char* lonStr, const char* latStr, const char* altStr);
298 SGPropertyNode_ptr _gpsNode;
299 SGPropertyNode_ptr _currentWayptNode;
300 SGPropertyNode_ptr _magvar_node;
301 SGPropertyNode_ptr _serviceable_node;
302 SGPropertyNode_ptr _electrical_node;
303 SGPropertyNode_ptr _tracking_bug_node;
304 SGPropertyNode_ptr _raim_node;
306 SGPropertyNode_ptr _odometer_node;
307 SGPropertyNode_ptr _trip_odometer_node;
308 SGPropertyNode_ptr _true_bug_error_node;
309 SGPropertyNode_ptr _magnetic_bug_error_node;
310 SGPropertyNode_ptr _eastWestVelocity;
311 SGPropertyNode_ptr _northSouthVelocity;
313 SGPropertyNode_ptr _ref_navaid_id_node;
314 SGPropertyNode_ptr _ref_navaid_bearing_node;
315 SGPropertyNode_ptr _ref_navaid_distance_node;
316 SGPropertyNode_ptr _ref_navaid_mag_bearing_node;
317 SGPropertyNode_ptr _ref_navaid_frequency_node;
318 SGPropertyNode_ptr _ref_navaid_name_node;
320 SGPropertyNode_ptr _route_active_node;
321 SGPropertyNode_ptr _route_current_wp_node;
322 SGPropertyNode_ptr _routeDistanceNm;
323 SGPropertyNode_ptr _routeETE;
324 SGPropertyNode_ptr _routeEditedSignal;
325 SGPropertyNode_ptr _routeFinishedSignal;
326 SGPropertyNode_ptr _desiredCourseNode;
328 double _selectedCourse;
329 double _desiredCourse;
334 double _last_speed_kts;
335 double _last_true_track;
336 double _last_vertical_speed;
337 double _lastEWVelocity;
338 double _lastNSVelocity;
341 GPSListener* _listener;
343 FGRouteMgr* _routeMgr;
345 bool _ref_navaid_set;
346 double _ref_navaid_elapsed;
347 FGPositionedRef _ref_navaid;
352 SGGeod _wp0_position;
353 SGGeod _indicated_pos;
354 double _legDistanceNm;
358 SGPropertyNode_ptr _scratchNode;
362 int _searchResultIndex;
363 std::string _searchQuery;
364 FGPositioned::Type _searchType;
366 FGPositioned::List _searchResults;
367 bool _searchIsRoute; ///< set if 'search' is actually the current route
368 bool _searchHasNext; ///< is there a result after this one?
369 bool _searchNames; ///< set if we're searching names instead of idents
372 bool _computeTurnData; ///< do we need to update the turn data?
373 bool _anticipateTurn; ///< are we anticipating the next turn or not?
374 bool _inTurn; // is a turn in progress?
375 bool _turnSequenced; // have we sequenced the new leg?
376 double _turnAngle; // angle to turn through, in degrees
377 double _turnStartBearing; // bearing of inbound leg
378 double _turnRadius; // radius of turn in nm
382 std::auto_ptr<flightgear::WayptController> _wayptController;
384 SGPropertyNode_ptr _realismSimpleGps; ///< should the GPS be simple or realistic?
385 flightgear::WayptRef _prevWaypt;
386 flightgear::WayptRef _currentWaypt;
388 // autopilot drive properties
389 SGPropertyNode_ptr _apDrivingFlag;
390 SGPropertyNode_ptr _apTrueHeading;
391 SGPropertyNode_ptr _apTargetAltitudeFt;
392 SGPropertyNode_ptr _apAltitudeLock;
394 simgear::TiedPropertyList _tiedProperties;
398 #endif // __INSTRUMENTS_GPS_HXX