]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/tcas.hxx
6882c83175f3a4a34b8bca0e7bda7563d3091ef9
[flightgear.git] / src / Instrumentation / tcas.hxx
1 // tcas.hxx -- Traffic Alert and Collision Avoidance System (TCAS)
2 //
3 // Written by Thorsten Brehm, started December 2010.
4 //
5 // Copyright (C) 2010 Thorsten Brehm - brehmt (at) gmail com
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 #ifndef __INSTRUMENTS_TCAS_HXX
22 #define __INSTRUMENTS_TCAS_HXX
23
24 #include <assert.h>
25
26 #include <vector>
27 #include <deque>
28 #include <map>
29
30 #include <simgear/props/props.hxx>
31 #include <simgear/sound/sample_openal.hxx>
32 #include <simgear/structure/subsystem_mgr.hxx>
33 #include "mk_viii.hxx" // voiceplayer only
34
35 using std::vector;
36 using std::deque;
37 using std::map;
38
39 class SGSampleGroup;
40
41 #include <Main/globals.hxx>
42
43 #ifdef _MSC_VER
44 #  pragma warning( push )
45 #  pragma warning( disable: 4355 )
46 #endif
47
48 ///////////////////////////////////////////////////////////////////////////////
49 // TCAS  //////////////////////////////////////////////////////////////////////
50 ///////////////////////////////////////////////////////////////////////////////
51
52 class TCAS : public SGSubsystem
53 {
54
55     typedef enum
56     {
57         AdvisoryClear         = 0,                          /*< Clear of traffic */
58         AdvisoryIntrusion     = 1,                          /*< Intrusion flag */
59         AdvisoryClimb         = AdvisoryIntrusion|(1 << 1), /*< RA climb */
60         AdvisoryDescend       = AdvisoryIntrusion|(1 << 2), /*< RA descend */
61         AdvisoryAdjustVSpeed  = AdvisoryIntrusion|(1 << 3), /*< RA adjust vertical speed (TCAS II 7.0 only) */
62         AdvisoryMaintVSpeed   = AdvisoryIntrusion|(1 << 4), /*< RA maintain vertical speed */
63         AdvisoryMonitorVSpeed = AdvisoryIntrusion|(1 << 5), /*< RA monitor vertical speed */
64         AdvisoryLevelOff      = AdvisoryIntrusion|(1 << 6)  /*< RA level off (TCAS II 7.1 only) */
65     } EnumAdvisory;
66
67     typedef enum
68     {
69         OptionNone            = 0,        /*< no option modifier */
70         OptionIncreaseClimb   = (1 << 0), /*< increase climb */
71         OptionIncreaseDescend = (1 << 1), /*< increase descend */
72         OptionCrossingClimb   = (1 << 2), /*< crossing climb */
73         OptionCrossingDescent = (1 << 3)  /*< crossing descent */
74     } EnumAdvisoryOption;
75
76     typedef enum
77     {
78         SwitchOff        = 0, /*< TCAS switched off */
79         SwitchStandby    = 1, /*< TCAS standby (no TA/RA) */
80         SwitchTaOnly     = 2, /*< TCAS in TA-only mode (no RA) */
81         SwitchAuto       = 3  /*< TCAS in TA/RA mode */
82     } EnumModeSwitch;
83
84     typedef enum
85     {
86         ThreatInvisible    = -1,/*< Traffic is invisible to TCAS (i.e. no transponder) */
87         ThreatNone         = 0, /*< Traffic is visible but no threat. */
88         ThreatProximity    = 1, /*< Proximity intruder traffic (no threat). */
89         ThreatTA           = 2, /*< TA-level threat traffic. */
90         ThreatRA           = 3  /*< RA-level threat traffic. */
91     } EnumThreatLevel;
92
93     typedef struct
94     {
95       int  threatLevel;  /*< intruder threat level: 0=clear, 1=proximity,
96                              2=intruder, 3=proximity intruder */
97       int  RA;           /*< resolution advisory */
98       int  RAOption;     /*< option flags for advisory */
99     } ResolutionAdvisory;
100
101     typedef struct
102     {
103         float Tau;       /*< vertical/horizontal protection range in seconds */ 
104         float DMOD;      /*< horizontal protection range in nm */
105         float ALIM;      /*< vertical protection range in ft */
106     } Thresholds;
107
108     typedef struct
109     {
110         double    maxAltitude; /*< max altitude for this sensitivity level */
111         int        sl;         /*< sensitivity level */
112         Thresholds TA;         /*< thresholds for TA-level threats */
113         Thresholds RA;         /*< thresholds for RA-level threats */
114     } SensitivityLevel;
115
116     typedef struct
117     {
118         bool  verticalTA;
119         bool  verticalRA;
120         bool  horizontalTA;
121         bool  horizontalRA;
122         float horizontalTau;
123         float verticalTau;
124         float relativeAltitudeFt;
125         float verticalFps;
126     } ThreatInfo;
127
128     typedef struct
129     {
130         double lat;
131         double lon;
132         float  altFt;
133         float  heading;
134         float  velocityKt;
135         float  verticalFps;
136     } LocalInfo; /*< info structure for local aircraft */
137
138 //    /////////////////////////////////////////////////////////////////////////////
139 //    // TCAS::Timer //////////////////////////////////////////////////////////////
140 //    /////////////////////////////////////////////////////////////////////////////
141 //
142 //    class Timer
143 //    {
144 //        double start_time;
145 //
146 //    public:
147 //        bool   running;
148 //
149 //        inline Timer ()
150 //          : running(false) {}
151 //
152 //        inline void start () { running = true; start_time = globals->get_sim_time_sec(); }
153 //        inline void stop ()  { running = false; }
154 //        inline double elapsed () const { assert(running); return globals->get_sim_time_sec() - start_time; }
155 //        inline double start_or_elapsed ()
156 //        {
157 //            if (running)
158 //                return elapsed();
159 //            else
160 //            {
161 //                start();
162 //                return 0;
163 //            }
164 //        }
165 //    };
166
167     /////////////////////////////////////////////////////////////////////////////
168     // TCAS::PropertiesHandler ///////////////////////////////////////////////
169     /////////////////////////////////////////////////////////////////////////////
170
171     class PropertiesHandler : public FGVoicePlayer::PropertiesHandler
172     {
173       TCAS *tcas;
174
175     public:
176       PropertiesHandler (TCAS *device) :
177         FGVoicePlayer::PropertiesHandler(), tcas(device) {}
178
179       PropertiesHandler (void) : FGVoicePlayer::PropertiesHandler() {}
180     };
181
182     /////////////////////////////////////////////////////////////////////////////
183     // TCAS::VoicePlayer ////////////////////////////////////////////////////////
184     /////////////////////////////////////////////////////////////////////////////
185
186     class VoicePlayer :
187         public FGVoicePlayer
188     {
189     public:
190         VoicePlayer (TCAS* tcas) :
191           FGVoicePlayer(&tcas->properties_handler, "tcas") {}
192
193         ~VoicePlayer (void) {}
194
195         void init    (void);
196
197         struct
198         {
199           Voice* pTrafficTraffic;
200           Voice* pClimb;
201           Voice* pClimbNow;
202           Voice* pClimbCrossing;
203           Voice* pClimbIncrease;
204           Voice* pDescend;
205           Voice* pDescendNow;
206           Voice* pDescendCrossing;
207           Voice* pDescendIncrease;
208           Voice* pClear;
209           Voice* pAdjustVSpeed;
210           Voice* pMaintVSpeed;
211           Voice* pMonitorVSpeed;
212           Voice* pLevelOff;
213           Voice* pTestOk;
214           Voice* pTestFail;
215         } Voices;
216     private:
217         SGPropertyNode_ptr nodeSoundFilePrefix;
218     };
219
220     /////////////////////////////////////////////////////////////////////////////
221     // TCAS::Annunciator ////////////////////////////////////////////////////////
222     /////////////////////////////////////////////////////////////////////////////
223
224     class Annunciator
225     {
226     public:
227         Annunciator    (TCAS* tcas);
228         ~Annunciator   (void) {}
229         void bind      (SGPropertyNode* node);
230         void init      (void);
231         void update    (void);
232
233         void trigger   (const ResolutionAdvisory& newAdvisory, bool revertedRA);
234         void test      (bool testOk);
235         void clear     (void);
236         bool isPlaying (void) { return voicePlayer.is_playing();}
237
238     private:
239         ResolutionAdvisory previous;
240         FGVoicePlayer::Voice* pLastVoice;
241         VoicePlayer voicePlayer;
242         SGPropertyNode_ptr nodeGpwsAlertOn;
243     };
244
245     /////////////////////////////////////////////////////////////////////////////
246     // TCAS::AdvisoryCoordinator ////////////////////////////////////////////////
247     /////////////////////////////////////////////////////////////////////////////
248
249     class AdvisoryCoordinator
250     {
251     public:
252         AdvisoryCoordinator  (TCAS* _tcas);
253         ~AdvisoryCoordinator (void) {}
254
255         void bind            (SGPropertyNode* node);
256         void init            (void);
257         void update          (int mode);
258
259         void clear           (void);
260         void add             (const ResolutionAdvisory& newAdvisory);
261
262     private:
263         TCAS* tcas;
264         double lastTATime;
265         ResolutionAdvisory current;
266         ResolutionAdvisory previous;
267         SGPropertyNode_ptr nodeTAWarning;
268     };
269
270     /////////////////////////////////////////////////////////////////////////////
271     // TCAS::AdvisoryGenerator //////////////////////////////////////////////////
272     /////////////////////////////////////////////////////////////////////////////
273
274     class AdvisoryGenerator
275     {
276     public:
277         AdvisoryGenerator        (TCAS* _tcas);
278         ~AdvisoryGenerator       (void) {}
279
280         void init                (const LocalInfo* _pSelf, const ThreatInfo* _pCurrentThreat);
281
282         void setAlarmThresholds  (const SensitivityLevel* _pAlarmThresholds);
283
284         int   resolution         (int mode, int threatLevel, float distanceNm,
285                                   float altFt, float heading, float velocityKt);
286
287     private:
288         float verticalSeparation (float newVerticalFps);
289         void  determineRAsense   (int& RASense, bool& isCrossing);
290
291     private:
292         TCAS*             tcas;
293         const LocalInfo*  pSelf;          /*< info structure for local aircraft */
294         const ThreatInfo* pCurrentThreat; /*< info structure on current intruder/threat */
295         const SensitivityLevel* pAlarmThresholds;
296     };
297
298     /////////////////////////////////////////////////////////////////////////////
299     // TCAS::ThreatDetector /////////////////////////////////////////////////////
300     /////////////////////////////////////////////////////////////////////////////
301
302     class ThreatDetector
303     {
304     public:
305         ThreatDetector            (TCAS* _tcas);
306         ~ThreatDetector           (void) {}
307
308         void  init                (void);
309         void  update              (void);
310
311         bool  checkTransponder    (const SGPropertyNode* pModel, float velocityKt);
312         int   checkThreat         (int mode, const SGPropertyNode* pModel);
313         void  checkVerticalThreat (void);
314         void  horizontalThreat    (float bearing, float distanceNm, float heading,
315                                    float velocityKt);
316
317         void  setAlt              (float altFt) { self.altFt = altFt;}
318         float getAlt              (void)        { return self.altFt;}
319         float getVelocityKt       (void)        { return self.velocityKt;}
320
321     private:
322         void  unitTest            (void);
323
324     private:
325         static const SensitivityLevel sensitivityLevels[];
326
327         TCAS*              tcas;
328         int                checkCount;
329
330         SGPropertyNode_ptr nodeLat;
331         SGPropertyNode_ptr nodeLon;
332         SGPropertyNode_ptr nodeAlt;
333         SGPropertyNode_ptr nodeHeading;
334         SGPropertyNode_ptr nodeVelocity;
335         SGPropertyNode_ptr nodeVerticalFps;
336
337         LocalInfo          self;          /*< info structure for local aircraft */
338         ThreatInfo         currentThreat; /*< info structure on current intruder/threat */
339         const SensitivityLevel* pAlarmThresholds;
340     };
341
342 private:
343     string              name;
344     int                 num;
345     double              nextUpdateTime;
346     int                 selfTestStep;
347
348     SGPropertyNode_ptr  nodeModeSwitch;
349     SGPropertyNode_ptr  nodeServiceable;
350     SGPropertyNode_ptr  nodeSelfTest;
351     SGPropertyNode_ptr  nodeDebugTrigger;
352     SGPropertyNode_ptr  nodeDebugRA;
353     SGPropertyNode_ptr  nodeDebugThreat;
354
355     PropertiesHandler   properties_handler;
356     ThreatDetector      threatDetector;
357     AdvisoryCoordinator advisoryCoordinator;
358     AdvisoryGenerator   advisoryGenerator;
359     Annunciator         annunciator;
360
361 private:
362     void selfTest       (void);
363
364 public:
365     TCAS (SGPropertyNode* node);
366
367     virtual void bind   (void);
368     virtual void unbind (void);
369     virtual void init   (void);
370     virtual void update (double dt);
371 };
372
373 #ifdef _MSC_VER
374 #  pragma warning( pop )
375 #endif
376
377 #endif // __INSTRUMENTS_TCAS_HXX