]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/gps.hxx
GPSs uses FlightPlans directly.
[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 <Navaids/FlightPlan.hxx>
19 #include <Instrumentation/rnav_waypt_controller.hxx>
20
21
22 /**
23  * Model a GPS radio.
24  *
25  * Input properties:
26  *
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
33  * 
34  *
35  * Output properties:
36  *
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
44  *
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
56  */
57 class GPS : public SGSubsystem,
58             public flightgear::RNAV,
59             public flightgear::FlightPlan::Delegate
60 {
61 public:
62     GPS (SGPropertyNode *node, bool defaultGPSMode = false);
63     GPS ();
64     virtual ~GPS ();
65
66   // SGSubsystem interface
67     virtual void init ();
68     virtual void reinit ();
69     virtual void update (double delta_time_sec);
70
71     virtual void bind();
72     virtual void unbind();
73
74   // RNAV interface
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();
82
83 private:
84     friend class SearchFilter;
85
86     /**
87      * Configuration manager, track data relating to aircraft installation
88      */
89     class Config
90     {
91     public:
92       Config();
93
94       void bind(GPS* aOwner, SGPropertyNode* aCfg);
95
96       bool turnAnticipationEnabled() const { return _enableTurnAnticipation; }
97
98       /**
99        * Desired turn rate in degrees/second. From this we derive the turn
100        * radius and hence how early we need to anticipate it.
101        */
102       double turnRateDegSec() const        { return _turnRate; }
103
104       /**
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.
108        */
109       double overflightArmDistanceNm() const { return _overflightArmDistance; }
110
111       /**
112        * Time before the next WP to activate an external annunciator
113        */
114       double waypointAlertTime() const     { return _waypointAlertTime; }
115
116       bool requireHardSurface() const      { return _requireHardSurface; }
117
118       bool cdiDeflectionIsAngular() const  { return (_cdiMaxDeflectionNm <= 0.0); }
119
120       double cdiDeflectionLinearPeg() const
121       {
122         assert(_cdiMaxDeflectionNm > 0.0);
123         return _cdiMaxDeflectionNm;
124       }
125
126       bool driveAutopilot() const          { return _driveAutopilot; }
127
128       bool courseSelectable() const        { return _courseSelectable; }
129
130     private:
131       bool _enableTurnAnticipation;
132
133       // desired turn rate in degrees per second
134       double _turnRate;
135
136       // distance from waypoint to arm overflight sequencing (in nm)
137       double _overflightArmDistance;
138
139       // time before reaching a waypoint to trigger annunciator light/sound
140       // (in seconds)
141       double _waypointAlertTime;
142
143       // should we require a hard-surfaced runway when filtering?
144       bool _requireHardSurface;
145
146       double _cdiMaxDeflectionNm;
147
148       // should we drive the autopilot directly or not?
149       bool _driveAutopilot;
150
151       // is selected-course-deg read to set desired-course or not?
152       bool _courseSelectable;
153     };
154
155     class SearchFilter : public FGPositioned::Filter
156     {
157     public:
158       virtual bool pass(FGPositioned* aPos) const;
159
160       virtual FGPositioned::Type minType() const;
161       virtual FGPositioned::Type maxType() const;
162     };
163
164     /** reset all output properties to default / non-service values */
165     void clearOutput();
166
167     void updateBasicData(double dt);
168
169     void updateTrackingBug();
170     void updateRouteData();
171     void driveAutopilot();
172
173     void updateTurn();
174     void updateOverflight();
175     void beginTurn();
176     void endTurn();
177
178     double computeTurnProgress(double aBearing) const;
179     void computeTurnData();
180     void updateTurnData();
181     double computeTurnRadiusNm(double aGroundSpeedKts) const;
182
183     /** Update one-shot things when WP1 / leg data change */
184     void wp1Changed();
185
186     void clearScratch();
187
188     /** Predicate, determine if the lon/lat position in the scratch is
189      * valid or not. */
190     bool isScratchPositionValid() const;
191
192
193 // command handlers
194     void selectLegMode();
195     void selectOBSMode(flightgear::Waypt* waypt);
196     void directTo();
197
198 // tied-property getter/setters
199     void setCommand(const char* aCmd);
200     const char* getCommand() const { return ""; }
201
202     const char* getMode() const { return _mode.c_str(); }
203     bool getScratchValid() const { return _scratchValid; }
204
205     double getSelectedCourse() const { return _selectedCourse; }
206     void setSelectedCourse(double crs);
207     double getDesiredCourse() const { return _desiredCourse; }
208
209     double getCDIDeflection() const;
210
211     double getLegDistance() const;
212     double getLegCourse() const;
213     double getLegMagCourse() const;
214
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; }
219
220     const char* getWP0Ident() const;
221     const char* getWP0Name() const;
222
223     const char* getWP1Ident() const;
224     const char* getWP1Name() const;
225
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;
235
236     // true-bearing-error and mag-bearing-error
237
238
239     /**
240      * Tied-properties helper, record nodes which are tied for easy un-tie-ing
241      */
242     template <typename T>
243     void tie(SGPropertyNode* aNode, const char* aRelPath, const SGRawValue<T>& aRawValue)
244     {
245         _tiedProperties.Tie(aNode->getNode(aRelPath, true), aRawValue);
246     }
247
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);
251   
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);
255
256 // FlightPlan::Delegate
257     virtual void currentWaypointChanged();
258     virtual void waypointsChanged();
259     virtual void cleared();
260     virtual void endOfFlightPlan();
261     
262     void sequence();
263     void routeManagerFlightPlanChanged(SGPropertyNode*);
264     void routeActivated(SGPropertyNode*);
265     
266 // members
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;
274
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;
281     
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;
287     
288     double _selectedCourse;
289     double _desiredCourse;
290
291     bool _dataValid;
292     SGGeod _last_pos;
293     bool _lastPosValid;
294     double _last_speed_kts;
295     double _last_true_track;
296     double _last_vertical_speed;
297     double _lastEWVelocity;
298     double _lastNSVelocity;
299
300     /**
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.
306      */
307     bool _defaultGPSMode;
308     
309     std::string _mode;
310     Config _config;
311     std::string _name;
312     int _num;
313
314     SGGeod _wp0_position;
315     SGGeod _indicated_pos;
316     double _legDistanceNm;
317
318 // scratch data
319     SGGeod _scratchPos;
320     SGPropertyNode_ptr _scratchNode;
321     bool _scratchValid;
322     
323 // turn data
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
331     SGGeod _turnPt;
332     SGGeod _turnCentre;
333
334     std::auto_ptr<flightgear::WayptController> _wayptController;
335
336     flightgear::WayptRef _prevWaypt;
337     flightgear::WayptRef _currentWaypt;
338
339 // autopilot drive properties
340     SGPropertyNode_ptr _apDrivingFlag;
341     SGPropertyNode_ptr _apTrueHeading;
342     
343     simgear::TiedPropertyList _tiedProperties;
344
345     SGSharedPtr<flightgear::FlightPlan> _route;
346     
347     SGPropertyChangeCallback<GPS> _callbackFlightPlanChanged;
348     SGPropertyChangeCallback<GPS> _callbackRouteActivated;
349 };
350
351 #endif // __INSTRUMENTS_GPS_HXX