JSBSim Flight Dynamics Model  1.0 (02 March 2017)
An Open Source Flight Dynamics and Control Software Library in C++
FGAccelerations.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 
3  Module: FGAccelerations.cpp
4  Author: Jon S. Berndt
5  Date started: 07/12/11
6  Purpose: Calculates derivatives of rotational and translational rates, and
7  of the attitude quaternion.
8  Called by: FGFDMExec
9 
10  ------------- Copyright (C) 2011 Jon S. Berndt (jon@jsbsim.org) -------------
11 
12  This program is free software; you can redistribute it and/or modify it under
13  the terms of the GNU Lesser General Public License as published by the Free Software
14  Foundation; either version 2 of the License, or (at your option) any later
15  version.
16 
17  This program is distributed in the hope that it will be useful, but WITHOUT
18  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
20  details.
21 
22  You should have received a copy of the GNU Lesser General Public License along with
23  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
24  Place - Suite 330, Boston, MA 02111-1307, USA.
25 
26  Further information about the GNU Lesser General Public License can also be found on
27  the world wide web at http://www.gnu.org.
28 
29 FUNCTIONAL DESCRIPTION
30 --------------------------------------------------------------------------------
31 This class encapsulates the calculation of the derivatives of the state vectors
32 UVW and PQR - the translational and rotational rates relative to the planet
33 fixed frame. The derivatives relative to the inertial frame are also calculated
34 as a side effect. Also, the derivative of the attitude quaterion is also calculated.
35 
36 HISTORY
37 --------------------------------------------------------------------------------
38 07/12/11 JSB Created
39 
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41 COMMENTS, REFERENCES, and NOTES
42 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43 [1] Stevens and Lewis, "Aircraft Control and Simulation", Second edition (2004)
44  Wiley
45 [2] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
46  NASA-Ames", NASA CR-2497, January 1975
47 [3] Erin Catto, "Iterative Dynamics with Temporal Coherence", February 22, 2005
48 [4] Mark Harris and Robert Lyle, "Spacecraft Gravitational Torques",
49  NASA SP-8024, May 1969
50 
51 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52 INCLUDES
53 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
54 
55 #include "FGAccelerations.h"
56 #include "FGFDMExec.h"
57 #include "input_output/FGPropertyManager.h"
58 
59 using namespace std;
60 
61 namespace JSBSim {
62 
63 IDENT(IdSrc,"$Id: FGAccelerations.cpp,v 1.29 2016/05/22 10:28:23 bcoconni Exp $");
64 IDENT(IdHdr,ID_ACCELERATIONS);
65 
66 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
67 CLASS IMPLEMENTATION
68 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
69 
70 FGAccelerations::FGAccelerations(FGFDMExec* fdmex)
71  : FGModel(fdmex)
72 {
73  Debug(0);
74  Name = "FGAccelerations";
75  gravType = gtWGS84;
76  gravTorque = false;
77 
78  vPQRidot.InitMatrix();
79  vUVWidot.InitMatrix();
80  vUVWdot.InitMatrix();
81  vGravAccel.InitMatrix();
82  vBodyAccel.InitMatrix();
83 
84  bind();
85  Debug(0);
86 }
87 
88 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
89 
91 {
92  Debug(1);
93 }
94 
95 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
96 
98 {
99  if (!FGModel::InitModel()) return false;
100 
101  vPQRidot.InitMatrix();
102  vUVWidot.InitMatrix();
103  vUVWdot.InitMatrix();
104  vGravAccel.InitMatrix();
105  vBodyAccel.InitMatrix();
106 
107  return true;
108 }
109 
110 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
111 /*
112 Purpose: Called on a schedule to calculate derivatives.
113 */
114 
115 bool FGAccelerations::Run(bool Holding)
116 {
117  if (FGModel::Run(Holding)) return true; // Fast return if we have nothing to do ...
118  if (Holding) return false;
119 
120  CalculatePQRdot(); // Angular rate derivative
121  CalculateUVWdot(); // Translational rate derivative
122 
123  if (!FDMExec->GetHoldDown())
124  ResolveFrictionForces(in.DeltaT * rate); // Update rate derivatives with friction forces
125 
126  Debug(2);
127  return false;
128 }
129 
130 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
131 // Compute body frame rotational accelerations based on the current body moments
132 //
133 // vPQRdot is the derivative of the absolute angular velocity of the vehicle
134 // (body rate with respect to the ECEF frame), expressed in the body frame,
135 // where the derivative is taken in the body frame.
136 // J is the inertia matrix
137 // Jinv is the inverse inertia matrix
138 // vMoments is the moment vector in the body frame
139 // in.vPQRi is the total inertial angular velocity of the vehicle
140 // expressed in the body frame.
141 // Reference: See Stevens and Lewis, "Aircraft Control and Simulation",
142 // Second edition (2004), eqn 1.5-16e (page 50)
143 
144 void FGAccelerations::CalculatePQRdot(void)
145 {
146  if (gravTorque) {
147  // Compute the gravitational torque
148  // Reference: See Harris and Lyle "Spacecraft Gravitational Torques",
149  // NASA SP-8024 (1969) eqn (2) (page 7)
151  double invRadius = 1.0 / R.Magnitude();
152  R *= invRadius;
153  in.Moment += (3.0 * in.GAccel * invRadius) * (R * (in.J * R));
154  }
155 
156  // Compute body frame rotational accelerations based on the current body
157  // moments and the total inertial angular velocity expressed in the body
158  // frame.
159 // if (HoldDown && !FDMExec->GetTrimStatus()) {
160  if (FDMExec->GetHoldDown()) {
161  // The rotational acceleration in ECI is calculated so that the rotational
162  // acceleration is zero in the body frame.
163  vPQRdot.InitMatrix();
164  vPQRidot = in.vPQRi * (in.Ti2b * in.vOmegaPlanet);
165  }
166  else {
167  vPQRidot = in.Jinv * (in.Moment - in.vPQRi * (in.J * in.vPQRi));
168  vPQRdot = vPQRidot - in.vPQRi * (in.Ti2b * in.vOmegaPlanet);
169  }
170 }
171 
172 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
173 // This set of calculations results in the body and inertial frame accelerations
174 // being computed.
175 // Compute body and inertial frames accelerations based on the current body
176 // forces including centripetal and Coriolis accelerations for the former.
177 // in.vOmegaPlanet is the Earth angular rate - expressed in the inertial frame -
178 // so it has to be transformed to the body frame. More completely,
179 // in.vOmegaPlanet is the rate of the ECEF frame relative to the Inertial
180 // frame (ECI), expressed in the Inertial frame.
181 // in.Force is the total force on the vehicle in the body frame.
182 // in.vPQR is the vehicle body rate relative to the ECEF frame, expressed
183 // in the body frame.
184 // in.vUVW is the vehicle velocity relative to the ECEF frame, expressed
185 // in the body frame.
186 // Reference: See Stevens and Lewis, "Aircraft Control and Simulation",
187 // Second edition (2004), eqns 1.5-13 (pg 48) and 1.5-16d (page 50)
188 
189 void FGAccelerations::CalculateUVWdot(void)
190 {
191  if (FDMExec->GetHoldDown() && !FDMExec->GetTrimStatus())
192  vBodyAccel.InitMatrix();
193  else
194  vBodyAccel = in.Force / in.Mass;
195 
196  vUVWdot = vBodyAccel - (in.vPQR + 2.0 * (in.Ti2b * in.vOmegaPlanet)) * in.vUVW;
197 
198  // Include Centripetal acceleration.
199  vUVWdot -= in.Ti2b * (in.vOmegaPlanet * (in.vOmegaPlanet * in.vInertialPosition));
200 
201  // Include Gravitation accel
202  switch (gravType) {
203  case gtStandard:
204  {
205  double radius = in.vInertialPosition.Magnitude();
206  vGravAccel = -(in.GAccel / radius) * in.vInertialPosition;
207  }
208  break;
209  case gtWGS84:
210  vGravAccel = in.Tec2i * in.J2Grav;
211  break;
212  }
213 
214  if (FDMExec->GetHoldDown()) {
215  // The acceleration in ECI is calculated so that the acceleration is zero
216  // in the body frame.
217  vUVWidot = in.vOmegaPlanet * (in.vOmegaPlanet * in.vInertialPosition);
218  vUVWdot.InitMatrix();
219  }
220  else {
221  vUVWdot += in.Ti2b * vGravAccel;
222  vUVWidot = in.Tb2i * vBodyAccel + vGravAccel;
223  }
224 }
225 
226 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
227 
229 {
230  if (hd) {
231  vUVWidot = in.vOmegaPlanet * (in.vOmegaPlanet * in.vInertialPosition);
232  vUVWdot.InitMatrix();
233  vPQRidot = in.vPQRi * (in.Ti2b * in.vOmegaPlanet);
234  vPQRdot.InitMatrix();
235  }
236 }
237 
238 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
239 // Resolves the contact forces just before integrating the EOM.
240 // This routine is using Lagrange multipliers and the projected Gauss-Seidel
241 // (PGS) method.
242 // Reference: See Erin Catto, "Iterative Dynamics with Temporal Coherence",
243 // February 22, 2005
244 // In JSBSim there is only one rigid body (the aircraft) and there can be
245 // multiple points of contact between the aircraft and the ground. As a
246 // consequence our matrix Jac*M^-1*Jac^T is not sparse and the algorithm
247 // described in Catto's paper has been adapted accordingly.
248 // The friction forces are resolved in the body frame relative to the origin
249 // (Earth center).
250 
251 void FGAccelerations::ResolveFrictionForces(double dt)
252 {
253  const double invMass = 1.0 / in.Mass;
254  const FGMatrix33& Jinv = in.Jinv;
255  FGColumnVector3 vdot, wdot;
256  vector<LagrangeMultiplier*>& multipliers = *in.MultipliersList;
257  size_t n = multipliers.size();
258 
259  vFrictionForces.InitMatrix();
260  vFrictionMoments.InitMatrix();
261 
262  // If no gears are in contact with the ground then return
263  if (!n) return;
264 
265  vector<double> a(n*n); // Will contain Jac*M^-1*Jac^T
266  vector<double> rhs(n);
267 
268  // Assemble the linear system of equations
269  for (unsigned int i=0; i < n; i++) {
270  FGColumnVector3 v1 = invMass * multipliers[i]->ForceJacobian;
271  FGColumnVector3 v2 = Jinv * multipliers[i]->MomentJacobian; // Should be J^-T but J is symmetric and so is J^-1
272 
273  for (unsigned int j=0; j < i; j++)
274  a[i*n+j] = a[j*n+i]; // Takes advantage of the symmetry of Jac^T*M^-1*Jac
275  for (unsigned int j=i; j < n; j++)
276  a[i*n+j] = DotProduct(v1, multipliers[j]->ForceJacobian)
277  + DotProduct(v2, multipliers[j]->MomentJacobian);
278  }
279 
280  // Assemble the RHS member
281 
282  // Translation
283  vdot = vUVWdot;
284  if (dt > 0.) // Zeroes out the relative movement between the aircraft and the ground
285  vdot += (in.vUVW - in.Tec2b * in.TerrainVelocity) / dt;
286 
287  // Rotation
288  wdot = vPQRdot;
289  if (dt > 0.) // Zeroes out the relative movement between the aircraft and the ground
290  wdot += (in.vPQR - in.Tec2b * in.TerrainAngularVel) / dt;
291 
292  // Prepare the linear system for the Gauss-Seidel algorithm :
293  // 1. Compute the right hand side member 'rhs'
294  // 2. Divide every line of 'a' and 'rhs' by a[i,i]. This is in order to save
295  // a division computation at each iteration of Gauss-Seidel.
296  for (unsigned int i=0; i < n; i++) {
297  double d = 1.0 / a[i*n+i];
298 
299  rhs[i] = -(DotProduct(multipliers[i]->ForceJacobian, vdot)
300  +DotProduct(multipliers[i]->MomentJacobian, wdot))*d;
301  for (unsigned int j=0; j < n; j++)
302  a[i*n+j] *= d;
303  }
304 
305  // Resolve the Lagrange multipliers with the projected Gauss-Seidel method
306  for (int iter=0; iter < 50; iter++) {
307  double norm = 0.;
308 
309  for (unsigned int i=0; i < n; i++) {
310  double lambda0 = multipliers[i]->value;
311  double dlambda = rhs[i];
312 
313  for (unsigned int j=0; j < n; j++)
314  dlambda -= a[i*n+j]*multipliers[j]->value;
315 
316  multipliers[i]->value = Constrain(multipliers[i]->Min, lambda0+dlambda, multipliers[i]->Max);
317  dlambda = multipliers[i]->value - lambda0;
318 
319  norm += fabs(dlambda);
320  }
321 
322  if (norm < 1E-5) break;
323  }
324 
325  // Calculate the total friction forces and moments
326 
327  for (unsigned int i=0; i< n; i++) {
328  double lambda = multipliers[i]->value;
329  vFrictionForces += lambda * multipliers[i]->ForceJacobian;
330  vFrictionMoments += lambda * multipliers[i]->MomentJacobian;
331  }
332 
333  FGColumnVector3 accel = invMass * vFrictionForces;
334  FGColumnVector3 omegadot = Jinv * vFrictionMoments;
335 
336  vBodyAccel += accel;
337  vUVWdot += accel;
338  vUVWidot += in.Tb2i * accel;
339  vPQRdot += omegadot;
340  vPQRidot += omegadot;
341 }
342 
343 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
344 
346 {
347  // Make an initial run and set past values
348  CalculatePQRdot(); // Angular rate derivative
349  CalculateUVWdot(); // Translational rate derivative
350  ResolveFrictionForces(0.); // Update rate derivatives with friction forces
351 }
352 
353 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
354 
355 void FGAccelerations::bind(void)
356 {
357  typedef double (FGAccelerations::*PMF)(int) const;
358 
359  PropertyManager->Tie("accelerations/pdot-rad_sec2", this, eP, (PMF)&FGAccelerations::GetPQRdot);
360  PropertyManager->Tie("accelerations/qdot-rad_sec2", this, eQ, (PMF)&FGAccelerations::GetPQRdot);
361  PropertyManager->Tie("accelerations/rdot-rad_sec2", this, eR, (PMF)&FGAccelerations::GetPQRdot);
362 
363  PropertyManager->Tie("accelerations/udot-ft_sec2", this, eU, (PMF)&FGAccelerations::GetUVWdot);
364  PropertyManager->Tie("accelerations/vdot-ft_sec2", this, eV, (PMF)&FGAccelerations::GetUVWdot);
365  PropertyManager->Tie("accelerations/wdot-ft_sec2", this, eW, (PMF)&FGAccelerations::GetUVWdot);
366 
367  PropertyManager->Tie("accelerations/gravity-ft_sec2", this, &FGAccelerations::GetGravAccelMagnitude);
368  PropertyManager->Tie("simulation/gravity-model", &gravType);
369  PropertyManager->Tie("simulation/gravitational-torque", &gravTorque);
370  PropertyManager->Tie("forces/fbx-weight-lbs", this, eX, (PMF)&FGAccelerations::GetWeight);
371  PropertyManager->Tie("forces/fby-weight-lbs", this, eY, (PMF)&FGAccelerations::GetWeight);
372  PropertyManager->Tie("forces/fbz-weight-lbs", this, eZ, (PMF)&FGAccelerations::GetWeight);
373 
374  PropertyManager->Tie("forces/fbx-total-lbs", this, eX, (PMF)&FGAccelerations::GetForces);
375  PropertyManager->Tie("forces/fby-total-lbs", this, eY, (PMF)&FGAccelerations::GetForces);
376  PropertyManager->Tie("forces/fbz-total-lbs", this, eZ, (PMF)&FGAccelerations::GetForces);
377  PropertyManager->Tie("moments/l-total-lbsft", this, eL, (PMF)&FGAccelerations::GetMoments);
378  PropertyManager->Tie("moments/m-total-lbsft", this, eM, (PMF)&FGAccelerations::GetMoments);
379  PropertyManager->Tie("moments/n-total-lbsft", this, eN, (PMF)&FGAccelerations::GetMoments);
380 
381  PropertyManager->Tie("moments/l-gear-lbsft", this, eL, (PMF)&FGAccelerations::GetGroundMoments);
382  PropertyManager->Tie("moments/m-gear-lbsft", this, eM, (PMF)&FGAccelerations::GetGroundMoments);
383  PropertyManager->Tie("moments/n-gear-lbsft", this, eN, (PMF)&FGAccelerations::GetGroundMoments);
384  PropertyManager->Tie("forces/fbx-gear-lbs", this, eX, (PMF)&FGAccelerations::GetGroundForces);
385  PropertyManager->Tie("forces/fby-gear-lbs", this, eY, (PMF)&FGAccelerations::GetGroundForces);
386  PropertyManager->Tie("forces/fbz-gear-lbs", this, eZ, (PMF)&FGAccelerations::GetGroundForces);
387 }
388 
389 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
390 // The bitmasked value choices are as follows:
391 // unset: In this case (the default) JSBSim would only print
392 // out the normally expected messages, essentially echoing
393 // the config files as they are read. If the environment
394 // variable is not set, debug_lvl is set to 1 internally
395 // 0: This requests JSBSim not to output any messages
396 // whatsoever.
397 // 1: This value explicity requests the normal JSBSim
398 // startup messages
399 // 2: This value asks for a message to be printed out when
400 // a class is instantiated
401 // 4: When this value is set, a message is displayed when a
402 // FGModel object executes its Run() method
403 // 8: When this value is set, various runtime state variables
404 // are printed out periodically
405 // 16: When set various parameters are sanity checked and
406 // a message is printed out when they go out of bounds
407 
408 void FGAccelerations::Debug(int from)
409 {
410  if (debug_lvl <= 0) return;
411 
412  if (debug_lvl & 1) { // Standard console startup message output
413  if (from == 0) { // Constructor
414 
415  }
416  }
417  if (debug_lvl & 2 ) { // Instantiation/Destruction notification
418  if (from == 0) cout << "Instantiated: FGAccelerations" << endl;
419  if (from == 1) cout << "Destroyed: FGAccelerations" << endl;
420  }
421  if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
422  }
423  if (debug_lvl & 8 && from == 2) { // Runtime state variables
424  }
425  if (debug_lvl & 16) { // Sanity checking
426  }
427  if (debug_lvl & 64) {
428  if (from == 0) { // Constructor
429  cout << IdSrc << endl;
430  cout << IdHdr << endl;
431  }
432  }
433 }
434 }
FGColumnVector3 TerrainAngularVel
Terrain angular velocities with respect to the local frame (expressed in the ECEF frame)...
FGMatrix33 Jinv
The inverse of the inertia matrix J.
bool Run(bool Holding)
Runs the state propagation model; called by the Executive Can pass in a value indicating if the execu...
static double Constrain(double min, double value, double max)
Constrain a value between a minimum and a maximum value.
Definition: FGJSBBase.h:332
FGMatrix33 Ti2b
Transformation matrix from the ECI to the Body frame.
FGColumnVector3 vPQRi
Angular velocities of the body with respect to the ECI frame (expressed in the body frame)...
FGColumnVector3 TerrainVelocity
Terrain velocities with respect to the local frame (expressed in the ECEF frame). ...
std::vector< LagrangeMultiplier * > * MultipliersList
List of Lagrange multipliers set by FGLGear for friction forces calculations.
STL namespace.
FGColumnVector3 Force
Total forces applied to the body except friction and gravity (expressed in the body frame) ...
Evaluate gravity using WGS84 formulas that take the Earth oblateness into account.
const FGColumnVector3 & GetUVWdot(void) const
Retrieves the body axis acceleration.
FGColumnVector3 vOmegaPlanet
Earth rotating vector (expressed in the ECI frame).
FGColumnVector3 vUVW
Velocities of the body with respect to the local frame (expressed in the body frame).
FGColumnVector3 vPQR
Angular velocities of the body with respect to the local frame (expressed in the body frame)...
FGColumnVector3 Moment
Total moments applied to the body except friction and gravity (expressed in the body frame) ...
virtual bool Run(bool Holding)
Runs the model; called by the Executive.
Definition: FGModel.cpp:92
void Tie(const std::string &name, bool *pointer, bool useDefault=true)
Tie a property to an external bool variable.
void InitializeDerivatives(void)
Initializes the FGAccelerations class prior to a new execution.
FGColumnVector3 vInertialPosition
Body position (X,Y,Z) measured in the ECI frame.
double GAccel
Gravity intensity assuming the Earth is spherical.
Base class for all scheduled JSBSim models.
Definition: FGModel.h:74
This class implements a 3 element column vector.
FGColumnVector3 J2Grav
Gravity intensity vector using WGS84 formulas (expressed in the ECEF frame).
FGMatrix33 Tec2i
Transformation matrix from the ECEF to the ECI frame.
bool InitModel(void)
Initializes the FGAccelerations class after instantiation and prior to first execution.
FGMatrix33 J
The body inertia matrix expressed in the body frame.
Evaluate gravity using Newton&#39;s classical formula assuming the Earth is spherical.
Handles the calculation of accelerations.
FGMatrix33 Tec2b
Transformation matrix from the ECEF to the Body frame.
Handles matrix math operations.
Definition: FGMatrix33.h:92
double Magnitude(void) const
Length of the vector.
const FGColumnVector3 & GetPQRdot(void) const
Retrieves the body axis angular acceleration vector.
~FGAccelerations()
Destructor.
void SetHoldDown(bool hd)
Sets the property forces/hold-down.
Encapsulates the JSBSim simulation executive.
Definition: FGFDMExec.h:189
FGMatrix33 Tb2i
Transformation matrix from the Body to the ECI frame.
bool GetHoldDown(void) const
Gets the value of the property forces/hold-down.
Definition: FGFDMExec.h:600