]> git.mxchange.org Git - flightgear.git/commitdiff
Added Alex's patches for more accurate instrument modeling (compass, vsi,
authorcurt <curt>
Tue, 21 Mar 2000 20:51:03 +0000 (20:51 +0000)
committercurt <curt>
Tue, 21 Mar 2000 20:51:03 +0000 (20:51 +0000)
altitute)

src/Cockpit/Makefile.am
src/Cockpit/panel.cxx
src/Cockpit/steam.cxx [new file with mode: 0644]
src/Cockpit/steam.hxx [new file with mode: 0644]
src/GUI/gui.cxx
src/Main/main.cxx

index 9c1948027be3be87226be08cef3794ddd93cabe4..03abeb0c10b406f43e6234b0a2ee2cb27f4c678f 100644 (file)
@@ -7,6 +7,7 @@ libCockpit_a_SOURCES = \
        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
index cac9080114a1fe31268e96318f5dcb3ce0456109..d6154dc4ecfa84a1b51cab7bec0a4b20d4ceaa09 100644 (file)
@@ -43,6 +43,7 @@
 #include "cockpit.hxx"
 #include "panel.hxx"
 #include "hud.hxx"
+#include "steam.hxx"
 
 extern fgAPDataPtr APDataGlobal;
 
@@ -101,7 +102,7 @@ createAirspeedIndicator (int x, int y)
                                // 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;
 }
@@ -162,21 +163,21 @@ createAltimeter (int x, int y)
                                // 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;
@@ -198,14 +199,14 @@ createTurnCoordinator (int x, int y)
                                // 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;
@@ -224,14 +225,14 @@ createGyroCompass (int x, int y)
                                // 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,
@@ -259,7 +260,7 @@ createVerticalVelocity (int x, int y)
                                // 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;
diff --git a/src/Cockpit/steam.cxx b/src/Cockpit/steam.cxx
new file mode 100644 (file)
index 0000000..0d8ca25
--- /dev/null
@@ -0,0 +1,167 @@
+// 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
diff --git a/src/Cockpit/steam.hxx b/src/Cockpit/steam.hxx
new file mode 100644 (file)
index 0000000..adc2228
--- /dev/null
@@ -0,0 +1,82 @@
+// 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
index c6f40e324a7a03d4a021c1536893061602c3c2f0..44c634fda362ae394f6301acb32b89df0b8de772 100644 (file)
@@ -1387,7 +1387,7 @@ char *viewSubmenu               [] = {
     /* "Cockpit View > ", "View >","------------", */ "Toggle Panel...", NULL
 };
 puCallback viewSubmenuCb        [] = {
-    /* notCb, notCb, NULL, guiTogglePanel, */ NULL
+    /* notCb, notCb, NULL, */ guiTogglePanel, NULL
 };
 
 char *aircraftSubmenu           [] = {
index 3ddedea8a8a3b8e62fd6689d536fdbbeec8369ab..56c90562a7bb47cc5f260235da8793108f95a955 100644 (file)
@@ -78,6 +78,7 @@
 
 #include <Autopilot/autopilot.hxx>
 #include <Cockpit/cockpit.hxx>
+#include <Cockpit/steam.hxx>
 #include <GUI/gui.h>
 #include <Joystick/joystick.hxx>
 #ifdef FG_NETWORK_OLK
@@ -662,10 +663,12 @@ void fgUpdateTimeDepCalcs(int multi_loop, int remainder) {
                     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 );