]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/heading_indicator.cxx
5ca92fd6ecf3491f81bb3728aa74120794c7d3e7
[flightgear.git] / src / Instrumentation / heading_indicator.cxx
1 // heading_indicator.cxx - a vacuum-powered heading indicator.
2 // Written by David Megginson, started 2002.
3 //
4 // This file is in the Public Domain and comes with no warranty.
5
6 #include "heading_indicator.hxx"
7 #include <Main/fg_props.hxx>
8 #include <Main/util.hxx>
9
10
11 HeadingIndicator::HeadingIndicator ()
12 {
13 }
14
15 HeadingIndicator::~HeadingIndicator ()
16 {
17 }
18
19 void
20 HeadingIndicator::init ()
21 {
22     _serviceable_node =
23         fgGetNode("/instrumentation/heading-indicator/serviceable", true);
24     _spin_node =
25         fgGetNode("/instrumentation/heading-indicator/spin", true);
26     _offset_node =
27         fgGetNode("/instrumentation/heading-indicator/offset-deg", true);
28     _heading_in_node = fgGetNode("/orientation/heading-deg", true);
29     _suction_node = fgGetNode("/systems/vacuum[0]/suction-inhg", true);
30     _heading_out_node =
31         fgGetNode("/instrumentation/heading-indicator/indicated-heading-deg",
32                   true);
33     _last_heading_deg = (_heading_in_node->getDoubleValue() +
34                          _offset_node->getDoubleValue());
35 }
36
37 void
38 HeadingIndicator::bind ()
39 {
40 }
41
42 void
43 HeadingIndicator::unbind ()
44 {
45 }
46
47 void
48 HeadingIndicator::update (double dt)
49 {
50                                 // First, calculate the bogo-spin from 0 to 1.
51                                 // All numbers are made up.
52
53     double spin = _spin_node->getDoubleValue();
54     spin -= 0.005 * dt;         // spin decays every 0.5% every second.
55
56                                 // spin increases up to 25% every second
57                                 // if suction is available and the gauge
58                                 // is serviceable.
59     if (_serviceable_node->getBoolValue()) {
60         double suction = _suction_node->getDoubleValue();
61         double step = 0.25 * (suction / 5.0) * dt;
62         if ((spin + step) <= (suction / 5.0))
63             spin += step;
64     }
65     if (spin > 1.0)
66         spin = 1.0;
67     else if (spin < 0.0)
68         spin = 0.0;
69     _spin_node->setDoubleValue(spin);
70
71                                 // Next, calculate time-based precession
72     double offset = _offset_node->getDoubleValue();
73     offset -= dt * (0.25 / 60.0); // 360deg/day
74     while (offset < -360)
75         offset += 360;
76     while (offset > 360)
77         offset -= 360;
78     _offset_node->setDoubleValue(offset);
79
80                                 // TODO: movement-induced error
81
82                                 // Next, calculate the indicated heading,
83                                 // introducing errors.
84     double factor = 0.01 / (spin * spin * spin * spin * spin * spin);
85     double heading = _heading_in_node->getDoubleValue();
86
87                                 // Now, we have to get the current
88                                 // heading and the last heading into
89                                 // the same range.
90     while ((heading - _last_heading_deg) > 180)
91         _last_heading_deg += 360;
92     while ((heading - _last_heading_deg) < -180)
93         _last_heading_deg -= 360;
94
95     heading = fgGetLowPass(_last_heading_deg, heading, dt/factor);
96     _last_heading_deg = heading;
97
98     heading += offset;
99     while (heading < 0)
100         heading += 360;
101     while (heading > 360)
102         heading -= 360;
103
104     _heading_out_node->setDoubleValue(heading);
105 }
106
107 // end of heading_indicator.cxx