X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FCockpit%2Fsteam.cxx;h=af1a588963e9c906d932b1dafd43b235ded34953;hb=29275ce1ecf9c4ea302aacca8c5ae5d4d3319a17;hp=618671e1de04f0e24799ec7dc5616a55de26da14;hpb=152a5902c82013c75ba4b09149523867b8d9d136;p=flightgear.git diff --git a/src/Cockpit/steam.cxx b/src/Cockpit/steam.cxx index 618671e1d..af1a58896 100644 --- a/src/Cockpit/steam.cxx +++ b/src/Cockpit/steam.cxx @@ -34,7 +34,6 @@ #include #include #include
-#include
#include FG_USING_NAMESPACE(std); @@ -54,9 +53,16 @@ static bool isTied = false; double FGSteam::the_STATIC_inhg = 29.92; -double FGSteam::the_ALT_ft = 0.0; +double FGSteam::the_ALT_ft = 0.0; // Indicated altitude double FGSteam::get_ALT_ft() { _CatchUp(); return the_ALT_ft; } +double FGSteam::the_ALT_datum_mb = 1013.0; +double FGSteam::get_ALT_datum_mb() { return the_ALT_datum_mb; } + +void FGSteam::set_ALT_datum_mb ( double datum_mb ) { + the_ALT_datum_mb = datum_mb; +} + double FGSteam::get_ASI_kias() { return FGBFI::getAirspeed(); } double FGSteam::the_VSI_case = 29.92; @@ -96,40 +102,33 @@ double FGSteam::get_TC_std () { _CatchUp(); return the_TC_std; } int FGSteam::_UpdatesPending = 1000000; /* Forces filter to reset */ + // FIXME: no need to use static + // functions any longer. + void FGSteam::update ( int timesteps ) { if (!isTied) { isTied = true; - current_properties.tieDouble("/steam/airspeed", - FGSteam::get_ASI_kias); - current_properties.tieDouble("/steam/altitude", - FGSteam::get_ALT_ft); - current_properties.tieDouble("/steam/turn-rate", - FGSteam::get_TC_std); - current_properties.tieDouble("/steam/slip-skid", - FGSteam::get_TC_rad); - current_properties.tieDouble("/steam/vertical-speed", - FGSteam::get_VSI_fps); - current_properties.tieDouble("/steam/gyro-compass", - FGSteam::get_DG_deg); - current_properties.tieDouble("/steam/vor1", - FGSteam::get_HackVOR1_deg); - current_properties.tieDouble("/steam/vor2", - FGSteam::get_HackVOR2_deg); - current_properties.tieDouble("/steam/glidescope1", - FGSteam::get_HackGS_deg); - current_properties.tieDouble("/steam/adf", - FGSteam::get_HackADF_deg); - current_properties.tieDouble("/steam/gyro-compass-error", - FGSteam::get_DG_err, - FGSteam::set_DG_err); - current_properties.tieDouble("/steam/mag-compass", - FGSteam::get_MH_deg); + fgTie("/steam/airspeed", FGSteam::get_ASI_kias); + fgTie("/steam/altitude", FGSteam::get_ALT_ft); + fgTie("/steam/altimeter-datum-mb", + FGSteam::get_ALT_datum_mb, FGSteam::set_ALT_datum_mb, + false); /* don't modify the value */ + fgTie("/steam/turn-rate", FGSteam::get_TC_std); + fgTie("/steam/slip-skid", FGSteam::get_TC_rad); + fgTie("/steam/vertical-speed", FGSteam::get_VSI_fps); + fgTie("/steam/gyro-compass", FGSteam::get_DG_deg); + fgTie("/steam/adf", FGSteam::get_HackADF_deg); + fgTie("/steam/gyro-compass-error", + FGSteam::get_DG_err, FGSteam::set_DG_err, + false); /* don't modify the value */ + fgTie("/steam/mag-compass", FGSteam::get_MH_deg); } _UpdatesPending += timesteps; } +/* tc should be (elapsed_time_between_updates / desired_smoothing_time) */ void FGSteam::set_lowpass ( double *outthe, double inthe, double tc ) { if ( tc < 0.0 ) @@ -141,7 +140,7 @@ void FGSteam::set_lowpass ( double *outthe, double inthe, double tc ) } } else if ( tc < 0.2 ) - { /* Normal mode of operation */ + { /* Normal mode of operation; fast approximation to exp(-tc) */ (*outthe) = (*outthe) * ( 1.0 - tc ) + inthe * tc; } else @@ -158,6 +157,38 @@ void FGSteam::set_lowpass ( double *outthe, double inthe, double tc ) } +#define INHG_TO_MB 33.86388 /* Inches_of_mercury * INHG_TO_MB == millibars. */ + +// Convert air pressure to altitude by ICAO Standard Atmosphere +double pressInHgToAltFt(double p_inhg) +{ + // Ref. Aviation Formulary, Ed Williams, www.best.com/~williams/avform.htm + const double P_0 = 29.92126; // Std. MSL pressure, inHg. (=1013.25 mb) + const double p_Tr = 0.2233609 * P_0; // Pressure at tropopause, same units. + const double h_Tr = 36089.24; // Alt of tropopause, ft. (=11.0 km) + + if (p_inhg > p_Tr) // 0.0 to 11.0 km + return (1.0 - pow((p_inhg / P_0), 1.0 / 5.2558797)) / 6.8755856e-6; + return h_Tr + log10(p_inhg / p_Tr) / -4.806346e-5; // 11.0 to 20.0 km + // We could put more code for higher altitudes here. +} + + +// Convert altitude to air pressure by ICAO Standard Atmosphere +double altFtToPressInHg(double alt_ft) +{ + // Ref. Aviation Formulary, Ed Williams, www.best.com/~williams/avform.htm + const double P_0 = 29.92126; // Std. MSL pressure, inHg. (=1013.25 mb) + const double p_Tr = 0.2233609 * P_0; // Pressure at tropopause, same units. + const double h_Tr = 36089.24; // Alt of tropopause, ft. (=11.0 km) + + if (alt_ft < h_Tr) // 0.0 to 11.0 km + return P_0 * pow(1.0 - 6.8755856e-6 * alt_ft, 5.2558797); + return p_Tr * exp(-4.806346e-5 * (alt_ft - h_Tr)); // 11.0 to 20.0 km + // We could put more code for higher altitudes here. +} + + //////////////////////////////////////////////////////////////////////// // Here the fun really begins @@ -167,7 +198,7 @@ void FGSteam::set_lowpass ( double *outthe, double inthe, double tc ) void FGSteam::_CatchUp() { if ( _UpdatesPending != 0 ) { double dt = _UpdatesPending * 1.0 / - globals->get_options()->get_model_hz(); + fgGetInt("/sim/model-hz"); // FIXME: inefficient double AccN, AccE, AccU; int i /*,j*/; double d, the_ENGINE_rpm; @@ -291,26 +322,16 @@ void FGSteam::_CatchUp() scaling capability for the vacuum pump later on. When we have a real engine model, we can ask it. */ - the_ENGINE_rpm = FGBFI::getThrottle() * 26.0; - - /************************** - This is just temporary, until the static source works, - so we just filter the actual value by one second to - account for the line impedance of the plumbing. - */ - set_lowpass ( & the_ALT_ft, FGBFI::getAltitude(), dt ); + the_ENGINE_rpm = controls.get_throttle(0) * 26.0; /************************** First, we need to know what the static line is reporting, which is a whole simulation area in itself. For now, we cheat. + We filter the actual value by one second to + account for the line impedance of the plumbing. */ - the_STATIC_inhg = 29.92; - i = (int) the_ALT_ft; - while ( i > 9000 ) - { the_STATIC_inhg *= 0.707; - i -= 9000; - } - the_STATIC_inhg *= ( 1.0 - 0.293 * i / 9000.0 ); + double static_inhg = altFtToPressInHg(FGBFI::getAltitude()); + set_lowpass ( & the_STATIC_inhg, static_inhg, dt ); /* NO alternate static source error (student feature), @@ -318,6 +339,21 @@ void FGSteam::_CatchUp() NO slip-induced error, important for C172 for example. */ + /************************** + Altimeter. + ICAO standard atmosphere MSL pressure is 1013.25 mb, and pressure + gradient is about 28 ft per mb at MSL increasing to about 32 at + 5000 and 38 at 10000 ft. + Standard altimeters apply the subscale offset to the output altitude, + not to the input pressure; I don't know exactly what pressure gradient + they assume for this. I choose to make it accurate at low altitudes. + Remember, we are trying to simulate a real altimeter, not an ideal one. + */ + set_lowpass ( & the_ALT_ft, + pressInHgToAltFt(the_STATIC_inhg) + + (the_ALT_datum_mb - 1013.25) * 28.0, /* accurate at low alt. */ + dt * 10 ); /* smoothing time 0.1 s */ + /************************** The VSI case is a low-pass filter of the static line pressure. The instrument reports the difference, scaled to approx ft. @@ -374,6 +410,8 @@ void FGSteam::_CatchUp() //////////////////////////////////////////////////////////////////////// +#if 0 + double FGSteam::get_HackGS_deg () { if ( current_radiostack->get_nav1_inrange() && current_radiostack->get_nav1_has_gs() ) @@ -393,14 +431,8 @@ double FGSteam::get_HackVOR1_deg () { double r; if ( current_radiostack->get_nav1_inrange() ) { - if ( current_radiostack->get_nav1_loc() ) { - // localizer doesn't need magvar offset - r = current_radiostack->get_nav1_heading() - - current_radiostack->get_nav1_radial(); - } else { - r = current_radiostack->get_nav1_heading() - FGBFI::getMagVar() - - current_radiostack->get_nav1_radial(); - } + r = current_radiostack->get_nav1_heading() + - current_radiostack->get_nav1_radial(); // cout << "Radial = " << current_radiostack->get_nav1_radial() // << " Bearing = " << current_radiostack->get_nav1_heading() // << endl; @@ -423,14 +455,8 @@ double FGSteam::get_HackVOR2_deg () { double r; if ( current_radiostack->get_nav2_inrange() ) { - if ( current_radiostack->get_nav2_loc() ) { - // localizer doesn't need magvar offset - r = current_radiostack->get_nav2_heading() - - current_radiostack->get_nav2_radial(); - } else { - r = current_radiostack->get_nav2_heading() - FGBFI::getMagVar() - - current_radiostack->get_nav2_radial(); - } + r = current_radiostack->get_nav2_heading() + - current_radiostack->get_nav2_radial(); // cout << "Radial = " << current_radiostack->get_nav1_radial() // << " Bearing = " << current_radiostack->get_nav1_heading() << endl; @@ -444,6 +470,7 @@ double FGSteam::get_HackVOR2_deg () { return r; } +#endif double FGSteam::get_HackOBS1_deg () {