]> git.mxchange.org Git - flightgear.git/commitdiff
Add Bertrand Coconnier's latest landing gear code
authorehofman <ehofman>
Thu, 20 Aug 2009 05:33:20 +0000 (05:33 +0000)
committerTim Moore <timoore@redhat.com>
Sun, 23 Aug 2009 19:43:09 +0000 (21:43 +0200)
src/FDM/JSBSim/JSBSim.cxx
src/FDM/JSBSim/input_output/FGPropertyManager.h
src/FDM/JSBSim/input_output/FGScript.cpp
src/FDM/JSBSim/models/FGLGear.cpp
src/FDM/JSBSim/models/FGLGear.h
src/FDM/JSBSim/models/FGOutput.h

index f5dd9008ed5936afc670746f911befd7839e9f67..abab0414d8bdc47ad526d6b6ced11bad9c0e4d41 100644 (file)
@@ -103,8 +103,8 @@ public:
     double contact[3], normal[3], vel[3], agl = 0;
     mInterface->get_agl_ft(t, loc_cart, SG_METER_TO_FEET*2, contact, normal,
                            vel, &agl);
-    n = l.GetTec2l()*FGColumnVector3( normal[0], normal[1], normal[2] );
-    v = l.GetTec2l()*FGColumnVector3( vel[0], vel[1], vel[2] );
+    n = FGColumnVector3( -normal[0], -normal[1], -normal[2] );
+    v = FGColumnVector3( vel[0], vel[1], vel[2] );
     cont = FGColumnVector3( contact[0], contact[1], contact[2] );
     return agl;
   }
index 8f191fe87fa3cb2b3d174d63c0bb97aacf731b65..876b490b79f4ecfeabde48cb074897b5df0c3e96 100644 (file)
@@ -35,14 +35,17 @@ SENTRY
 INCLUDES
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
 
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
 #include <string>
 #include <iostream>
 #include <simgear/props/props.hxx>
-#include <simgear/math/SGMath.hxx>
+#if !PROPS_STANDALONE
+  // This is needed by MSVC9 when included in FlightGear because of
+  // the new Vec4d class in props.hxx
+# if defined( HAVE_CONFIG_H )
+#  include <config.h>
+# endif
+# include <simgear/math/SGMath.hxx>
+#endif
 
 #include "FGJSBBase.h"
 
index dc033e26f4708f81812acd8eb9860ed2e04fb0b3..5605b615cf635561360e8bd1b549ced5b64b9fe9 100755 (executable)
@@ -274,14 +274,14 @@ bool FGScript::LoadScript( string script )
       newEvent->newValue.push_back(0.0);
       newEvent->ValueSpan.push_back(0.0);
       string tempCompare = set_element->GetAttributeValue("type");
-      if      (tempCompare == "FG_DELTA") newEvent->Type.push_back(FG_DELTA);
-      else if (tempCompare == "FG_BOOL")  newEvent->Type.push_back(FG_BOOL);
-      else if (tempCompare == "FG_VALUE") newEvent->Type.push_back(FG_VALUE);
+      if      (to_lower(tempCompare).find("delta") != string::npos) newEvent->Type.push_back(FG_DELTA);
+      else if (to_lower(tempCompare).find("bool") != string::npos)  newEvent->Type.push_back(FG_BOOL);
+      else if (to_lower(tempCompare).find("value") != string::npos) newEvent->Type.push_back(FG_VALUE);
       else                                newEvent->Type.push_back(FG_VALUE); // DEFAULT
       tempCompare = set_element->GetAttributeValue("action");
-      if      (tempCompare == "FG_RAMP") newEvent->Action.push_back(FG_RAMP);
-      else if (tempCompare == "FG_STEP") newEvent->Action.push_back(FG_STEP);
-      else if (tempCompare == "FG_EXP")  newEvent->Action.push_back(FG_EXP);
+      if      (to_lower(tempCompare).find("ramp") != string::npos) newEvent->Action.push_back(FG_RAMP);
+      else if (to_lower(tempCompare).find("step") != string::npos) newEvent->Action.push_back(FG_STEP);
+      else if (to_lower(tempCompare).find("exp") != string::npos) newEvent->Action.push_back(FG_EXP);
       else                               newEvent->Action.push_back(FG_STEP); // DEFAULT
 
       if (!set_element->GetAttributeValue("tc").empty())
index 96d8d2308f28f370730913fb4a7b56d219d1c639..2a9b472e9004badf4cf5aec71863246336616211 100644 (file)
@@ -3,6 +3,7 @@
  Module:       FGLGear.cpp
  Author:       Jon S. Berndt
                Norman H. Princen
+               Bertrand Coconnier
  Date started: 11/18/99
  Purpose:      Encapsulates the landing gear elements
  Called by:    FGAircraft
@@ -33,6 +34,7 @@ HISTORY
 --------------------------------------------------------------------------------
 11/18/99   JSB   Created
 01/30/01   NHP   Extended gear model to properly simulate steering and braking
+07/08/09   BC    Modified gear model to support large angles between aircraft and ground
 
 /%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 INCLUDES
@@ -225,13 +227,14 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
   TakeoffReported = LandingReported = false;
   LandingDistanceTraveled = TakeoffDistanceTraveled = TakeoffDistanceTraveled50ft = 0.0;
   MaximumStrutForce = MaximumStrutTravel = 0.0;
-  SideForce = RollingForce = 0.0;
   SinkRate = GroundSpeed = 0.0;
 
   vWhlBodyVec = MassBalance->StructuralToBody(vXYZ);
 
   vLocalGear = Propagate->GetTb2l() * vWhlBodyVec;
 
+  vLocalWhlVel.InitMatrix();
+
   compressLength  = 0.0;
   compressSpeed   = 0.0;
   brakePct        = 0.0;
@@ -240,12 +243,6 @@ FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number) :
   WheelSlip = 0.0;
   TirePressureNorm = 1.0;
 
-  SideWhlVel    = 0.0;
-  RollingWhlVel = 0.0;
-
-  SinWheel = 0.0;
-  CosWheel = 0.0;
-
   // Set Pacejka terms
 
   Stiffness = 0.06;
@@ -272,6 +269,7 @@ FGColumnVector3& FGLGear::Force(void)
   dT = State->Getdt()*Exec->GetGroundReactions()->GetRate();
 
   vForce.InitMatrix();
+  vLocalForce.InitMatrix();
   vMoment.InitMatrix();
 
   if (isRetractable) ComputeRetractionState();
@@ -282,9 +280,21 @@ FGColumnVector3& FGLGear::Force(void)
     vLocalGear = Propagate->GetTb2l() * vWhlBodyVec; // Get local frame wheel location
 
     gearLoc = Propagate->GetLocation().LocalToLocation(vLocalGear);
-    compressLength = -Exec->GetGroundCallback()->GetAGLevel(t, gearLoc, contact, normal, cvel);
-
-    // The compression length is measured in the Z-axis, only, at this time.
+    // Compute the height of the theoritical location of the wheel (if struct was not compressed) with
+    // respect to the ground level
+    double height = Exec->GetGroundCallback()->GetAGLevel(t, gearLoc, contact, normal, cvel);
+    vGroundNormal = -1. * Propagate->GetTec2b() * normal;
+
+    switch (eContactType) {
+    case ctBOGEY:
+      // Project the height in the local coordinate frame of the strut to compute the actual compression
+      // length. The strut is assumed to be parallel to Z in the body frame.
+      compressLength = vGroundNormal(eZ) < 0.0 ? height / vGroundNormal(eZ) : 0.0;
+      break;
+    case ctSTRUCTURE:
+      compressLength = -height;
+      break;
+    }
 
     if (compressLength > 0.00) {
 
@@ -293,22 +303,38 @@ FGColumnVector3& FGLGear::Force(void)
       // [The next equation should really use the vector to the contact patch of
       // the tire including the strut compression and not the original vWhlBodyVec.]
 
-      vWhlVelVec      =  Propagate->GetTb2l() * (Propagate->GetPQR() * vWhlBodyVec);
-      vWhlVelVec     +=  Propagate->GetVel() - cvel;
-      compressSpeed   =  vWhlVelVec(eZ);
+      FGColumnVector3 vWhlContactVec = vWhlBodyVec - FGColumnVector3(0., 0., compressLength);
+      vWhlVelVec      =  Propagate->GetPQR() * vWhlContactVec;
+      vWhlVelVec     +=  Propagate->GetUVW() - Propagate->GetTec2b() * cvel;
 
       InitializeReporting();
-      ComputeBrakeForceCoefficient();
       ComputeSteeringAngle();
-      ComputeSlipAngle();
-      ComputeSideForceCoefficient();
+      ComputeGroundCoordSys();
+
+      vLocalWhlVel = Tb2g * vWhlVelVec;
+
+      compressSpeed = -vLocalWhlVel(eZ);
+      if (eContactType == ctBOGEY)
+        // Project the compression speed in the local coordinate frame of the strut
+        compressSpeed /= -vGroundNormal(eZ);
+
       ComputeVerticalStrutForce();
 
       // Compute the forces in the wheel ground plane.
-
-      double sign = RollingWhlVel>0?1.0:(RollingWhlVel<0?-1.0:0.0);
-      RollingForce = ((1.0 - TirePressureNorm) * 30 + vLocalForce(eZ) * BrakeFCoeff) * sign;
-      SideForce    = vLocalForce(eZ) * FCoeff;
+      if (eContactType == ctBOGEY) {
+        ComputeSlipAngle();
+        ComputeBrakeForceCoefficient();
+        ComputeSideForceCoefficient();
+        double sign = vLocalWhlVel(eX)>0?1.0:(vLocalWhlVel(eX)<0?-1.0:0.0);
+        vLocalForce(eX) = - ((1.0 - TirePressureNorm) * 30 + vLocalForce(eZ) * BrakeFCoeff) * sign;
+        vLocalForce(eY) = vLocalForce(eZ) * FCoeff;
+      }
+      else if (eContactType == ctSTRUCTURE) {
+        FGColumnVector3 vSlipVec = vLocalWhlVel;
+        vSlipVec(eZ) = 0.;
+        vSlipVec.Normalize();
+        vLocalForce -= staticFCoeff * vLocalForce(eZ) * vSlipVec;
+      }
 
       // Lag and attenuate the XY-plane forces dependent on velocity. This code
       // uses a lag filter, C/(s + C) where "C" is the filter coefficient. When
@@ -317,24 +343,18 @@ FGColumnVector3& FGLGear::Force(void)
       // If a coefficient is set to something equal to or less than zero, the
       // filter is bypassed.
 
-      if (LongForceLagFilterCoeff > 0) RollingForce = LongForceFilter.execute(RollingForce);
-      if (LatForceLagFilterCoeff > 0)  SideForce = LatForceFilter.execute(SideForce);
+      if (LongForceLagFilterCoeff > 0) vLocalForce(eX) = LongForceFilter.execute(vLocalForce(eX));
+      if (LatForceLagFilterCoeff > 0)  vLocalForce(eY) = LatForceFilter.execute(vLocalForce(eY));
 
-      if ((fabs(RollingWhlVel) <= RFRV) && RFRV > 0) RollingForce *= fabs(RollingWhlVel)/RFRV;
-      if ((fabs(SideWhlVel) <= SFRV) && SFRV > 0) SideForce *= fabs(SideWhlVel)/SFRV;
+      if ((fabs(vLocalWhlVel(eX)) <= RFRV) && RFRV > 0) vLocalForce(eX) *= fabs(vLocalWhlVel(eX))/RFRV;
+      if ((fabs(vLocalWhlVel(eY)) <= SFRV) && SFRV > 0) vLocalForce(eY) *= fabs(vLocalWhlVel(eY))/SFRV;
 
-      // Transform these forces back to the local reference frame.
-
-      vLocalForce(eX) = RollingForce*CosWheel - SideForce*SinWheel;
-      vLocalForce(eY) = SideForce*CosWheel    + RollingForce*SinWheel;
+      // End section for attenuating gear jitter
 
       // Transform the forces back to the body frame and compute the moment.
 
-      vForce  = Propagate->GetTl2b() * vLocalForce;
-
-      // End section for attentuating gear jitter
-
-      vMoment = vWhlBodyVec * vForce;
+      vForce  = Tg2b * vLocalForce;
+      vMoment = vWhlContactVec * vForce;
 
     } else { // Gear is NOT compressed
 
@@ -342,12 +362,9 @@ FGColumnVector3& FGLGear::Force(void)
       compressLength = 0.0;
       compressSpeed = 0.0;
 
-      // No wheel conditions
-      SideWhlVel = WheelSlip = 0.0;
-
       // Let wheel spin down slowly
-      RollingWhlVel -= 13.0*dT;
-      if (RollingWhlVel < 0.0) RollingWhlVel = 0.0;
+      vLocalWhlVel(eX) -= 13.0*dT;
+      if (vLocalWhlVel(eX) < 0.0) vLocalWhlVel(eX) = 0.0;
 
       // Return to neutral position between 1.0 and 0.8 gear pos.
       SteerAngle *= max(GetGearUnitPos()-0.8, 0.0)/0.2;
@@ -367,6 +384,45 @@ FGColumnVector3& FGLGear::Force(void)
   return vForce;
 }
 
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+// Build a local "ground" coordinate system defined by
+//  eX : projection of the rolling direction on the ground
+//  eY : projection of the sliping direction on the ground
+//  eZ : normal to the ground
+
+void FGLGear::ComputeGroundCoordSys(void)
+{
+  // Compute the rolling direction projected on the ground
+  // It consists in finding a vector 'r' such that 'r' lies in the plane (w,z) and r.n = 0 (scalar
+  // product) where:
+  // 'n' is the normal to the ground,
+  // (x,y,z) are the directions defined in the body coord system
+  // and 'w' is 'x' rotated by the steering angle (SteerAngle) in the plane (x,y). 
+  // r = u * w + v * z and r.n = 0 => v/u = -w.n/z.n = a
+  // We also want u**2+v**2=1 and u > 0 (i.e. r orientated in the same 'direction' than w)
+  // after some arithmetic, one finds that :
+  double a = -(vGroundNormal(eX)*cos(SteerAngle)+vGroundNormal(eY)*sin(SteerAngle)) / vGroundNormal(eZ);
+  double u = 1. / sqrt(1. + a*a);
+  double v = a * u;
+  FGColumnVector3 vRollingGroundVec = FGColumnVector3(u * cos(SteerAngle), u * sin(SteerAngle), v);
+
+  // The sliping direction is the cross product multiplication of the ground normal and rolling
+  // directions
+  FGColumnVector3 vSlipGroundVec = vGroundNormal * vRollingGroundVec;
+
+  Tg2b(1,1) = vRollingGroundVec(eX);
+  Tg2b(2,1) = vRollingGroundVec(eY);
+  Tg2b(3,1) = vRollingGroundVec(eZ);
+  Tg2b(1,2) = vSlipGroundVec(eX);
+  Tg2b(2,2) = vSlipGroundVec(eY);
+  Tg2b(3,2) = vSlipGroundVec(eZ);
+  Tg2b(1,3) = vGroundNormal(eX);
+  Tg2b(2,3) = vGroundNormal(eY);
+  Tg2b(3,3) = vGroundNormal(eZ);
+
+  Tb2g = Tg2b.Transposed();
+}
+
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 void FGLGear::ComputeRetractionState(void)
@@ -376,7 +432,7 @@ void FGLGear::ComputeRetractionState(void)
     GearUp   = true;
     WOW      = false;
     GearDown = false;
-    RollingWhlVel = 0.0;
+    vLocalWhlVel.InitMatrix();
   } else if (gearPos > 0.99) {
     GearDown = true;
     GearUp   = false;
@@ -390,12 +446,8 @@ void FGLGear::ComputeRetractionState(void)
 
 void FGLGear::ComputeSlipAngle(void)
 {
-  // Transform the wheel velocities from the local axis system to the wheel axis system.
-  RollingWhlVel = vWhlVelVec(eX)*CosWheel + vWhlVelVec(eY)*SinWheel;
-  SideWhlVel    = vWhlVelVec(eY)*CosWheel - vWhlVelVec(eX)*SinWheel;
-
   // Calculate tire slip angle.
-  WheelSlip = atan2(SideWhlVel, fabs(RollingWhlVel))*radtodeg;
+  WheelSlip = -atan2(vLocalWhlVel(eY), fabs(vLocalWhlVel(eX)))*radtodeg;
 
   // Filter the wheel slip angle
   if (WheelSlipLagFilterCoeff > 0) WheelSlip = WheelSlipFilter.execute(WheelSlip);
@@ -407,9 +459,6 @@ void FGLGear::ComputeSlipAngle(void)
 
 void FGLGear::ComputeSteeringAngle(void)
 {
-  double casterLocalFrameAngleRad = 0.0;
-  double casterAngle = 0.0;
-
   switch (eSteerType) {
   case stSteer:
     SteerAngle = degtorad * FCS->GetSteerPosDeg(GearNumber);
@@ -418,20 +467,12 @@ void FGLGear::ComputeSteeringAngle(void)
     SteerAngle = 0.0;
     break;
   case stCaster:
-    // This is not correct for castering gear. Should make steer angle parallel
-    // to the actual velocity vector of the wheel, given aircraft velocity vector
-    // and omega.
-    SteerAngle = 0.0;
-    casterLocalFrameAngleRad = acos(vWhlVelVec(eX)/vWhlVelVec.Magnitude());
-    casterAngle = casterLocalFrameAngleRad - Propagate->GetEuler(ePsi);
+    SteerAngle = atan2(fabs(vWhlVelVec(eX)), vWhlVelVec(eY));
     break;
   default:
     cerr << "Improper steering type membership detected for this gear." << endl;
     break;
   }
-
-  SinWheel      = sin(Propagate->GetEuler(ePsi) + SteerAngle);
-  CosWheel      = cos(Propagate->GetEuler(ePsi) + SteerAngle);
 }
 
 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -612,10 +653,22 @@ void FGLGear::ComputeVerticalStrutForce(void)
       dampForce   =  compressSpeed * compressSpeed * bDampRebound;
 
   }
-  vLocalForce(eZ) =  min(springForce + dampForce, (double)0.0);
+
+  StrutForce = min(springForce + dampForce, (double)0.0);
+
+  // The reaction force of the wheel is always normal to the ground
+  switch (eContactType) {
+  case ctBOGEY:
+    // Project back the strut force in the local coordinate frame of the ground
+    vLocalForce(eZ) =  StrutForce / vGroundNormal(eZ);
+    break;
+  case ctSTRUCTURE:
+    vLocalForce(eZ) = -StrutForce;
+    break;
+  }
 
   // Remember these values for reporting
-  MaximumStrutForce = max(MaximumStrutForce, fabs(vLocalForce(eZ)));
+  MaximumStrutForce = max(MaximumStrutForce, fabs(StrutForce));
   MaximumStrutTravel = max(MaximumStrutTravel, fabs(compressLength));
 }
 
@@ -644,7 +697,8 @@ void FGLGear::bind(void)
     property_name = base_property_name + "/WOW";
     Exec->GetPropertyManager()->Tie( property_name.c_str(), &WOW );
     property_name = base_property_name + "/wheel-speed-fps";
-    Exec->GetPropertyManager()->Tie( property_name.c_str(), &RollingWhlVel );
+    Exec->GetPropertyManager()->Tie( property_name.c_str(), (FGLGear*)this,
+                          &FGLGear::GetWheelRollVel);
     property_name = base_property_name + "/z-position";
     Exec->GetPropertyManager()->Tie( property_name.c_str(), (FGLGear*)this,
                           &FGLGear::GetZPosition, &FGLGear::SetZPosition);
index a62549f2899e42157c6b31fa53f44fb179a83dab..09a143873fef38f0d29c636c1e3f5ced8efb6b4c 100644 (file)
@@ -234,55 +234,55 @@ public:
   double GetLocalGear(int idx) const { return vLocalGear(idx); }
 
   /// Gets the name of the gear
-  inline string GetName(void) const {return name;          }
+  string GetName(void) const {return name;          }
   /// Gets the Weight On Wheels flag value
-  inline bool   GetWOW(void) const {return WOW;           }
+  bool   GetWOW(void) const {return WOW;           }
   /// Gets the current compressed length of the gear in feet
-  inline double  GetCompLen(void) const {return compressLength;}
+  double  GetCompLen(void) const {return compressLength;}
   /// Gets the current gear compression velocity in ft/sec
-  inline double  GetCompVel(void) const {return compressSpeed; }
+  double  GetCompVel(void) const {return compressSpeed; }
   /// Gets the gear compression force in pounds
-  inline double  GetCompForce(void) const {return vForce(eZ);    }
-  inline double  GetBrakeFCoeff(void) const {return BrakeFCoeff;}
+  double  GetCompForce(void) const {return StrutForce;   }
+  double  GetBrakeFCoeff(void) const {return BrakeFCoeff;}
 
   /// Gets the current normalized tire pressure
-  inline double  GetTirePressure(void) const { return TirePressureNorm; }
+  double  GetTirePressure(void) const { return TirePressureNorm; }
   /// Sets the new normalized tire pressure
-  inline void    SetTirePressure(double p) { TirePressureNorm = p; }
+  void    SetTirePressure(double p) { TirePressureNorm = p; }
 
   /// Sets the brake value in percent (0 - 100)
-  inline void SetBrake(double bp) {brakePct = bp;}
+  void SetBrake(double bp) {brakePct = bp;}
 
   /// Sets the weight-on-wheels flag.
   void SetWOW(bool wow) {WOW = wow;}
 
   /** Set the console touchdown reporting feature
       @param flag true turns on touchdown reporting, false turns it off */
-  inline void SetReport(bool flag) { ReportEnable = flag; }
+  void SetReport(bool flag) { ReportEnable = flag; }
   /** Get the console touchdown reporting feature
       @return true if reporting is turned on */
-  inline bool GetReport(void) const  { return ReportEnable; }
+  bool GetReport(void) const  { return ReportEnable; }
   double GetSteerNorm(void) const    { return radtodeg/maxSteerAngle*SteerAngle; }
   double GetDefaultSteerAngle(double cmd) const { return cmd*maxSteerAngle; }
   double GetstaticFCoeff(void) const { return staticFCoeff; }
 
-  inline int GetBrakeGroup(void) const { return (int)eBrakeGrp; }
-  inline int GetSteerType(void) const  { return (int)eSteerType; }
+  int GetBrakeGroup(void) const { return (int)eBrakeGrp; }
+  int GetSteerType(void) const  { return (int)eSteerType; }
 
-  inline double GetZPosition(void) const { return vXYZ(3); }
-  inline void SetZPosition(double z) { vXYZ(3) = z; }
+  double GetZPosition(void) const { return vXYZ(3); }
+  void SetZPosition(double z) { vXYZ(3) = z; }
 
   bool GetSteerable(void) const { return eSteerType != stFixed; }
-  inline bool GetRetractable(void) const      { return isRetractable;   }
-  inline bool GetGearUnitUp(void) const       { return GearUp;          }
-  inline bool GetGearUnitDown(void) const     { return GearDown;        }
-  inline double GetWheelSideForce(void) const { return SideForce;       }
-  inline double GetWheelRollForce(void) const { return RollingForce;    }
-  inline double GetWheelSideVel(void) const   { return SideWhlVel;      }
-  inline double GetWheelRollVel(void) const   { return RollingWhlVel;   }
-  inline double GetBodyXForce(void) const     { return vLocalForce(eX); }
-  inline double GetBodyYForce(void) const     { return vLocalForce(eY); }
-  inline double GetWheelSlipAngle(void) const { return WheelSlip;       }
+  bool GetRetractable(void) const      { return isRetractable;   }
+  bool GetGearUnitUp(void) const       { return GearUp;          }
+  bool GetGearUnitDown(void) const     { return GearDown;        }
+  double GetWheelSideForce(void) const { return vLocalForce(eY); }
+  double GetWheelRollForce(void) const { return vLocalForce(eX); }
+  double GetWheelSideVel(void) const   { return vWhlVelVec(eY);  }
+  double GetWheelRollVel(void) const   { return vWhlVelVec(eX);  }
+  double GetBodyXForce(void) const     { return vForce(eX);      }
+  double GetBodyYForce(void) const     { return vForce(eY);      }
+  double GetWheelSlipAngle(void) const { return WheelSlip;       }
   double GetWheelVel(int axis) const          { return vWhlVelVec(axis);}
   bool IsBogey(void) const                    { return (eContactType == ctBOGEY);}
   double GetGearUnitPos(void);
@@ -291,15 +291,15 @@ public:
 
 private:
   int GearNumber;
+  FGMatrix33 Tg2b, Tb2g;
   FGColumnVector3 vXYZ;
   FGColumnVector3 vMoment;
   FGColumnVector3 vWhlBodyVec;
   FGColumnVector3 vLocalGear;
   FGColumnVector3 vForce;
-  FGColumnVector3 last_vForce; // remove this
   FGColumnVector3 vLocalForce;
-  FGColumnVector3 vWhlVelVec;     // Velocity of this wheel (Local)
-  FGColumnVector3 normal, cvel;
+  FGColumnVector3 vWhlVelVec, vLocalWhlVel;     // Velocity of this wheel
+  FGColumnVector3 normal, cvel, vGroundNormal;
   FGLocation contact, gearLoc;
   FGTable *ForceY_Table;
   double dT;
@@ -319,13 +319,11 @@ private:
   double TakeoffDistanceTraveled;
   double TakeoffDistanceTraveled50ft;
   double LandingDistanceTraveled;
-  double MaximumStrutForce;
+  double MaximumStrutForce, StrutForce;
   double MaximumStrutTravel;
-  double SideWhlVel, RollingWhlVel;
-  double RollingForce, SideForce, FCoeff;
+  double FCoeff;
   double WheelSlip;
   double TirePressureNorm;
-  double SinWheel, CosWheel;
   double GearPos;
   bool   useFCSGearPos;
   bool WOW;
@@ -374,6 +372,7 @@ private:
   void ComputeSlipAngle(void);
   void ComputeSideForceCoefficient(void);
   void ComputeVerticalStrutForce(void);
+  void ComputeGroundCoordSys(void);
   void CrashDetect(void);
   void InitializeReporting(void);
   void ResetReporting(void);
index 8b3d1403c74c787e3fc7f27467c00072d6e93145..2aeef3ea60da054dfdf849aa42df143b9b788261 100644 (file)
@@ -83,7 +83,7 @@ CLASS DOCUMENTATION
       FLIGHTGEAR  A socket is created for sending binary data packets to
                   an external instance of FlightGear for visuals.  Parameters
                   defining the socket are given on the \<output> line.
-      TABULAR     Columnar data. NOT IMPLEMENTED YET!
+      TABULAR     Columnar data.
       TERMINAL    Output to terminal. NOT IMPLEMENTED YET!
       NONE        Specifies to do nothing. This setting makes it easy to turn on and
                   off the data output without having to mess with anything else.
@@ -91,7 +91,7 @@ CLASS DOCUMENTATION
       Examples:
 </pre>
 @code
-       <output name="localhost" type="FLIGHTGEAR" port="5500" protocol="tcp" rate="10"></output>
+       <output name="localhost" type="FLIGHTGEAR" port="5500" protocol="tcp" rate="10"/>
 @endcode
 @code
        <output name="B737_datalog.csv" type="CSV" rate="20">