FlightGear next
tcas.hxx
Go to the documentation of this file.
1/*
2 * SPDX-License-Identifier: GPL-2.0+
3 * SPDX-FileCopyrightText: 2010 (C) Thorsten Brehm - brehmt (at) gmail com
4 *
5 * tcas.hxx -- Traffic Alert and Collision Avoidance System (TCAS)
6 * Written by Thorsten Brehm, started December 2010.
7 *
8 * Copyright (C) 2010 Thorsten Brehm - brehmt (at) gmail com
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of the
13 * License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23*/
24
25#pragma once
26
27#include <assert.h>
28
29#include <vector>
30#include <deque>
31#include <map>
32
33#include <simgear/props/props.hxx>
34#include <simgear/structure/subsystem_mgr.hxx>
35#include <Sound/voiceplayer.hxx>
36
37class SGSampleGroup;
38
39#include <Main/globals.hxx>
40
41#ifdef _MSC_VER
42# pragma warning( push )
43# pragma warning( disable: 4355 )
44#endif
45
47// TCAS //////////////////////////////////////////////////////////////////////
49
50class TCAS : public SGSubsystem
51{
52 typedef enum
53 {
54 AdvisoryClear = 0, /*< Clear of traffic */
55 AdvisoryIntrusion = 1, /*< Intrusion flag */
56 AdvisoryClimb = AdvisoryIntrusion|(1 << 1), /*< RA climb */
57 AdvisoryDescend = AdvisoryIntrusion|(1 << 2), /*< RA descend */
58 AdvisoryAdjustVSpeed = AdvisoryIntrusion|(1 << 3), /*< RA adjust vertical speed (TCAS II 7.0 only) */
59 AdvisoryMaintVSpeed = AdvisoryIntrusion|(1 << 4), /*< RA maintain vertical speed */
60 AdvisoryMonitorVSpeed = AdvisoryIntrusion|(1 << 5), /*< RA monitor vertical speed */
61 AdvisoryLevelOff = AdvisoryIntrusion|(1 << 6) /*< RA level off (TCAS II 7.1 only) */
62 } EnumAdvisory;
63
64 typedef enum
65 {
66 OptionNone = 0, /*< no option modifier */
67 OptionIncreaseClimb = (1 << 0), /*< increase climb */
68 OptionIncreaseDescend = (1 << 1), /*< increase descend */
69 OptionCrossingClimb = (1 << 2), /*< crossing climb */
70 OptionCrossingDescent = (1 << 3) /*< crossing descent */
71 } EnumAdvisoryOption;
72
73 typedef enum
74 {
75 SwitchOff = 0, /*< TCAS switched off */
76 SwitchStandby = 1, /*< TCAS standby (no TA/RA) */
77 SwitchTaOnly = 2, /*< TCAS in TA-only mode (no RA) */
78 SwitchAuto = 3 /*< TCAS in TA/RA mode */
79 } EnumModeSwitch;
80
81 typedef enum
82 {
83 ThreatInvisible = -1,/*< Traffic is invisible to TCAS (i.e. no transponder) */
84 ThreatNone = 0, /*< Traffic is visible but no threat. */
85 ThreatProximity = 1, /*< Proximity intruder traffic (no threat). */
86 ThreatTA = 2, /*< TA-level threat traffic. */
87 ThreatRA = 3 /*< RA-level threat traffic. */
88 } EnumThreatLevel;
89
90 typedef struct
91 {
92 int threatLevel; /*< intruder threat level: 0=clear, 1=proximity,
93 2=intruder, 3=proximity intruder */
94 int RA; /*< resolution advisory */
95 int RAOption; /*< option flags for advisory */
96 } ResolutionAdvisory;
97
98 typedef struct
99 {
100 float Tau; /*< vertical/horizontal protection range in seconds */
101 float DMOD; /*< horizontal protection range in nm */
102 float ALIM; /*< vertical protection range in ft */
103 } Thresholds;
104
105 typedef struct
106 {
107 double maxAltitude; /*< max altitude for this sensitivity level */
108 int sl; /*< sensitivity level */
109 Thresholds TA; /*< thresholds for TA-level threats */
110 Thresholds RA; /*< thresholds for RA-level threats */
111 } SensitivityLevel;
112
113 typedef struct
114 {
115 std::string callsign;
116 bool verticalTA;
117 bool verticalRA;
118 bool horizontalTA;
119 bool horizontalRA;
120 bool isTracked;
121 float horizontalTau;
122 float verticalTau;
123 float relativeAltitudeFt;
124 float verticalFps;
125 int RASense;
126 } ThreatInfo;
127
128 typedef struct
129 {
130 int threatLevel;
131 double TAtimestamp;
132 double RAtimestamp;
133 } TrackerTarget;
134
135 typedef std::map<std::string,TrackerTarget*> TrackerTargets;
136
137 typedef struct
138 {
139 double lat;
140 double lon;
141 float pressureAltFt;
142 float radarAltFt;
143 float heading;
144 float velocityKt;
145 float verticalFps;
146 } LocalInfo; /*< info structure for local aircraft */
147
149 // TCAS::PropertiesHandler ///////////////////////////////////////////////
151
152 class PropertiesHandler : public FGVoicePlayer::PropertiesHandler
153 {
154 public:
155 PropertiesHandler (TCAS *) :
157
158 PropertiesHandler (void) : FGVoicePlayer::PropertiesHandler() {}
159 };
160
162 // TCAS::VoicePlayer ////////////////////////////////////////////////////////
164
165 class VoicePlayer :
166 public FGVoicePlayer
167 {
168 public:
169 VoicePlayer (TCAS* tcas) :
170 FGVoicePlayer(&tcas->properties_handler, "tcas") {}
171
172 ~VoicePlayer (void) {}
173
174 void init (void);
175
176 struct
177 {
178 Voice* pTrafficTraffic;
179 Voice* pClimb;
180 Voice* pClimbNow;
181 Voice* pClimbCrossing;
182 Voice* pClimbIncrease;
183 Voice* pDescend;
184 Voice* pDescendNow;
185 Voice* pDescendCrossing;
186 Voice* pDescendIncrease;
187 Voice* pClear;
188 Voice* pAdjustVSpeed;
189 Voice* pMaintVSpeed;
190 Voice* pMonitorVSpeed;
191 Voice* pLevelOff;
192 Voice* pTestOk;
193 Voice* pTestFail;
194 } Voices;
195 private:
196 SGPropertyNode_ptr nodeSoundFilePrefix;
197 };
198
200 // TCAS::Annunciator ////////////////////////////////////////////////////////
202
203 class Annunciator
204 {
205 public:
206 Annunciator (TCAS* tcas);
207 ~Annunciator (void) {}
208 void bind (SGPropertyNode* node);
209 void init (void);
210 void update (void);
211
212 void trigger (const ResolutionAdvisory& newAdvisory, bool revertedRA);
213 void test (bool testOk);
214 void clear (void);
215 bool isPlaying (void) { return voicePlayer.is_playing();}
216
217 private:
218 TCAS* tcas;
219 ResolutionAdvisory previous;
220 FGVoicePlayer::Voice* pLastVoice;
221 VoicePlayer voicePlayer;
222 SGPropertyNode_ptr nodeGpwsAlertOn;
223 };
224
226 // TCAS::AdvisoryCoordinator ////////////////////////////////////////////////
228
229 class AdvisoryCoordinator
230 {
231 public:
232 AdvisoryCoordinator (TCAS* _tcas);
233 ~AdvisoryCoordinator (void) {}
234
235 void bind (SGPropertyNode* node);
236 void init (void);
237 void reinit (void);
238 void update (int mode);
239
240 void clear (void);
241 void add (const ResolutionAdvisory& newAdvisory);
242
243 private:
244 TCAS* tcas;
245 double lastTATime;
246 ResolutionAdvisory current;
247 ResolutionAdvisory previous;
248 SGPropertyNode_ptr nodeTAWarning;
249 };
250
252 // TCAS::Tracker ////////////////////////////////////////////////////////////
254
255 class Tracker
256 {
257 public:
258 Tracker (TCAS* _tcas);
259 ~Tracker (void) {}
260
261 void update (void);
262
263 void add (const std::string callsign, int detectedLevel);
264 bool active (void) { return haveTargets;}
265 bool newTraffic (void) { return newTargets;}
266 bool isTracked (std::string callsign) { if (!haveTargets) return false;else return _isTracked(callsign);}
267 bool _isTracked (std::string callsign);
268 int getThreatLevel (std::string callsign);
269
270 private:
271 double currentTime;
272 bool haveTargets;
273 bool newTargets;
274 TrackerTargets targets;
275 };
276
278 // TCAS::AdvisoryGenerator //////////////////////////////////////////////////
280
281 class AdvisoryGenerator
282 {
283 public:
284 AdvisoryGenerator (TCAS* _tcas);
285 ~AdvisoryGenerator (void) {}
286
287 void init (const LocalInfo* _pSelf, ThreatInfo* _pCurrentThreat);
288
289 void setAlarmThresholds (const SensitivityLevel* _pAlarmThresholds);
290
291 int resolution (int mode, int threatLevel, float distanceNm,
292 float altFt, float heading, float velocityKt);
293
294 private:
295 float verticalSeparation (float newVerticalFps);
296 void determineRAsense (int& RASense, bool& isCrossing);
297
298 private:
299 TCAS* tcas;
300 const LocalInfo* pSelf; /*< info structure for local aircraft */
301 ThreatInfo* pCurrentThreat; /*< info structure on current intruder/threat */
302 const SensitivityLevel* pAlarmThresholds;
303 };
304
306 // TCAS::ThreatDetector /////////////////////////////////////////////////////
308
309 class ThreatDetector
310 {
311 public:
312 ThreatDetector (TCAS* _tcas);
313 ~ThreatDetector (void) {}
314
315 void init (void);
316 void update (void);
317
318 bool checkTransponder (const SGPropertyNode* pModel, float velocityKt);
319 int checkThreat (int mode, const SGPropertyNode* pModel);
320 void checkVerticalThreat (void);
321 void horizontalThreat (float bearing, float distanceNm, float heading,
322 float velocityKt);
323
324 void setPressureAlt (float altFt) { self.pressureAltFt = altFt;}
325 float getPressureAlt (void) { return self.pressureAltFt;}
326
327 void setRadarAlt (float altFt) { self.radarAltFt = altFt;}
328 float getRadarAlt (void) { return self.radarAltFt;}
329
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#ifdef FEATURE_TCAS_DEBUG_THREAT_DETECTOR
341 int checkCount;
342#endif // of FEATURE_TCAS_DEBUG_THREAT_DETECTOR
343
344 SGPropertyNode_ptr nodeLat;
345 SGPropertyNode_ptr nodeLon;
346 SGPropertyNode_ptr nodePressureAlt;
347 SGPropertyNode_ptr nodeRadarAlt;
348 SGPropertyNode_ptr nodeHeading;
349 SGPropertyNode_ptr nodeVelocity;
350 SGPropertyNode_ptr nodeVerticalFps;
351
352 LocalInfo self; /*< info structure for local aircraft */
353 ThreatInfo currentThreat; /*< info structure on current intruder/threat */
354 const SensitivityLevel* pAlarmThresholds;
355 };
356
357private:
358 std::string name;
359 int num;
360 double nextUpdateTime;
361 int selfTestStep;
362
363 SGPropertyNode_ptr nodeModeSwitch;
364 SGPropertyNode_ptr nodeServiceable;
365 SGPropertyNode_ptr nodeSelfTest;
366 SGPropertyNode_ptr nodeDebugTrigger;
367 SGPropertyNode_ptr nodeDebugRA;
368 SGPropertyNode_ptr nodeDebugThreat;
369
370 PropertiesHandler properties_handler;
371 ThreatDetector threatDetector;
372 Tracker tracker;
373 AdvisoryCoordinator advisoryCoordinator;
374 AdvisoryGenerator advisoryGenerator;
375 Annunciator annunciator;
376
377private:
378 void selfTest (void);
379
380public:
381 TCAS (SGPropertyNode* node);
382
383 // Subsystem API.
384 void bind() override;
385 void init() override;
386 void reinit() override;
387 void unbind() override;
388 void update(double dt) override;
389
390 // Subsystem identification.
391 static const char* staticSubsystemClassId() { return "tcas"; }
392
393 /* configuration options */
405};
406
407#ifdef _MSC_VER
408# pragma warning( pop )
409#endif
FGVoicePlayer(PropertiesHandler *properties_handler, std::string _dev_name)
int _proxLatRange
Definition tcas.hxx:397
int _intruderInhbSelfAlt
Definition tcas.hxx:404
void update(double dt) override
Monitor traffic for safety threats.
Definition tcas.cxx:1283
int _RAInhbAlt
Definition tcas.hxx:400
int _intruderInhbAlt
Definition tcas.hxx:402
int _incDesInhbAlt
Definition tcas.hxx:398
void unbind() override
Definition tcas.cxx:1276
int _verticalRange
Definition tcas.hxx:394
void reinit() override
Definition tcas.cxx:1239
TCAS(SGPropertyNode *node)
Definition tcas.cxx:1161
void bind() override
Definition tcas.cxx:1246
int _proxVertRange
Definition tcas.hxx:396
void init() override
Definition tcas.cxx:1231
int _TAInhbAlt
Definition tcas.hxx:401
static const char * staticSubsystemClassId()
Definition tcas.hxx:391
int _lateralRange
Definition tcas.hxx:395
bool _intruderInhbSelfAltToggle
Definition tcas.hxx:403
int _DesInhbAlt
Definition tcas.hxx:399
static void clear(FGReplayInternal &self)