]> git.mxchange.org Git - flightgear.git/commitdiff
Added a Gyro helper class to factor out some common code for managing
authordavid <david>
Sat, 25 Jan 2003 19:49:27 +0000 (19:49 +0000)
committerdavid <david>
Sat, 25 Jan 2003 19:49:27 +0000 (19:49 +0000)
a spinning gyro.

Changed FGInstrumentMgr to inherit from FGSubsystemGroup, greatly
simplifying the (already simple) class.  I should probably rename this
to FGInstrumentGroup or something similar, but not today.

Added the gyroscopic turn indicator (part of the TC).

src/Instrumentation/Makefile.am
src/Instrumentation/attitude_indicator.cxx
src/Instrumentation/attitude_indicator.hxx
src/Instrumentation/gyro.cxx [new file with mode: 0644]
src/Instrumentation/gyro.hxx [new file with mode: 0644]
src/Instrumentation/heading_indicator.cxx
src/Instrumentation/heading_indicator.hxx
src/Instrumentation/instrument_mgr.cxx
src/Instrumentation/instrument_mgr.hxx
src/Instrumentation/turn_indicator.cxx [new file with mode: 0644]
src/Instrumentation/turn_indicator.hxx [new file with mode: 0644]

index c21a1127318cf072576c47a0da701df6ff43e017..02eff900c318038ab08ade11e736d2244d52d19a 100644 (file)
@@ -1,9 +1,11 @@
 noinst_LIBRARIES = libInstrumentation.a
 
 libInstrumentation_a_SOURCES = instrument_mgr.cxx instrument_mgr.hxx \
+                               gyro.cxx gyro.hxx \
                                airspeed_indicator.cxx airspeed_indicator.hxx \
-                               altimeter.cxx altimeter.hxx \
                                attitude_indicator.cxx attitude_indicator.hxx \
+                               altimeter.cxx altimeter.hxx \
+                               turn_indicator.cxx turn_indicator.hxx \
                                heading_indicator.cxx heading_indicator.hxx \
                                vertical_speed_indicator.cxx vertical_speed_indicator.hxx
 
index 5378e15ed8fd29630ef362355c5fe5ea4f3a71c0..02a249e4c3a6991fa8a3b4e06d032a6489653c6e 100644 (file)
@@ -24,9 +24,6 @@ AttitudeIndicator::init ()
 {
                                 // TODO: allow index of pump and AI
                                 // to be configured.
-    _serviceable_node =
-        fgGetNode("/instrumentation/attitude-indicator/serviceable", true);
-    _spin_node = fgGetNode("/instrumentation/attitude-indicator/spin", true);
     _pitch_in_node = fgGetNode("/orientation/pitch-deg", true);
     _roll_in_node = fgGetNode("/orientation/roll-deg", true);
     _suction_node = fgGetNode("/systems/vacuum[0]/suction-inhg", true);
@@ -41,36 +38,26 @@ AttitudeIndicator::init ()
 void
 AttitudeIndicator::bind ()
 {
+    fgTie("/instrumentation/attitude-indicator/serviceable",
+          &_gyro, &Gyro::is_serviceable);
+    fgTie("/instrumentation/attitude-indicator/spin",
+          &_gyro, &Gyro::get_spin_norm, &Gyro::set_spin_norm);
 }
 
 void
 AttitudeIndicator::unbind ()
 {
+    fgUntie("/instrumentation/attitude-indicator/serviceable");
+    fgUntie("/instrumentation/attitude-indicator/spin");
 }
 
 void
 AttitudeIndicator::update (double dt)
 {
-                                // First, calculate the bogo-spin from 0 to 1.
-                                // All numbers are made up.
-
-    double spin = _spin_node->getDoubleValue();
-    spin -= 0.005 * dt;         // spin decays every 0.5% every second.
-
-                                // spin increases up to 25% every second
-                                // if suction is available and the gauge
-                                // is serviceable.
-    if (_serviceable_node->getBoolValue()) {
-        double suction = _suction_node->getDoubleValue();
-        double step = 0.25 * (suction / 5.0) * dt;
-        if ((spin + step) <= (suction / 5.0))
-            spin += step;
-    }
-    if (spin > 1.0)
-        spin = 1.0;
-    else if (spin < 0.0)
-        spin = 0.0;
-    _spin_node->setDoubleValue(spin);
+                                // Get the spin from the gyro
+    _gyro.set_power_norm(_suction_node->getDoubleValue()/5.0);
+    _gyro.update(dt);
+    double spin = _gyro.get_spin_norm();
 
                                 // Next, calculate the indicated roll
                                 // and pitch, introducing errors.
index 26196eb032170ce753fcec0d75549ea9137a1f29..32bc8b72f3fcc028a34d1dbfd090d13ce1121db3 100644 (file)
@@ -14,6 +14,8 @@
 #include <simgear/misc/props.hxx>
 #include <Main/fgfs.hxx>
 
+#include "gyro.hxx"
+
 
 /**
  * Model a vacuum-powered attitude indicator.
@@ -23,7 +25,6 @@
  * Input properties:
  *
  * /instrumentation/attitude-indicator/serviceable
- * /instrumentation/attitude-indicator/spin
  * /orientation/pitch-deg
  * /orientation/roll-deg
  * /systems/vacuum[0]/suction-inhg
@@ -48,8 +49,8 @@ public:
 
 private:
 
-    SGPropertyNode_ptr _serviceable_node;
-    SGPropertyNode_ptr _spin_node;
+    Gyro _gyro;
+
     SGPropertyNode_ptr _pitch_in_node;
     SGPropertyNode_ptr _roll_in_node;
     SGPropertyNode_ptr _suction_node;
diff --git a/src/Instrumentation/gyro.cxx b/src/Instrumentation/gyro.cxx
new file mode 100644 (file)
index 0000000..3cb5b31
--- /dev/null
@@ -0,0 +1,69 @@
+// gyro.cxx - simple implementation of a spinning gyro model.
+
+#include "gyro.hxx"
+
+Gyro::Gyro ()
+    : _serviceable(true),
+      _power_norm(0.0),
+      _spin_norm(0.0)
+{
+}
+
+Gyro::~Gyro ()
+{
+}
+
+void
+Gyro::update (double delta_time_sec)
+{
+                                // spin decays 0.5% every second
+    _spin_norm -= 0.005 * delta_time_sec;
+
+                                // power can increase spin by 25%
+                                // every second, but only up to the
+                                // level of power available
+    if (_serviceable) {
+        double step = 0.25 * _power_norm * delta_time_sec;
+        if ((_spin_norm + step) <= _power_norm)
+            _spin_norm += step;
+    }
+
+                                // clamp the spin to 0.0:1.0
+    if (_spin_norm < 0.0)
+        _spin_norm = 0.0;
+    else if (_spin_norm > 1.0)
+        _spin_norm = 1.0;
+}
+
+void
+Gyro::set_power_norm (double power_norm)
+{
+    _power_norm = power_norm;
+}
+
+double
+Gyro::get_spin_norm () const
+{
+    return _spin_norm;
+}
+
+void
+Gyro::set_spin_norm (double spin_norm)
+{
+    _spin_norm = spin_norm;
+}
+
+bool
+Gyro::is_serviceable () const
+{
+    return _serviceable;
+}
+
+void
+Gyro::set_serviceable (bool serviceable)
+{
+    _serviceable = serviceable;
+}
+
+// end of gyro.cxx
+
diff --git a/src/Instrumentation/gyro.hxx b/src/Instrumentation/gyro.hxx
new file mode 100644 (file)
index 0000000..eee834c
--- /dev/null
@@ -0,0 +1,88 @@
+// gyro.hxx - simple model of a spinning gyro.
+
+#ifndef __INSTRUMENTATION_GYRO_HXX
+#define __INSTRUMENTATION_GYRO_HXX 1
+
+/**
+ * Simple model of a spinning gyro.
+ *
+ * The gyro decelerates gradually if no power is available to keep it
+ * spinning, and spins up quickly when power becomes available.
+ */
+class Gyro
+{
+public:
+
+    /**
+     * Constructor.
+     */
+    Gyro ();
+
+
+    /**
+     * Destructor.
+     */
+    virtual ~Gyro ();
+
+
+    /**
+     * Update the gyro.
+     *
+     * @param delta_time_sec The elapsed time since the last update.
+     * @param power_norm The power available to drive the gyro, from
+     *        0.0 to 1.0.
+     */
+    virtual void update (double delta_time_sec);
+
+
+    /**
+     * Set the power available to the gyro.
+     *
+     * @param power_norm The amount of power (vacuum or electrical)
+     *        available to keep the gyro spinning, from 0.0 (none) to
+     *        1.0 (full power)
+     */
+    virtual void set_power_norm (double power_norm);
+
+
+    /**
+     * Get the gyro's current spin.
+     *
+     * @return The spin from 0.0 (not spinning) to 1.0 (full speed).
+     */
+    virtual double get_spin_norm () const;
+
+
+    /**
+     * Set the gyro's current spin.
+     *
+     * @spin_norm The spin from 0.0 (not spinning) to 1.0 (full speed).
+     */
+    virtual void set_spin_norm (double spin_norm);
+
+
+    /**
+     * Test if the gyro is serviceable.
+     *
+     * @return true if the gyro is serviceable, false otherwise.
+     */
+    virtual bool is_serviceable () const;
+
+
+    /**
+     * Set the gyro's serviceability.
+     *
+     * @param serviceable true if the gyro is functional, false otherwise.
+     */
+    virtual void set_serviceable (bool serviceable);
+
+
+private:
+
+    bool _serviceable;
+    double _power_norm;
+    double _spin_norm;
+
+};
+
+#endif // __INSTRUMENTATION_GYRO_HXX
index 5ca92fd6ecf3491f81bb3728aa74120794c7d3e7..66fdd833c70c461d833941cc0ad728e58cb0d70e 100644 (file)
@@ -19,10 +19,6 @@ HeadingIndicator::~HeadingIndicator ()
 void
 HeadingIndicator::init ()
 {
-    _serviceable_node =
-        fgGetNode("/instrumentation/heading-indicator/serviceable", true);
-    _spin_node =
-        fgGetNode("/instrumentation/heading-indicator/spin", true);
     _offset_node =
         fgGetNode("/instrumentation/heading-indicator/offset-deg", true);
     _heading_in_node = fgGetNode("/orientation/heading-deg", true);
@@ -37,36 +33,26 @@ HeadingIndicator::init ()
 void
 HeadingIndicator::bind ()
 {
+    fgTie("/instrumentation/heading-indicator/serviceable",
+          &_gyro, &Gyro::is_serviceable);
+    fgTie("/instrumentation/heading-indicator/spin",
+          &_gyro, &Gyro::get_spin_norm, &Gyro::set_spin_norm);
 }
 
 void
 HeadingIndicator::unbind ()
 {
+    fgUntie("/instrumentation/heading-indicator/serviceable");
+    fgUntie("/instrumentation/heading-indicator/spin");
 }
 
 void
 HeadingIndicator::update (double dt)
 {
-                                // First, calculate the bogo-spin from 0 to 1.
-                                // All numbers are made up.
-
-    double spin = _spin_node->getDoubleValue();
-    spin -= 0.005 * dt;         // spin decays every 0.5% every second.
-
-                                // spin increases up to 25% every second
-                                // if suction is available and the gauge
-                                // is serviceable.
-    if (_serviceable_node->getBoolValue()) {
-        double suction = _suction_node->getDoubleValue();
-        double step = 0.25 * (suction / 5.0) * dt;
-        if ((spin + step) <= (suction / 5.0))
-            spin += step;
-    }
-    if (spin > 1.0)
-        spin = 1.0;
-    else if (spin < 0.0)
-        spin = 0.0;
-    _spin_node->setDoubleValue(spin);
+                                // Get the spin from the gyro
+    _gyro.set_power_norm(_suction_node->getDoubleValue()/5.0);
+    _gyro.update(dt);
+    double spin = _gyro.get_spin_norm();
 
                                 // Next, calculate time-based precession
     double offset = _offset_node->getDoubleValue();
index 7941010fa8b3007133fd8554da2ef5e60c13d7f8..90d62104c5dffe8871e1b462f16fa6e280a1a8f1 100644 (file)
@@ -14,6 +14,8 @@
 #include <simgear/misc/props.hxx>
 #include <Main/fgfs.hxx>
 
+#include "gyro.hxx"
+
 
 /**
  * Model a vacuum-powered heading indicator.
@@ -47,10 +49,9 @@ public:
 
 private:
 
+    Gyro _gyro;
     double _last_heading_deg;
 
-    SGPropertyNode_ptr _serviceable_node;
-    SGPropertyNode_ptr _spin_node;
     SGPropertyNode_ptr _offset_node;
     SGPropertyNode_ptr _heading_in_node;
     SGPropertyNode_ptr _suction_node;
index 38504df7ae38249edd1dab01a8b48321d60ff143..410245cb7499d14148c0617c66e42a1c335881ef 100644 (file)
@@ -6,57 +6,25 @@
 
 #include "instrument_mgr.hxx"
 #include "airspeed_indicator.hxx"
-#include "altimeter.hxx"
 #include "attitude_indicator.hxx"
+#include "altimeter.hxx"
+#include "turn_indicator.hxx"
 #include "heading_indicator.hxx"
 #include "vertical_speed_indicator.hxx"
 
 
 FGInstrumentMgr::FGInstrumentMgr ()
 {
-    // NO-OP
+    set_subsystem("asi", new AirspeedIndicator);
+    set_subsystem("ai", new AttitudeIndicator);
+    set_subsystem("alt", new Altimeter);
+    set_subsystem("ti", new TurnIndicator);
+    set_subsystem("hi", new HeadingIndicator);
+    set_subsystem("vsi", new VerticalSpeedIndicator);
 }
 
 FGInstrumentMgr::~FGInstrumentMgr ()
 {
-    for (unsigned int i = 0; i < _instruments.size(); i++) {
-        delete _instruments[i];
-        _instruments[i] = 0;
-    }
-}
-
-void
-FGInstrumentMgr::init ()
-{
-                                // TODO: replace with XML configuration
-    _instruments.push_back(new AirspeedIndicator);
-    _instruments.push_back(new Altimeter);
-    _instruments.push_back(new AttitudeIndicator);
-    _instruments.push_back(new HeadingIndicator);
-    _instruments.push_back(new VerticalSpeedIndicator);
-
-                                // Initialize the individual instruments
-    for (unsigned int i = 0; i < _instruments.size(); i++)
-        _instruments[i]->init();
-}
-
-void
-FGInstrumentMgr::bind ()
-{
-    // NO-OP
-}
-
-void
-FGInstrumentMgr::unbind ()
-{
-    // NO-OP
-}
-
-void
-FGInstrumentMgr::update (double dt)
-{
-    for (unsigned int i = 0; i < _instruments.size(); i++)
-        _instruments[i]->update(dt);
 }
 
 // end of instrument_manager.cxx
index 6e0bf4d12a072e0cd6bc48b3272aa7af30a48581..68a2294045072ff066e9443ce29f6411e87f37c3 100644 (file)
@@ -30,21 +30,13 @@ SG_USING_STD(vector);
  * In the initial draft, the instruments present are hard-coded, but they
  * will soon be configurable for individual aircraft.
  */
-class FGInstrumentMgr : public FGSubsystem
+class FGInstrumentMgr : public FGSubsystemGroup
 {
 public:
 
     FGInstrumentMgr ();
     virtual ~FGInstrumentMgr ();
 
-    virtual void init ();
-    virtual void bind ();
-    virtual void unbind ();
-    virtual void update (double dt);
-
-private:
-    vector<FGSubsystem *> _instruments;
-
 };
 
 #endif // __INSTRUMENT_MGR_HXX
diff --git a/src/Instrumentation/turn_indicator.cxx b/src/Instrumentation/turn_indicator.cxx
new file mode 100644 (file)
index 0000000..5e05239
--- /dev/null
@@ -0,0 +1,73 @@
+// turn_indicator.cxx - an electric-powered turn indicator.
+// Written by David Megginson, started 2003.
+//
+// This file is in the Public Domain and comes with no warranty.
+
+#include "turn_indicator.hxx"
+#include <Main/fg_props.hxx>
+#include <Main/util.hxx>
+
+
+TurnIndicator::TurnIndicator ()
+{
+}
+
+TurnIndicator::~TurnIndicator ()
+{
+}
+
+void
+TurnIndicator::init ()
+{
+    _roll_rate_node = fgGetNode("/orientation/roll-rate-degps", true);
+    _yaw_rate_node = fgGetNode("/orientation/yaw-rate-degps", true);
+    _electric_current_node = 
+        fgGetNode("/systems/electrical/outputs/turn-coordinator", true);
+    _rate_out_node = 
+        fgGetNode("/instrumentation/turn-indicator/indicated-turn-rate", true);
+}
+
+void
+TurnIndicator::bind ()
+{
+    fgTie("/instrumentation/turn-indicator/serviceable",
+          &_gyro, &Gyro::is_serviceable);
+    fgTie("/instrumentation/turn-indicator/spin",
+          &_gyro, &Gyro::get_spin_norm, &Gyro::set_spin_norm);
+}
+
+void
+TurnIndicator::unbind ()
+{
+    fgUntie("/instrumentation/turn-indicator/serviceable");
+    fgUntie("/instrumentation/turn-indicator/spin");
+}
+
+void
+TurnIndicator::update (double dt)
+{
+                                // Get the spin from the gyro
+    _gyro.set_power_norm(_electric_current_node->getDoubleValue()/60.0);
+    _gyro.update(dt);
+    double spin = _gyro.get_spin_norm();
+
+                                // Calculate the indicated rate
+    double factor = 1.0 - ((1.0 - spin) * (1.0 - spin) * (1.0 - spin));
+    double rate = ((_roll_rate_node->getDoubleValue() / 20.0) +
+                   (_yaw_rate_node->getDoubleValue() / 3.0));
+
+                                // Clamp the rate
+    if (rate < -2.5)
+        rate = -2.5;
+    else if (rate > 2.5)
+        rate = 2.5;
+
+                                // Add a lag, based on gyro spin
+    rate = fgGetLowPass(_last_rate, rate, dt/(factor*3));
+    _last_rate = rate;
+    
+                                // Publish the indicated rate
+    _rate_out_node->setDoubleValue(rate);
+}
+
+// end of turn_indicator.cxx
diff --git a/src/Instrumentation/turn_indicator.hxx b/src/Instrumentation/turn_indicator.hxx
new file mode 100644 (file)
index 0000000..e730f74
--- /dev/null
@@ -0,0 +1,63 @@
+// turn_indicator.hxx - an electric-powered turn indicator.
+// Written by David Megginson, started 2003.
+//
+// This file is in the Public Domain and comes with no warranty.
+
+
+#ifndef __INSTRUMENTS_TURN_INDICATOR_HXX
+#define __INSTRUMENTS_TURN_INDICATOR_HXX 1
+
+#ifndef __cplusplus
+# error This library requires C++
+#endif
+
+#include <simgear/misc/props.hxx>
+#include <Main/fgfs.hxx>
+
+#include "gyro.hxx"
+
+
+/**
+ * Model an electric-powered turn indicator.
+ *
+ * This class does not model the slip/skid ball; that is properly 
+ * a separate instrument.
+ *
+ * Input properties:
+ *
+ * /instrumentation/turn-indicator/serviceable
+ * /instrumentation/turn-indicator/spin
+ * /orientation/roll-rate-degps
+ * /orientation/yaw-rate-degps
+ * /systems/electrical/outputs/turn-coordinator
+ *
+ * Output properties:
+ *
+ * /instrumentation/turn-indicator/indicated-turn-rate
+ */
+class TurnIndicator : public FGSubsystem
+{
+
+public:
+
+    TurnIndicator ();
+    virtual ~TurnIndicator ();
+
+    virtual void init ();
+    virtual void bind ();
+    virtual void unbind ();
+    virtual void update (double dt);
+
+private:
+
+    Gyro _gyro;
+    double _last_rate;
+
+    SGPropertyNode_ptr _roll_rate_node;
+    SGPropertyNode_ptr _yaw_rate_node;
+    SGPropertyNode_ptr _electric_current_node;
+    SGPropertyNode_ptr _rate_out_node;
+    
+};
+
+#endif // __INSTRUMENTS_TURN_INDICATOR_HXX