1
0
Fork 0

Use angular momentum so that the compass can overshoot and oscillate

before settling.
This commit is contained in:
david 2004-11-06 16:23:18 +00:00
parent 079bc3196e
commit 2f13bafff5

View file

@ -11,6 +11,7 @@
#endif #endif
#include <plib/sg.h> #include <plib/sg.h>
#include <simgear/sg_inlines.h>
#include "mag_compass.hxx" #include "mag_compass.hxx"
#include <Main/fg_props.hxx> #include <Main/fg_props.hxx>
@ -76,8 +77,6 @@ MagCompass::init ()
_z_accel_node = _z_accel_node =
fgGetNode("/accelerations/pilot/z-accel-fps_sec", true); fgGetNode("/accelerations/pilot/z-accel-fps_sec", true);
_out_node = node->getChild("indicated-heading-deg", 0, true); _out_node = node->getChild("indicated-heading-deg", 0, true);
_serviceable_node->setBoolValue(true);
} }
@ -85,18 +84,17 @@ void
MagCompass::update (double delta_time_sec) MagCompass::update (double delta_time_sec)
{ {
// This is the real magnetic // This is the real magnetic
// heading, which will almost // which would be displayed
// never appear. // if the compass had no errors.
double heading_mag_deg = _heading_node->getDoubleValue(); 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()) if (!_serviceable_node->getBoolValue())
return; return;
/* // jam on excessive sideslip
Jam on an excessive sideslip.
*/
if (fabs(_beta_node->getDoubleValue()) > 12.0) { if (fabs(_beta_node->getDoubleValue()) > 12.0) {
_rate_degps = 0.0; _rate_degps = 0.0;
return; return;
@ -114,10 +112,11 @@ MagCompass::update (double delta_time_sec)
Hc = atan2(sin(Hm)cos(theta)-tan(mu)sin(theta), cos(Hm)) Hc = atan2(sin(Hm)cos(theta)-tan(mu)sin(theta), cos(Hm))
This function changes the variable names to the more common This function changes the variable names to the more common psi
psi for the heading, theta for the pitch, and phi for the for the heading, theta for the pitch, and phi for the roll (and
roll. It also modifies the equation to incorporate pitch target_deg for Hc). It also modifies the equation to
as well as roll, as suggested by Chris Metzler. incorporate pitch as well as roll, as suggested by Chris
Metzler.
*/ */
// bank angle (radians) // bank angle (radians)
@ -153,7 +152,7 @@ MagCompass::update (double delta_time_sec)
phi -= 0.07 * y_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 // these are expensive: don't repeat
@ -172,13 +171,28 @@ MagCompass::update (double delta_time_sec)
- sin_theta * sin_mu; - sin_theta * sin_mu;
// This is the value that the compass // This is the value that the compass
// is *trying* to display, but it // is *trying* to display.
// takes time to move there, and because double target_deg = atan2(a, b) * SGD_RADIANS_TO_DEGREES;
// of momentum, the compass will often double old_deg = _out_node->getDoubleValue();
// overshoot.
double Hc = atan2(a, b) * SGD_RADIANS_TO_DEGREES;
_out_node->setDoubleValue(Hc); 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 // end of altimeter.cxx