]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/models/FGGasCell.h
Update to the latest version of JSBSim which supports Lighter Than Air craft
[flightgear.git] / src / FDM / JSBSim / models / FGGasCell.h
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Header:       FGGasCell.h
4  Author:       Anders Gidenstam
5  Date started: 01/21/2006
6
7  ----- Copyright (C) 2006 - 2008  Anders Gidenstam (anders(at)gidenstam.org) --
8
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
17  details.
18
19  You should have received a copy of the GNU Lesser General Public License along with
20  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21  Place - Suite 330, Boston, MA  02111-1307, USA.
22
23  Further information about the GNU Lesser General Public License can also be found on
24  the world wide web at http://www.gnu.org.
25
26 FUNCTIONAL DESCRIPTION
27 --------------------------------------------------------------------------------
28
29 This class simulates a generic gas cell for static buoyancy.
30
31 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32 SENTRY
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
34
35 #ifndef FGGasCell_H
36 #define FGGasCell_H
37
38 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39 INCLUDES
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
41
42 #include <FGJSBBase.h>
43 #include <input_output/FGXMLElement.h>
44 #include <math/FGColumnVector3.h>
45 #include <models/propulsion/FGForce.h>
46 #include <math/FGFunction.h>
47
48 #ifdef FGFS
49 #  include <simgear/compiler.h>
50 #  include STL_STRING
51   SG_USING_STD(string);
52   SG_USING_STD(cerr);
53   SG_USING_STD(endl);
54   SG_USING_STD(cout);
55 #else
56 # include <string>
57   using std::string;
58 # if !defined(sgi) || defined(__GNUC__) || (_COMPILER_VERSION >= 740)
59    using std::cerr;
60    using std::endl;
61    using std::cout;
62 # endif
63 #endif
64
65 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66 DEFINITIONS
67 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
68
69 #define ID_GASCELL "$Id$"
70
71 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72 FORWARD DECLARATIONS
73 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
74
75 namespace JSBSim {
76
77 class FGBallonet;
78
79 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80 CLASS DOCUMENTATION
81 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
82
83 /** Models a gas cell.
84     @author Anders Gidenstam
85
86 <h3>Configuration File Format:</h3>
87 @code
88 <buoyant_forces>
89   <gas_cell type="{HYDROGEN | HELIUM | AIR}">
90     <location unit="{M | IN}">
91       <x> {number} </x>
92       <y> {number} </y>
93       <z> {number} </z>
94     </location>
95     <x_width unit="{M | IN}"> {number} </x_width>
96     <y_radius unit="{M | IN}"> {number} </y_radius>
97     <z_radius unit="{M | IN}"> {number} </z_radius>
98     <max_overpressure unit="{PA | PSI}"> {number} </max_overpressure>
99     <valve_coefficient unit="{M4*SEC/KG | FT4*SEC/SLUG}"> {number} </valve_coefficient>
100     <fullness> {number} </fullness>  
101     <heat>
102       {heat transfer coefficients} [lbs ft / sec]
103     </heat>
104     <ballonet>
105       <location unit="{M | IN}">
106         <x> {number} </x>
107         <y> {number} </y>
108         <z> {number} </z>
109       </location>
110       <x_width unit="{M | IN}"> {number} </x_width>
111       <y_radius unit="{M | IN}"> {number} </y_radius>
112       <z_radius unit="{M | IN}"> {number} </z_radius>
113       <max_overpressure unit="{PA | PSI}"> {number} </max_overpressure>
114       <valve_coefficient unit="{M4*SEC/KG | FT4*SEC/SLUG}"> {number} </valve_coefficient>
115       <fullness> {number} </fullness>  
116       <heat>
117        {heat transfer coefficients} [lb ft / (sec Rankine)]
118       </heat>
119       <blower_input>
120        {input air flow function} [ft^3 / sec]
121       </blower_input>
122     </ballonet>
123   </gas_cell>
124 </buoyant_forces>
125 @endcode
126
127 Definition of the gas cell configuration file parameters:
128 - <b>type</b> -
129     One of HYDROGEN, HELIUM or AIR.
130 - <b>location</b> -
131     Location of cell center in the aircraft's structural frame.
132     Currently this is were the forces of the cell is applied.
133 - <b>{x|y|z}_radius</b> -
134     Radius along in the respective direction (both ends).
135 - <b>{x|y|z}_width</b> -
136     Width in the respective direction.
137     <b>NOTE:</b> A 'x', 'y', 'z'-radius/width combination must be specified.
138 - <b>fullness</b> -
139     Initial fullness of the cell, normally [0,1],
140     values >1 initialize the cell at pressure.
141 - <b>max_overpressure</b> -
142     Maximum cell overpressure (excess is automatically valved off).
143 - <b>valve_coefficient</b> -
144     Capacity of the manual valve. The valve is
145     considered to be located at the top of the cell.
146     The valve coefficient determine the flow out
147     of the cell according to:
148     <i>dVolume/dt = ValveCoefficient * DeltaPressure</i>.
149 - <b>heat</b> -
150     Zero or more FGFunction:s describing the heat flow from
151     the atmosphere into the gas cell.
152     Unit: [lb ft / (sec Rankine)].
153     If there are no heat transfer functions at all the gas cell
154     temperature will equal that of the surrounding atmosphere.
155     A constant function returning 0 results in adiabatic behaviour.
156 - <b>ballonet</b> -
157     Zero or more ballonets, i.e. air bags inside the gas cell.
158     Ballonets are used to maintain the volume of the gas cell
159     and keep its internal pressure higher than that of the
160     surrounding environment.
161   - <b>location</b> -
162       Location of ballonet center in the aircraft's structural frame.
163   - <b>{x|y|z}_radius</b> -
164       Radius along in the respective direction (both ends).
165   - <b>{x|y|z}_width</b> -
166       Width in the respective direction.
167   - <b>max_overpressure</b> -
168       Maximum ballonet overpressure (excess is automatically valved off).
169   - <b>valve_coefficient</b> -
170       Capacity of the exit valve between the ballonet
171       and the atmosphere. The valve coefficient
172       determine the flow out of the cell according to:
173       <i>dVolume/dt = ValveCoefficient * DeltaPressure</i>.
174   - <b>heat</b> -
175       Zero or more FGFunction:s describing the heat flow from
176       the enclosing gas cell into the ballonet.
177       Unit: [lb ft / (sec Rankine)]
178   - <b>blower_input</b> -
179       One FGFunction describing the air flow into the
180       ballonet. Unit: [ft<sup>3</sup> / sec] (at the temperature and
181       pressure of the ballonet.)
182   */
183
184 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
185 CLASS DECLARATION
186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
187 class FGGasCell : public FGForce
188 {
189 public:
190   /** Constructor
191       @param exec Executive a pointer to the parent executive object
192       @param el   Pointer to configuration file XML node
193       @param num  Gas cell index number. */
194   FGGasCell(FGFDMExec* exec, Element* el, int num);
195   ~FGGasCell();
196
197   /** Runs the gas cell model; called by BuoyantForces
198    */
199   void Calculate(double dt);
200
201   /** Get the index of this gas cell
202       @return gas cell index. */
203   int GetIndex(void) {return CellNum;}
204
205   /** Get the center of gravity location of the gas cell
206       (including any ballonets)
207       @return CoG location in the structural frame. */
208   const FGColumnVector3& GetXYZ(void) {return vXYZ;}
209
210   /** Get the center of gravity location of the gas cell
211       (including any ballonets)
212       @return CoG location in the structural frame. */
213   double GetXYZ(int idx) {return vXYZ(idx);}
214
215   /** Get the current mass of the gas cell (including any ballonets)
216       @return gas mass in slug. */
217   double GetMass(void) {return Mass;}
218
219   /** Get the moments of inertia of the gas cell (including any ballonets)
220       @return moments of inertia matrix in slug ft<sup>2</sup>. */
221   FGMatrix33& GetInertia(void) {return gasCellJ;}
222
223   /** Get the moment due to mass of the gas cell (including any ballonets)
224
225       Note that the buoyancy of the gas cell is handled separately by the
226       FGForce part and not included here.
227       @return moment vector in lbs ft. */
228   FGColumnVector3& GetMassMoment(void) {return gasCellM;}
229
230   /** Get the current gas temperature inside the gas cell
231       @return gas temperature in Rankine. */
232   double GetTemperature(void) {return Temperature;}
233
234   /** Get the current gas pressure inside the gas cell
235       @return gas pressure in lbs / ft<sup>2</sup>. */
236   double GetPressure(void) {return Pressure;}
237
238 private:
239
240   enum GasType {ttUNKNOWN, ttHYDROGEN, ttHELIUM, ttAIR};
241
242   GasType Type;
243   string type;
244   int CellNum;
245   // Structural constants
246   double MaxVolume;                 // [ft�]
247   double MaxOverpressure;           // [lbs/ft�]
248   FGColumnVector3 vXYZ;             // [in]
249   double Xradius, Yradius, Zradius; // [ft]
250   double Xwidth, Ywidth, Zwidth;    // [ft]
251   double ValveCoefficient;          // [ft^4 sec / slug]
252   typedef vector <FGFunction*> CoeffArray;
253   CoeffArray HeatTransferCoeff;
254   typedef vector <FGBallonet*> BallonetArray;
255   BallonetArray Ballonet;
256   // Variables
257   double Pressure;          // [lbs/ft�]
258   double Contents;          // [mol]
259   double Volume;            // [ft�]
260   double dVolumeIdeal;      // [ft�]
261   double Temperature;       // [Rankine]
262   double Buoyancy;          // [lbs] Note: Gross lift.
263                             // Does not include the weight of the gas itself.
264   double ValveOpen;         // 0 <= ValveOpen <= 1 (or higher).
265   double Mass;              // [slug]
266   FGMatrix33 gasCellJ;      // [slug foot�]
267   FGColumnVector3 gasCellM; // [lbs ft]
268
269   FGAuxiliary* Auxiliary;
270   FGAtmosphere* Atmosphere;
271   FGPropertyManager* PropertyManager;
272   FGInertial* Inertial;
273   FGMassBalance* MassBalance;
274   void Debug(int from);
275
276   /* Constants. */
277   const static double R;          // [lbs ft/(mol Rankine)]
278   const static double M_air;      // [slug/mol]
279   const static double M_hydrogen; // [slug/mol]
280   const static double M_helium;   // [slug/mol]
281
282   double M_gas() {                // [slug/mol]
283     switch (Type) {
284     case ttHYDROGEN:
285       return M_hydrogen;
286     case ttHELIUM:
287       return M_helium;
288     case ttAIR:
289       return M_air;
290     default:
291       return M_air;
292     }
293   }
294
295   double Cv_gas() {               // [??]
296     switch (Type) {
297     case ttHYDROGEN:
298       return 5.0/2.0;
299     case ttHELIUM:
300       return 3.0/2.0;
301     case ttAIR:
302       return 5.0/2.0;
303     default:
304       return 5.0/2.0;
305     }
306   }
307
308 };
309
310 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
311 /** Models a ballonet inside a gas cell.
312     Models a ballonet inside a gas cell.
313     Not intended to be used outside FGGasCell.
314     See FGGasCell for the configuration file format.
315     @author Anders Gidenstam
316 */
317 class FGBallonet : public FGJSBBase
318 {
319 public:
320   FGBallonet(FGFDMExec* exec, Element* el, int num, FGGasCell* parent);
321   ~FGBallonet();
322
323   /** Runs the ballonet model; called by FGGasCell
324    */
325   void Calculate(double dt);
326
327
328   /** Get the center of gravity location of the ballonet
329       @return CoG location in the structural frame. */
330   const FGColumnVector3& GetXYZ(void) {return vXYZ;}
331   /** Get the center of gravity location of the ballonet
332       @return CoG location in the structural frame. */
333   double GetXYZ(int idx) {return vXYZ(idx);}
334
335   /** Get the current mass of the ballonets
336       @return mass in slug. */
337   double GetMass(void) {return Contents * M_air;}
338
339   /** Get the moments of inertia of the ballonet
340       @return moments of inertia matrix in slug ft<sup>2</sup>. */
341   FGMatrix33& GetInertia(void) {return ballonetJ;}
342
343   /** Get the current volume of the ballonet
344       @return volume in ft<sup>3</sup>. */
345   double GetVolume(void) {return Volume;}
346   /** Get the current heat flow into the ballonet
347       @return heat flow in lbs ft / sec. */
348   double GetHeatFlow(void) {return dU;}             // [lbs ft / sec]
349
350 private:
351   int CellNum;
352   // Structural constants
353   double MaxVolume;                 // [ft�]
354   double MaxOverpressure;           // [lbs/ft�]
355   FGColumnVector3 vXYZ;             // [in]
356   double Xradius, Yradius, Zradius; // [ft]
357   double Xwidth, Ywidth, Zwidth;    // [ft]
358   double ValveCoefficient;          // [ft^4 sec / slug]
359   typedef vector <FGFunction*> CoeffArray;
360   CoeffArray HeatTransferCoeff;     // [lbs ft / sec]
361   FGFunction* BlowerInput;          // [ft^3 / sec]
362   FGGasCell* Parent;
363   // Variables
364   double Pressure;         // [lbs/ft�]
365   double Contents;         // [mol]
366   double Volume;           // [ft�]
367   double dVolumeIdeal;     // [ft�]
368   double dU;               // [lbs ft / sec]
369   double Temperature;      // [Rankine]
370   double ValveOpen;        // 0 <= ValveOpen <= 1 (or higher).
371   FGMatrix33 ballonetJ;     // [slug foot�]
372
373   FGAuxiliary* Auxiliary;
374   FGAtmosphere* Atmosphere;
375   FGPropertyManager* PropertyManager;
376   FGInertial* Inertial;
377   void Debug(int from);
378
379   /* Constants. */
380   const static double R;          // [lbs ft/(mol Rankine)]
381   const static double M_air;      // [slug/mol]
382   const static double Cv_air;     // [??]
383 };
384 }
385 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
386 #endif