]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/FGLGear.cpp
Square the /environment/turbulence-norm property before scaling it for
[flightgear.git] / src / FDM / JSBSim / FGLGear.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Module:       FGLGear.cpp
4  Author:       Jon S. Berndt
5                Norman H. Princen
6  Date started: 11/18/99
7  Purpose:      Encapsulates the landing gear elements
8  Called by:    FGAircraft
9
10  ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
11
12  This program is free software; you can redistribute it and/or modify it under
13  the terms of the GNU 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 General Public License for more
20  details.
21
22  You should have received a copy of the GNU 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 General Public License can also be found on
27  the world wide web at http://www.gnu.org.
28
29 FUNCTIONAL DESCRIPTION
30 --------------------------------------------------------------------------------
31
32 HISTORY
33 --------------------------------------------------------------------------------
34 11/18/99   JSB   Created
35 01/30/01   NHP   Extended gear model to properly simulate steering and braking
36
37 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38 INCLUDES
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
40
41 #include "FGLGear.h"
42 #include <algorithm>
43
44 namespace JSBSim {
45
46 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47 DEFINITIONS
48 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
49
50 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
51 GLOBAL DATA
52 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
53
54 static const char *IdSrc = "$Id$";
55 static const char *IdHdr = ID_LGEAR;
56
57 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
58 CLASS IMPLEMENTATION
59 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
60
61 FGLGear::FGLGear(FGConfigFile* AC_cfg, FGFDMExec* fdmex) : Exec(fdmex)
62 {
63   string tmp;
64   
65   *AC_cfg >> tmp >> name >> vXYZ(1) >> vXYZ(2) >> vXYZ(3)
66             >> kSpring >> bDamp>> dynamicFCoeff >> staticFCoeff
67                   >> rollingFCoeff >> sSteerType >> sBrakeGroup 
68                      >> maxSteerAngle >> sRetractable;
69
70   if      (sBrakeGroup == "LEFT"  ) eBrakeGrp = bgLeft;
71   else if (sBrakeGroup == "RIGHT" ) eBrakeGrp = bgRight;
72   else if (sBrakeGroup == "CENTER") eBrakeGrp = bgCenter;
73   else if (sBrakeGroup == "NOSE"  ) eBrakeGrp = bgNose;
74   else if (sBrakeGroup == "TAIL"  ) eBrakeGrp = bgTail;
75   else if (sBrakeGroup == "NONE"  ) eBrakeGrp = bgNone;
76   else {
77     cerr << "Improper braking group specification in config file: "
78          << sBrakeGroup << " is undefined." << endl;
79   }
80
81   if      (sSteerType == "STEERABLE") eSteerType = stSteer;
82   else if (sSteerType == "FIXED"    ) eSteerType = stFixed;
83   else if (sSteerType == "CASTERED" ) eSteerType = stCaster;
84   else {
85     cerr << "Improper steering type specification in config file: "
86          << sSteerType << " is undefined." << endl;
87   }
88   
89   if ( sRetractable == "RETRACT" ) {
90     isRetractable = true;
91   } else  {
92     isRetractable = false;
93   }  
94   
95   GearUp = false;
96   GearDown = true;
97
98 // Add some AI here to determine if gear is located properly according to its
99 // brake group type ??
100
101   State       = Exec->GetState();
102   Aircraft    = Exec->GetAircraft();
103   Position    = Exec->GetPosition();
104   Rotation    = Exec->GetRotation();
105   FCS         = Exec->GetFCS();
106   MassBalance = Exec->GetMassBalance();
107
108   WOW = lastWOW = true; // should the value be initialized to true?
109   ReportEnable = true;
110   FirstContact = false;
111   StartedGroundRun = false;
112   TakeoffReported = LandingReported = false;
113   LandingDistanceTraveled = TakeoffDistanceTraveled = TakeoffDistanceTraveled50ft = 0.0;
114   MaximumStrutForce = MaximumStrutTravel = 0.0;
115   SinkRate = GroundSpeed = 0.0;
116
117   vWhlBodyVec     = (vXYZ - MassBalance->GetXYZcg()) / 12.0;
118   vWhlBodyVec(eX) = -vWhlBodyVec(eX);
119   vWhlBodyVec(eZ) = -vWhlBodyVec(eZ);
120   
121   vLocalGear = State->GetTb2l() * vWhlBodyVec;
122
123   compressLength  = 0.0;
124   compressSpeed   = 0.0;
125   brakePct        = 0.0;
126   maxCompLen      = 0.0;
127
128   WheelSlip = lastWheelSlip = 0.0;
129
130   compressLength  = 0.0;
131   compressSpeed   = 0.0;
132   brakePct        = 0.0;
133   maxCompLen      = 0.0;
134
135   Debug(0);
136 }
137
138 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
139
140 FGLGear::FGLGear(const FGLGear& lgear)
141 {
142   State    = lgear.State;
143   Aircraft = lgear.Aircraft;
144   Position = lgear.Position;
145   Rotation = lgear.Rotation;
146   Exec     = lgear.Exec;
147   FCS      = lgear.FCS;
148   MassBalance = lgear.MassBalance;
149
150   vXYZ = lgear.vXYZ;
151   vMoment = lgear.vMoment;
152   vWhlBodyVec = lgear.vWhlBodyVec;
153   vLocalGear = lgear.vLocalGear;
154
155   WOW                = lgear.WOW;
156   lastWOW            = lgear.lastWOW;
157   ReportEnable       = lgear.ReportEnable;
158   FirstContact       = lgear.FirstContact;
159   StartedGroundRun   = lgear.StartedGroundRun;
160   LandingDistanceTraveled   = lgear.LandingDistanceTraveled;
161   TakeoffDistanceTraveled   = lgear.TakeoffDistanceTraveled;
162   TakeoffDistanceTraveled50ft   = lgear.TakeoffDistanceTraveled50ft;
163   MaximumStrutForce  = lgear.MaximumStrutForce;
164   MaximumStrutTravel = lgear.MaximumStrutTravel;
165
166   kSpring         = lgear.kSpring;
167   bDamp           = lgear.bDamp;
168   compressLength  = lgear.compressLength;
169   compressSpeed   = lgear.compressSpeed;
170   staticFCoeff    = lgear.staticFCoeff;
171   dynamicFCoeff   = lgear.dynamicFCoeff;
172   rollingFCoeff   = lgear.rollingFCoeff;
173   brakePct        = lgear.brakePct;
174   maxCompLen      = lgear.maxCompLen;
175   SinkRate        = lgear.SinkRate;
176   GroundSpeed     = lgear.GroundSpeed;
177   LandingReported = lgear.LandingReported;
178   TakeoffReported = lgear.TakeoffReported;
179   name            = lgear.name;
180   sSteerType      = lgear.sSteerType;
181   sRetractable    = lgear.sRetractable;
182   eSteerType      = lgear.eSteerType;
183   sBrakeGroup     = lgear.sBrakeGroup;
184   eBrakeGrp       = lgear.eBrakeGrp;
185   maxSteerAngle   = lgear.maxSteerAngle;
186   isRetractable   = lgear.isRetractable;
187   GearUp          = lgear.GearUp;
188   GearDown        = lgear.GearDown;
189   WheelSlip       = lgear.WheelSlip;
190   lastWheelSlip   = lgear.lastWheelSlip;
191 }
192
193 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
194
195 FGLGear::~FGLGear()
196 {
197   Debug(1);
198 }
199
200 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
201
202 FGColumnVector3& FGLGear::Force(void)
203 {
204   double SteerGain = 0;
205   double SinWheel, CosWheel;
206   double deltaT;
207
208   vForce.InitMatrix();
209   vMoment.InitMatrix();
210
211   if (isRetractable) {
212     if (FCS->GetGearPos() < 0.01) {
213       GearUp   = true;
214       GearDown = false;
215      } else if (FCS->GetGearPos() > 0.99) {
216       GearDown = true;
217       GearUp   = false;
218      } else {
219       GearUp   = false;
220       GearDown = false;
221      }
222   } else {
223       GearUp   = false;
224       GearDown = true;
225   }         
226       
227   if (GearDown) {
228
229     vWhlBodyVec     = (vXYZ - MassBalance->GetXYZcg()) / 12.0;
230     vWhlBodyVec(eX) = -vWhlBodyVec(eX);
231     vWhlBodyVec(eZ) = -vWhlBodyVec(eZ);
232
233 // vWhlBodyVec now stores the vector from the cg to this wheel
234
235     vLocalGear = State->GetTb2l() * vWhlBodyVec;
236
237 // vLocalGear now stores the vector from the cg to the wheel in local coords.
238
239     compressLength = vLocalGear(eZ) - Position->GetDistanceAGL();
240
241 // The compression length is currently measured in the Z-axis, only, at this time.
242 // It should be measured along the strut axis. If the local-frame gear position
243 // "hangs down" below the CG greater than the altitude, then the compressLength
244 // will be positive - i.e. the gear will have made contact.
245
246     if (compressLength > 0.00) {
247
248       WOW = true;// Weight-On-Wheels is true
249
250 // The next equation should really use the vector to the contact patch of the tire
251 // including the strut compression and not vWhlBodyVec.  Will fix this later.
252 // As it stands, now, the following equation takes the aircraft body-frame
253 // rotational rate and calculates the cross-product with the vector from the CG
254 // to the wheel, thus producing the instantaneous velocity vector of the tire
255 // in Body coords. The frame is also converted to local coordinates. When the
256 // aircraft local-frame velocity is added to this quantity, the total velocity of
257 // the wheel in local frame is then known. Subsequently, the compression speed
258 // (used for calculating damping force) is found by taking the Z-component of the
259 // wheel velocity.
260
261       vWhlVelVec      =  State->GetTb2l() * (Rotation->GetPQR() * vWhlBodyVec);
262
263       vWhlVelVec     +=  Position->GetVel();
264
265       compressSpeed   =  vWhlVelVec(eZ);
266
267 // If this is the first time the wheel has made contact, remember some values
268 // for later printout.
269
270       if (!FirstContact) {
271         FirstContact  = true;
272         SinkRate      =  compressSpeed;
273         GroundSpeed   =  Position->GetVel().Magnitude();
274         TakeoffReported = false;
275       }
276
277 // If the takeoff run is starting, initialize.
278
279       if ((Position->GetVel().Magnitude() > 0.1) &&
280           (FCS->GetBrake(bgLeft) == 0) &&
281           (FCS->GetBrake(bgRight) == 0) &&
282           (FCS->GetThrottlePos(0) == 1) && !StartedGroundRun)
283       {
284         TakeoffDistanceTraveled = 0;
285         TakeoffDistanceTraveled50ft = 0;
286         StartedGroundRun = true;
287       }
288
289 // The following needs work regarding friction coefficients and braking and
290 // steering The BrakeFCoeff formula assumes that an anti-skid system is used.
291 // It also assumes that we won't be turning and braking at the same time.
292 // Will fix this later.
293 // [JSB] The braking force coefficients include normal rolling coefficient +
294 // a percentage of the static friction coefficient based on braking applied.
295
296       switch (eBrakeGrp) {
297       case bgLeft:
298         SteerGain = 0.10;
299         BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgLeft)) +
300                                               staticFCoeff*FCS->GetBrake(bgLeft);
301         break;
302       case bgRight:
303         SteerGain = 0.10;
304         BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgRight)) +
305                                              staticFCoeff*FCS->GetBrake(bgRight);
306         break;
307       case bgCenter:
308         SteerGain = 0.10;
309         BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgCenter)) +
310                                              staticFCoeff*FCS->GetBrake(bgCenter);
311         break;
312       case bgNose:
313         SteerGain = -0.50;
314         BrakeFCoeff = rollingFCoeff;
315         break;
316       case bgTail:
317         SteerGain = -0.10;
318         BrakeFCoeff = rollingFCoeff;
319         break;
320       case bgNone:
321         SteerGain = 0.0;
322         BrakeFCoeff = rollingFCoeff;
323         break;
324       default:
325         cerr << "Improper brake group membership detected for this gear." << endl;
326         break;
327       }
328
329       switch (eSteerType) {
330       case stSteer:
331         SteerAngle = SteerGain*FCS->GetDrCmd()*0.349; // 20 deg
332         break;
333       case stFixed:
334         SteerAngle = 0.0;
335         break;
336       case stCaster:
337 // Note to Jon: This is not correct for castering gear.  I'll fix it later.
338         SteerAngle = 0.0;
339         break;
340       default:
341         cerr << "Improper steering type membership detected for this gear." << endl;
342         break;
343       }
344
345 // Transform the wheel velocities from the local axis system to the wheel axis system.
346 // For now, steering angle is assumed to happen in the Local Z axis,
347 // not the strut axis as it should be.  Will fix this later.
348
349       SinWheel      = sin(Rotation->Getpsi() + SteerAngle);
350       CosWheel      = cos(Rotation->Getpsi() + SteerAngle);
351       RollingWhlVel = vWhlVelVec(eX)*CosWheel + vWhlVelVec(eY)*SinWheel;
352       SideWhlVel    = vWhlVelVec(eY)*CosWheel - vWhlVelVec(eX)*SinWheel;
353
354 // Calculate tire slip angle.
355
356       if (RollingWhlVel == 0.0 && SideWhlVel == 0.0) {
357         WheelSlip = 0.0;
358       } else if (fabs(RollingWhlVel) < 0.10) {
359         WheelSlip = 0.05*radtodeg*atan2(SideWhlVel, RollingWhlVel) + 0.95*WheelSlip;
360       } else {
361         WheelSlip = radtodeg*atan2(SideWhlVel, RollingWhlVel);
362       }
363
364       if ((WheelSlip < 0.0 && lastWheelSlip > 0.0) ||
365           (WheelSlip > 0.0 && lastWheelSlip < 0.0))
366       {
367         WheelSlip = 0.0;
368       }
369       
370       lastWheelSlip = WheelSlip;
371
372 // Compute the sideforce coefficients using similar assumptions to LaRCSim for now.
373 // Allow a maximum of 10 degrees tire slip angle before wheel slides.  At that point,
374 // transition from static to dynamic friction.  There are more complicated formulations
375 // of this that avoid the discrete jump.  Will fix this later.
376
377       if (fabs(WheelSlip) <= 20.0) {
378         FCoeff = staticFCoeff*WheelSlip/20.0;
379       } else if (fabs(WheelSlip) <= 40.0) {
380 //        FCoeff = dynamicFCoeff*fabs(WheelSlip)/WheelSlip;
381         FCoeff = (dynamicFCoeff*(fabs(WheelSlip) - 20.0)/20.0 + 
382                   staticFCoeff*(40.0 - fabs(WheelSlip))/20.0)*fabs(WheelSlip)/WheelSlip;
383       } else {
384         FCoeff = dynamicFCoeff*fabs(WheelSlip)/WheelSlip;
385       }
386
387 // Compute the vertical force on the wheel using square-law damping (per comment
388 // in paper AIAA-2000-4303 - see header prologue comments). We might consider
389 // allowing for both square and linear damping force calculation. Also need to
390 // possibly give a "rebound damping factor" that differs from the compression
391 // case.
392
393       vLocalForce(eZ) =  min(-compressLength * kSpring
394                              - compressSpeed * bDamp, (double)0.0);
395
396       MaximumStrutForce = max(MaximumStrutForce, fabs(vLocalForce(eZ)));
397       MaximumStrutTravel = max(MaximumStrutTravel, fabs(compressLength));
398
399 // Compute the forces in the wheel ground plane.
400
401       RollingForce = 0;
402       if (fabs(RollingWhlVel) > 1E-3) {
403         RollingForce = vLocalForce(eZ) * BrakeFCoeff * fabs(RollingWhlVel)/RollingWhlVel;
404       }
405       SideForce    = vLocalForce(eZ) * FCoeff;
406
407 // Transform these forces back to the local reference frame.
408
409       vLocalForce(eX) = RollingForce*CosWheel - SideForce*SinWheel;
410       vLocalForce(eY) = SideForce*CosWheel    + RollingForce*SinWheel;
411
412 // Note to Jon: At this point the forces will be too big when the airplane is
413 // stopped or rolling to a stop.  We need to make sure that the gear forces just
414 // balance out the non-gear forces when the airplane is stopped.  That way the
415 // airplane won't start to accelerate until the non-gear/ forces are larger than
416 // the gear forces.  I think that the proper fix should go into FGAircraft::FMGear.
417 // This routine would only compute the local strut forces and return them to
418 // FMGear. All of the gear forces would get adjusted in FMGear using the total
419 // non-gear forces. Then the gear moments would be calculated. If strange things
420 // start happening to the airplane during testing as it rolls to a stop, then we
421 // need to implement this change.  I ran out of time to do it now but have the
422 // equations.
423
424 // Transform the forces back to the body frame and compute the moment.
425
426       vForce  = State->GetTl2b() * vLocalForce;
427       vMoment = vWhlBodyVec * vForce;
428
429     } else {
430
431       WOW = false;
432
433       if (Position->GetDistanceAGL() > 200.0) {
434         FirstContact = false;
435         StartedGroundRun = false;
436         LandingReported = false;
437         LandingDistanceTraveled = 0.0;
438         MaximumStrutForce = MaximumStrutTravel = 0.0;
439       }
440
441       compressLength = 0.0; // reset compressLength to zero for data output validity
442     }
443
444     deltaT = State->Getdt()*Aircraft->GetRate();
445
446     if (FirstContact) LandingDistanceTraveled += Position->GetVground()*deltaT;
447   
448     if (StartedGroundRun) {
449        TakeoffDistanceTraveled50ft += Position->GetVground()*deltaT;
450       if (WOW) TakeoffDistanceTraveled += Position->GetVground()*deltaT;
451     }
452
453     if (ReportEnable && Position->GetVground() <= 0.05 && !LandingReported) {
454       if (debug_lvl > 0) Report(erLand);
455     }
456
457     if (ReportEnable && !TakeoffReported &&
458        (vLocalGear(eZ) - Position->GetDistanceAGL()) < -50.0)
459     {
460       if (debug_lvl > 0) Report(erTakeoff);
461     }
462
463     if (lastWOW != WOW) {
464       PutMessage("GEAR_CONTACT: " + name, WOW);
465     }
466
467     lastWOW = WOW;
468
469 // Crash detection logic (really out-of-bounds detection)
470
471     if (compressLength > 500.0 ||
472         vForce.Magnitude() > 100000000.0 ||
473         vMoment.Magnitude() > 5000000000.0 ||
474         SinkRate > 1.4666*30)
475     {
476       PutMessage("Crash Detected: Simulation FREEZE.");
477       Exec->Freeze();
478     }
479   } 
480   return vForce; 
481 }
482
483 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
484
485 void FGLGear::Report(ReportType repType)
486 {
487   switch(repType) {
488   case erLand:
489     cout << endl << "Touchdown report for " << name << endl;
490     cout << "  Sink rate at contact:  " << SinkRate                << " fps,    "
491                                 << SinkRate*0.3408          << " mps"     << endl;
492     cout << "  Contact ground speed:  " << GroundSpeed*.5925       << " knots,  "
493                                 << GroundSpeed*0.3408       << " mps"     << endl;
494     cout << "  Maximum contact force: " << MaximumStrutForce       << " lbs,    "
495                                 << MaximumStrutForce*4.448  << " Newtons" << endl;
496     cout << "  Maximum strut travel:  " << MaximumStrutTravel*12.0 << " inches, "
497                                 << MaximumStrutTravel*30.48 << " cm"      << endl;
498     cout << "  Distance traveled:     " << LandingDistanceTraveled        << " ft,     "
499                                 << LandingDistanceTraveled*0.3408  << " meters"  << endl;
500     LandingReported = true;
501     break;
502   case erTakeoff:
503     cout << endl << "Takeoff report for " << name << endl;
504     cout << "  Distance traveled:                " << TakeoffDistanceTraveled
505          << " ft,     " << TakeoffDistanceTraveled*0.3408  << " meters"  << endl;
506     cout << "  Distance traveled (over 50'):     " << TakeoffDistanceTraveled50ft
507          << " ft,     " << TakeoffDistanceTraveled50ft*0.3408 << " meters" << endl;
508     TakeoffReported = true;
509     break;
510   }
511 }
512
513 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
514 //    The bitmasked value choices are as follows:
515 //    unset: In this case (the default) JSBSim would only print
516 //       out the normally expected messages, essentially echoing
517 //       the config files as they are read. If the environment
518 //       variable is not set, debug_lvl is set to 1 internally
519 //    0: This requests JSBSim not to output any messages
520 //       whatsoever.
521 //    1: This value explicity requests the normal JSBSim
522 //       startup messages
523 //    2: This value asks for a message to be printed out when
524 //       a class is instantiated
525 //    4: When this value is set, a message is displayed when a
526 //       FGModel object executes its Run() method
527 //    8: When this value is set, various runtime state variables
528 //       are printed out periodically
529 //    16: When set various parameters are sanity checked and
530 //       a message is printed out when they go out of bounds
531
532 void FGLGear::Debug(int from)
533 {
534   if (debug_lvl <= 0) return;
535
536   if (debug_lvl & 1) { // Standard console startup message output
537     if (from == 0) { // Constructor
538       cout << "    Name: "               << name          << endl;
539       cout << "      Location: "         << vXYZ          << endl;
540       cout << "      Spring Constant:  " << kSpring       << endl;
541       cout << "      Damping Constant: " << bDamp         << endl;
542       cout << "      Dynamic Friction: " << dynamicFCoeff << endl;
543       cout << "      Static Friction:  " << staticFCoeff  << endl;
544       cout << "      Rolling Friction: " << rollingFCoeff << endl;
545       cout << "      Steering Type:    " << sSteerType    << endl;
546       cout << "      Grouping:         " << sBrakeGroup   << endl;
547       cout << "      Max Steer Angle:  " << maxSteerAngle << endl;
548       cout << "      Retractable:      " << sRetractable  << endl;
549     }
550   }
551   if (debug_lvl & 2 ) { // Instantiation/Destruction notification
552     if (from == 0) cout << "Instantiated: FGLGear" << endl;
553     if (from == 1) cout << "Destroyed:    FGLGear" << endl;
554   }
555   if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
556   }
557   if (debug_lvl & 8 ) { // Runtime state variables
558   }
559   if (debug_lvl & 16) { // Sanity checking
560   }
561   if (debug_lvl & 64) {
562     if (from == 0) { // Constructor
563       cout << IdSrc << endl;
564       cout << IdHdr << endl;
565     }
566   }
567 }
568
569 } // namespace JSBSim
570