]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/FGAircraft.cpp
20010710 sync with JSBSim.
[flightgear.git] / src / FDM / JSBSim / FGAircraft.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2  
3  Module:       FGAircraft.cpp
4  Author:       Jon S. Berndt
5  Date started: 12/12/98                                   
6  Purpose:      Encapsulates an aircraft
7  Called by:    FGFDMExec
8
9  ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
10  
11  This program is free software; you can redistribute it and/or modify it under
12  the terms of the GNU General Public License as published by the Free Software
13  Foundation; either version 2 of the License, or (at your option) any later
14  version.
15  
16  This program is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
19  details.
20  
21  You should have received a copy of the GNU General Public License along with
22  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
23  Place - Suite 330, Boston, MA  02111-1307, USA.
24  
25  Further information about the GNU General Public License can also be found on
26  the world wide web at http://www.gnu.org.
27  
28 FUNCTIONAL DESCRIPTION
29 --------------------------------------------------------------------------------
30 Models the aircraft reactions and forces. This class is instantiated by the
31 FGFDMExec class and scheduled as an FDM entry. 
32  
33 HISTORY
34 --------------------------------------------------------------------------------
35 12/12/98   JSB   Created
36 04/03/99   JSB   Changed Aero() method to correct body axis force calculation
37                  from wind vector. Fix provided by Tony Peden.
38 05/03/99   JSB   Changed (for the better?) the way configurations are read in.
39 9/17/99     TP   Combined force and moment functions. Added aero reference 
40                  point to config file. Added calculations for moments due to 
41                  difference in cg and aero reference point
42  
43 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
44 COMMENTS, REFERENCES,  and NOTES
45 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
46
47 [1] Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
48       Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420  Naval Postgraduate
49       School, January 1994
50 [2] D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices",
51       JSC 12960, July 1977
52 [3] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
53       NASA-Ames", NASA CR-2497, January 1975
54 [4] Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
55       Wiley & Sons, 1979 ISBN 0-471-03032-5
56 [5] Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons,
57       1982 ISBN 0-471-08936-2
58  
59 The aerodynamic coefficients used in this model are:
60  
61 Longitudinal
62   CL0 - Reference lift at zero alpha
63   CD0 - Reference drag at zero alpha
64   CDM - Drag due to Mach
65   CLa - Lift curve slope (w.r.t. alpha)
66   CDa - Drag curve slope (w.r.t. alpha)
67   CLq - Lift due to pitch rate
68   CLM - Lift due to Mach
69   CLadt - Lift due to alpha rate
70  
71   Cmadt - Pitching Moment due to alpha rate
72   Cm0 - Reference Pitching moment at zero alpha
73   Cma - Pitching moment slope (w.r.t. alpha)
74   Cmq - Pitch damping (pitch moment due to pitch rate)
75   CmM - Pitch Moment due to Mach
76  
77 Lateral
78   Cyb - Side force due to sideslip
79   Cyr - Side force due to yaw rate
80  
81   Clb - Dihedral effect (roll moment due to sideslip)
82   Clp - Roll damping (roll moment due to roll rate)
83   Clr - Roll moment due to yaw rate
84   Cnb - Weathercocking stability (yaw moment due to sideslip)
85   Cnp - Rudder adverse yaw (yaw moment due to roll rate)
86   Cnr - Yaw damping (yaw moment due to yaw rate)
87  
88 Control
89   CLDe - Lift due to elevator
90   CDDe - Drag due to elevator
91   CyDr - Side force due to rudder
92   CyDa - Side force due to aileron
93  
94   CmDe - Pitch moment due to elevator
95   ClDa - Roll moment due to aileron
96   ClDr - Roll moment due to rudder
97   CnDr - Yaw moment due to rudder
98   CnDa - Yaw moment due to aileron
99  
100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
101 INCLUDES
102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
103
104 #include <sys/stat.h>
105 #include <sys/types.h>
106
107 #ifdef FGFS
108 #  ifndef __BORLANDC__
109 #    include <simgear/compiler.h>
110 #  endif
111 #  ifdef SG_HAVE_STD_INCLUDES
112 #    include <cmath>
113 #  else
114 #    include <math.h>
115 #  endif
116 #else
117 #  include <cmath>
118 #endif
119
120 #include "FGAircraft.h"
121 #include "FGMassBalance.h"
122 #include "FGInertial.h"
123 #include "FGAerodynamics.h"
124 #include "FGTranslation.h"
125 #include "FGRotation.h"
126 #include "FGAtmosphere.h"
127 #include "FGState.h"
128 #include "FGFDMExec.h"
129 #include "FGFCS.h"
130 #include "FGPosition.h"
131 #include "FGAuxiliary.h"
132 #include "FGOutput.h"
133
134 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135 DEFINITIONS
136 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
137
138 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
139 GLOBAL DATA
140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
141
142 static const char *IdSrc = "$Id$";
143 static const char *IdHdr = ID_AIRCRAFT;
144
145 extern char highint[5];
146 extern char halfint[5];
147 extern char normint[6];
148 extern char reset[5];
149 extern char underon[5];
150 extern char underoff[6];
151 extern char fgblue[6];
152 extern char fgcyan[6];
153 extern char fgred[6];
154 extern char fggreen[6];
155 extern char fgdef[6];
156
157 extern short debug_lvl;
158
159 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
160 CLASS IMPLEMENTATION
161 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
162
163 FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex),
164     vMoments(3),
165     vForces(3),
166     vXYZrp(3),
167     vXYZep(3),
168     vEuler(3),
169     vDXYZcg(3),
170     vAeroBodyForces(3)
171 {
172   Name = "FGAircraft";
173
174   GearUp = false;
175
176   alphaclmin = alphaclmax = 0;
177
178   if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
179 }
180
181
182 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
183
184
185 FGAircraft::~FGAircraft()
186 {
187   if (debug_lvl & 2) cout << "Destroyed:    FGAircraft" << endl;
188 }
189
190 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
191
192 bool FGAircraft::Load(FGConfigFile* AC_cfg)
193 {
194   string token;
195
196   ReadPrologue(AC_cfg);
197
198   while ((AC_cfg->GetNextConfigLine() != "EOF") &&
199          (token = AC_cfg->GetValue()) != "/FDM_CONFIG") {
200     if (token == "METRICS") {
201       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Metrics" << fgdef << endl;
202       ReadMetrics(AC_cfg);
203     } else if (token == "AERODYNAMICS") {
204       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Aerodynamics" << fgdef << endl;
205       ReadAerodynamics(AC_cfg);
206     } else if (token == "UNDERCARRIAGE") {
207       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Landing Gear" << fgdef << endl;
208       ReadUndercarriage(AC_cfg);
209     } else if (token == "PROPULSION") {
210       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Propulsion" << fgdef << endl;
211       ReadPropulsion(AC_cfg);
212     } else if (token == "FLIGHT_CONTROL") {
213       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Flight Control" << fgdef << endl;
214       ReadFlightControls(AC_cfg);
215     } else if (token == "OUTPUT") {
216       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Output directives" << fgdef << endl;
217       ReadOutput(AC_cfg);
218     }
219   }
220
221   return true;
222 }
223
224 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
225
226 bool FGAircraft::Run(void)
227 {
228   if (!FGModel::Run()) {                 // if false then execute this Run()
229     GetState();
230
231     vForces.InitMatrix();
232     vMoments.InitMatrix();
233
234     FMProp();
235     FMAero();
236     FMMass();
237     FMGear();
238
239     return false;
240   } else {                               // skip Run() execution this time
241     return true;
242   }
243 }
244
245 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
246
247 void FGAircraft::FMAero(void)
248 {
249     vForces += Aerodynamics->GetForces();
250     vMoments += Aerodynamics->GetMoments();
251 }
252
253 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
254
255 void FGAircraft::FMGear(void)
256 {
257   if ( !GearUp ) {
258     vector <FGLGear>::iterator iGear = lGear.begin();
259     while (iGear != lGear.end()) {
260       vForces  += iGear->Force();
261       vMoments += iGear->Moment();
262       iGear++;
263     }
264   } else {
265     // Crash Routine
266   }
267 }
268
269 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
270
271 void FGAircraft::FMMass(void)
272 {
273   vForces += Inertial->GetForces();
274 }
275
276 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
277
278 void FGAircraft::FMProp(void)
279 {
280   vForces += Propulsion->GetForces();
281   vMoments += Propulsion->GetMoments();
282 }
283
284 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
285
286 void FGAircraft::GetState(void)
287 {
288   dt = State->Getdt();
289
290   alpha = Translation->Getalpha();
291   beta = Translation->Getbeta();
292   vEuler = Rotation->GetEuler();
293 }
294
295 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
296
297 void FGAircraft::ReadMetrics(FGConfigFile* AC_cfg)
298 {
299   string token = "";
300   string parameter;
301   float EW, bixx, biyy, bizz, bixz, biyz;
302   FGColumnVector vbaseXYZcg(3);
303
304   AC_cfg->GetNextConfigLine();
305
306   while ((token = AC_cfg->GetValue()) != "/METRICS") {
307     *AC_cfg >> parameter;
308     if (parameter == "AC_WINGAREA") {
309       *AC_cfg >> WingArea;
310       if (debug_lvl > 0) cout << "    WingArea: " << WingArea  << endl;
311     } else if (parameter == "AC_WINGSPAN") {
312       *AC_cfg >> WingSpan;
313       if (debug_lvl > 0) cout << "    WingSpan: " << WingSpan  << endl;
314     } else if (parameter == "AC_CHORD") {
315       *AC_cfg >> cbar;
316       if (debug_lvl > 0) cout << "    Chord: " << cbar << endl;
317     } else if (parameter == "AC_IXX") {
318       *AC_cfg >> bixx;
319       if (debug_lvl > 0) cout << "    baseIxx: " << bixx << endl;
320       MassBalance->SetBaseIxx(bixx);
321     } else if (parameter == "AC_IYY") {
322       *AC_cfg >> biyy;
323       if (debug_lvl > 0) cout << "    baseIyy: " << biyy << endl;
324       MassBalance->SetBaseIyy(biyy);
325     } else if (parameter == "AC_IZZ") {
326       *AC_cfg >> bizz;
327       if (debug_lvl > 0) cout << "    baseIzz: " << bizz << endl;
328       MassBalance->SetBaseIzz(bizz);
329     } else if (parameter == "AC_IXZ") {
330       *AC_cfg >> bixz;
331       if (debug_lvl > 0) cout << "    baseIxz: " << bixz  << endl;
332       MassBalance->SetBaseIxz(bixz);
333     } else if (parameter == "AC_IYZ") {
334       *AC_cfg >> biyz;
335       if (debug_lvl > 0) cout << "    baseIyz: " << biyz  << endl;
336       MassBalance->SetBaseIyz(biyz);
337     } else if (parameter == "AC_EMPTYWT") {
338       *AC_cfg >> EW;
339       MassBalance->SetEmptyWeight(EW);
340       if (debug_lvl > 0) cout << "    EmptyWeight: " << EW  << endl;
341     } else if (parameter == "AC_CGLOC") {
342       *AC_cfg >> vbaseXYZcg(eX) >> vbaseXYZcg(eY) >> vbaseXYZcg(eZ);
343       MassBalance->SetBaseCG(vbaseXYZcg);
344       if (debug_lvl > 0) cout << "    CG (x, y, z): " << vbaseXYZcg << endl;
345     } else if (parameter == "AC_EYEPTLOC") {
346       *AC_cfg >> vXYZep(eX) >> vXYZep(eY) >> vXYZep(eZ);
347       if (debug_lvl > 0) cout << "    Eyepoint (x, y, z): " << vXYZep << endl;
348     } else if (parameter == "AC_AERORP") {
349       *AC_cfg >> vXYZrp(eX) >> vXYZrp(eY) >> vXYZrp(eZ);
350       if (debug_lvl > 0) cout << "    Ref Pt (x, y, z): " << vXYZrp << endl;
351     } else if (parameter == "AC_ALPHALIMITS") {
352       *AC_cfg >> alphaclmin >> alphaclmax;
353       if (debug_lvl > 0) cout << "    Maximum Alpha: " << alphaclmax
354              << "    Minimum Alpha: " << alphaclmin
355              << endl;
356     }
357   }
358 }
359
360 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
361
362 void FGAircraft::ReadPropulsion(FGConfigFile* AC_cfg) {
363   if (!Propulsion->Load(AC_cfg)) {
364     cerr << "Propulsion not successfully loaded" << endl;
365   }
366 }
367
368 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
369
370 void FGAircraft::ReadFlightControls(FGConfigFile* AC_cfg) {
371   if (!FCS->Load(AC_cfg)) {
372     cerr << "Flight Controls not successfully loaded" << endl;
373   }
374 }
375
376 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
377
378 void FGAircraft::ReadAerodynamics(FGConfigFile* AC_cfg)
379 {
380   if (!Aerodynamics->Load(AC_cfg)) {
381     cerr << "Aerodynamics not successfully loaded" << endl;
382   }
383
384 }
385
386 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
387
388 void FGAircraft::ReadUndercarriage(FGConfigFile* AC_cfg) {
389   string token;
390
391   AC_cfg->GetNextConfigLine();
392
393   while ((token = AC_cfg->GetValue()) != "/UNDERCARRIAGE") {
394     lGear.push_back(FGLGear(AC_cfg, FDMExec));
395   }
396 }
397
398 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
399
400 void FGAircraft::ReadOutput(FGConfigFile* AC_cfg) {
401   string token, parameter;
402   int OutRate = 0;
403   int subsystems = 0;
404
405   token = AC_cfg->GetValue("NAME");
406   Output->SetFilename(token);
407   token = AC_cfg->GetValue("TYPE");
408   Output->SetType(token);
409   AC_cfg->GetNextConfigLine();
410
411   while ((token = AC_cfg->GetValue()) != "/OUTPUT") {
412     *AC_cfg >> parameter;
413     if (parameter == "RATE_IN_HZ") *AC_cfg >> OutRate;
414     if (parameter == "SIMULATION") {
415       *AC_cfg >> parameter;
416       if (parameter == "ON") subsystems += ssSimulation;
417     }
418     if (parameter == "AEROSURFACES") {
419       *AC_cfg >> parameter;
420       if (parameter == "ON") subsystems += ssAerosurfaces;
421     }
422     if (parameter == "RATES") {
423       *AC_cfg >> parameter;
424       if (parameter == "ON") subsystems += ssRates;
425     }
426     if (parameter == "VELOCITIES") {
427       *AC_cfg >> parameter;
428       if (parameter == "ON") subsystems += ssVelocities;
429     }
430     if (parameter == "FORCES") {
431       *AC_cfg >> parameter;
432       if (parameter == "ON") subsystems += ssForces;
433     }
434     if (parameter == "MOMENTS") {
435       *AC_cfg >> parameter;
436       if (parameter == "ON") subsystems += ssMoments;
437     }
438     if (parameter == "ATMOSPHERE") {
439       *AC_cfg >> parameter;
440       if (parameter == "ON") subsystems += ssAtmosphere;
441     }
442     if (parameter == "MASSPROPS") {
443       *AC_cfg >> parameter;
444       if (parameter == "ON") subsystems += ssMassProps;
445     }
446     if (parameter == "POSITION") {
447       *AC_cfg >> parameter;
448       if (parameter == "ON") subsystems += ssPosition;
449     }
450     if (parameter == "COEFFICIENTS") {
451       *AC_cfg >> parameter;
452       if (parameter == "ON") subsystems += ssCoefficients;
453     }
454     if (parameter == "GROUND_REACTIONS") {
455       *AC_cfg >> parameter;
456       if (parameter == "ON") subsystems += ssGroundReactions;
457     }
458     if (parameter == "FCS") {
459       *AC_cfg >> parameter;
460       if (parameter == "ON") subsystems += ssFCS;
461     }
462     if (parameter == "PROPULSION") {
463       *AC_cfg >> parameter;
464       if (parameter == "ON") subsystems += ssPropulsion;
465     }
466   }
467
468   Output->SetSubsystems(subsystems);
469
470   OutRate = OutRate>120?120:(OutRate<0?0:OutRate);
471   Output->SetRate( (int)(0.5 + 1.0/(State->Getdt()*OutRate)) );
472 }
473
474 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
475
476 void FGAircraft::ReadPrologue(FGConfigFile* AC_cfg) {
477   string token = AC_cfg->GetValue();
478   string scratch;
479   AircraftName = AC_cfg->GetValue("NAME");
480   if (debug_lvl > 0) cout << underon << "Reading Aircraft Configuration File"
481             << underoff << ": " << highint << AircraftName << normint << endl;
482   scratch = AC_cfg->GetValue("VERSION").c_str();
483
484   CFGVersion = AC_cfg->GetValue("VERSION");
485
486   if (debug_lvl > 0)
487     cout << "                            Version: " << highint << CFGVersion
488                                                              << normint << endl;
489   if (CFGVersion != NEEDED_CFG_VERSION) {
490     cerr << endl << fgred << "YOU HAVE AN INCOMPATIBLE CFG FILE FOR THIS AIRCRAFT."
491             " RESULTS WILL BE UNPREDICTABLE !!" << endl;
492     cerr << "Current version needed is: " << NEEDED_CFG_VERSION << endl;
493     cerr << "         You have version: " << CFGVersion << endl << fgdef << endl;
494   }
495 }
496
497 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
498
499 string FGAircraft::GetGroundReactionStrings(void) {
500   string GroundReactionStrings = "";
501   bool firstime = true;
502
503   for (unsigned int i=0;i<lGear.size();i++) {
504     if (!firstime) GroundReactionStrings += ", ";
505     GroundReactionStrings += (lGear[i].GetName() + "_WOW, ");
506     GroundReactionStrings += (lGear[i].GetName() + "_compressLength, ");
507     GroundReactionStrings += (lGear[i].GetName() + "_compressSpeed, ");
508     GroundReactionStrings += (lGear[i].GetName() + "_Force");
509
510     firstime = false;
511   }
512
513   return GroundReactionStrings;
514 }
515
516 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
517
518 string FGAircraft::GetGroundReactionValues(void) {
519   char buff[20];
520   string GroundReactionValues = "";
521
522   bool firstime = true;
523
524   for (unsigned int i=0;i<lGear.size();i++) {
525     if (!firstime) GroundReactionValues += ", ";
526     GroundReactionValues += string( lGear[i].GetWOW()?"1":"0" ) + ", ";
527     GroundReactionValues += (string(gcvt(lGear[i].GetCompLen(),    5, buff)) + ", ");
528     GroundReactionValues += (string(gcvt(lGear[i].GetCompVel(),    6, buff)) + ", ");
529     GroundReactionValues += (string(gcvt(lGear[i].GetCompForce(), 10, buff)));
530
531     firstime = false;
532   }
533
534   return GroundReactionValues;
535 }
536
537 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
538
539 void FGAircraft::Debug(void)
540 {
541     //TODO: Add your source code here
542 }
543