15#include <simgear/constants.h>
16#include <simgear/math/interpolater.hxx>
26#define RESPONSIVENESS 50.0
30 _name(node->getStringValue(
"name",
"airspeed-indicator")),
31 _num(node->getIntValue(
"number", 0)),
32 _total_pressure(node->getStringValue(
"total-pressure",
"/systems/pitot/total-pressure-inhg")),
33 _static_pressure(node->getStringValue(
"static-pressure",
"/systems/static/pressure-inhg")),
34 _has_overspeed(node->getBoolValue(
"has-overspeed-indicator",false)),
35 _pressure_alt_source(node->getStringValue(
"pressure-alt-source",
"/instrumentation/altimeter/pressure-alt-ft")),
36 _ias_limit(node->getDoubleValue(
"ias-limit", 248.0)),
37 _mach_limit(node->getDoubleValue(
"mach-limit", 0.48)),
38 _alt_threshold(node->getDoubleValue(
"alt-threshold", 13200))
40 _environmentManager = NULL;
51 branch =
"/instrumentation/" + _name;
53 SGPropertyNode *node =
fgGetNode(branch, _num,
true );
54 _serviceable_node = node->getChild(
"serviceable", 0,
true);
55 _total_pressure_node =
fgGetNode(_total_pressure,
true);
56 _static_pressure_node =
fgGetNode(_static_pressure,
true);
57 _density_node =
fgGetNode(
"/environment/density-slugft3",
true);
58 _speed_node = node->getChild(
"indicated-speed-kt", 0,
true);
59 _tas_node = node->getChild(
"true-speed-kt", 0,
true);
60 _mach_node = node->getChild(
"indicated-mach", 0,
true);
64 _ias_limit_node = node->getNode(
"ias-limit",0,
true);
65 _mach_limit_node = node->getNode(
"mach-limit",0,
true);
66 _alt_threshold_node = node->getNode(
"alt-threshold",0,
true);
68 if (!_ias_limit_node->hasValue()) {
69 _ias_limit_node->setDoubleValue(_ias_limit);
72 if (!_mach_limit_node->hasValue()) {
73 _mach_limit_node->setDoubleValue(_mach_limit);
76 if (!_alt_threshold_node->hasValue()) {
77 _alt_threshold_node->setDoubleValue(_alt_threshold);
80 _airspeed_limit = node->getChild(
"airspeed-limit-kt", 0,
true);
81 _pressure_alt =
fgGetNode(_pressure_alt_source,
true);
90 _speed_node->setDoubleValue(0.0);
96 if (!_serviceable_node->getBoolValue()) {
100 double pt = _total_pressure_node->getDoubleValue() ;
101 double p = _static_pressure_node->getDoubleValue() ;
102 double qc = ( pt -
p ) * SG_INHG_TO_PA ;
106 qc = std::max( qc , 0.0 );
109 double v_cal = sqrt( 7 * SG_p0_Pa/SG_rho0_kg_p_m3 * ( pow( 1 + qc/SG_p0_Pa , 1/3.5 ) -1 ) );
112 double last_speed_kt = _speed_node->getDoubleValue();
113 double current_speed_kt = v_cal * SG_MPS_TO_KT;
117 _speed_node->setDoubleValue(filtered_speed);
120 if (!_has_overspeed) {
124 double lmt = _ias_limit_node->getDoubleValue();
125 if (_pressure_alt->getDoubleValue() > _alt_threshold_node->getDoubleValue()) {
126 double mmo = _mach_limit_node->getDoubleValue();
127 lmt = (filtered_speed/_mach_node->getDoubleValue())* mmo;
130 _airspeed_limit->setDoubleValue(lmt);
134AirspeedIndicator::computeMach()
136 if (!_environmentManager) {
140 const auto env = _environmentManager->getAircraftEnvironment();
142 double oatK = env->get_temperature_degc() + SG_T0_K - 15.0 ;
143 oatK = std::max( oatK , 0.001 );
144 double c = sqrt(SG_gamma * SG_R_m2_p_s2_p_K * oatK);
145 double pt = _total_pressure_node->getDoubleValue() * SG_INHG_TO_PA;
146 double p = _static_pressure_node->getDoubleValue() * SG_INHG_TO_PA;
147 p = std::max(
p , 0.001 );
148 double rho = _density_node->getDoubleValue() * SG_SLUGFT3_TO_KGPM3;
149 rho = std::max( rho , 0.001 );
152 pt = std::max( pt ,
p );
153 double V_true = sqrt( 7 *
p/rho * (pow( 1 + (pt-
p)/
p , 1/3.5 ) -1 ) );
155 double mach = V_true / c;
158 _mach_node->setDoubleValue(mach);
159 _tas_node->setDoubleValue(V_true * SG_MPS_TO_KT );
165SGSubsystemMgr::InstancedRegistrant<AirspeedIndicator> registrantAirspeedIndicator(
167 {{
"instrumentation", SGSubsystemMgr::Dependency::HARD}});
void update(double dt) override
virtual ~AirspeedIndicator()
AirspeedIndicator(SGPropertyNode *node)
Manage environment information.
SGPropertyNode * fgGetNode(const char *path, bool create)
Get a property node.
double fgGetLowPass(double current, double target, double timeratio)
Move a value towards a target.