54#include <simgear/compiler.h>
55#include <simgear/sg_inlines.h>
56#include <simgear/debug/logstream.hxx>
71 _mode((Mode) node->getIntValue(
"mode", 1))
76 if (node->hasChild(
"bus-volts")) {
77 SG_LOG(SG_INSTR, SG_DEV_WARN,
"Transponder: use new supply-volatge prop: 'minimum-supply-volts' instead of 'bus-volts'");
81 _altitudeSourcePath = node->getStringValue(
"encoder-path",
"/instrumentation/altimeter");
82 _autoGroundPath = node->getStringValue(
"auto-ground");
83 _airspeedSourcePath = node->getStringValue(
"airspeed-path",
"/instrumentation/airspeed-indicator/indicated-speed-kt");
84 _machSourcePath = node->getStringValue(
"mach-path",
"/instrumentation/airspeed-indicator/indicated-mach");
85 _kt70Compat = node->getBoolValue(
"kt70-compatibility",
false);
100 _pressureAltitude_node =
fgGetNode(_altitudeSourcePath,
true);
101 _autoGround_node =
fgGetNode(_autoGroundPath,
true);
102 _airspeedIndicator_node =
fgGetNode(_airspeedSourcePath,
true);
103 _machSource_node =
fgGetNode(_machSourcePath,
true);
105 SGPropertyNode *in_node = node->getChild(
"inputs", 0,
true);
106 for (
int i=0;
i<4;++
i) {
107 _digit_node[
i] = in_node->getChild(
"digit",
i,
true);
108 _digit_node[
i]->addChangeListener(
this);
111 _knob_node = in_node->getChild(
"knob-mode", 0,
true);
112 if (!_knob_node->hasValue()) {
116 _knob_node->setIntValue(_knob);
118 _knob =
static_cast<KnobPosition
>(_knob_node->getIntValue());
121 _knob_node->addChangeListener(
this);
123 _mode_node = in_node->getChild(
"mode", 0,
true);
124 _mode_node->setIntValue(_mode);
125 _mode_node->addChangeListener(
this);
127 _identBtn_node = in_node->getChild(
"ident-btn", 0,
true);
128 _identBtn_node->setBoolValue(
false);
129 _identBtn_node->addChangeListener(
this);
131 _idCode_node = node->getChild(
"id-code", 0,
true);
132 _idCode_node->addChangeListener(
this);
134 if (!_idCode_node->hasValue()) {
135 _idCode_node->setIntValue(1200);
139 _altitude_node = node->getChild(
"altitude", 0,
true);
140 _altitudeValid_node = node->getChild(
"altitude-valid", 0,
true);
141 _ident_node = node->getChild(
"ident", 0,
true);
142 _transmittedId_node = node->getChild(
"transmitted-id", 0,
true);
143 _ground_node = node->getChild(
"ground-bit", 0,
true);
144 _airspeed_node = node->getChild(
"airspeed-kt", 0,
true);
145 _mach_node = node->getChild(
"mach-number", 0,
true);
149 SGPropertyNode_ptr output = node->getChild(
"outputs", 0,
true);
150 output->getChild(
"flight-level", 0,
true)->alias(_altitude_node,
true);
151 output->getChild(
"id-code", 0,
true)->alias(_idCode_node,
true);
152 in_node->getChild(
"func-knob", 0,
true)->alias(_knob_node,
true);
160 _tiedProperties.setRoot(node);
162 _tiedProperties.Tie(
"annunciators/fl",
this,
163 &Transponder::getFLAnnunciator );
164 _tiedProperties.Tie(
"annunciators/alt",
this,
165 &Transponder::getAltAnnunciator );
166 _tiedProperties.Tie(
"annunciators/gnd",
this,
167 &Transponder::getGroundAnnuciator );
168 _tiedProperties.Tie(
"annunciators/on",
this,
169 &Transponder::getOnAnnunciator );
170 _tiedProperties.Tie(
"annunciators/sby",
this,
171 &Transponder::getStandbyAnnunciator );
172 _tiedProperties.Tie(
"annunciators/reply",
this,
173 &Transponder::getReplyAnnunciator );
179 _tiedProperties.Untie();
188 Mode effectiveMode = (_knob == KNOB_ALT || _knob == KNOB_GROUND) ? _mode : MODE_A;
189 SGPropertyNode* altitudeSource = NULL;
191 switch (effectiveMode) {
193 altitudeSource = _pressureAltitude_node->getChild(
"mode-c-alt-ft");
196 altitudeSource = _pressureAltitude_node->getChild(
"mode-s-alt-ft");
203 if (effectiveMode != MODE_A) {
204 if (altitudeSource) {
205 alt = altitudeSource->getIntValue();
208 SG_LOG(SG_INSTR, SG_INFO,
"transponder altitude input for mode " << _mode <<
" is missing");
212 _altitude_node->setIntValue(alt);
219 _ident_node->setBoolValue(
false);
224 if (_knob >= KNOB_GROUND) {
225 _transmittedId_node->setIntValue(_idCode_node->getIntValue());
230 if (_mode == MODE_S && _knob >= KNOB_GROUND) {
231 if (_autoGround_node->hasValue()) {
233 _ground_node->setBoolValue(_autoGround_node->getBoolValue());
236 _ground_node->setBoolValue(_knob == KNOB_GROUND);
239 _ground_node->setBoolValue(
false);
242 if (_mode == MODE_S && _knob >= KNOB_GROUND && _airspeedIndicator_node->hasValue()) {
243 _airspeed_node->setIntValue(_airspeedIndicator_node->getIntValue());
248 if (_mode == MODE_S && _machSource_node->hasValue()) {
249 _mach_node->setDoubleValue(_machSource_node->getDoubleValue());
257 _altitudeValid_node->setBoolValue(
false);
258 _ident_node->setBoolValue(
false);
259 _ground_node->setBoolValue(
false);
275 assert(digitValue >= 0 && digitValue < 8);
278 return codeWithoutDigit + (digitValue *
p);
281void Transponder::valueChanged(SGPropertyNode *prop)
284 if (prop == _identBtn_node) {
285 if (prop->getBoolValue()) {
287 _ident_node->setBoolValue(
true);
295 if (prop == _mode_node) {
296 _mode =
static_cast<Mode
>(prop->getIntValue());
300 if (prop == _knob_node) {
301 _knob =
static_cast<KnobPosition
>(prop->getIntValue());
305 if (_listener_active)
310 if (prop == _idCode_node) {
312 for (
int i=0;
i<4; ++
i) {
317 int index = prop->getIndex();
318 int digitValue = prop->getIntValue();
319 SG_CLAMP_RANGE<int>(digitValue, 0, 7);
320 _idCode_node->setIntValue(
modifyCodeDigit(_idCode_node->getIntValue(), index, digitValue));
321 prop->setIntValue(digitValue);
327bool Transponder::getFLAnnunciator()
const
329 return (_knob == KNOB_ALT) || (_knob == KNOB_GROUND) || (_knob == KNOB_TEST);
332bool Transponder::getAltAnnunciator()
const
334 return (_knob == KNOB_ALT) || (_knob == KNOB_TEST);
337bool Transponder::getGroundAnnuciator()
const
339 return (_knob == KNOB_GROUND) || (_knob == KNOB_TEST);
342bool Transponder::getOnAnnunciator()
const
344 return (_knob == KNOB_ON) || (_knob == KNOB_TEST);
347bool Transponder::getStandbyAnnunciator()
const
349 return (_knob == KNOB_STANDBY) || (_knob == KNOB_TEST);
352bool Transponder::getReplyAnnunciator()
const
354 return _identMode || (_knob == KNOB_TEST);
359 return (_knob_node->getIntValue() >= KNOB_STANDBY);
365SGSubsystemMgr::InstancedRegistrant<Transponder> registrantTransponder(
367 {{
"instrumentation", SGSubsystemMgr::Dependency::HARD}},
void initServicePowerProperties(SGPropertyNode *node)
void setMinimumSupplyVolts(double v)
void readConfig(SGPropertyNode *config, std::string defaultName)
std::string nodePath() const
bool isServiceableAndPowered() const
Transponder(SGPropertyNode *node)
void update(double dt) override
bool isPowerSwitchOn() const override
SGPropertyNode * fgGetNode(const char *path, bool create)
Get a property node.
const double IDENT_TIMEOUT
static int extractCodeDigit(int code, int index)
const float INVALID_MACH_NUM
const int INVALID_AIRSPEED
static int modifyCodeDigit(int code, int index, int digitValue)
const int INVALID_ALTITUDE