]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/steam.cxx
Updates to vacuum system model from Alex Perry.
[flightgear.git] / src / Cockpit / steam.cxx
1 // steam.cxx - Steam Gauge Calculations
2 //
3 // Copyright (C) 2000  Alexander Perry - alex.perry@ieee.org
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License as
7 // published by the Free Software Foundation; either version 2 of the
8 // License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 //
19 // $Id$
20
21
22 #ifdef HAVE_CONFIG_H
23 #  include <config.h>
24 #endif
25
26 #if defined( FG_HAVE_NATIVE_SGI_COMPILERS )
27 #  include <iostream.h>
28 #else
29 #  include <iostream>
30 #endif
31
32 #include <simgear/constants.h>
33 #include <simgear/math/fg_types.hxx>
34 #include <Main/options.hxx>
35 #include <Main/bfi.hxx>
36
37 FG_USING_NAMESPACE(std);
38
39 #include "steam.hxx"
40
41
42 \f
43 ////////////////////////////////////////////////////////////////////////
44 // Declare the functions that read the variables
45 ////////////////////////////////////////////////////////////////////////
46
47 // Anything that reads the BFI directly is not implemented at all!
48
49
50 double FGSteam::the_STATIC_inhg = 29.92;
51 double FGSteam::the_ALT_ft = 0.0;
52 double FGSteam::get_ALT_ft() { _CatchUp(); return the_ALT_ft; }
53
54 double FGSteam::get_ASI_kias() { return FGBFI::getAirspeed(); }
55
56 double FGSteam::the_VSI_case = 29.92;
57 double FGSteam::the_VSI_fps = 0.0;
58 double FGSteam::get_VSI_fps() { _CatchUp(); return the_VSI_fps; }
59
60 double FGSteam::the_VACUUM_inhg = 0.0;
61 double FGSteam::get_VACUUM_inhg() { _CatchUp(); return the_VACUUM_inhg; }
62
63 double FGSteam::get_MH_deg () { return FGBFI::getHeading (); }
64 double FGSteam::get_DG_deg () { return FGBFI::getHeading (); }
65
66 double FGSteam::get_TC_rad   () { return FGBFI::getSideSlip (); }
67 double FGSteam::get_TC_radps () { return FGBFI::getRoll (); }
68
69
70 \f
71 ////////////////////////////////////////////////////////////////////////
72 // Recording the current time
73 ////////////////////////////////////////////////////////////////////////
74
75
76 int FGSteam::_UpdatesPending = 9999;  /* Forces filter to reset */
77
78
79 void FGSteam::update ( int timesteps )
80 {
81         _UpdatesPending += timesteps;
82 }
83
84
85 void FGSteam::set_lowpass ( double *outthe, double inthe, double tc )
86 {
87         if ( tc < 0.0 )
88         {       if ( tc < -1.0 )
89                 {       /* time went backwards; kill the filter */
90                         (*outthe) = inthe;
91                 } else
92                 {       /* ignore mildly negative time */
93                 }
94         } else
95         if ( tc < 0.2 )
96         {       /* Normal mode of operation */
97                 (*outthe) = (*outthe) * ( 1.0 - tc )
98                           +    inthe  * tc;
99         } else
100         if ( tc > 5.0 )
101         {       /* Huge time step; assume filter has settled */
102                 (*outthe) = inthe;
103         } else
104         {       /* Moderate time step; non linear response */
105                 double keep = exp ( -tc );
106                 printf ( "ARP: Keep is %f\n", keep );
107                 (*outthe) = (*outthe) * keep
108                           +    inthe  * ( 1.0 - keep );
109         }
110 }
111
112
113 \f
114 ////////////////////////////////////////////////////////////////////////
115 // Here the fun really begins
116 ////////////////////////////////////////////////////////////////////////
117
118
119 void FGSteam::_CatchUp()
120 { if ( _UpdatesPending != 0 )
121   {     double dt = _UpdatesPending * 1.0 / current_options.get_model_hz();
122         int i,j;
123         double d, the_ENGINE_rpm;
124         /*
125         Someone has called our update function and
126         it turns out that we are running somewhat behind.
127         Here, we recalculate everything for a 'dt' second step.
128         */
129
130         /**************************
131         This is not actually correct, but provides a
132         scaling capability for the vacuum pump later on.
133         When we have a real engine model, we can ask it.
134         */
135         the_ENGINE_rpm = FGBFI::getThrottle() * 26.0;
136
137         /**************************
138         This is just temporary, until the static source works,
139         so we just filter the actual value by one second to
140         account for the line impedance of the plumbing.
141         */
142         set_lowpass ( & the_ALT_ft, FGBFI::getAltitude(), dt );
143
144         /**************************
145         First, we need to know what the static line is reporting,
146         which is a whole simulation area in itself.  For now, we cheat.
147         */
148         the_STATIC_inhg = 29.92; 
149         i = (int) the_ALT_ft;
150         while ( i > 9000 )
151         {       the_STATIC_inhg *= 0.707;
152                 i -= 9000;
153         }
154         the_STATIC_inhg *= ( 1.0 - 0.293 * i / 9000.0 );
155
156         /*
157         NO alternate static source error (student feature), 
158         NO possibility of blockage (instructor feature),
159         NO slip-induced error, important for C172 for example.
160         */
161
162         /**************************
163         The VSI case is a low-pass filter of the static line pressure.
164         The instrument reports the difference, scaled to approx ft.
165         NO option for student to break glass when static source fails.
166         NO capability for a fixed non-zero reading when level.
167         NO capability to have a scaling error of maybe a factor of two.
168         */
169         the_VSI_fps = ( the_VSI_case - the_STATIC_inhg )
170                     * 7000.0; /* manual scaling factor */       
171         set_lowpass ( & the_VSI_case, the_STATIC_inhg, dt/9.0 );
172
173         /**************************
174         The engine driven vacuum pump is directly attached
175         to the engine shaft, so each engine rotation pumps
176         a fixed volume.  The amount of air in that volume
177         is determined by the vacuum line's internal pressure.
178         The instruments are essentially leaking air like
179         a fixed source impedance from atmospheric pressure.
180         The regulator provides a digital limit setting,
181         which is open circuit unless the pressure drop is big.
182         Thus, we can compute the vacuum line pressure directly.
183         We assume that there is negligible reservoir space.
184         NO failure of the pump supported (yet)
185         */
186         the_VACUUM_inhg = the_STATIC_inhg *
187                 the_ENGINE_rpm / ( the_ENGINE_rpm + 10000.0 );
188         if ( the_VACUUM_inhg > 5.0 )
189              the_VACUUM_inhg = 5.0;
190
191 /*
192 > I was merely going to do the engine rpm driven vacuum pump for both
193 > the AI and DG, have the gyros spin down down in power off descents, 
194 > have it tumble when you exceed the usual pitch or bank limits,
195 > put in those insidious turning errors ... for now anyway.
196 */
197
198         /**************************
199         Finished updates, now clear the timer 
200         */
201         _UpdatesPending = 0;
202   }
203 }
204
205
206 // end of steam.cxx