]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/gps.hxx
Clean up/simplify NasalPositioned_cppbind
[flightgear.git] / src / Instrumentation / gps.hxx
1 // gps.hxx - distance-measuring equipment.
2 // Written by David Megginson, started 2003.
3 //
4 // This file is in the Public Domain and comes with no warranty.
5
6
7 #ifndef __INSTRUMENTS_GPS_HXX
8 #define __INSTRUMENTS_GPS_HXX 1
9
10 #include <cassert>
11 #include <memory>
12
13 #include <simgear/props/props.hxx>
14 #include <simgear/structure/subsystem_mgr.hxx>
15 #include <simgear/props/tiedpropertylist.hxx>
16
17 #include <Navaids/positioned.hxx>
18 #include <Instrumentation/rnav_waypt_controller.hxx>
19
20 // forward decls
21 class SGRoute;
22 class FGRouteMgr;
23 class GPSListener;
24
25 /**
26  * Model a GPS radio.
27  *
28  * Input properties:
29  *
30  * /position/longitude-deg
31  * /position/latitude-deg
32  * /position/altitude-ft
33  * /environment/magnetic-variation-deg
34  * /systems/electrical/outputs/gps
35  * /instrumentation/gps/serviceable
36  * 
37  *
38  * Output properties:
39  *
40  * /instrumentation/gps/indicated-longitude-deg
41  * /instrumentation/gps/indicated-latitude-deg
42  * /instrumentation/gps/indicated-altitude-ft
43  * /instrumentation/gps/indicated-vertical-speed-fpm
44  * /instrumentation/gps/indicated-track-true-deg
45  * /instrumentation/gps/indicated-track-magnetic-deg
46  * /instrumentation/gps/indicated-ground-speed-kt
47  *
48  * /instrumentation/gps/wp-distance-nm
49  * /instrumentation/gps/wp-bearing-deg
50  * /instrumentation/gps/wp-bearing-mag-deg
51  * /instrumentation/gps/TTW
52  * /instrumentation/gps/course-deviation-deg
53  * /instrumentation/gps/course-error-nm
54  * /instrumentation/gps/to-flag
55  * /instrumentation/gps/odometer
56  * /instrumentation/gps/trip-odometer
57  * /instrumentation/gps/true-bug-error-deg
58  * /instrumentation/gps/magnetic-bug-error-deg
59  */
60 class GPS : public SGSubsystem, public flightgear::RNAV
61 {
62 public:
63     GPS (SGPropertyNode *node);
64     GPS ();
65     virtual ~GPS ();
66
67   // SGSubsystem interface
68     virtual void init ();
69     virtual void reinit ();
70     virtual void update (double delta_time_sec);
71
72     virtual void bind();
73     virtual void unbind();
74
75   // RNAV interface
76     virtual SGGeod position();
77     virtual double trackDeg();
78     virtual double groundSpeedKts();
79     virtual double vspeedFPM();
80     virtual double magvarDeg();
81     virtual double selectedMagCourse();
82     virtual double overflightArmDistanceM();
83
84 private:
85     friend class GPSListener;
86     friend class SearchFilter;
87
88     /**
89      * Configuration manager, track data relating to aircraft installation
90      */
91     class Config
92     {
93     public:
94       Config();
95
96       void bind(GPS* aOwner, SGPropertyNode* aCfg);
97
98       bool turnAnticipationEnabled() const { return _enableTurnAnticipation; }
99
100       /**
101        * Desired turn rate in degrees/second. From this we derive the turn
102        * radius and hence how early we need to anticipate it.
103        */
104       double turnRateDegSec() const        { return _turnRate; }
105
106       /**
107        * Distance at which we arm overflight sequencing. Once inside this
108        * distance, a change of the wp1 'TO' flag to false will be considered
109        * overlight of the wp.
110        */
111       double overflightArmDistanceNm() const { return _overflightArmDistance; }
112
113       /**
114        * Time before the next WP to activate an external annunciator
115        */
116       double waypointAlertTime() const     { return _waypointAlertTime; }
117
118       bool requireHardSurface() const      { return _requireHardSurface; }
119
120       bool cdiDeflectionIsAngular() const  { return (_cdiMaxDeflectionNm <= 0.0); }
121
122       double cdiDeflectionLinearPeg() const
123       {
124         assert(_cdiMaxDeflectionNm > 0.0);
125         return _cdiMaxDeflectionNm;
126       }
127
128       bool driveAutopilot() const          { return _driveAutopilot; }
129
130       bool courseSelectable() const        { return _courseSelectable; }
131
132     private:
133       bool _enableTurnAnticipation;
134
135       // desired turn rate in degrees per second
136       double _turnRate;
137
138       // distance from waypoint to arm overflight sequencing (in nm)
139       double _overflightArmDistance;
140
141       // time before reaching a waypoint to trigger annunciator light/sound
142       // (in seconds)
143       double _waypointAlertTime;
144
145       // minimum runway length to require when filtering
146       double _minRunwayLengthFt;
147
148       // should we require a hard-surfaced runway when filtering?
149       bool _requireHardSurface;
150
151       double _cdiMaxDeflectionNm;
152
153       // should we drive the autopilot directly or not?
154       bool _driveAutopilot;
155
156       // is selected-course-deg read to set desired-course or not?
157       bool _courseSelectable;
158     };
159
160     class SearchFilter : public FGPositioned::Filter
161     {
162     public:
163       virtual bool pass(FGPositioned* aPos) const;
164
165       virtual FGPositioned::Type minType() const;
166       virtual FGPositioned::Type maxType() const;
167     };
168
169     /** reset all output properties to default / non-service values */
170     void clearOutput();
171
172     void updateBasicData(double dt);
173
174     void updateTrackingBug();
175     void updateReferenceNavaid(double dt);
176     void referenceNavaidSet(const std::string& aNavaid);
177     void updateRouteData();
178     void driveAutopilot();
179     
180     void routeActivated();
181     void routeManagerSequenced();
182     void routeEdited();
183     void routeFinished();
184
185     void updateTurn();
186     void updateOverflight();
187     void beginTurn();
188     void endTurn();
189
190     double computeTurnProgress(double aBearing) const;
191     void computeTurnData();
192     void updateTurnData();
193     double computeTurnRadiusNm(double aGroundSpeedKts) const;
194
195     /** Update one-shot things when WP1 / leg data change */
196     void wp1Changed();
197
198 // scratch maintenance utilities
199     void setScratchFromPositioned(FGPositioned* aPos, int aIndex);
200     void setScratchFromCachedSearchResult();
201     void setScratchFromRouteWaypoint(int aIndex);
202
203     /** Add airport-specific information to a scratch result */
204     void addAirportToScratch(FGAirport* aAirport);
205   
206     void clearScratch();
207
208     /** Predicate, determine if the lon/lat position in the scratch is
209      * valid or not. */
210     bool isScratchPositionValid() const;
211
212     FGPositioned::Filter* createFilter(FGPositioned::Type aTy);
213   
214    /** Search kernel - called each time we step through a result */
215     void performSearch();
216
217 // command handlers
218     void selectLegMode();
219     void selectOBSMode();
220     void directTo();
221     void loadRouteWaypoint();
222     void loadNearest();
223     void search();
224     void nextResult();
225     void previousResult();
226     void defineWaypoint();
227     void insertWaypointAtIndex(int aIndex);
228     void removeWaypointAtIndex(int aIndex);
229
230 // tied-property getter/setters
231     void setCommand(const char* aCmd);
232     const char* getCommand() const { return ""; }
233
234     const char* getMode() const { return _mode.c_str(); }
235
236     bool getScratchValid() const { return _scratchValid; }
237     double getScratchDistance() const;
238     double getScratchMagBearing() const;
239     double getScratchTrueBearing() const;
240     bool getScratchHasNext() const;
241
242     double getSelectedCourse() const { return _selectedCourse; }
243     void setSelectedCourse(double crs);
244     double getDesiredCourse() const { return _desiredCourse; }
245
246     double getCDIDeflection() const;
247
248     double getLegDistance() const;
249     double getLegCourse() const;
250     double getLegMagCourse() const;
251
252     double getTrueTrack() const { return _last_true_track; }
253     double getMagTrack() const;
254     double getGroundspeedKts() const { return _last_speed_kts; }
255     double getVerticalSpeed() const { return _last_vertical_speed; }
256
257     //bool getLegMode() const { return _mode == "leg"; }
258     //bool getObsMode() const { return _mode == "obs"; }
259
260     const char* getWP0Ident() const;
261     const char* getWP0Name() const;
262
263     const char* getWP1Ident() const;
264     const char* getWP1Name() const;
265
266     double getWP1Distance() const;
267     double getWP1TTW() const;
268     const char* getWP1TTWString() const;
269     double getWP1Bearing() const;
270     double getWP1MagBearing() const;
271     double getWP1CourseDeviation() const;
272     double getWP1CourseErrorNm() const;
273     bool getWP1ToFlag() const;
274     bool getWP1FromFlag() const;
275
276     // true-bearing-error and mag-bearing-error
277
278
279     /**
280      * Tied-properties helper, record nodes which are tied for easy un-tie-ing
281      */
282     template <typename T>
283     void tie(SGPropertyNode* aNode, const char* aRelPath, const SGRawValue<T>& aRawValue)
284     {
285         _tiedProperties.Tie(aNode->getNode(aRelPath, true), aRawValue);
286     }
287
288     /** helper, tie the lat/lon/elev of a SGGeod to the named children of aNode */
289     void tieSGGeod(SGPropertyNode* aNode, SGGeod& aRef,
290                    const char* lonStr, const char* latStr, const char* altStr);
291   
292     /** helper, tie a SGGeod to proeprties, but read-only */
293     void tieSGGeodReadOnly(SGPropertyNode* aNode, SGGeod& aRef,
294                            const char* lonStr, const char* latStr, const char* altStr);
295
296 // members
297     SGPropertyNode_ptr _gpsNode;
298     SGPropertyNode_ptr _currentWayptNode;
299     SGPropertyNode_ptr _magvar_node;
300     SGPropertyNode_ptr _serviceable_node;
301     SGPropertyNode_ptr _electrical_node;
302     SGPropertyNode_ptr _tracking_bug_node;
303     SGPropertyNode_ptr _raim_node;
304
305     SGPropertyNode_ptr _odometer_node;
306     SGPropertyNode_ptr _trip_odometer_node;
307     SGPropertyNode_ptr _true_bug_error_node;
308     SGPropertyNode_ptr _magnetic_bug_error_node;
309     SGPropertyNode_ptr _eastWestVelocity;
310     SGPropertyNode_ptr _northSouthVelocity;
311
312     SGPropertyNode_ptr _ref_navaid_id_node;
313     SGPropertyNode_ptr _ref_navaid_bearing_node;
314     SGPropertyNode_ptr _ref_navaid_distance_node;
315     SGPropertyNode_ptr _ref_navaid_mag_bearing_node;
316     SGPropertyNode_ptr _ref_navaid_frequency_node;
317     SGPropertyNode_ptr _ref_navaid_name_node;
318
319     SGPropertyNode_ptr _route_active_node;
320     SGPropertyNode_ptr _route_current_wp_node;
321     SGPropertyNode_ptr _routeDistanceNm;
322     SGPropertyNode_ptr _routeETE;
323     SGPropertyNode_ptr _routeEditedSignal;
324     SGPropertyNode_ptr _routeFinishedSignal;
325     SGPropertyNode_ptr _desiredCourseNode;
326
327     double _selectedCourse;
328     double _desiredCourse;
329
330     bool _dataValid;
331     SGGeod _last_pos;
332     bool _lastPosValid;
333     double _last_speed_kts;
334     double _last_true_track;
335     double _last_vertical_speed;
336     double _lastEWVelocity;
337     double _lastNSVelocity;
338
339     std::string _mode;
340     GPSListener* _listener;
341     Config _config;
342     FGRouteMgr* _routeMgr;
343
344     bool _ref_navaid_set;
345     double _ref_navaid_elapsed;
346     FGPositionedRef _ref_navaid;
347
348     std::string _name;
349     int _num;
350
351     SGGeod _wp0_position;
352     SGGeod _indicated_pos;
353     double _legDistanceNm;
354
355 // scratch data
356     SGGeod _scratchPos;
357     SGPropertyNode_ptr _scratchNode;
358     bool _scratchValid;
359
360 // search data
361     int _searchResultIndex;
362     std::string _searchQuery;
363     FGPositioned::Type _searchType;
364     bool _searchExact;
365     FGPositionedList _searchResults;
366     bool _searchIsRoute; ///< set if 'search' is actually the current route
367     bool _searchHasNext; ///< is there a result after this one?
368     bool _searchNames; ///< set if we're searching names instead of idents
369
370 // turn data
371     bool _computeTurnData; ///< do we need to update the turn data?
372     bool _anticipateTurn; ///< are we anticipating the next turn or not?
373     bool _inTurn; // is a turn in progress?
374     bool _turnSequenced; // have we sequenced the new leg?
375     double _turnAngle; // angle to turn through, in degrees
376     double _turnStartBearing; // bearing of inbound leg
377     double _turnRadius; // radius of turn in nm
378     SGGeod _turnPt;
379     SGGeod _turnCentre;
380
381     std::auto_ptr<flightgear::WayptController> _wayptController;
382
383     SGPropertyNode_ptr _realismSimpleGps; ///< should the GPS be simple or realistic?
384     flightgear::WayptRef _prevWaypt;
385     flightgear::WayptRef _currentWaypt;
386
387 // autopilot drive properties
388     SGPropertyNode_ptr _apDrivingFlag;
389     SGPropertyNode_ptr _apTrueHeading;
390     SGPropertyNode_ptr _apTargetAltitudeFt;
391     SGPropertyNode_ptr _apAltitudeLock;
392
393     simgear::TiedPropertyList _tiedProperties;
394
395 };
396
397 #endif // __INSTRUMENTS_GPS_HXX