]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/tcas.hxx
Merge branch 'next' of http://git.gitorious.org/fg/flightgear into next
[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" // FGVoicePlayer 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         string callsign;
119         bool   verticalTA;
120         bool   verticalRA;
121         bool   horizontalTA;
122         bool   horizontalRA;
123         bool   isTracked;
124         float  horizontalTau;
125         float  verticalTau;
126         float  relativeAltitudeFt;
127         float  verticalFps;
128         int    RASense;
129     } ThreatInfo;
130
131     typedef struct
132     {
133         int    threatLevel;
134         double TAtimestamp;
135         double RAtimestamp;
136     } TrackerTarget;
137
138     typedef map<string,TrackerTarget*> TrackerTargets;
139
140     typedef struct
141     {
142         double lat;
143         double lon;
144         float  altFt;
145         float  heading;
146         float  velocityKt;
147         float  verticalFps;
148     } LocalInfo; /*< info structure for local aircraft */
149
150     /////////////////////////////////////////////////////////////////////////////
151     // TCAS::PropertiesHandler ///////////////////////////////////////////////
152     /////////////////////////////////////////////////////////////////////////////
153
154     class PropertiesHandler : public FGVoicePlayer::PropertiesHandler
155     {
156       TCAS *tcas;
157
158     public:
159       PropertiesHandler (TCAS *device) :
160         FGVoicePlayer::PropertiesHandler(), tcas(device) {}
161
162       PropertiesHandler (void) : FGVoicePlayer::PropertiesHandler() {}
163     };
164
165     /////////////////////////////////////////////////////////////////////////////
166     // TCAS::VoicePlayer ////////////////////////////////////////////////////////
167     /////////////////////////////////////////////////////////////////////////////
168
169     class VoicePlayer :
170         public FGVoicePlayer
171     {
172     public:
173         VoicePlayer (TCAS* tcas) :
174           FGVoicePlayer(&tcas->properties_handler, "tcas") {}
175
176         ~VoicePlayer (void) {}
177
178         void init    (void);
179
180         struct
181         {
182           Voice* pTrafficTraffic;
183           Voice* pClimb;
184           Voice* pClimbNow;
185           Voice* pClimbCrossing;
186           Voice* pClimbIncrease;
187           Voice* pDescend;
188           Voice* pDescendNow;
189           Voice* pDescendCrossing;
190           Voice* pDescendIncrease;
191           Voice* pClear;
192           Voice* pAdjustVSpeed;
193           Voice* pMaintVSpeed;
194           Voice* pMonitorVSpeed;
195           Voice* pLevelOff;
196           Voice* pTestOk;
197           Voice* pTestFail;
198         } Voices;
199     private:
200         SGPropertyNode_ptr nodeSoundFilePrefix;
201     };
202
203     /////////////////////////////////////////////////////////////////////////////
204     // TCAS::Annunciator ////////////////////////////////////////////////////////
205     /////////////////////////////////////////////////////////////////////////////
206
207     class Annunciator
208     {
209     public:
210         Annunciator    (TCAS* tcas);
211         ~Annunciator   (void) {}
212         void bind      (SGPropertyNode* node);
213         void init      (void);
214         void update    (void);
215
216         void trigger   (const ResolutionAdvisory& newAdvisory, bool revertedRA);
217         void test      (bool testOk);
218         void clear     (void);
219         bool isPlaying (void) { return voicePlayer.is_playing();}
220
221     private:
222         TCAS* tcas;
223         ResolutionAdvisory previous;
224         FGVoicePlayer::Voice* pLastVoice;
225         VoicePlayer voicePlayer;
226         SGPropertyNode_ptr nodeGpwsAlertOn;
227     };
228
229     /////////////////////////////////////////////////////////////////////////////
230     // TCAS::AdvisoryCoordinator ////////////////////////////////////////////////
231     /////////////////////////////////////////////////////////////////////////////
232
233     class AdvisoryCoordinator
234     {
235     public:
236         AdvisoryCoordinator  (TCAS* _tcas);
237         ~AdvisoryCoordinator (void) {}
238
239         void bind            (SGPropertyNode* node);
240         void init            (void);
241         void update          (int mode);
242
243         void clear           (void);
244         void add             (const ResolutionAdvisory& newAdvisory);
245
246     private:
247         TCAS* tcas;
248         double lastTATime;
249         ResolutionAdvisory current;
250         ResolutionAdvisory previous;
251         SGPropertyNode_ptr nodeTAWarning;
252     };
253
254     /////////////////////////////////////////////////////////////////////////////
255     // TCAS::Tracker ////////////////////////////////////////////////////////////
256     /////////////////////////////////////////////////////////////////////////////
257
258     class Tracker
259     {
260     public:
261         Tracker  (TCAS* _tcas);
262         ~Tracker (void) {}
263
264         void update          (void);
265
266         void add             (const string callsign, int detectedLevel);
267         bool active          (void) { return haveTargets;}
268         bool newTraffic      (void) { return newTargets;}
269         bool isTracked       (string callsign) { if (!haveTargets) return false;else return _isTracked(callsign);}
270         bool _isTracked      (string callsign);
271         int  getThreatLevel  (string callsign);
272
273     private:
274         TCAS*  tcas;
275         double currentTime;
276         bool   haveTargets;
277         bool   newTargets;
278         TrackerTargets targets;
279     };
280     
281     /////////////////////////////////////////////////////////////////////////////
282     // TCAS::AdvisoryGenerator //////////////////////////////////////////////////
283     /////////////////////////////////////////////////////////////////////////////
284
285     class AdvisoryGenerator
286     {
287     public:
288         AdvisoryGenerator        (TCAS* _tcas);
289         ~AdvisoryGenerator       (void) {}
290
291         void init                (const LocalInfo* _pSelf, ThreatInfo* _pCurrentThreat);
292
293         void setAlarmThresholds  (const SensitivityLevel* _pAlarmThresholds);
294
295         int   resolution         (int mode, int threatLevel, float distanceNm,
296                                   float altFt, float heading, float velocityKt);
297
298     private:
299         float verticalSeparation (float newVerticalFps);
300         void  determineRAsense   (int& RASense, bool& isCrossing);
301
302     private:
303         TCAS*             tcas;
304         const LocalInfo*  pSelf;          /*< info structure for local aircraft */
305         ThreatInfo* pCurrentThreat; /*< info structure on current intruder/threat */
306         const SensitivityLevel* pAlarmThresholds;
307     };
308
309     /////////////////////////////////////////////////////////////////////////////
310     // TCAS::ThreatDetector /////////////////////////////////////////////////////
311     /////////////////////////////////////////////////////////////////////////////
312
313     class ThreatDetector
314     {
315     public:
316         ThreatDetector            (TCAS* _tcas);
317         ~ThreatDetector           (void) {}
318
319         void  init                (void);
320         void  update              (void);
321
322         bool  checkTransponder    (const SGPropertyNode* pModel, float velocityKt);
323         int   checkThreat         (int mode, const SGPropertyNode* pModel);
324         void  checkVerticalThreat (void);
325         void  horizontalThreat    (float bearing, float distanceNm, float heading,
326                                    float velocityKt);
327
328         void  setAlt              (float altFt) { self.altFt = altFt;}
329         float getAlt              (void)        { return self.altFt;}
330         float getVelocityKt       (void)        { return self.velocityKt;}
331         int   getRASense          (void)        { return currentThreat.RASense;}
332
333     private:
334         void  unitTest            (void);
335
336     private:
337         static const SensitivityLevel sensitivityLevels[];
338
339         TCAS*              tcas;
340         int                checkCount;
341
342         SGPropertyNode_ptr nodeLat;
343         SGPropertyNode_ptr nodeLon;
344         SGPropertyNode_ptr nodeAlt;
345         SGPropertyNode_ptr nodeHeading;
346         SGPropertyNode_ptr nodeVelocity;
347         SGPropertyNode_ptr nodeVerticalFps;
348
349         LocalInfo          self;          /*< info structure for local aircraft */
350         ThreatInfo         currentThreat; /*< info structure on current intruder/threat */
351         const SensitivityLevel* pAlarmThresholds;
352     };
353
354 private:
355     string              name;
356     int                 num;
357     double              nextUpdateTime;
358     int                 selfTestStep;
359
360     SGPropertyNode_ptr  nodeModeSwitch;
361     SGPropertyNode_ptr  nodeServiceable;
362     SGPropertyNode_ptr  nodeSelfTest;
363     SGPropertyNode_ptr  nodeDebugTrigger;
364     SGPropertyNode_ptr  nodeDebugRA;
365     SGPropertyNode_ptr  nodeDebugThreat;
366
367     PropertiesHandler   properties_handler;
368     ThreatDetector      threatDetector;
369     Tracker             tracker;
370     AdvisoryCoordinator advisoryCoordinator;
371     AdvisoryGenerator   advisoryGenerator;
372     Annunciator         annunciator;
373
374 private:
375     void selfTest       (void);
376
377 public:
378     TCAS (SGPropertyNode* node);
379
380     virtual void bind   (void);
381     virtual void unbind (void);
382     virtual void init   (void);
383     virtual void update (double dt);
384 };
385
386 #ifdef _MSC_VER
387 #  pragma warning( pop )
388 #endif
389
390 #endif // __INSTRUMENTS_TCAS_HXX