1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 Header: FGMassBalance.h
5 Date started: 09/12/2000
7 ------------- Copyright (C) 2000 Jon S. Berndt (jon@jsbsim.org) --------------
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
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
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.
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.
27 --------------------------------------------------------------------------------
28 09/12/2000 JSB Created
30 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
34 #ifndef FGMASSBALANCE_H
35 #define FGMASSBALANCE_H
37 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
42 #include "math/FGColumnVector3.h"
43 #include "math/FGMatrix33.h"
44 #include "input_output/FGXMLElement.h"
48 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
50 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
52 #define ID_MASSBALANCE "$Id: FGMassBalance.h,v 1.27 2011/11/09 21:58:26 bcoconni Exp $"
54 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
56 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
62 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
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.
74 <h3>Configuration File Format:</h3>
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}">
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>
94 <weight unit="{LBS | KG}"> {number} </weight>
95 <location name="{string}" unit="{IN | FT | M}">
101 ... other point masses ...]
106 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
110 class FGMassBalance : public FGModel
114 FGMassBalance(FGFDMExec*);
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);
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);}
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 mass_sl the mass of this single pointmass given in slugs
142 @param r the location of this single pointmass in the structural frame
144 FGMatrix33 GetPointmassInertia(double mass_sl, const FGColumnVector3& r) const
146 FGColumnVector3 v = StructuralToBody( r );
147 FGColumnVector3 sv = mass_sl*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,
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
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.
168 FGColumnVector3 StructuralToBody(const FGColumnVector3& r) const;
170 void SetEmptyWeight(double EW) { EmptyWeight = EW;}
171 void SetBaseCG(const FGColumnVector3& CG) {vbaseXYZcg = vXYZcg = CG;}
173 void AddPointMass(Element* el);
174 double GetTotalPointMassWeight(void) const;
176 const FGColumnVector3& GetPointMassMoment(void);
177 const FGMatrix33& GetJ(void) const {return mJ;}
178 const FGMatrix33& GetJinv(void) const {return mJinv;}
179 void SetAircraftBaseInertias(const FGMatrix33& BaseJ) {baseJ = BaseJ;}
180 void GetMassPropertiesReport(void) const;
185 FGColumnVector3 GasMoment;
186 FGMatrix33 GasInertia;
187 FGColumnVector3 TanksMoment;
188 FGMatrix33 TankInertia;
199 FGColumnVector3 vXYZcg;
200 FGColumnVector3 vLastXYZcg;
201 FGColumnVector3 vDeltaXYZcg;
202 FGColumnVector3 vDeltaXYZcgBody;
203 FGColumnVector3 vXYZtank;
204 FGColumnVector3 vbaseXYZcg;
205 FGColumnVector3 vPMxyz;
206 FGColumnVector3 PointMassCG;
207 const FGMatrix33& CalculatePMInertias(void);
210 /** The PointMass structure encapsulates a point mass object, moments of inertia
211 mass, location, etc. */
213 PointMass(double w, FGColumnVector3& vXYZ) {
216 mPMInertia.InitMatrix();
221 void CalculateShapeInertia(void) {
224 mPMInertia(1,1) = (Weight/(slugtolb))*Radius*Radius; // mr^2
225 mPMInertia(2,2) = (Weight/(slugtolb*12))*(6*Radius*Radius + Length*Length);
226 mPMInertia(3,3) = mPMInertia(2,2);
229 mPMInertia(1,1) = (Weight/(slugtolb*2))*Radius*Radius; // 0.5*mr^2
230 mPMInertia(2,2) = (Weight/(slugtolb*12))*(3*Radius*Radius + Length*Length);
231 mPMInertia(3,3) = mPMInertia(2,2);
234 mPMInertia(1,1) = (Weight/(slugtolb*3))*Radius*Radius*2; // (2mr^2)/3
235 mPMInertia(2,2) = mPMInertia(1,1);
236 mPMInertia(3,3) = mPMInertia(1,1);
238 mPMInertia(1,1) = (Weight/(slugtolb*5))*Radius*Radius*2; // (2mr^2)/5
239 mPMInertia(2,2) = mPMInertia(1,1);
240 mPMInertia(3,3) = mPMInertia(1,1);
247 enum esShape {esUnspecified, esTube, esCylinder, esSphere, esBall} eShapeType;
248 FGColumnVector3 Location;
249 double Weight; /// Weight in pounds.
250 double Radius; /// Radius in feet.
251 double Length; /// Length in feet.
253 FGMatrix33 mPMInertia;
255 double GetPointMassLocation(int axis) const {return Location(axis);}
256 double GetPointMassWeight(void) const {return Weight;}
257 esShape GetShapeType(void) {return eShapeType;}
258 const FGColumnVector3& GetLocation(void) {return Location;}
259 const FGMatrix33& GetPointMassInertia(void) {return mPMInertia;}
260 const string& GetName(void) {return Name;}
262 void SetPointMassLocation(int axis, double value) {Location(axis) = value;}
263 void SetPointMassWeight(double wt) {Weight = wt;}
264 void SetPointMassShapeType(esShape st) {eShapeType = st;}
265 void SetRadius(double r) {Radius = r;}
266 void SetLength(double l) {Length = l;}
267 void SetName(string name) {Name = name;}
268 double GetPointMassMoI(int r, int c) {return mPMInertia(r,c);}
270 void bind(FGPropertyManager* PropertyManager, int num);
273 std::vector <struct PointMass*> PointMasses;
276 void Debug(int from);
279 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%