1 // heading_indicator.cxx - a vacuum-powered heading indicator.
2 // Written by David Megginson, started 2002.
4 // This file is in the Public Domain and comes with no warranty.
6 #include <simgear/compiler.h>
11 #include "heading_indicator.hxx"
12 #include <Main/fg_props.hxx>
13 #include <Main/util.hxx>
16 HeadingIndicator::HeadingIndicator ( SGPropertyNode *node )
18 _name(node->getStringValue("name", "heading-indicator")),
19 _num(node->getIntValue("number", 0)),
20 _suction(node->getStringValue("suction", "/systems/vacuum/suction-inhg"))
24 HeadingIndicator::~HeadingIndicator ()
29 HeadingIndicator::init ()
32 branch = "/instrumentation/" + _name;
34 SGPropertyNode *node = fgGetNode(branch.c_str(), _num, true );
35 _offset_node = node->getChild("offset-deg", 0, true);
36 _heading_in_node = fgGetNode("/orientation/heading-deg", true);
37 _suction_node = fgGetNode(_suction.c_str(), true);
38 _heading_out_node = node->getChild("indicated-heading-deg", 0, true);
39 _last_heading_deg = (_heading_in_node->getDoubleValue() +
40 _offset_node->getDoubleValue());
44 HeadingIndicator::bind ()
46 std::ostringstream temp;
49 branch = "/instrumentation/" + _name + "[" + temp.str() + "]";
51 fgTie((branch + "/serviceable").c_str(),
52 &_gyro, &Gyro::is_serviceable, &Gyro::set_serviceable);
53 fgTie((branch + "/spin").c_str(),
54 &_gyro, &Gyro::get_spin_norm, &Gyro::set_spin_norm);
58 HeadingIndicator::unbind ()
60 std::ostringstream temp;
63 branch = "/instrumentation/" + _name + "[" + temp.str() + "]";
65 fgUntie((branch + "/serviceable").c_str());
66 fgUntie((branch + "/spin").c_str());
70 HeadingIndicator::update (double dt)
72 // Get the spin from the gyro
73 _gyro.set_power_norm(_suction_node->getDoubleValue()/5.0);
75 double spin = _gyro.get_spin_norm();
77 // Next, calculate time-based precession
78 double offset = _offset_node->getDoubleValue();
79 offset -= dt * (0.25 / 60.0); // 360deg/day
84 _offset_node->setDoubleValue(offset);
86 // TODO: movement-induced error
88 // Next, calculate the indicated heading,
89 // introducing errors.
90 double factor = 0.01 / (spin * spin * spin * spin * spin * spin);
91 double heading = _heading_in_node->getDoubleValue();
93 // Now, we have to get the current
94 // heading and the last heading into
96 while ((heading - _last_heading_deg) > 180)
97 _last_heading_deg += 360;
98 while ((heading - _last_heading_deg) < -180)
99 _last_heading_deg -= 360;
101 heading = fgGetLowPass(_last_heading_deg, heading, dt/factor);
102 _last_heading_deg = heading;
107 while (heading > 360)
110 _heading_out_node->setDoubleValue(heading);
113 // end of heading_indicator.cxx