1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 Header: FGAccelerations.h
7 ------------- Copyright (C) 2011 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 --------------------------------------------------------------------------------
30 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
34 #ifndef FGACCELERATIONS_H
35 #define FGACCELERATIONS_H
37 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
43 #include "models/FGModel.h"
44 #include "math/FGColumnVector3.h"
45 #include "math/LagrangeMultiplier.h"
46 #include "math/FGMatrix33.h"
47 #include "math/FGQuaternion.h"
49 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
51 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
53 #define ID_ACCELERATIONS "$Id: FGAccelerations.h,v 1.12 2012/02/19 14:07:27 bcoconni Exp $"
55 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
57 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
61 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
63 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
65 /** Handles the calculation of accelerations.
67 - Calculate the angular accelerations
68 - Calculate the translational accelerations
69 - Calculate the angular rate
70 - Calculate the translational velocity
72 This class is collecting all the forces and the moments acting on the body
73 to calculate the corresponding accelerations according to Newton's second
74 law. This is also where the friction forces related to the ground reactions
77 JSBSim provides several ways to calculate the influence of the gravity on
78 the vehicle. The different options can be selected via the following
80 @property simulation/gravity-model (read/write) Selects the gravity model.
81 Two options are available : 0 (Standard gravity assuming the Earth
82 is spherical) or 1 (WGS84 gravity taking the Earth oblateness into
83 account). WGS84 gravity is the default.
84 @property simulation/gravitational-torque (read/write) Enables/disables the
85 calculations of the gravitational torque on the vehicle. This is
86 mainly relevant for spacecrafts that are orbiting at low altitudes.
87 Gravitational torque calculations are disabled by default.
89 Special care is taken in the calculations to obtain maximum fidelity in
90 JSBSim results. In FGAccelerations, this is obtained by avoiding as much as
91 possible the transformations from one frame to another. As a consequence,
92 the frames in which the accelerations are primarily evaluated are dictated
93 by the frames in which FGPropagate resolves the equations of movement (the
94 ECI frame for the translations and the body frame for the rotations).
96 @see Mark Harris and Robert Lyle, "Spacecraft Gravitational Torques",
97 NASA SP-8024, May 1969
99 @author Jon S. Berndt, Mathias Froehlich, Bertrand Coconnier
100 @version $Id: FGAccelerations.h,v 1.12 2012/02/19 14:07:27 bcoconni Exp $
103 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
107 class FGAccelerations : public FGModel {
110 @param Executive a pointer to the parent executive object */
111 FGAccelerations(FGFDMExec* Executive);
116 /// These define the indices use to select the gravitation models.
118 /// Evaluate gravity using Newton's classical formula assuming the Earth is spherical
120 /// Evaluate gravity using WGS84 formulas that take the Earth oblateness into account
124 /** Initializes the FGAccelerations class after instantiation and prior to first execution.
125 The base class FGModel::InitModel is called first, initializing pointers to the
126 other FGModel objects (and others). */
127 bool InitModel(void);
129 /** Runs the state propagation model; called by the Executive
130 Can pass in a value indicating if the executive is directing the simulation to Hold.
131 @param Holding if true, the executive has been directed to hold the sim from
132 advancing time. Some models may ignore this flag, such as the Input
133 model, which may need to be active to listen on a socket for the
134 "Resume" command to be given.
135 @return false if no error */
136 bool Run(bool Holding);
138 /** Retrieves the time derivative of the body orientation quaternion.
139 Retrieves the time derivative of the body orientation quaternion based on
140 the rate of change of the orientation between the body and the ECI frame.
141 The quaternion returned is represented by an FGQuaternion reference. The
142 quaternion is 1-based, so that the first element can be retrieved using
145 @return The time derivative of the body orientation quaternion.
147 const FGQuaternion& GetQuaterniondot(void) const {return vQtrndot;}
149 /** Retrieves the body axis acceleration.
150 Retrieves the computed body axis accelerations based on the
151 applied forces and accounting for a rotating body frame.
152 The vector returned is represented by an FGColumnVector3 reference. The vector
153 for the acceleration in Body frame is organized (Ax, Ay, Az). The vector
154 is 1-based, so that the first element can be retrieved using the "()" operator.
155 In other words, vUVWdot(1) is Ax. Various convenience enumerators are defined
156 in FGJSBBase. The relevant enumerators for the vector returned by this call are,
159 @return Body axis translational acceleration in ft/sec^2.
161 const FGColumnVector3& GetUVWdot(void) const { return vUVWdot; }
163 /** Retrieves the body axis acceleration in the ECI frame.
164 Retrieves the computed body axis accelerations based on the applied forces.
165 The ECI frame being an inertial frame this vector does not contain the
166 Coriolis and centripetal accelerations. The vector is expressed in the
168 The vector returned is represented by an FGColumnVector3 reference. The
169 vector for the acceleration in Body frame is organized (Aix, Aiy, Aiz). The
170 vector is 1-based, so that the first element can be retrieved using the
171 "()" operator. In other words, vUVWidot(1) is Aix. Various convenience
172 enumerators are defined in FGJSBBase. The relevant enumerators for the
173 vector returned by this call are, eX=1, eY=2, eZ=3.
175 @return Body axis translational acceleration in ft/sec^2.
177 const FGColumnVector3& GetUVWidot(void) const { return vUVWidot; }
179 /** Retrieves the body axis angular acceleration vector.
180 Retrieves the body axis angular acceleration vector in rad/sec^2. The
181 angular acceleration vector is determined from the applied moments and
182 accounts for a rotating frame.
183 The vector returned is represented by an FGColumnVector3 reference. The vector
184 for the angular acceleration in Body frame is organized (Pdot, Qdot, Rdot). The vector
185 is 1-based, so that the first element can be retrieved using the "()" operator.
186 In other words, vPQRdot(1) is Pdot. Various convenience enumerators are defined
187 in FGJSBBase. The relevant enumerators for the vector returned by this call are,
190 @return The angular acceleration vector.
192 const FGColumnVector3& GetPQRdot(void) const {return vPQRdot;}
194 /** Retrieves the axis angular acceleration vector in the ECI frame.
195 Retrieves the body axis angular acceleration vector measured in the ECI
196 frame and expressed in the body frame. The angular acceleration vector is
197 determined from the applied moments.
198 The vector returned is represented by an FGColumnVector3 reference. The
199 vector for the angular acceleration in Body frame is organized (Pidot,
200 Qidot, Ridot). The vector is 1-based, so that the first element can be
201 retrieved using the "()" operator. In other words, vPQRidot(1) is Pidot.
202 Various convenience enumerators are defined in FGJSBBase. The relevant
203 enumerators for the vector returned by this call are, eP=1, eQ=2, eR=3.
205 @return The angular acceleration vector.
207 const FGColumnVector3& GetPQRidot(void) const {return vPQRidot;}
209 /** Retrieves a body frame acceleration component.
210 Retrieves a body frame acceleration component. The acceleration returned
211 is extracted from the vUVWdot vector (an FGColumnVector3). The vector for
212 the acceleration in Body frame is organized (Ax, Ay, Az). The vector is
213 1-based. In other words, GetUVWdot(1) returns Ax. Various convenience
214 enumerators are defined in FGJSBBase. The relevant enumerators for the
215 acceleration returned by this call are, eX=1, eY=2, eZ=3.
217 @param idx the index of the acceleration component desired (1-based).
218 @return The body frame acceleration component.
220 double GetUVWdot(int idx) const { return vUVWdot(idx); }
222 /** Retrieves the acceleration resulting from the applied forces.
223 Retrieves the ratio of the sum of all forces applied on the craft to its
224 mass. This does include the friction forces but not the gravity.
225 The vector returned is represented by an FGColumnVector3 reference. The
226 vector for the acceleration in Body frame is organized (Ax, Ay, Az). The
227 vector is 1-based, so that the first element can be retrieved using the
228 "()" operator. In other words, vBodyAccel(1) is Ax. Various convenience
229 enumerators are defined in FGJSBBase. The relevant enumerators for the
230 vector returned by this call are, eX=1, eY=2, eZ=3.
232 @return The acceleration resulting from the applied forces.
234 const FGColumnVector3& GetBodyAccel(void) const { return vBodyAccel; }
237 /** Retrieves a component of the acceleration resulting from the applied forces.
238 Retrieves a component of the ratio between the sum of all forces applied
239 on the craft to its mass. The value returned is extracted from the vBodyAccel
240 vector (an FGColumnVector3). The vector for the acceleration in Body frame
241 is organized (Ax, Ay, Az). The vector is 1-based. In other words,
242 GetBodyAccel(1) returns Ax. Various convenience enumerators are defined
243 in FGJSBBase. The relevant enumerators for the vector returned by this
244 call are, eX=1, eY=2, eZ=3.
246 @param idx the index of the acceleration component desired (1-based).
247 @return The component of the acceleration resulting from the applied forces.
249 double GetBodyAccel(int idx) const { return vBodyAccel(idx); }
251 /** Retrieves a body frame angular acceleration component.
252 Retrieves a body frame angular acceleration component. The angular
253 acceleration returned is extracted from the vPQRdot vector (an
254 FGColumnVector3). The vector for the angular acceleration in Body frame
255 is organized (Pdot, Qdot, Rdot). The vector is 1-based. In other words,
256 GetPQRdot(1) returns Pdot (roll acceleration). Various convenience
257 enumerators are defined in FGJSBBase. The relevant enumerators for the
258 angular acceleration returned by this call are, eP=1, eQ=2, eR=3.
260 @param axis the index of the angular acceleration component desired (1-based).
261 @return The body frame angular acceleration component.
263 double GetPQRdot(int axis) const {return vPQRdot(axis);}
265 /** Retrieves a component of the total moments applied on the body.
266 Retrieves a component of the total moments applied on the body. This does
267 include the moments generated by friction forces and the gravitational
268 torque (if the property \e simulation/gravitational-torque is set to true).
269 The vector for the total moments in the body frame is organized (Mx, My
270 , Mz). The vector is 1-based. In other words, GetMoments(1) returns Mx.
271 Various convenience enumerators are defined in FGJSBBase. The relevant
272 enumerators for the moments returned by this call are, eX=1, eY=2, eZ=3.
274 @param idx the index of the moments component desired (1-based).
275 @return The total moments applied on the body.
277 double GetMoments(int idx) const { return in.Moment(idx) + vFrictionMoments(idx); }
279 /** Retrieves the total forces applied on the body.
280 Retrieves the total forces applied on the body. This does include the
281 friction forces but not the gravity.
282 The vector for the total forces in the body frame is organized (Fx, Fy
283 , Fz). The vector is 1-based. In other words, GetForces(1) returns Fx.
284 Various convenience enumerators are defined in FGJSBBase. The relevant
285 enumerators for the forces returned by this call are, eX=1, eY=2, eZ=3.
287 @param idx the index of the forces component desired (1-based).
288 @return The total forces applied on the body.
290 double GetForces(int idx) const { return in.Force(idx) + vFrictionForces(idx); }
292 /** Retrieves the ground moments applied on the body.
293 Retrieves the ground moments applied on the body. This does include the
294 ground normal reaction and friction moments.
295 The vector for the ground moments in the body frame is organized (Mx, My
296 , Mz). The vector is 1-based. In other words, GetGroundMoments(1) returns
297 Mx. Various convenience enumerators are defined in FGJSBBase. The relevant
298 enumerators for the moments returned by this call are, eX=1, eY=2, eZ=3.
300 @param idx the index of the moments component desired (1-based).
301 @return The ground moments applied on the body.
303 double GetGroundMoments(int idx) const { return in.GroundMoment(idx) + vFrictionMoments(idx); }
305 /** Retrieves the ground forces applied on the body.
306 Retrieves the ground forces applied on the body. This does include the
307 ground normal reaction and friction forces.
308 The vector for the total moments in the body frame is organized (Fx, Fy
309 , Fz). The vector is 1-based. In other words, GetGroundForces(1) returns
310 Fx. Various convenience enumerators are defined in FGJSBBase. The relevant
311 enumerators for the forces returned by this call are, eX=1, eY=2, eZ=3.
313 @param idx the index of the forces component desired (1-based).
314 @return The ground forces applied on the body.
316 double GetGroundForces(int idx) const { return in.GroundForce(idx) + vFrictionForces(idx); }
318 /** Initializes the FGAccelerations class prior to a new execution.
319 Initializes the class prior to a new execution when the input data stored
320 in the Inputs structure have been set to their initial values.
322 void InitializeDerivatives(void);
325 /// The body inertia matrix expressed in the body frame
327 /// The inverse of the inertia matrix J
329 /// Transformation matrix from the ECI to the Body frame
331 /// Transformation matrix from the Body to the ECI frame
333 /// Transformation matrix from the ECEF to the Body frame
335 /// Transformation matrix from the ECEF to the ECI frame
337 /// Orientation quaternion of the body with respect to the ECI frame
338 FGQuaternion qAttitudeECI;
339 /// Total moments applied to the body except friction and gravity (expressed in the body frame)
340 FGColumnVector3 Moment;
341 /// Moments generated by the ground normal reactions expressed in the body frame. Does not account for friction.
342 FGColumnVector3 GroundMoment;
343 /// Total forces applied to the body except friction and gravity (expressed in the body frame)
344 FGColumnVector3 Force;
345 /// Forces generated by the ground normal reactions expressed in the body frame. Does not account for friction.
346 FGColumnVector3 GroundForce;
347 /// Gravity intensity vector using WGS84 formulas (expressed in the ECEF frame).
348 FGColumnVector3 J2Grav;
349 /// Angular velocities of the body with respect to the ECI frame (expressed in the body frame).
350 FGColumnVector3 vPQRi;
351 /// Angular velocities of the body with respect to the local frame (expressed in the body frame).
352 FGColumnVector3 vPQR;
353 /// Velocities of the body with respect to the local frame (expressed in the body frame).
354 FGColumnVector3 vUVW;
355 /// Body position (X,Y,Z) measured in the ECI frame.
356 FGColumnVector3 vInertialPosition;
357 /// Earth rotating vector (expressed in the ECI frame).
358 FGColumnVector3 vOmegaPlanet;
359 /// Terrain velocities with respect to the local frame (expressed in the ECEF frame).
360 FGColumnVector3 TerrainVelocity;
361 /// Terrain angular velocities with respect to the local frame (expressed in the ECEF frame).
362 FGColumnVector3 TerrainAngularVel;
367 /// Gravity intensity assuming the Earth is spherical
369 /// List of Lagrange multipliers set by FGLGear for friction forces calculations.
370 std::vector<LagrangeMultiplier*> *MultipliersList;
375 FGColumnVector3 vPQRdot, vPQRidot;
376 FGColumnVector3 vUVWdot, vUVWidot;
377 FGQuaternion vQtrndot;
378 FGColumnVector3 vBodyAccel;
379 FGColumnVector3 vGravAccel;
380 FGColumnVector3 vFrictionForces;
381 FGColumnVector3 vFrictionMoments;
386 void CalculatePQRdot(void);
387 void CalculateQuatdot(void);
388 void CalculateUVWdot(void);
390 void ResolveFrictionForces(double dt);
393 void Debug(int from);
396 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%