]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/models/FGMassBalance.h
sync with JSBSim CVS
[flightgear.git] / src / FDM / JSBSim / models / FGMassBalance.h
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Header:       FGMassBalance.h
4  Author:       Jon S. Berndt
5  Date started: 09/12/2000
6
7  ------------- Copyright (C) 2000  Jon S. Berndt (jon@jsbsim.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 HISTORY
27 --------------------------------------------------------------------------------
28 09/12/2000  JSB  Created
29
30 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31 SENTRY
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
33
34 #ifndef FGMASSBALANCE_H
35 #define FGMASSBALANCE_H
36
37 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38 INCLUDES
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
40
41 #include "FGModel.h"
42 #include "math/FGColumnVector3.h"
43 #include "math/FGMatrix33.h"
44 #include "input_output/FGXMLElement.h"
45 #include <vector>
46 #include <string>
47
48 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
49 DEFINITIONS
50 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
51
52 #define ID_MASSBALANCE "$Id: FGMassBalance.h,v 1.23 2011/05/20 03:18:36 jberndt Exp $"
53
54 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
55 FORWARD DECLARATIONSS
56 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
57
58 using std::string;
59
60 namespace JSBSim {
61
62 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
63 CLASS DOCUMENTATION
64 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
65
66 /** Models weight, balance and moment of inertia information.  Maintains a vector
67     of point masses. Sums the contribution of all, and provides this to FGPropagate.
68     Loads the \<mass_balance> section of the aircraft configuration file. There
69     can be any number of <pointmasses>. Each can also have a shape which - if
70     present - causes an associated moment of inertia to be calculated based on
71     the shape. Note that a cylinder is solid, a tube is hollow, a ball is solid
72     and a sphere is hollow.
73
74     <h3>Configuration File Format:</h3>
75 @code
76     <mass_balance>
77         <ixx unit="{SLUG*FT2 | KG*M2}"> {number} </ixx>
78         <iyy unit="{SLUG*FT2 | KG*M2}"> {number} </iyy>
79         <izz unit="{SLUG*FT2 | KG*M2}"> {number} </izz>
80         <ixy unit="{SLUG*FT2 | KG*M2}"> {number} </ixy>
81         <ixz unit="{SLUG*FT2 | KG*M2}"> {number} </ixz>
82         <iyz unit="{SLUG*FT2 | KG*M2}"> {number} </iyz>
83         <emptywt unit="{LBS | KG"> {number} </emptywt>
84         <location name="CG" unit="{IN | FT | M}">
85             <x> {number} </x>
86             <y> {number} </y>
87             <z> {number} </z>
88         </location>
89         [<pointmass name="{string}">
90             <form shape="{tube | cylinder | sphere | ball}">
91                <radius unit="{IN | FT | M}"> {number} </radius>
92                <length unit="{IN | FT | M}"> {number} </length>
93             </form> 
94             <weight unit="{LBS | KG}"> {number} </weight>
95             <location name="{string}" unit="{IN | FT | M}">
96                 <x> {number} </x>
97                 <y> {number} </y>
98                 <z> {number} </z>
99             </location>
100         </pointmass>
101         ... other point masses ...]
102     </mass_balance>
103 @endcode
104   */
105
106 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
107 CLASS DECLARATION
108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
109
110 class FGMassBalance : public FGModel
111 {
112
113 public:
114   FGMassBalance(FGFDMExec*);
115   ~FGMassBalance();
116
117   bool Load(Element* el);
118   bool InitModel(void);
119   /** Runs the Mass Balance model; called by the Executive
120       Can pass in a value indicating if the executive is directing the simulation to Hold.
121       @param Holding if true, the executive has been directed to hold the sim from 
122                      advancing time. Some models may ignore this flag, such as the Input
123                      model, which may need to be active to listen on a socket for the
124                      "Resume" command to be given.
125       @return false if no error */
126   bool Run(bool Holding);
127
128   double GetMass(void) const {return Mass;}
129   double GetWeight(void) const {return Weight;}
130   double GetEmptyWeight(void) const {return EmptyWeight;}
131   const FGColumnVector3& GetXYZcg(void) const {return vXYZcg;}
132   double GetXYZcg(int axis) const  {return vXYZcg(axis);}
133   const FGColumnVector3& GetDeltaXYZcg(void) const {return vDeltaXYZcg;}
134   double GetDeltaXYZcg(int axis) const  {return vDeltaXYZcg(axis);}
135
136   /** Computes the inertia contribution of a pointmass.
137       Computes and returns the inertia matrix of a pointmass of mass
138       slugs at the given vector r in the structural frame. The units
139       should be for the mass in slug and the vector in the structural
140       frame as usual in inches.
141       @param slugs the mass of this single pointmass given in slugs
142       @param r the location of this single pointmass in the structural frame
143    */
144   FGMatrix33 GetPointmassInertia(double slugs, const FGColumnVector3& r) const
145   {
146     FGColumnVector3 v = StructuralToBody( r );
147     FGColumnVector3 sv = slugs*v;
148     double xx = sv(1)*v(1);
149     double yy = sv(2)*v(2);
150     double zz = sv(3)*v(3);
151     double xy = -sv(1)*v(2);
152     double xz = -sv(1)*v(3);
153     double yz = -sv(2)*v(3);
154     return FGMatrix33( yy+zz, xy, xz,
155                        xy, xx+zz, yz,
156                        xz, yz, xx+yy );
157   }
158
159   /** Conversion from the structural frame to the body frame.
160       Converts the location given in the structural frame
161       coordinate system to the body frame. The units of the structural
162       frame are assumed to be in inches. The unit of the result is in
163       ft.
164       @param r vector coordinate in the structural reference frame (X positive
165                aft, measurements in inches).
166       @return vector coordinate in the body frame, in feet.
167    */
168   FGColumnVector3 StructuralToBody(const FGColumnVector3& r) const;
169
170   void SetEmptyWeight(double EW) { EmptyWeight = EW;}
171   void SetBaseCG(const FGColumnVector3& CG) {vbaseXYZcg = vXYZcg = CG;}
172
173   void AddPointMass(Element* el);
174   double GetTotalPointMassWeight(void);
175
176   FGColumnVector3& GetPointMassMoment(void);
177   const FGMatrix33& GetJ(void) const {return mJ;}
178   const FGMatrix33& GetJinv(void) const {return mJinv;}
179   void SetAircraftBaseInertias(FGMatrix33 BaseJ) {baseJ = BaseJ;}
180   void GetMassPropertiesReport(void) const;
181   
182 private:
183   double Weight;
184   double EmptyWeight;
185   double Mass;
186   FGMatrix33 mJ;
187   FGMatrix33 mJinv;
188   FGMatrix33 pmJ;
189   FGMatrix33 baseJ;
190   FGColumnVector3 vXYZcg;
191   FGColumnVector3 vLastXYZcg;
192   FGColumnVector3 vDeltaXYZcg;
193   FGColumnVector3 vDeltaXYZcgBody;
194   FGColumnVector3 vXYZtank;
195   FGColumnVector3 vbaseXYZcg;
196   FGColumnVector3 vPMxyz;
197   FGColumnVector3 PointMassCG;
198   FGMatrix33& CalculatePMInertias(void);
199
200
201   /** The PointMass structure encapsulates a point mass object, moments of inertia
202      mass, location, etc. */
203   struct PointMass {
204     PointMass(double w, FGColumnVector3& vXYZ) {
205       Weight = w;
206       Location = vXYZ;
207       mPMInertia.InitMatrix();
208       Radius = 0.0;
209       Length = 0.0;
210     }
211
212     void CalculateShapeInertia(void) {
213       switch(eShapeType) {
214         case esTube:
215           mPMInertia(1,1) = (Weight/(slugtolb))*Radius*Radius; // mr^2
216           mPMInertia(2,2) = (Weight/(slugtolb*12))*(6*Radius*Radius + Length*Length);
217           mPMInertia(3,3) = mPMInertia(2,2);
218           break;
219         case esCylinder:
220           mPMInertia(1,1) = (Weight/(slugtolb*2))*Radius*Radius; // 0.5*mr^2
221           mPMInertia(2,2) = (Weight/(slugtolb*12))*(3*Radius*Radius + Length*Length);
222           mPMInertia(3,3) = mPMInertia(2,2);
223           break;
224         case esSphere:
225           mPMInertia(1,1) = (Weight/(slugtolb*3))*Radius*Radius*2; // (2mr^2)/3
226           mPMInertia(2,2) = mPMInertia(1,1);
227           mPMInertia(3,3) = mPMInertia(1,1);
228         case esBall:
229           mPMInertia(1,1) = (Weight/(slugtolb*5))*Radius*Radius*2; // (2mr^2)/5
230           mPMInertia(2,2) = mPMInertia(1,1);
231           mPMInertia(3,3) = mPMInertia(1,1);
232           break;
233         default:
234           break;
235       }
236     }
237
238     enum esShape {esUnspecified, esTube, esCylinder, esSphere, esBall} eShapeType;
239     FGColumnVector3 Location;
240     double Weight; /// Weight in pounds.
241     double Radius; /// Radius in feet.
242     double Length; /// Length in feet.
243     string Name;
244     FGMatrix33 mPMInertia;
245
246     double GetPointMassLocation(int axis) const {return Location(axis);}
247     double GetPointMassWeight(void) const {return Weight;}
248     esShape GetShapeType(void) {return eShapeType;}
249     FGColumnVector3 GetLocation(void) {return Location;}
250     FGMatrix33 GetPointMassInertia(void) {return mPMInertia;}
251     string GetName(void) {return Name;}
252
253     void SetPointMassLocation(int axis, double value) {Location(axis) = value;}
254     void SetPointMassWeight(double wt) {Weight = wt;}
255     void SetPointMassShapeType(esShape st) {eShapeType = st;}
256     void SetRadius(double r) {Radius = r;}
257     void SetLength(double l) {Length = l;}
258     void SetName(string name) {Name = name;}
259     double GetPointMassMoI(int r, int c) {return mPMInertia(r,c);}
260
261     void bind(FGPropertyManager* PropertyManager, int num);
262   };
263
264   std::vector <struct PointMass*> PointMasses;
265
266   void bind(void);
267   void Debug(int from);
268 };
269 }
270 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
271 #endif