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