28 _name(node->getStringValue(
"name",
"attitude-indicator")),
29 _num(node->getIntValue(
"number", 0)),
30 _suction(node->getStringValue(
"suction",
"/systems/vacuum/suction-inhg")),
35 _minVacuum = node->getDoubleValue(
"minimum-vacuum", 4.5);
37 SGPropertyNode* limits_cfg = node->getChild(
"limits", 0,
true);
38 spin_thresh = limits_cfg->getDoubleValue(
"spin-thresh", 0.8);
39 max_roll_error = limits_cfg->getDoubleValue(
"max-roll-error-deg", 40.0);
40 max_pitch_error = limits_cfg->getDoubleValue(
"max-pitch-error-deg", 12.0);
42 SGPropertyNode* gyro_cfg = node->getChild(
"gyro", 0,
true);
43 _gyro_spin_up = gyro_cfg->getDoubleValue(
"spin-up-sec", 4.0);
44 _gyro_spin_down = gyro_cfg->getDoubleValue(
"spin-down-sec", 180.0);
55 branch =
"/instrumentation/" + _name;
57 SGPropertyNode *node =
fgGetNode(branch, _num,
true );
60 _pitch_in_node =
fgGetNode(
"/orientation/pitch-deg",
true);
61 _roll_in_node =
fgGetNode(
"/orientation/roll-deg",
true);
62 _suction_node =
fgGetNode(_suction,
true);
63 SGPropertyNode *cnode = node->getChild(
"config", 0,
true);
64 _tumble_flag_node = cnode->getChild(
"tumble-flag", 0,
true);
65 _caged_node = node->getChild(
"caged-flag", 0,
true);
66 _tumble_node = node->getChild(
"tumble-norm", 0,
true);
67 if( ( n = cnode->getChild(
"spin-thresh", 0,
false ) ) != NULL )
68 spin_thresh = n->getDoubleValue();
69 if( ( n = cnode->getChild(
"max-roll-error-deg", 0,
false ) ) != NULL )
70 max_roll_error = n->getDoubleValue();
71 if( ( n = cnode->getChild(
"max-pitch-error-deg", 0,
false ) ) != NULL )
72 max_pitch_error = n->getDoubleValue();
73 _pitch_int_node = node->getChild(
"internal-pitch-deg", 0,
true);
74 _roll_int_node = node->getChild(
"internal-roll-deg", 0,
true);
75 _pitch_out_node = node->getChild(
"indicated-pitch-deg", 0,
true);
76 _roll_out_node = node->getChild(
"indicated-roll-deg", 0,
true);
78 _spin_node = node->getChild(
"spin", 0,
true);
80 SGPropertyNode* gyro_node = node->getChild(
"gyro", 0,
true);
81 _gyro_spin_up_node = gyro_node->getChild(
"spin-up-sec", 0,
true);
82 _gyro_spin_down_node = gyro_node->getChild(
"spin-down-sec", 0,
true);
83 if (!_gyro_spin_up_node->hasValue())
84 _gyro_spin_up_node->setDoubleValue(_gyro_spin_up);
85 if (!_gyro_spin_down_node->hasValue())
86 _gyro_spin_down_node->setDoubleValue(_gyro_spin_down);
87 _minVacuum_node = node->getChild(
"minimum-vacuum", 0,
true);
88 if (!_minVacuum_node->hasValue())
89 _minVacuum_node->setDoubleValue(_minVacuum);
129 _minVacuum = _minVacuum_node->getDoubleValue();
130 _gyro.set_power_norm(_suction_node->getDoubleValue() / _minVacuum);
131 _gyro.set_spin_up(_gyro_spin_up_node->getDoubleValue());
132 _gyro.set_spin_down(_gyro_spin_down_node->getDoubleValue());
133 _gyro.set_spin_norm(_spin_node->getDoubleValue());
135 double spin = _gyro.get_spin_norm();
136 _spin_node->setDoubleValue(spin);
139 double responsiveness = spin * spin * spin * spin * spin * spin;
142 double roll = _roll_in_node->getDoubleValue();
143 double pitch = _pitch_in_node->getDoubleValue();
144 bool isCaged = _caged_node->getBoolValue();
148 if (_tumble_flag_node->getBoolValue()) {
149 double tumble = _tumble_node->getDoubleValue();
150 if (fabs(roll) > 45.0) {
151 double target = (fabs(roll) - 45.0) / 45.0;
156 if (fabs(target) > fabs(tumble))
161 else if (tumble < -1.0)
165 double t_reerect = isCaged ? 1.0 : 300.0;
166 double step = dt / t_reerect;
169 else if (tumble > step)
173 _tumble_node->setDoubleValue(tumble);
178 _roll_int_node->setDoubleValue(0.0);
179 _pitch_int_node->setDoubleValue(0.0);
183 roll =
fgGetLowPass(_roll_int_node->getDoubleValue(), roll,
185 pitch =
fgGetLowPass(_pitch_int_node->getDoubleValue(), pitch,
189 _roll_int_node->setDoubleValue(roll);
190 _pitch_int_node->setDoubleValue(pitch);
195 if ( spin <= spin_thresh ) {
196 double roll_error_factor = (spin_thresh - spin) / spin_thresh;
197 double pitch_error_factor = (spin_thresh - spin) / spin_thresh;
198 roll_error = roll_error_factor * roll_error_factor * max_roll_error;
199 pitch_error = pitch_error_factor * pitch_error_factor * max_pitch_error;
205 _roll_out_node->setDoubleValue(roll + roll_error);
206 _pitch_out_node->setDoubleValue(pitch + pitch_error);
void fgTie(const char *name, V(*getter)(), void(*setter)(V)=0, bool useDefault=true)
Tie a property to a pair of simple functions.