1 // tcas.hxx -- Traffic Alert and Collision Avoidance System (TCAS)
3 // Written by Thorsten Brehm, started December 2010.
5 // Copyright (C) 2010 Thorsten Brehm - brehmt (at) gmail com
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.
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.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
21 #ifndef __INSTRUMENTS_TCAS_HXX
22 #define __INSTRUMENTS_TCAS_HXX
30 #include <simgear/props/props.hxx>
31 #include <simgear/structure/subsystem_mgr.hxx>
32 #include <Sound/voiceplayer.hxx>
40 #include <Main/globals.hxx>
43 # pragma warning( push )
44 # pragma warning( disable: 4355 )
47 ///////////////////////////////////////////////////////////////////////////////
48 // TCAS //////////////////////////////////////////////////////////////////////
49 ///////////////////////////////////////////////////////////////////////////////
51 class TCAS : public SGSubsystem
56 AdvisoryClear = 0, /*< Clear of traffic */
57 AdvisoryIntrusion = 1, /*< Intrusion flag */
58 AdvisoryClimb = AdvisoryIntrusion|(1 << 1), /*< RA climb */
59 AdvisoryDescend = AdvisoryIntrusion|(1 << 2), /*< RA descend */
60 AdvisoryAdjustVSpeed = AdvisoryIntrusion|(1 << 3), /*< RA adjust vertical speed (TCAS II 7.0 only) */
61 AdvisoryMaintVSpeed = AdvisoryIntrusion|(1 << 4), /*< RA maintain vertical speed */
62 AdvisoryMonitorVSpeed = AdvisoryIntrusion|(1 << 5), /*< RA monitor vertical speed */
63 AdvisoryLevelOff = AdvisoryIntrusion|(1 << 6) /*< RA level off (TCAS II 7.1 only) */
68 OptionNone = 0, /*< no option modifier */
69 OptionIncreaseClimb = (1 << 0), /*< increase climb */
70 OptionIncreaseDescend = (1 << 1), /*< increase descend */
71 OptionCrossingClimb = (1 << 2), /*< crossing climb */
72 OptionCrossingDescent = (1 << 3) /*< crossing descent */
77 SwitchOff = 0, /*< TCAS switched off */
78 SwitchStandby = 1, /*< TCAS standby (no TA/RA) */
79 SwitchTaOnly = 2, /*< TCAS in TA-only mode (no RA) */
80 SwitchAuto = 3 /*< TCAS in TA/RA mode */
85 ThreatInvisible = -1,/*< Traffic is invisible to TCAS (i.e. no transponder) */
86 ThreatNone = 0, /*< Traffic is visible but no threat. */
87 ThreatProximity = 1, /*< Proximity intruder traffic (no threat). */
88 ThreatTA = 2, /*< TA-level threat traffic. */
89 ThreatRA = 3 /*< RA-level threat traffic. */
94 int threatLevel; /*< intruder threat level: 0=clear, 1=proximity,
95 2=intruder, 3=proximity intruder */
96 int RA; /*< resolution advisory */
97 int RAOption; /*< option flags for advisory */
102 float Tau; /*< vertical/horizontal protection range in seconds */
103 float DMOD; /*< horizontal protection range in nm */
104 float ALIM; /*< vertical protection range in ft */
109 double maxAltitude; /*< max altitude for this sensitivity level */
110 int sl; /*< sensitivity level */
111 Thresholds TA; /*< thresholds for TA-level threats */
112 Thresholds RA; /*< thresholds for RA-level threats */
117 std::string callsign;
125 float relativeAltitudeFt;
137 typedef map<std::string,TrackerTarget*> TrackerTargets;
148 } LocalInfo; /*< info structure for local aircraft */
150 /////////////////////////////////////////////////////////////////////////////
151 // TCAS::PropertiesHandler ///////////////////////////////////////////////
152 /////////////////////////////////////////////////////////////////////////////
154 class PropertiesHandler : public FGVoicePlayer::PropertiesHandler
157 PropertiesHandler (TCAS *) :
158 FGVoicePlayer::PropertiesHandler() {}
160 PropertiesHandler (void) : FGVoicePlayer::PropertiesHandler() {}
163 /////////////////////////////////////////////////////////////////////////////
164 // TCAS::VoicePlayer ////////////////////////////////////////////////////////
165 /////////////////////////////////////////////////////////////////////////////
171 VoicePlayer (TCAS* tcas) :
172 FGVoicePlayer(&tcas->properties_handler, "tcas") {}
174 ~VoicePlayer (void) {}
180 Voice* pTrafficTraffic;
183 Voice* pClimbCrossing;
184 Voice* pClimbIncrease;
187 Voice* pDescendCrossing;
188 Voice* pDescendIncrease;
190 Voice* pAdjustVSpeed;
192 Voice* pMonitorVSpeed;
198 SGPropertyNode_ptr nodeSoundFilePrefix;
201 /////////////////////////////////////////////////////////////////////////////
202 // TCAS::Annunciator ////////////////////////////////////////////////////////
203 /////////////////////////////////////////////////////////////////////////////
208 Annunciator (TCAS* tcas);
209 ~Annunciator (void) {}
210 void bind (SGPropertyNode* node);
214 void trigger (const ResolutionAdvisory& newAdvisory, bool revertedRA);
215 void test (bool testOk);
217 bool isPlaying (void) { return voicePlayer.is_playing();}
221 ResolutionAdvisory previous;
222 FGVoicePlayer::Voice* pLastVoice;
223 VoicePlayer voicePlayer;
224 SGPropertyNode_ptr nodeGpwsAlertOn;
227 /////////////////////////////////////////////////////////////////////////////
228 // TCAS::AdvisoryCoordinator ////////////////////////////////////////////////
229 /////////////////////////////////////////////////////////////////////////////
231 class AdvisoryCoordinator
234 AdvisoryCoordinator (TCAS* _tcas);
235 ~AdvisoryCoordinator (void) {}
237 void bind (SGPropertyNode* node);
240 void update (int mode);
243 void add (const ResolutionAdvisory& newAdvisory);
248 ResolutionAdvisory current;
249 ResolutionAdvisory previous;
250 SGPropertyNode_ptr nodeTAWarning;
253 /////////////////////////////////////////////////////////////////////////////
254 // TCAS::Tracker ////////////////////////////////////////////////////////////
255 /////////////////////////////////////////////////////////////////////////////
260 Tracker (TCAS* _tcas);
265 void add (const std::string callsign, int detectedLevel);
266 bool active (void) { return haveTargets;}
267 bool newTraffic (void) { return newTargets;}
268 bool isTracked (std::string callsign) { if (!haveTargets) return false;else return _isTracked(callsign);}
269 bool _isTracked (std::string callsign);
270 int getThreatLevel (std::string callsign);
276 TrackerTargets targets;
279 /////////////////////////////////////////////////////////////////////////////
280 // TCAS::AdvisoryGenerator //////////////////////////////////////////////////
281 /////////////////////////////////////////////////////////////////////////////
283 class AdvisoryGenerator
286 AdvisoryGenerator (TCAS* _tcas);
287 ~AdvisoryGenerator (void) {}
289 void init (const LocalInfo* _pSelf, ThreatInfo* _pCurrentThreat);
291 void setAlarmThresholds (const SensitivityLevel* _pAlarmThresholds);
293 int resolution (int mode, int threatLevel, float distanceNm,
294 float altFt, float heading, float velocityKt);
297 float verticalSeparation (float newVerticalFps);
298 void determineRAsense (int& RASense, bool& isCrossing);
302 const LocalInfo* pSelf; /*< info structure for local aircraft */
303 ThreatInfo* pCurrentThreat; /*< info structure on current intruder/threat */
304 const SensitivityLevel* pAlarmThresholds;
307 /////////////////////////////////////////////////////////////////////////////
308 // TCAS::ThreatDetector /////////////////////////////////////////////////////
309 /////////////////////////////////////////////////////////////////////////////
314 ThreatDetector (TCAS* _tcas);
315 ~ThreatDetector (void) {}
320 bool checkTransponder (const SGPropertyNode* pModel, float velocityKt);
321 int checkThreat (int mode, const SGPropertyNode* pModel);
322 void checkVerticalThreat (void);
323 void horizontalThreat (float bearing, float distanceNm, float heading,
326 void setPressureAlt (float altFt) { self.pressureAltFt = altFt;}
327 float getPressureAlt (void) { return self.pressureAltFt;}
329 void setRadarAlt (float altFt) { self.radarAltFt = altFt;}
330 float getRadarAlt (void) { return self.radarAltFt;}
332 float getVelocityKt (void) { return self.velocityKt;}
333 int getRASense (void) { return currentThreat.RASense;}
336 void unitTest (void);
339 static const SensitivityLevel sensitivityLevels[];
342 #ifdef FEATURE_TCAS_DEBUG_THREAT_DETECTOR
344 #endif // of FEATURE_TCAS_DEBUG_THREAT_DETECTOR
346 SGPropertyNode_ptr nodeLat;
347 SGPropertyNode_ptr nodeLon;
348 SGPropertyNode_ptr nodePressureAlt;
349 SGPropertyNode_ptr nodeRadarAlt;
350 SGPropertyNode_ptr nodeHeading;
351 SGPropertyNode_ptr nodeVelocity;
352 SGPropertyNode_ptr nodeVerticalFps;
354 LocalInfo self; /*< info structure for local aircraft */
355 ThreatInfo currentThreat; /*< info structure on current intruder/threat */
356 const SensitivityLevel* pAlarmThresholds;
362 double nextUpdateTime;
365 SGPropertyNode_ptr nodeModeSwitch;
366 SGPropertyNode_ptr nodeServiceable;
367 SGPropertyNode_ptr nodeSelfTest;
368 SGPropertyNode_ptr nodeDebugTrigger;
369 SGPropertyNode_ptr nodeDebugRA;
370 SGPropertyNode_ptr nodeDebugThreat;
372 PropertiesHandler properties_handler;
373 ThreatDetector threatDetector;
375 AdvisoryCoordinator advisoryCoordinator;
376 AdvisoryGenerator advisoryGenerator;
377 Annunciator annunciator;
380 void selfTest (void);
383 TCAS (SGPropertyNode* node);
385 virtual void bind (void);
386 virtual void unbind (void);
387 virtual void init (void);
388 virtual void reinit (void);
389 virtual void update (double dt);
393 # pragma warning( pop )
396 #endif // __INSTRUMENTS_TCAS_HXX