]> git.mxchange.org Git - flightgear.git/blobdiff - src/Instrumentation/mag_compass.cxx
reticle should fit into bounding box (don't take diameter as radius)
[flightgear.git] / src / Instrumentation / mag_compass.cxx
index e44981cf577cd9606ca2199bc5c5ee3fae5c3157..e67d35074b1d248f9e2b45e73b00535204928f5d 100644 (file)
@@ -11,6 +11,7 @@
 #endif
 
 #include <plib/sg.h>
+#include <simgear/sg_inlines.h>
 
 #include "mag_compass.hxx"
 #include <Main/fg_props.hxx>
@@ -76,8 +77,6 @@ MagCompass::init ()
     _z_accel_node =
         fgGetNode("/accelerations/pilot/z-accel-fps_sec", true);
     _out_node = node->getChild("indicated-heading-deg", 0, true);
-
-    _serviceable_node->setBoolValue(true);
 }
 
 
@@ -85,22 +84,29 @@ void
 MagCompass::update (double delta_time_sec)
 {
                                 // This is the real magnetic
-                                // heading, which will almost
-                                // never appear.
-    double heading_mag_deg = _heading_node->getDoubleValue();
+                                // which would be displayed
+                                // if the compass had no errors.
+    //double heading_mag_deg = _heading_node->getDoubleValue();
 
 
-                                // don't update if it's broken
+                                // don't update if the compass
+                                // is broken
     if (!_serviceable_node->getBoolValue())
         return;
 
     /*
-      Jam on an excessive sideslip.
-    */
+     * Vassilii: commented out because this way, even when parked,
+     * w/o any accelerations and level, the compass is jammed.
+     * If somebody wants to model jamming, real forces (i.e. accelerations)
+     * and not sideslip angle must be considered.
+     */
+#if 0
+                               // jam on excessive sideslip
     if (fabs(_beta_node->getDoubleValue()) > 12.0) {
         _rate_degps = 0.0;
         return;
     }
+#endif
 
 
     /*
@@ -114,10 +120,11 @@ MagCompass::update (double delta_time_sec)
 
       Hc = atan2(sin(Hm)cos(theta)-tan(mu)sin(theta), cos(Hm))
 
-      This function changes the variable names to the more common
-      psi for the heading, theta for the pitch, and phi for the
-      roll.  It also modifies the equation to incorporate pitch
-      as well as roll, as suggested by Chris Metzler.
+      This function changes the variable names to the more common psi
+      for the heading, theta for the pitch, and phi for the roll (and
+      target_deg for Hc).  It also modifies the equation to
+      incorporate pitch as well as roll, as suggested by Chris
+      Metzler.
     */
 
                                 // bank angle (radians)
@@ -147,13 +154,13 @@ MagCompass::update (double delta_time_sec)
     */
     double x_accel_g = _x_accel_node->getDoubleValue() / 32;
     double y_accel_g = _y_accel_node->getDoubleValue() / 32;
-    double z_accel_g = _z_accel_node->getDoubleValue() / 32;
+    //double z_accel_g = _z_accel_node->getDoubleValue() / 32;
 
     theta -= 0.07 * x_accel_g;
     phi -= 0.07 * y_accel_g;
     
     ////////////////////////////////////////////////////////////////////
-    // calculate target compass heading Hc in degrees
+    // calculate target compass heading degrees
     ////////////////////////////////////////////////////////////////////
 
                                 // these are expensive: don't repeat
@@ -172,13 +179,28 @@ MagCompass::update (double delta_time_sec)
         - sin_theta * sin_mu;
 
                                 // This is the value that the compass
-                                // is *trying* to display, but it
-                                // takes time to move there, and because
-                                // of momentum, the compass will often
-                                // overshoot.
-    double Hc = atan2(a, b) * SGD_RADIANS_TO_DEGREES;
-
-    _out_node->setDoubleValue(Hc);
+                                // is *trying* to display.
+    double target_deg = atan2(a, b) * SGD_RADIANS_TO_DEGREES;
+    double old_deg = _out_node->getDoubleValue();
+
+    while ((target_deg - old_deg) > 180.0)
+        target_deg -= 360.0;
+    while ((target_deg - old_deg) < -180.0)
+        target_deg += 360.0;
+
+                                // The compass has a current rate of
+                                // rotation -- move the rate of rotation
+                                // towards one that will turn the compass
+                                // to the correct heading, but lag a bit.
+                                // (so that the compass can keep overshooting
+                                // and coming back).
+    double error = target_deg - old_deg;
+    _rate_degps = fgGetLowPass(_rate_degps, error, delta_time_sec / 5.0);
+    double indicated_deg = old_deg + _rate_degps * delta_time_sec;
+    SG_NORMALIZE_RANGE(indicated_deg, 0.0, 360.0);
+
+                                // That's it -- set the messed-up heading.
+    _out_node->setDoubleValue(indicated_deg);
 }
 
 // end of altimeter.cxx