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