1
0
Fork 0

Integrate the latest terrain handling code

This commit is contained in:
Erik Hofman 2014-01-29 13:45:19 +01:00
parent b7a9aee796
commit 7bdd1d617d
6 changed files with 146 additions and 82 deletions

View file

@ -73,14 +73,10 @@ CLASS DECLARATION
extern std::string& to_lower(std::string& str);
extern bool is_number(const std::string& str);
std::vector <std::string> split(std::string str, char d);
// libc++ has these as built-ins for all C++ language versions
#if !defined(_LIBCPP_VERSION)
/* Comment out to_string functions when they are defined already - C++ 11 defines these */
extern std::string to_string(int);
extern std::string to_string(double);
extern std::string to_string(float);
#endif
extern std::string replace(std::string str, const std::string& old, const std::string& newstr);
#else
#include <cctype>

View file

@ -49,14 +49,16 @@ using namespace std;
namespace JSBSim {
IDENT(IdSrc,"$Id: FGGroundReactions.cpp,v 1.47 2014/01/13 10:46:07 ehofman Exp $");
IDENT(IdSrc,"$Id: FGGroundReactions.cpp,v 1.49 2014/01/28 09:42:21 ehofman Exp $");
IDENT(IdHdr,ID_GROUNDREACTIONS);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGGroundReactions::FGGroundReactions(FGFDMExec* fgex) : FGModel(fgex)
FGGroundReactions::FGGroundReactions(FGFDMExec* fgex) :
FGModel(fgex),
FGSurface(fgex)
{
Name = "FGGroundReactions";
@ -261,6 +263,9 @@ string FGGroundReactions::GetGroundReactionValues(string delimeter) const
void FGGroundReactions::bind(void)
{
eSurfaceType = ctGROUND;
FGSurface::bind();
PropertyManager->Tie("gear/num-units", this, &FGGroundReactions::GetNumGearUnits);
PropertyManager->Tie("gear/wow", this, &FGGroundReactions::GetWOW);
}

View file

@ -62,7 +62,7 @@ DEFINITIONS
GLOBAL DATA
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
IDENT(IdSrc,"$Id: FGLGear.cpp,v 1.111 2014/01/16 14:00:30 ehofman Exp $");
IDENT(IdSrc,"$Id: FGLGear.cpp,v 1.114 2014/01/28 09:42:21 ehofman Exp $");
IDENT(IdHdr,ID_LGEAR);
// Body To Structural (body frame is rotated 180 deg about Y and lengths are given in
@ -75,6 +75,7 @@ CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGLGear::FGLGear(Element* el, FGFDMExec* fdmex, int number, const struct Inputs& inputs) :
FGSurface(fdmex, number),
FGForce(fdmex),
in(inputs),
GearNumber(number),
@ -286,12 +287,12 @@ const FGColumnVector3& FGLGear::GetBodyForces(FGSurface *surface)
// not compressed) with respect to the ground level
double height = gearLoc.GetContactPoint(t, contact, normal, terrainVel, dummy);
double maxForce = DBL_MAX;
bool isSolid = true;
// Does this surface contact point interact with another surface?
if (surface) {
height -= (*surface).GetBumpHeight();
frictionFactor = (*surface).GetFrictionFactor();
maxForce = (*surface).GetMaximumForce();
staticFFactor = (*surface).GetStaticFFactor();
rollingFFactor = (*surface).GetRollingFFactor();
maximumForce = (*surface).GetMaximumForce();
isSolid = (*surface).GetSolid();
}
@ -315,7 +316,7 @@ const FGColumnVector3& FGLGear::GetBodyForces(FGSurface *surface)
compressLength = LGearProj > 0.0 ? height * normalZ / LGearProj : 0.0;
vWhlDisplVec = mTGear * FGColumnVector3(0., 0., -compressLength);
} else {
// Gears don't (or hardly) compress is liquids
// Gears don't (or hardly) compress in liquids
compressLength = 0.0;
vWhlDisplVec = 0.0 * vGroundNormal;
}
@ -353,7 +354,7 @@ const FGColumnVector3& FGLGear::GetBodyForces(FGSurface *surface)
compressSpeed /= LGearProj;
}
ComputeVerticalStrutForce(maxForce);
ComputeVerticalStrutForce();
// Compute the friction coefficients in the wheel ground plane.
if (eContactType == ctBOGEY) {
@ -575,10 +576,10 @@ void FGLGear::CrashDetect(void)
void FGLGear::ComputeBrakeForceCoefficient(void)
{
BrakeFCoeff = frictionFactor * rollingFCoeff;
BrakeFCoeff = rollingFFactor * rollingFCoeff;
if (eBrakeGrp != bgNone)
BrakeFCoeff += in.BrakePos[eBrakeGrp] * frictionFactor * (staticFCoeff - rollingFCoeff);
BrakeFCoeff += in.BrakePos[eBrakeGrp] * staticFFactor * (staticFCoeff - rollingFCoeff);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -599,7 +600,7 @@ void FGLGear::ComputeSideForceCoefficient(void)
double StiffSlip = Stiffness*WheelSlip;
FCoeff = Peak * sin(Shape*atan(StiffSlip - Curvature*(StiffSlip - atan(StiffSlip))));
}
FCoeff *= frictionFactor;
FCoeff *= staticFFactor;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -609,7 +610,7 @@ void FGLGear::ComputeSideForceCoefficient(void)
// possibly give a "rebound damping factor" that differs from the compression
// case.
void FGLGear::ComputeVerticalStrutForce(double maxForce)
void FGLGear::ComputeVerticalStrutForce()
{
double springForce = 0;
double dampForce = 0;
@ -636,8 +637,8 @@ void FGLGear::ComputeVerticalStrutForce(double maxForce)
}
StrutForce = min(springForce + dampForce, (double)0.0);
if (StrutForce > maxForce) {
StrutForce = maxForce;
if (StrutForce > maximumForce) {
StrutForce = maximumForce;
compressLength = -StrutForce / kSpring;
}
}
@ -691,7 +692,7 @@ void FGLGear::ComputeJacobian(const FGColumnVector3& vWhlContactVec)
LMultiplier[ftDynamic].ForceJacobian = mT * velocityDirection;
LMultiplier[ftDynamic].MomentJacobian = vWhlContactVec * LMultiplier[ftDynamic].ForceJacobian;
LMultiplier[ftDynamic].Max = 0.;
LMultiplier[ftDynamic].Min = -fabs(frictionFactor * dynamicFCoeff * vFn(eZ));
LMultiplier[ftDynamic].Min = -fabs(staticFFactor * dynamicFCoeff * vFn(eZ));
// The Lagrange multiplier value obtained from the previous iteration is kept
// This is supposed to accelerate the convergence of the projected Gauss-Seidel
@ -719,7 +720,7 @@ void FGLGear::ComputeJacobian(const FGColumnVector3& vWhlContactVec)
LMultiplier[ftSide].Max = fabs(FCoeff * vFn(eZ));
break;
case ctSTRUCTURE:
LMultiplier[ftRoll].Max = fabs(staticFCoeff * vFn(eZ));
LMultiplier[ftRoll].Max = fabs(staticFFactor * staticFCoeff * vFn(eZ));
LMultiplier[ftSide].Max = LMultiplier[ftRoll].Max;
break;
}
@ -773,14 +774,17 @@ void FGLGear::bind(void)
switch(eContactType) {
case ctBOGEY:
eSurfaceType = FGSurface::ctBOGEY;
base_property_name = CreateIndexedPropertyName("gear/unit", GearNumber);
break;
case ctSTRUCTURE:
eSurfaceType = FGSurface::ctSTRUCTURE;
base_property_name = CreateIndexedPropertyName("contact/unit", GearNumber);
break;
default:
return;
}
FGSurface::bind();
property_name = base_property_name + "/WOW";
PropertyManager->Tie( property_name.c_str(), &WOW );

View file

@ -49,7 +49,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_LGEAR "$Id: FGLGear.h,v 1.61 2014/01/16 14:00:42 ehofman Exp $"
#define ID_LGEAR "$Id: FGLGear.h,v 1.64 2014/01/28 09:42:21 ehofman Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -178,7 +178,7 @@ CLASS DOCUMENTATION
</contact>
@endcode
@author Jon S. Berndt
@version $Id: FGLGear.h,v 1.61 2014/01/16 14:00:42 ehofman Exp $
@version $Id: FGLGear.h,v 1.64 2014/01/28 09:42:21 ehofman Exp $
@see Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
NASA-Ames", NASA CR-2497, January 1975
@see Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
@ -191,7 +191,7 @@ CLASS DOCUMENTATION
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGLGear : public FGForce, protected FGSurface
class FGLGear : protected FGSurface, public FGForce
{
public:
struct Inputs {
@ -237,7 +237,9 @@ public:
/// Destructor
~FGLGear();
/// The Force vector for this gear
/** The Force vector for this gear
@param surface another surface to interact with, set to NULL for none.
*/
const FGColumnVector3& GetBodyForces(FGSurface *surface = NULL);
/// Gets the location of the gear in Body axes
@ -334,6 +336,7 @@ private:
double bDampRebound;
double compressLength;
double compressSpeed;
double rollingFCoeff;
double Stiffness, Shape, Peak, Curvature; // Pacejka factors
double BrakeFCoeff;
double maxCompLen;
@ -377,7 +380,7 @@ private:
void ComputeSteeringAngle(void);
void ComputeSlipAngle(void);
void ComputeSideForceCoefficient(void);
void ComputeVerticalStrutForce(double maxForce = DBL_MAX);
void ComputeVerticalStrutForce(void);
void ComputeGroundFrame(void);
void ComputeJacobian(const FGColumnVector3& vWhlContactVec);
void UpdateForces(void);

View file

@ -38,13 +38,14 @@ HISTORY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGSurface.h"
#include "input_output/FGPropertyManager.h"
#include "models/FGSurface.h"
using namespace std;
namespace JSBSim {
IDENT(IdSrc,"$Id: FGSurface.cpp,v 1.2 2014/01/16 12:31:50 ehofman Exp $");
IDENT(IdSrc,"$Id: FGSurface.cpp,v 1.5 2014/01/28 09:42:21 ehofman Exp $");
IDENT(IdHdr,ID_SURFACE);
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -55,22 +56,12 @@ GLOBAL DECLARATIONS
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
FGSurface::FGSurface()
FGSurface::FGSurface(FGFDMExec* fdmex, int number) :
contactNumber(number)
{
frictionFactor = 1.0;
rollingFCoeff = 0.02;
MaximumForce = DBL_MAX;
bumpiness = 0.0;
isSolid = true;
}
FGSurface::FGSurface(FGFDMExec* fdmex)
{
frictionFactor = 1.0;
rollingFCoeff = 0.02;
MaximumForce = DBL_MAX;
bumpiness = 0.0;
isSolid = true;
eSurfaceType = ctBOGEY;
_PropertyManager = fdmex->GetPropertyManager();
resetValues();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -81,6 +72,52 @@ FGSurface::~FGSurface()
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGSurface::resetValues(void)
{
staticFFactor = 1.0;
rollingFFactor = 1.0;
maximumForce = DBL_MAX;
bumpiness = 0.0;
isSolid = true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGSurface::bind(void)
{
if (!_PropertyManager) return;
string base_property_name;
string property_name;
switch(eSurfaceType) {
case ctBOGEY:
base_property_name = _CreateIndexedPropertyName("gear/unit", contactNumber);
break;
case ctSTRUCTURE:
base_property_name = _CreateIndexedPropertyName("contact/unit", contactNumber);
break;
case ctGROUND:
base_property_name = "ground";
break;
default:
return;
}
property_name = base_property_name + "/solid";
_PropertyManager->Tie( property_name.c_str(), &isSolid);
property_name = base_property_name + "/bumpiness";
_PropertyManager->Tie( property_name.c_str(), &bumpiness);
property_name = base_property_name + "/maximum-force-lbs";
_PropertyManager->Tie( property_name.c_str(), &maximumForce);
property_name = base_property_name + "/rolling_friction-factor";
_PropertyManager->Tie( property_name.c_str(), &rollingFFactor);
property_name = base_property_name + "/static-friction-factor";
_PropertyManager->Tie( property_name.c_str(), &staticFFactor);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
float FGSurface::GetBumpHeight()
{
if (bumpiness < 0.001) return 0.0f;
@ -105,15 +142,24 @@ float FGSurface::GetBumpHeight()
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGSurface::_CreateIndexedPropertyName(const string& Property, int index)
{
std::ostringstream buf;
buf << Property << '[' << index << ']';
return buf.str();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGSurface::GetSurfaceStrings(string delimeter) const
{
std::ostringstream buf;
buf << "FrictionFactor" << delimeter
<< "RollingFriction" << delimeter
<< "MaximumForce" << delimeter
<< "Bumpiness" << delimeter
<< "IsSolid";
buf << "staticFFactor" << delimeter
<< "rollingFFactor" << delimeter
<< "maximumForce" << delimeter
<< "bumpiness" << delimeter
<< "isSolid";
return buf.str();
}
@ -124,14 +170,15 @@ string FGSurface::GetSurfaceValues(string delimeter) const
{
std::ostringstream buf;
buf << GetFrictionFactor() << delimeter
<< GetRollingFriction() << delimeter
<< GetMaximumForce() << delimeter
<< GetBumpiness() << delimeter
<< (GetSolid() ? "1" : "0");
buf << staticFFactor << delimeter
<< rollingFFactor << delimeter
<< maximumForce << delimeter
<< bumpiness << delimeter
<< (isSolid ? "1" : "0");
return buf.str();
}
}
} // namespace JSBSim

View file

@ -44,7 +44,7 @@ INCLUDES
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_SURFACE "$Id: FGSurface.h,v 1.2 2014/01/16 12:31:50 ehofman Exp $"
#define ID_SURFACE "$Id: FGSurface.h,v 1.5 2014/01/28 09:42:21 ehofman Exp $"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
@ -68,21 +68,29 @@ class FGSurface
{
public:
/// Constructor
FGSurface();
enum ContactType {ctBOGEY, ctSTRUCTURE, ctGROUND};
/// Constructor
FGSurface(FGFDMExec* fdmex);
FGSurface(FGFDMExec* fdmex, int number = -1);
/// Destructor
~FGSurface();
/// Sets the friction factor of the surface area
void SetFrictionFactor(double friction) { frictionFactor = friction; }
void bind(void);
/// Sets the load capacity of the surface area
void SetMaximumForce(double force ) { MaximumForce = force; }
/// Reset all surface values to a default
void resetValues(void);
/// Sets the bumpiness factor associated with the surface
/// Sets the static friction factor of the surface area
void SetStaticFFactor(double friction) { staticFFactor = friction; }
/// Sets the rolling friction factor of the surface area
void SetRollingFFactor(double friction) { rollingFFactor = friction; }
/// Sets the maximum force for the surface area
void SetMaximumForce(double force) { maximumForce = force; }
/// Sets the normalized bumpiness factor associated with the surface
void SetBumpiness(double bump) { bumpiness = bump; }
/// Sets the surface is a solid flag value
@ -94,26 +102,20 @@ public:
}
/// Gets the friction factor of the surface area
double GetFrictionFactor(void) const { return frictionFactor; }
/// Gets the static friction factor of the surface area
double GetStaticFFactor(void) { return staticFFactor; }
/// Gets the rolling friction of the surface area
double GetRollingFriction(void) const { return rollingFCoeff; }
/// Gets the rolling friction factor of the surface area
double GetRollingFFactor(void) { return rollingFFactor; }
/// Gets the static friction of the surface area
double GetStaticFriction(void) const { return staticFCoeff; }
/// Gets the maximum force of the surface area
double GetMaximumForce(void) { return maximumForce; }
/// Gets the dynamic friction of the surface area
double GetDynamicFriction(void) const { return dynamicFCoeff; }
/// Gets the maximum force for this surface point
double GetMaximumForce(void) const { return MaximumForce; }
/// Gets the bumpiness factor associated with the surface
double GetBumpiness(void) const { return bumpiness; }
/// Gets the normalized bumpiness factor associated with the surface
double GetBumpiness(void) { return bumpiness; }
/// Gets the surface is a solid flag value
bool GetSolid(void) const { return isSolid; }
bool GetSolid(void) { return isSolid; }
/// Returns the height of the bump at the provided offset
float GetBumpHeight();
@ -122,14 +124,21 @@ public:
std::string GetSurfaceValues(std::string delimeter) const;
protected:
double staticFCoeff, dynamicFCoeff, rollingFCoeff;
double frictionFactor;
double MaximumForce;
ContactType eSurfaceType;
double staticFFactor, rollingFFactor;
double maximumForce;
double bumpiness;
bool isSolid;
double staticFCoeff, dynamicFCoeff;
private:
int contactNumber;
double pos[3];
FGPropertyManager* _PropertyManager;
static std::string _CreateIndexedPropertyName(const std::string& Property, int index);
};
}