hud_labl.cxx hud_ladr.cxx \
hud_lat.cxx hud_lon.cxx \
hud_scal.cxx hud_tbi.cxx \
- panel.cxx panel.hxx
+ panel.cxx panel.hxx \
+ steam.cxx steam.hxx
INCLUDES += -I$(top_builddir) -I$(top_builddir)/src
#include "cockpit.hxx"
#include "panel.hxx"
#include "hud.hxx"
+#include "steam.hxx"
extern fgAPDataPtr APDataGlobal;
// Rotates with airspeed.
inst->addLayer(1, createTexture("Textures/Panel/long-needle.rgb"));
inst->addTransformation(1, FGInstrumentLayer::ROTATION,
- FGBFI::getAirspeed,
+ FGSteam::get_ASI_kias,
30.0, 220.0, 36.0 / 20.0, -54.0);
return inst;
}
// moves with altitude
inst->addLayer(1, createTexture("Textures/Panel/long-needle.rgb"));
inst->addTransformation(1, FGInstrumentLayer::ROTATION,
- FGBFI::getAltitude,
+ FGSteam::get_ALT_ft,
0.0, 100000.0, 360.0 / 1000.0, 0.0);
// Layer 2: thousands needle (short)
// moves with altitude
inst->addLayer(2, createTexture("Textures/Panel/short-needle.rgb"));
inst->addTransformation(2, FGInstrumentLayer::ROTATION,
- FGBFI::getAltitude,
+ FGSteam::get_ALT_ft,
0.0, 100000.0, 360.0 / 10000.0, 0.0);
// Layer 3: ten thousands bug (outside)
// moves with altitude
inst->addLayer(3, createTexture("Textures/Panel/bug.rgb"));
inst->addTransformation(3, FGInstrumentLayer::ROTATION,
- FGBFI::getAltitude,
+ FGSteam::get_ALT_ft,
0.0, 100000.0, 360.0 / 100000.0, 0.0);
return inst;
// moves with roll
inst->addLayer(1, createTexture("Textures/Panel/turn.rgb"));
inst->addTransformation(1, FGInstrumentLayer::ROTATION,
- FGBFI::getRoll,
+ FGSteam::get_TC_radps,
-30.0, 30.0, 1.0, 0.0);
// Layer 2: little ball
// moves with slip/skid
inst->addLayer(2, createTexture("Textures/Panel/ball.rgb"));
inst->addTransformation(2, FGInstrumentLayer::ROTATION,
- FGBFI::getSideSlip,
+ FGSteam::get_TC_radps,
-0.1, 0.1, 450.0, 0.0);
return inst;
// rotates with heading
inst->addLayer(0, createTexture("Textures/Panel/gyro-bg.rgb"));
inst->addTransformation(0, FGInstrumentLayer::ROTATION,
- FGBFI::getHeading,
+ FGSteam::get_DG_deg,
-360.0, 360.0, -1.0, 0.0);
// Layer 1: heading bug
// rotates with heading and AP heading
inst->addLayer(1, createTexture("Textures/Panel/bug.rgb"));
inst->addTransformation(1, FGInstrumentLayer::ROTATION,
- FGBFI::getHeading,
+ FGSteam::get_DG_deg,
-360.0, 360.0, -1.0, 0.0);
inst->addTransformation(1, FGInstrumentLayer::ROTATION,
FGBFI::getAPHeading,
// moves with vertical velocity
inst->addLayer(1, createTexture("Textures/Panel/long-needle.rgb"));
inst->addTransformation(1, FGInstrumentLayer::ROTATION,
- FGBFI::getVerticalSpeed,
+ FGSteam::get_VSI_fps,
-2000.0, 2000.0, 42.0/500.0, 270.0);
return inst;
--- /dev/null
+// steam.cxx - Steam Gauge Calculations
+//
+// Copyright (C) 2000 Alexander Perry - alex.perry@ieee.org
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined( FG_HAVE_NATIVE_SGI_COMPILERS )
+# include <iostream.h>
+#else
+# include <iostream>
+#endif
+
+#include <simgear/constants.h>
+#include <simgear/math/fg_types.hxx>
+#include <Main/options.hxx>
+#include <Main/bfi.hxx>
+
+FG_USING_NAMESPACE(std);
+
+#include "steam.hxx"
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Declare the functions that read the variables
+////////////////////////////////////////////////////////////////////////
+
+// Anything that reads the BFI directly is not implemented at all!
+
+
+double FGSteam::the_STATIC_inhg = 29.92;
+double FGSteam::the_ALT_ft = 0.0;
+double FGSteam::get_ALT_ft() { _CatchUp(); return the_ALT_ft; }
+
+double FGSteam::get_ASI_kias() { return FGBFI::getAirspeed(); }
+
+double FGSteam::the_VSI_case = 29.92;
+double FGSteam::the_VSI_fps = 0.0;
+double FGSteam::get_VSI_fps() { _CatchUp(); return the_VSI_fps; }
+
+double FGSteam::get_MH_deg () { return FGBFI::getHeading (); }
+double FGSteam::get_DG_deg () { return FGBFI::getHeading (); }
+
+double FGSteam::get_TC_rad () { return FGBFI::getSideSlip (); }
+double FGSteam::get_TC_radps () { return FGBFI::getRoll (); }
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Recording the current time
+////////////////////////////////////////////////////////////////////////
+
+
+int FGSteam::_UpdatesPending = 9999; /* Forces filter to reset */
+
+
+void FGSteam::update ( int timesteps )
+{
+ _UpdatesPending += timesteps;
+}
+
+
+void FGSteam::set_lowpass ( double *outthe, double inthe, double tc )
+{
+ if ( tc < 0.0 )
+ { if ( tc < -1.0 )
+ { /* time went backwards; kill the filter */
+ (*outthe) = inthe;
+ } else
+ { /* ignore mildly negative time */
+ }
+ } else
+ if ( tc < 0.2 )
+ { /* Normal mode of operation */
+ (*outthe) = (*outthe) * ( 1.0 - tc )
+ + inthe * tc;
+ } else
+ if ( tc > 5 )
+ { /* Huge time step; assume filter has settled */
+ (*outthe) = inthe;
+ } else
+ { /* Moderate time step; non linear response */
+ tc = exp ( -tc );
+ (*outthe) = (*outthe) * ( 1.0 - tc )
+ + inthe * tc;
+ }
+}
+
+
+\f
+////////////////////////////////////////////////////////////////////////
+// Here the fun really begins
+////////////////////////////////////////////////////////////////////////
+
+
+void FGSteam::_CatchUp()
+{ if ( _UpdatesPending != 0 )
+ { double dt = _UpdatesPending * 1.0 / current_options.get_model_hz();
+ int i,j;
+ double d;
+ /*
+ Someone has called our update function and we haven't
+ incorporated this into our instrument modelling yet
+ */
+
+ /**************************
+ This is just temporary
+ */
+ the_ALT_ft = FGBFI::getAltitude();
+
+ /**************************
+ First, we need to know what the static line is reporting,
+ which is a whole simulation area in itself. For now, we cheat.
+ */
+ the_STATIC_inhg = 29.92;
+ i = (int) the_ALT_ft;
+ while ( i > 18000 )
+ { the_STATIC_inhg /= 2;
+ i -= 18000;
+ }
+ the_STATIC_inhg /= ( 1.0 + i / 18000.0 );
+
+ /*
+ NO alternate static source error (student feature),
+ NO possibility of blockage (instructor feature),
+ NO slip-induced error, important for C172 for example.
+ */
+
+ /**************************
+ The VSI case is a low-pass filter of the static line pressure.
+ The instrument reports the difference, scaled to approx ft.
+ NO option for student to break glass when static source fails.
+ NO capability for a fixed non-zero reading when level.
+ NO capability to have a scaling error of maybe a factor of two.
+ */
+ set_lowpass ( & the_VSI_case, the_STATIC_inhg, dt/9.0 );
+ the_VSI_fps = ( the_VSI_case - the_STATIC_inhg )
+ * 7000.0; /* manual scaling factor */
+
+ /**************************
+ Finished updates, now clear the timer
+ */
+ _UpdatesPending = 0;
+ }
+}
+
+
+// end of steam.cxx
--- /dev/null
+// steam.hxx - Steam Gauge Indications
+//
+// Started by Alex Perry
+//
+// Copyright (C) 2000 Alexander Perry - alex.perry@ieee.org
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// $Id$
+
+
+#ifndef FG_STEAM
+#define FG_STEAM
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <simgear/compiler.h>
+
+#include <time.h>
+#include STL_STRING
+
+FG_USING_NAMESPACE(std);
+
+
+/**
+ * STEAM GAUGES
+ *
+ * This class is a mapping layer, which retrieves information from
+ * the BFI (which reports truthful and ideal values) and generates
+ * all the instrument errors and inaccuracies that pilots (err)
+ * love, of course. Please report any missing flaws (!).
+ *
+ * These should be used to operate cockpit instruments,
+ * and autopilot features where these are slaved thus.
+ * They should not be used for other simulation purposes.
+ *
+ */
+class FGSteam
+{
+public:
+
+ static void update ( int timesteps );
+
+ // Position
+ static double get_ALT_ft ();
+ static double get_MH_deg ();
+ static double get_DG_deg ();
+ static double get_TC_rad ();
+
+ // Velocities
+ static double get_ASI_kias ();
+ static double get_TC_radps ();
+ static double get_VSI_fps ();
+
+private:
+ static double the_ALT_ft, the_STATIC_inhg;
+ static double the_VSI_fps, the_VSI_case;
+
+ static int _UpdatesPending;
+ static void _CatchUp ();
+
+ static void set_lowpass ( double *outthe,
+ double inthe, double tc );
+};
+
+
+#endif // FG_STEAM
/* "Cockpit View > ", "View >","------------", */ "Toggle Panel...", NULL
};
puCallback viewSubmenuCb [] = {
- /* notCb, notCb, NULL, guiTogglePanel, */ NULL
+ /* notCb, notCb, NULL, */ guiTogglePanel, NULL
};
char *aircraftSubmenu [] = {
#include <Autopilot/autopilot.hxx>
#include <Cockpit/cockpit.hxx>
+#include <Cockpit/steam.hxx>
#include <GUI/gui.h>
#include <Joystick/joystick.hxx>
#ifdef FG_NETWORK_OLK
multi_loop * current_options.get_speed_up(),
remainder ); */
cur_fdm_state->update( multi_loop * current_options.get_speed_up() );
+ FGSteam::update( multi_loop * current_options.get_speed_up() );
} else {
// fgFDMUpdate( current_options.get_flight_model(),
// fdm_state, 0, remainder );
cur_fdm_state->update( 0 );
+ FGSteam::update( 0 );
}
fdm_list.push_back( *cur_fdm_state );