1
0
Fork 0

Sync. w. JSBSim CVS.

This commit is contained in:
ehofman 2005-05-22 08:06:47 +00:00
parent 9c146d5527
commit 56a9034d95
52 changed files with 761 additions and 97 deletions

View file

@ -50,8 +50,10 @@ static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_AERODYNAMICS;
const unsigned NAxes=6;
const char* AxisNames[] = { "drag", "side-force", "lift", "rolling-moment",
"pitching-moment","yawing-moment" };
const char* AxisNames[] = { "drag", "side", "lift", "roll",
"pitch","yaw" };
const char* AxisNamesUpper[] = { "DRAG", "SIDE", "LIFT", "ROLL",
"PITCH","YAW" };
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
@ -358,6 +360,23 @@ void FGAerodynamics::unbind(void)
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGAerodynamics::convert(void)
{
for (int axis=0; axis<6; axis++) {
if (Coeff[axis].size()>0) {
cout << endl << " <axis name=\"" << AxisNamesUpper[axis] << "\">" << endl;
for (int c=0; c<Coeff[axis].size(); c++) {
Coeff[axis][c]->convert();
}
cout << " </axis>" << endl;
}
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print

View file

@ -169,6 +169,7 @@ public:
void bind(void);
void bindModel(void);
void unbind(void);
void convert(void);
private:
typedef map<string,int> AxisIndex;

View file

@ -148,7 +148,7 @@ bool FGAircraft::Run(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
float FGAircraft::GetNlf(void)
double FGAircraft::GetNlf(void)
{
return -1*Aerodynamics->GetvFs(3)/MassBalance->GetWeight();
}

View file

@ -152,7 +152,7 @@ public:
inline double GetXYZep(int idx) const { return vXYZep(idx); }
inline void SetAircraftName(string name) {AircraftName = name;}
float GetNlf(void);
double GetNlf(void);
inline FGColumnVector3& GetNwcg(void) { return vNwcg; }

View file

@ -75,6 +75,7 @@ FGCoefficient::FGCoefficient( FGFDMExec* fdex )
FDMExec = fdex;
State = FDMExec->GetState();
Table = 0;
IsFactor = false;
PropertyManager = FDMExec->GetPropertyManager();
@ -384,6 +385,72 @@ FGPropertyManager* FGCoefficient::resolveSymbol(string name)
return tmpn;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGCoefficient::convert(string prop)
{
if (IsFactor)
cout << " <function name=\"aero/function/" << name << "\">" << endl;
else
cout << " <function name=\"aero/coefficient/" << name << "\">" << endl;
cout << " <description>" << description << "</description>" << endl;
cout << " <product>" << endl;
for (int i=0; i<multipliers.size(); i++)
cout << " <property>" << (multipliers[i]->GetFullyQualifiedName()).substr(12) << "</property>" << endl;
if (!prop.empty())
cout << " <property>aero/function/" << prop << "</property>" << endl;
switch (type) {
case VALUE:
cout << " <value>" << StaticValue << "</value>" << endl;
break;
case VECTOR:
cout << " <table>" << endl;
cout << " <independentVar>" << (LookupR->GetFullyQualifiedName()).substr(12) << "</independentVar>" << endl;
cout << " <tableData>" << endl;
Table->Print(30);
cout << " </tableData>" << endl;
cout << " </table>" << endl;
break;
case TABLE:
cout << " <table>" << endl;
cout << " <independentVar lookup=\"row\">" << (LookupR->GetFullyQualifiedName()).substr(12) << "</independentVar>" << endl;
cout << " <independentVar lookup=\"column\">" << (LookupC->GetFullyQualifiedName()).substr(12) << "</independentVar>" << endl;
cout << " <tableData>" << endl;
Table->Print(30);
cout << " </tableData>" << endl;
cout << " </table>" << endl;
break;
case TABLE3D:
cout << " <table>" << endl;
cout << " <independentVar lookup=\"row\">" << (LookupR->GetFullyQualifiedName()).substr(12) << "</independentVar>" << endl;
cout << " <independentVar lookup=\"column\">" << (LookupC->GetFullyQualifiedName()).substr(12) << "</independentVar>" << endl;
cout << " <independentVar lookup=\"table\">" << (LookupT->GetFullyQualifiedName()).substr(12) << "</independentVar>" << endl;
cout << " <tableData>" << endl;
Table->Print(30);
cout << " </tableData>" << endl;
cout << " </table>" << endl;
break;
}
cout << " </product>" << endl;
cout << " </function>" << endl;
if (IsFactor) {
cout << " === MOVE THE ABOVE FACTOR " << name << " OUTSIDE OF AND BEFORE ANY <AXIS> DEFINITION ===" << endl;
for (int i=0; i<sum.size(); i++) {
sum[i]->convert(name);
}
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print

View file

@ -150,9 +150,13 @@ public:
virtual void bind(FGPropertyManager *parent);
virtual void unbind(void);
void convert(string prop="");
protected:
FGFDMExec* FDMExec;
bool IsFactor;
typedef vector<FGCoefficient*> CoeffArray;
CoeffArray sum;
private:
int numInstances;

View file

@ -131,27 +131,35 @@ void FGEngine::ConsumeFuel(void)
{
if (FuelFreeze) return;
unsigned int i;
double Fshortage, Oshortage, TanksWithFuel;
double Fshortage, Oshortage, TanksWithFuel, TanksWithOxidizer;
FGTank* Tank;
bool haveOxTanks = false;
if (TrimMode) return;
Fshortage = Oshortage = TanksWithFuel = 0.0;
Fshortage = Oshortage = TanksWithFuel = TanksWithOxidizer = 0.0;
// count how many assigned tanks have fuel
// count how many assigned tanks have fuel or oxidizer
for (i=0; i<SourceTanks.size(); i++) {
Tank = Propulsion->GetTank(SourceTanks[i]);
if (Tank->GetContents() > 0.0) {
++TanksWithFuel;
if (Tank->GetType() == FGTank::ttFUEL){
if (Tank->GetContents() > 0.0) {
++TanksWithFuel;
}
} else if (Tank->GetType() == FGTank::ttOXIDIZER) {
haveOxTanks = true;
if (Tank->GetContents() > 0.0) {
++TanksWithOxidizer;
}
}
}
if (!TanksWithFuel) return;
if (!TanksWithFuel || (haveOxTanks && !TanksWithOxidizer)) return;
for (i=0; i<SourceTanks.size(); i++) {
Tank = Propulsion->GetTank(SourceTanks[i]);
if (Tank->GetType() == FGTank::ttFUEL) {
Fshortage += Tank->Drain(CalcFuelNeed()/TanksWithFuel);
} else {
Oshortage += Tank->Drain(CalcOxidizerNeed()/TanksWithFuel);
} else if (Tank->GetType() == FGTank::ttOXIDIZER) {
Oshortage += Tank->Drain(CalcOxidizerNeed()/TanksWithOxidizer);
}
}
@ -212,7 +220,7 @@ FGColumnVector3& FGEngine::GetMoments(void)
bool FGEngine::LoadThruster(FGConfigFile* AC_cfg)
{
string token, fullpath, localpath;
string thrusterFileName, thrType, engineFileName;
string thrType, engineFileName;
FGConfigFile* Cfg_ptr = 0;
double xLoc, yLoc, zLoc, Pitch, Yaw;
double P_Factor = 0, Sense = 0.0;

View file

@ -114,6 +114,9 @@ public:
EngineType GetType(void) { return Type; }
virtual string GetName(void) { return Name; }
string GetThrusterFileName(void) {return thrusterFileName;}
void SetEngineFileName(string eng) {engineFileName = eng;}
string GetEngineFileName(void) {return engineFileName;}
// Engine controls
virtual double GetThrottleMin(void) { return MinThrottle; }
@ -164,6 +167,11 @@ public:
/// Sets engine placement information
virtual void SetPlacement(double x, double y, double z, double pitch, double yaw);
double GetPlacementX(void) const {return X;}
double GetPlacementY(void) const {return Y;}
double GetPlacementZ(void) const {return Z;}
double GetPitch(void) const {return EnginePitch;}
double GetYaw(void) const {return EngineYaw;}
virtual double GetPowerAvailable(void) {return 0.0;};
@ -178,10 +186,14 @@ public:
virtual string GetEngineLabels(string delimeter) = 0;
virtual string GetEngineValues(string delimeter) = 0;
int GetNumSourceTanks(void) {return SourceTanks.size();}
int GetSourceTank(int t) {return SourceTanks[t];}
protected:
FGPropertyManager* PropertyManager;
string Name;
string thrusterFileName;
string engineFileName;
const int EngineNumber;
EngineType Type;
double X, Y, Z;

View file

@ -828,6 +828,15 @@ void FGFCS::unbind(FGPropertyManager *node)
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFCS::convert(void)
{
for (int i=0; i<FCSComponents.size(); i++) {
FCSComponents[i]->convert();
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print

View file

@ -611,6 +611,7 @@ public:
void AddGear(void);
FGPropertyManager* GetPropertyManager(void) { return PropertyManager; }
void convert(void);
void bind(void);
void bindModel(void);

View file

@ -58,6 +58,7 @@ INCLUDES
#include "FGState.h"
#include "FGAtmosphere.h"
#include "FGFCS.h"
#include "FGGroundCallback.h"
#include "FGPropulsion.h"
#include "FGMassBalance.h"
#include "FGGroundReactions.h"
@ -120,6 +121,7 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root)
Inertial = 0;
GroundReactions = 0;
Aircraft = 0;
GroundCallback = 0;
Propagate = 0;
Auxiliary = 0;
Output = 0;
@ -190,6 +192,7 @@ bool FGFDMExec::Allocate(void)
Inertial = new FGInertial(this);
GroundReactions = new FGGroundReactions(this);
Aircraft = new FGAircraft(this);
GroundCallback = new FGGroundCallback();
Propagate = new FGPropagate(this);
Auxiliary = new FGAuxiliary(this);
Output = new FGOutput(this);
@ -280,6 +283,8 @@ bool FGFDMExec::DeAllocate(void)
delete IC;
delete Trim;
delete GroundCallback;
FirstModel = 0L;
Error = 0;
@ -369,6 +374,14 @@ bool FGFDMExec::RunIC(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFDMExec::SetGroundCallback(FGGroundCallback* p) {
if (GroundCallback)
delete GroundCallback;
GroundCallback = p;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
vector <string> FGFDMExec::EnumerateFDMs(void)
{
vector <string> FDMList;
@ -502,7 +515,7 @@ bool FGFDMExec::ReadPrologue(FGConfigFile* AC_cfg)
return false;
}
if (Release == "ALPHA") {
if (Release == "ALPHA" && debug_lvl > 0) {
#ifndef _MSC_VER
system("banner ALPHA");
#endif
@ -513,7 +526,7 @@ bool FGFDMExec::ReadPrologue(FGConfigFile* AC_cfg)
<< " will not fly as expected." << endl << endl
<< fgred << highint << "Use this model for development purposes ONLY!!!"
<< normint << reset << endl << endl;
} else if (Release == "BETA") {
} else if (Release == "BETA" && debug_lvl > 0) {
#ifndef _MSC_VER
system("banner BETA");
#endif

View file

@ -44,7 +44,9 @@ INCLUDES
#include "FGTrim.h"
#include "FGInitialCondition.h"
#include "FGJSBBase.h"
#include "FGGroundCallback.h"
#include "FGPropertyManager.h"
#include "FGPropagate.h"
#include <vector>
@ -142,6 +144,8 @@ public:
/// Resumes the sim
void Resume(void) {frozen = false;}
void SetGroundCallback(FGGroundCallback*);
/** Loads an aircraft model.
@param AircraftPath path to the aircraft directory. For instance:
"aircraft". Under aircraft, then, would be directories for various
@ -200,6 +204,8 @@ public:
inline FGAtmosphere* GetAtmosphere(void) {return Atmosphere;}
/// Returns the FGFCS pointer.
inline FGFCS* GetFCS(void) {return FCS;}
/// Returns the FGGroundCallback pointer.
inline FGGroundCallback* GetGroundCallback(void) {return GroundCallback;}
/// Returns the FGPropulsion pointer.
inline FGPropulsion* GetPropulsion(void) {return Propulsion;}
/// Returns the FGAircraft pointer.
@ -213,7 +219,7 @@ public:
/// Returns the FGAircraft pointer.
inline FGAircraft* GetAircraft(void) {return Aircraft;}
/// Returns the FGPropagate pointer.
inline FGPropagate* GetPropagate(void) {return Propagate;}
inline FGPropagate* GetPropagate(void) {return Propagate;}
/// Returns the FGAuxiliary pointer.
inline FGAuxiliary* GetAuxiliary(void) {return Auxiliary;}
/// Returns the FGOutput pointer.
@ -281,6 +287,7 @@ private:
FGState* State;
FGAtmosphere* Atmosphere;
FGFCS* FCS;
FGGroundCallback* GroundCallback;
FGPropulsion* Propulsion;
FGMassBalance* MassBalance;
FGAerodynamics* Aerodynamics;

View file

@ -73,6 +73,7 @@ FGFactorGroup::FGFactorGroup( FGFDMExec* fdmex ) : FGCoefficient( fdmex)
{
FDMExec = fdmex;
totalValue = 0;
IsFactor = true;
Debug(0);
}

View file

@ -102,8 +102,8 @@ public:
void unbind(void);
private:
typedef vector<FGCoefficient*> CoeffArray;
CoeffArray sum;
// typedef vector<FGCoefficient*> CoeffArray;
// CoeffArray sum;
double SDtotal;
double totalValue;
string description;

View file

@ -0,0 +1,74 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGGroundCallback.cpp
Author: Mathias Froehlich
Date started: 05/21/04
------ Copyright (C) 2004 Mathias Froehlich (Mathias.Froehlich@web.de) -------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA.
Further information about the GNU General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
-------------------------------------------------------------------------------
05/21/00 MF Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGColumnVector3.h"
#include "FGLocation.h"
#include "FGGroundCallback.h"
namespace JSBSim {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGGroundCallback::FGGroundCallback()
{
mReferenceRadius = 20925650;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGGroundCallback::~FGGroundCallback()
{
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGGroundCallback::GetAltitude(const FGLocation& l) const
{
return l.GetRadius() - mReferenceRadius;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGGroundCallback::GetAGLevel(double t, const FGLocation& l,
FGLocation& cont, FGColumnVector3& n,
FGColumnVector3& v) const
{
v = FGColumnVector3(0.0, 0.0, 0.0);
n = (-1/FGColumnVector3(l).Magnitude())*FGColumnVector3(l);
double r = l.GetRadius();
double agl = GetAltitude(l);
cont = ((r-agl)/r)*FGColumnVector3(l);
return agl;
}
}

View file

@ -0,0 +1,88 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGGroundCallback.h
Author: Mathias Froehlich
Date started: 05/21/04
------ Copyright (C) 2004 Mathias Froehlich (Mathias.Froehlich@web.de) -------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA.
Further information about the GNU General Public License can also be found on
the world wide web at http://www.gnu.org.
HISTORY
-------------------------------------------------------------------------------
05/21/00 MF Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGGROUNDCALLBACK_H
#define FGGROUNDCALLBACK_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGColumnVector3.h"
#include "FGLocation.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_GROUNDCALLBACK "$Id$"
namespace JSBSim {
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** This class provides callback slots to get ground specific data like
ground elevation and such.
There is a default implementation, which returns values for a
ball formed earth.
@author Mathias Froehlich
@version $Id$
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGGroundCallback
: public FGJSBBase {
public:
FGGroundCallback();
virtual ~FGGroundCallback();
/** Compute the altitude above sealevel. */
virtual double GetAltitude(const FGLocation& l) const;
/** Compute the altitude above ground. Defaults to sealevel altitude. */
virtual double GetAGLevel(double t, const FGLocation& l, FGLocation& cont,
FGColumnVector3& n, FGColumnVector3& v) const;
private:
/// Reference radius.
double mReferenceRadius;
};
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif

View file

@ -110,9 +110,15 @@ bool FGGroundReactions::Load(FGConfigFile* AC_cfg)
AC_cfg->GetNextConfigLine();
while ((token = AC_cfg->GetValue()) != string("/UNDERCARRIAGE")) {
int num = lGear.size();
lGear.push_back(FGLGear(AC_cfg, FDMExec, num));
FCS->AddGear();
string type;
*AC_cfg >> type;
if (type == "AC_GEAR") {
int num = lGear.size();
lGear.push_back(FGLGear(AC_cfg, FDMExec, num));
FCS->AddGear();
} else {
cerr << "Unknown undercarriage type \"" << type << "\"" << endl;
}
}
return true;

View file

@ -423,9 +423,7 @@ void FGInitialCondition::SetAltitudeFtIC(double tt) {
//******************************************************************************
void FGInitialCondition::SetAltitudeAGLFtIC(double tt) {
fdmex->GetPropagate()->SetDistanceAGL(tt);
altitude=fdmex->GetPropagate()->Geth();
SetAltitudeFtIC(altitude);
SetAltitudeFtIC(terrain_altitude + tt);
}
//******************************************************************************

View file

@ -59,11 +59,9 @@ CLASS IMPLEMENTATION
FGLGear::FGLGear(FGConfigFile* AC_cfg, FGFDMExec* fdmex, int number) : Exec(fdmex)
{
string tmp;
GearNumber = number;
*AC_cfg >> tmp >> name >> vXYZ(1) >> vXYZ(2) >> vXYZ(3)
*AC_cfg >> name >> vXYZ(1) >> vXYZ(2) >> vXYZ(3)
>> kSpring >> bDamp>> dynamicFCoeff >> staticFCoeff
>> rollingFCoeff >> sSteerType >> sBrakeGroup
>> maxSteerAngle >> sRetractable;
@ -211,7 +209,7 @@ FGLGear::~FGLGear()
FGColumnVector3& FGLGear::Force(void)
{
double SinWheel, CosWheel;
double deltaT = State->Getdt()*Aircraft->GetRate();
double deltaT = State->Getdt()*Exec->GetGroundReactions()->GetRate();
vForce.InitMatrix();
vMoment.InitMatrix();
@ -251,6 +249,7 @@ FGColumnVector3& FGLGear::Force(void)
}
if (GearDown) {
double t = Exec->GetState()->Getsim_time();
vWhlBodyVec = MassBalance->StructuralToBody(vXYZ);
@ -260,7 +259,10 @@ FGColumnVector3& FGLGear::Force(void)
// vLocalGear now stores the vector from the cg to the wheel in local coords.
compressLength = vLocalGear(eZ) - Propagate->GetDistanceAGL();
FGColumnVector3 normal, cvel;
FGLocation contact;
FGLocation gearLoc = Propagate->GetLocation().LocalToLocation(vLocalGear);
compressLength = - Exec->GetGroundCallback()->GetAGLevel(t, gearLoc, contact, normal, cvel);
// The compression length is currently measured in the Z-axis, only, at this time.
// It should be measured along the strut axis. If the local-frame gear position
@ -283,7 +285,7 @@ FGColumnVector3& FGLGear::Force(void)
// wheel velocity.
vWhlVelVec = Propagate->GetTb2l() * (Propagate->GetPQR() * vWhlBodyVec);
vWhlVelVec += Propagate->GetVel();
vWhlVelVec += Propagate->GetVel() - cvel;
compressSpeed = vWhlVelVec(eZ);
// If this is the first time the wheel has made contact, remember some values
@ -420,9 +422,10 @@ FGColumnVector3& FGLGear::Force(void)
RollingForce = 0;
if (fabs(RollingWhlVel) > 1E-3) {
RollingForce = (1.0 - TirePressureNorm) * 30
+ vLocalForce(eZ) * BrakeFCoeff
* fabs(RollingWhlVel)/RollingWhlVel;
double badPresResis = (1.0 - TirePressureNorm) * 30;
RollingForce = (badPresResis * min(fabs(RollingWhlVel), 1.0)
+ vLocalForce(eZ) * BrakeFCoeff)
* fabs(RollingWhlVel)/RollingWhlVel;
}
SideForce = vLocalForce(eZ) * FCoeff;

View file

@ -214,6 +214,7 @@ public:
/// Gets the gear compression force in pounds
inline double GetCompForce(void) {return Force()(3); }
inline double GetBrakeFCoeff(void) {return BrakeFCoeff;}
inline double GetXYZ(int i) {return vXYZ(i);}
/// Gets the current normalized tire pressure
inline double GetTirePressure(void) { return TirePressureNorm; }
@ -232,20 +233,28 @@ public:
double GetSteerNorm(void) const { return radtodeg/maxSteerAngle*SteerAngle; }
double GetDefaultSteerAngle(double cmd) const { return cmd*maxSteerAngle; }
double GetstaticFCoeff(void) { return staticFCoeff; }
double GetdynamicFCoeff(void) { return dynamicFCoeff; }
double GetrollingFCoeff(void) { return rollingFCoeff; }
inline int GetBrakeGroup(void) { return (int)eBrakeGrp; }
inline int GetSteerType(void) { return (int)eSteerType; }
bool GetSteerable(void) const { return eSteerType != stFixed; }
inline bool GetRetractable(void) { return isRetractable; }
inline bool GetGearUnitUp(void) { return GearUp; }
inline bool GetGearUnitDown(void) { return GearDown; }
inline double GetWheelSideForce(void) { return SideForce; }
inline double GetWheelRollForce(void) { return RollingForce; }
inline double GetBodyXForce(void) { return vLocalForce(eX); }
inline double GetBodyYForce(void) { return vLocalForce(eY); }
inline double GetWheelSlipAngle(void) { return WheelSlip; }
double GetWheelVel(int axis) { return vWhlVelVec(axis);}
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 GetBodyXForce(void) const { return vLocalForce(eX); }
inline double GetBodyYForce(void) const { return vLocalForce(eY); }
inline double GetWheelSlipAngle(void) const { return WheelSlip; }
double GetWheelVel(int axis) const { return vWhlVelVec(axis);}
double GetkSpring(void) const { return kSpring; }
double GetbDamp(void) const { return bDamp; }
double GetmaxSteerAngle(void) const { return maxSteerAngle; }
string GetsBrakeGroup(void) const { return sBrakeGroup; }
string GetsRetractable(void) const { return sRetractable; }
string GetsSteerType(void) const { return sSteerType; }
private:
int GearNumber;

View file

@ -77,8 +77,10 @@ public:
inline double GetMass(void) const {return Mass;}
inline double GetWeight(void) const {return Weight;}
inline double GetEmptyWeight(void) const {return EmptyWeight;}
inline FGColumnVector3& GetXYZcg(void) {return vXYZcg;}
inline double GetXYZcg(int axis) const {return vXYZcg(axis);}
inline double GetbaseXYZcg(int axis) const {return vbaseXYZcg(axis);}
/** Computes the inertia contribution of a pointmass.
Computes and returns the inertia matrix of a pointmass of mass
@ -123,6 +125,10 @@ public:
FGMatrix33& GetJ(void) {return mJ;}
FGMatrix33& GetJinv(void) {return mJinv;}
void SetAircraftBaseInertias(FGMatrix33 BaseJ) {baseJ = BaseJ;}
FGMatrix33& GetAircraftBaseInertias(void) {return baseJ;}
int GetNumPointMasses(void) {return PointMassLoc.size();}
FGColumnVector3& GetPointMassLoc(int i) {return PointMassLoc[i];}
double GetPointMassWeight(int i) {return PointMassWeight[i];}
void bind(void);
void unbind(void);

View file

@ -35,7 +35,6 @@ HISTORY
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include <stdio.h>
#include <sstream>
#include "FGNozzle.h"

View file

@ -75,7 +75,7 @@ FGPiston::FGPiston(FGFDMExec* exec, FGConfigFile* Eng_cfg, int engine_number)
MAP = Atmosphere->GetPressure() * 47.88; // psf to Pa
CylinderHeadTemp_degK = 0.0;
Displacement = 360;
MaxHP = 200;
MaxHP = 0;
Cycles = 2;
IdleRPM = 600;
Magnetos = 0;
@ -708,6 +708,8 @@ string FGPiston::GetEngineLabels(string delimeter)
buf << Name << "_PwrAvail[" << EngineNumber << "]" << delimeter
<< Name << "_HP[" << EngineNumber << "]" << delimeter
<< Name << "_equiv_ratio[" << EngineNumber << "]" << delimeter
<< Name << "_MAP[" << EngineNumber << "]" << delimeter
<< Thruster->GetThrusterLabels(EngineNumber, delimeter);
return buf.str();
@ -720,6 +722,7 @@ string FGPiston::GetEngineValues(string delimeter)
std::ostringstream buf;
buf << PowerAvailable << delimeter << HP << delimeter
<< equivalence_ratio << delimeter << MAP << delimeter
<< Thruster->GetThrusterValues(EngineNumber, delimeter);
return buf.str();

View file

@ -128,7 +128,7 @@ bool FGPropagate::InitModel(void)
void FGPropagate::SetInitialState(const FGInitialCondition *FGIC)
{
SeaLevelRadius = FGIC->GetSeaLevelRadiusFtIC();
RunwayRadius = FGIC->GetSeaLevelRadiusFtIC() + FGIC->GetTerrainAltitudeFtIC();
RunwayRadius = SeaLevelRadius;
// Set the position lat/lon/radius
VState.vLocation = FGLocation( FGIC->GetLongitudeRadIC(),
@ -155,6 +155,9 @@ void FGPropagate::SetInitialState(const FGInitialCondition *FGIC)
// Finaly make shure that the quaternion stays normalized.
VState.vQtrn.Normalize();
// Recompute the RunwayRadius level.
RecomputeRunwayRadius();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -177,6 +180,8 @@ bool FGPropagate::Run(void)
{
if (FGModel::Run()) return true; // Fast return if we have nothing to do ...
RecomputeRunwayRadius();
double dt = State->Getdt()*rate; // The 'stepsize'
const FGColumnVector3 omega( 0.0, 0.0, Inertial->omega() ); // earth rotation
const FGColumnVector3& vForces = Aircraft->GetForces(); // current forces
@ -245,6 +250,21 @@ bool FGPropagate::Run(void)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPropagate::RecomputeRunwayRadius(void)
{
// Get the runway radius.
// Boring: this does not belong here, but since Jon placed the RunwayRadius
// value here it is better done here than somewhere else.
FGLocation contactloc;
FGColumnVector3 dv;
FGGroundCallback* gcb = FDMExec->GetGroundCallback();
double t = State->Getsim_time();
gcb->GetAGLevel(t, VState.vLocation, contactloc, dv, dv);
RunwayRadius = contactloc.GetRadius();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPropagate::Seth(double tt)
{
VState.vLocation.SetRadius( tt + SeaLevelRadius );
@ -252,6 +272,20 @@ void FGPropagate::Seth(double tt)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGPropagate::GetRunwayRadius(void) const
{
return RunwayRadius;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
double FGPropagate::GetDistanceAGL(void) const
{
return VState.vLocation.GetRadius() - RunwayRadius;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPropagate::SetDistanceAGL(double tt)
{
VState.vLocation.SetRadius( tt + RunwayRadius );
@ -290,7 +324,7 @@ void FGPropagate::bind(void)
PropertyManager->Tie("position/h-agl-ft", this, &FGPropagate::GetDistanceAGL, &FGPropagate::SetDistanceAGL);
PropertyManager->Tie("position/radius-to-vehicle-ft", this, &FGPropagate::GetRadius);
PropertyManager->Tie("metrics/runway-radius", this, &FGPropagate::GetRunwayRadius, &FGPropagate::SetRunwayRadius);
PropertyManager->Tie("metrics/runway-radius", this, &FGPropagate::GetRunwayRadius);
PropertyManager->Tie("attitude/phi-rad", this, (int)ePhi, (PMF)&FGPropagate::GetEuler);
PropertyManager->Tie("attitude/theta-rad", this, (int)eTht, (PMF)&FGPropagate::GetEuler);

View file

@ -116,9 +116,9 @@ public:
zero if JSBSim is running in standalone mode.
@return distance of the runway from the center of the earth.
@units feet */
double GetRunwayRadius(void) const { return RunwayRadius; }
double GetRunwayRadius(void) const;
double GetSeaLevelRadius(void) const { return SeaLevelRadius; }
double GetDistanceAGL(void) const { return VState.vLocation.GetRadius()-RunwayRadius; }
double GetDistanceAGL(void) const;
double GetRadius(void) const { return VState.vLocation.GetRadius(); }
double GetLongitude(void) const { return VState.vLocation.GetLongitude(); }
double GetLatitude(void) const { return VState.vLocation.GetLatitude(); }
@ -139,11 +139,12 @@ public:
void SetRadius(double r) { VState.vLocation.SetRadius(r); }
void SetLocation(const FGLocation& l) { VState.vLocation = l; }
void Seth(double tt);
void SetRunwayRadius(double tt) { RunwayRadius = tt; }
void SetSeaLevelRadius(double tt) { SeaLevelRadius = tt; }
void SetDistanceAGL(double tt);
void SetInitialState(const FGInitialCondition *);
void RecomputeRunwayRadius(void);
void bind(void);
void unbind(void);

View file

@ -125,6 +125,9 @@ public:
the direction of flight. */
void SetSense(double s) { Sense = s;}
double GetSense(void) {return Sense;}
double GetPFactorValue(void) {return P_Factor;}
/// Retrieves the pitch of the propeller in degrees.
double GetPitch(void) { return Pitch; }

View file

@ -255,6 +255,8 @@ bool FGPropulsion::Load(FGConfigFile* AC_cfg)
return false;
}
Engines.back()->SetEngineFileName(engineFileName);
AC_cfg->GetNextConfigLine();
while ((token = AC_cfg->GetValue()) != string("/AC_ENGINE")) {
*AC_cfg >> token;

View file

@ -212,13 +212,13 @@ bool FGScript::LoadScript( string script )
cerr << "Initialization unsuccessful" << endl;
exit(-1);
}
/* comment this out for conversion capability
FGTrim fgt(FDMExec, tFull);
if ( !fgt.DoTrim() ) {
cout << "Trim Failed" << endl;
}
fgt.Report();
*/
return true;
}

View file

@ -165,8 +165,8 @@ FGMatrix33& FGState::GetTs2b(void)
FGMatrix33& FGState::GetTb2s(void)
{
float alpha,beta;
float ca, cb, sa, sb;
double alpha,beta;
double ca, cb, sa, sb;
alpha = Auxiliary->Getalpha();
beta = Auxiliary->Getbeta();

View file

@ -335,8 +335,9 @@ FGTable& FGTable::operator<<(const int n)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGTable::Print(void)
void FGTable::Print(int spaces)
{
string tabspace;
int startRow=0;
int startCol=0;
@ -349,9 +350,11 @@ void FGTable::Print(void)
ios::fmtflags flags = cout.setf(ios::fixed); // set up output stream
#endif
for (int i=0;i<spaces;i++) tabspace+=" ";
cout.precision(4);
for (int r=startRow; r<=nRows; r++) {
cout << " ";
cout << tabspace;
for (int c=startCol; c<=nCols; c++) {
if (r == 0 && c == 0) {
cout << " ";
@ -359,7 +362,7 @@ void FGTable::Print(void)
cout << Data[r][c] << " ";
if (Type == tt3D) {
cout << endl;
Tables[r-1].Print();
Tables[r-1].Print(spaces);
}
}
}

View file

@ -244,7 +244,7 @@ public:
FGTable& operator<<(const int n);
inline double GetElement(int r, int c) {return Data[r][c];}
inline double GetElement(int r, int c, int t);
void Print(void);
void Print(int spaces=0);
private:
enum type {tt1D, tt2D, tt3D} Type;

View file

@ -554,7 +554,7 @@ bool FGTrim::checkLimits(void) {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGTrim::setupPullup() {
float g,q,cgamma;
double g,q,cgamma;
g=fdmex->GetInertial()->gravity();
cgamma=cos(fgic->GetFlightPathAngleRadIC());
cout << "setPitchRateInPullup(): " << g << ", " << cgamma << ", "
@ -601,7 +601,7 @@ void FGTrim::updateRates(void){
fgic->SetQRadpsIC(q);
fgic->SetRRadpsIC(r);
} else if( mode == tPullup && fabs(targetNlf-1) > 0.01) {
float g,q,cgamma;
double g,q,cgamma;
g=fdmex->GetInertial()->gravity();
cgamma=cos(fgic->GetFlightPathAngleRadIC());
q=g*(targetNlf-cgamma)/fgic->GetVtrueFpsIC();

View file

@ -287,7 +287,7 @@ public:
*/
inline void DebugState(State state) { debug_axis=state; }
inline void SetTargetNlf(float nlf) { targetNlf=nlf; }
inline void SetTargetNlf(double nlf) { targetNlf=nlf; }
inline double GetTargetNlf(void) { return targetNlf; }
};

View file

@ -135,8 +135,8 @@ public:
void SetThetaOnGround(double ff);
void SetPhiOnGround(double ff);
inline void SetStateTarget(float target) { state_target=target; }
inline float GetStateTarget(void) { return state_target; }
inline void SetStateTarget(double target) { state_target=target; }
inline double GetStateTarget(void) { return state_target; }
bool initTheta(void);
@ -151,10 +151,10 @@ private:
State state;
Control control;
float state_target;
double state_target;
float state_value;
float control_value;
double state_value;
double control_value;
double control_min;
double control_max;

View file

@ -26,6 +26,7 @@
#endif
#include <simgear/compiler.h>
#include <simgear/math/sg_geodesy.hxx>
#include <stdio.h> // size_t
#ifdef SG_MATH_EXCEPTION_CLASH
@ -61,6 +62,7 @@
#include <FDM/JSBSim/FGPropertyManager.h>
#include <FDM/JSBSim/FGEngine.h>
#include <FDM/JSBSim/FGPiston.h>
#include <FDM/JSBSim/FGGroundCallback.h>
#include <FDM/JSBSim/FGTurbine.h>
#include <FDM/JSBSim/FGRocket.h>
#include <FDM/JSBSim/FGElectric.h>
@ -76,6 +78,37 @@ FMAX (double a, double b)
return a > b ? a : b;
}
class FGFSGroundCallback : public FGGroundCallback {
public:
FGFSGroundCallback(FGInterface* ifc) : mInterface(ifc) {}
virtual ~FGFSGroundCallback() {}
/** Get the altitude above sea level depenent on the location. */
virtual double GetAltitude(const FGLocation& l) const {
double pt[3] = { SG_FEET_TO_METER*l(eX),
SG_FEET_TO_METER*l(eY),
SG_FEET_TO_METER*l(eZ) };
double lat, lon, alt;
sgCartToGeod( pt, &lat, &lon, &alt);
return alt * SG_METER_TO_FEET;
}
/** Compute the altitude above ground. */
virtual double GetAGLevel(double t, const FGLocation& l,
FGLocation& cont,
FGColumnVector3& n, FGColumnVector3& v) const {
double loc_cart[3] = { l(eX), l(eY), l(eZ) };
double contact[3], normal[3], vel[3], lc, ff, agl;
int groundtype;
mInterface->get_agl_ft(t, loc_cart, contact, normal, vel,
&groundtype, &lc, &ff, &agl);
n = l.GetTec2l()*FGColumnVector3( normal[0], normal[1], normal[2] );
v = l.GetTec2l()*FGColumnVector3( vel[0], vel[1], vel[2] );
cont = FGColumnVector3( contact[0], contact[1], contact[2] );
return agl;
}
private:
FGInterface* mInterface;
};
/******************************************************************************/
@ -111,6 +144,9 @@ FGJSBsim::FGJSBsim( double dt )
fdmex = new FGFDMExec( (FGPropertyManager*)globals->get_props() );
// Register ground callback.
fdmex->SetGroundCallback( new FGFSGroundCallback(this) );
State = fdmex->GetState();
Atmosphere = fdmex->GetAtmosphere();
FCS = fdmex->GetFCS();
@ -349,7 +385,36 @@ void FGJSBsim::update( double dt )
int i;
// double save_alt = 0.0;
// Compute the radius of the aircraft. That is the radius of a ball
// where all gear units are in. At the moment it is at least 10ft ...
double acrad = 10.0;
int n_gears = GroundReactions->GetNumGearUnits();
for (i=0; i<n_gears; ++i) {
FGColumnVector3 bl = GroundReactions->GetGearUnit(i)->GetBodyLocation();
double r = bl.Magnitude();
if (acrad < r)
acrad = r;
}
// Compute the potential movement of this aircraft and query for the
// ground in this area.
double groundCacheRadius = acrad + 2*dt*Propagate->GetUVW().Magnitude();
FGColumnVector3 cart = Auxiliary->GetLocationVRP();
if ( needTrim && startup_trim->getBoolValue() ) {
double alt = fgic->GetAltitudeFtIC();
double slr = fgic->GetSeaLevelRadiusFtIC();
double lat = fgic->GetLatitudeDegIC() * SGD_DEGREES_TO_RADIANS;
double lon = fgic->GetLongitudeDegIC() * SGD_DEGREES_TO_RADIANS;
cart = FGLocation(lon, lat, alt+slr);
}
double cart_pos[3] = { cart(1), cart(2), cart(3) };
bool cache_ok = prepare_ground_cache_ft( State->Getsim_time(), cart_pos,
groundCacheRadius );
if (!cache_ok) {
SG_LOG(SG_FLIGHT, SG_WARN,
"FGInterface is beeing called without scenery below the aircraft!");
return;
}
copy_to_JSBsim();
@ -357,10 +422,18 @@ void FGJSBsim::update( double dt )
if ( needTrim ) {
if ( startup_trim->getBoolValue() ) {
double contact[3], dummy[3], lc, ff, agl;
int groundtype;
get_agl_ft(State->Getsim_time(), cart_pos, contact,
dummy, dummy, &groundtype, &lc, &ff, &agl);
double terrain_alt = sqrt(contact[0]*contact[0] + contact[1]*contact[1]
+ contact[2]*contact[2]) - fgic->GetSeaLevelRadiusFtIC();
SG_LOG(SG_FLIGHT, SG_INFO,
"Ready to trim, terrain altitude is: "
<< cur_fdm_state->get_Runway_altitude() * SG_METER_TO_FEET );
fgic->SetTerrainAltitudeFtIC( cur_fdm_state->get_ground_elev_ft() );
<< terrain_alt * SG_METER_TO_FEET );
fgic->SetTerrainAltitudeFtIC( terrain_alt );
do_trim();
} else {
fdmex->RunIC(); //apply any changes made through the set_ functions
@ -472,10 +545,7 @@ bool FGJSBsim::copy_to_JSBsim()
}
_set_Runway_altitude( cur_fdm_state->get_Runway_altitude() );
Propagate->SetSeaLevelRadius( get_Sea_level_radius() );
Propagate->SetRunwayRadius( get_Runway_altitude()
+ get_Sea_level_radius() );
Atmosphere->SetExTemperature(
9.0/5.0*(temperature->getDoubleValue()+273.15) );
@ -552,9 +622,34 @@ bool FGJSBsim::copy_from_JSBsim()
Propagate->GetUVW(3) );
// Make the HUD work ...
_set_Velocities_Ground( Propagate->GetVel(eNorth),
Propagate->GetVel(eEast),
-Propagate->GetVel(eDown) );
{
const FGLocation& l = Auxiliary->GetLocationVRP();
double xyz[3] = { l(eX)*SG_FEET_TO_METER,
l(eY)*SG_FEET_TO_METER,
l(eZ)*SG_FEET_TO_METER };
double lat, lon, alt;
sgCartToGeod(xyz, &lat, &lon, &alt);
FGQuaternion Tec2geodhl(0, -0.5*M_PI-lat, lon);
FGColumnVector3 ecVel = l.GetTl2ec()*Propagate->GetVel();
FGColumnVector3 geodhlVel = Tec2geodhl.GetT()*ecVel;
_set_Velocities_Ground( geodhlVel(eNorth)*SG_FEET_TO_METER,
geodhlVel(eEast)*SG_FEET_TO_METER,
-geodhlVel(eDown)*SG_FEET_TO_METER );
// Transform the acceleration to the earth centered frame and then
// back to the geodetic hl frame.
FGColumnVector3 accel = Propagate->GetUVWdot();
accel -= Propagate->GetUVW()*Propagate->GetPQR();
accel = Propagate->GetTb2l()*accel;
accel = l.GetTl2ec()*accel;
accel = Tec2geodhl.GetT()*accel;
_set_Accels_Local( accel(eNorth)*SG_FEET_TO_METER,
accel(eEast)*SG_FEET_TO_METER,
-accel(eDown)*SG_FEET_TO_METER);
}
_set_V_rel_wind( Auxiliary->GetVt() );
@ -575,11 +670,21 @@ bool FGJSBsim::copy_from_JSBsim()
_set_Mach_number( Auxiliary->GetMach() );
// Positions of Visual Reference Point
_updateGeocentricPosition( Auxiliary->GetLocationVRP().GetLatitude(),
Auxiliary->GetLocationVRP().GetLongitude(),
Auxiliary->GethVRP() );
FGLocation l = Auxiliary->GetLocationVRP();
_updateGeocentricPosition( l.GetLatitude(), l.GetLongitude(),
l.GetRadius() - get_Sea_level_radius() );
_set_Altitude_AGL( Propagate->GetDistanceAGL() );
{
double loc_cart[3] = { l(eX), l(eY), l(eZ) };
double contact[3], d[3], sd, t;
int id;
is_valid_m(&t, d, &sd);
get_agl_ft(t, loc_cart, contact, d, d, &id, &sd, &sd, &sd);
double rwrad
= FGColumnVector3( contact[0], contact[1], contact[2] ).Magnitude();
_set_Runway_altitude( rwrad - get_Sea_level_radius() );
}
_set_Euler_Angles( Propagate->GetEuler(ePhi),
Propagate->GetEuler(eTht),
@ -766,8 +871,6 @@ void FGJSBsim::set_Latitude(double lat)
&sea_level_radius_meters, &lat_geoc );
_set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET );
fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET );
_set_Runway_altitude( cur_fdm_state->get_Runway_altitude() );
fgic->SetTerrainAltitudeFtIC( cur_fdm_state->get_ground_elev_ft() );
fgic->SetLatitudeRadIC( lat_geoc );
needTrim=true;
}
@ -782,8 +885,6 @@ void FGJSBsim::set_Longitude(double lon)
update_ic();
fgic->SetLongitudeRadIC( lon );
_set_Runway_altitude( cur_fdm_state->get_Runway_altitude() );
fgic->SetTerrainAltitudeFtIC( cur_fdm_state->get_ground_elev_ft() );
needTrim=true;
}
@ -804,8 +905,6 @@ void FGJSBsim::set_Altitude(double alt)
&sea_level_radius_meters, &lat_geoc);
_set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET );
fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET );
_set_Runway_altitude( cur_fdm_state->get_Runway_altitude() );
fgic->SetTerrainAltitudeFtIC( cur_fdm_state->get_ground_elev_ft() );
SG_LOG(SG_FLIGHT, SG_INFO,
"Terrain altitude: " << cur_fdm_state->get_Runway_altitude() * SG_METER_TO_FEET );
fgic->SetLatitudeRadIC( lat_geoc );

View file

@ -222,8 +222,8 @@ private:
FGGroundReactions *GroundReactions;
int runcount;
float trim_elev;
float trim_throttle;
double trim_elev;
double trim_throttle;
SGPropertyNode *startup_trim;
SGPropertyNode *trimmed;

View file

@ -47,6 +47,7 @@ libJSBSim_a_SOURCES = \
FGLocation.cpp FGLocation.h \
FGQuaternion.cpp FGQuaternion.h \
FGElectric.cpp FGElectric.h \
FGGroundCallback.cpp FGGroundCallback.h \
JSBSim.cxx JSBSim.hxx

View file

@ -51,8 +51,6 @@ string FGCondition::indent = " ";
FGCondition::FGCondition(FGConfigFile* AC_cfg, FGPropertyManager* PropertyManager) :
PropertyManager(PropertyManager)
{
string property1, property2;
mComparison["EQ"] = eEQ;
mComparison["NE"] = eNE;
mComparison["GT"] = eGT;
@ -207,6 +205,16 @@ void FGCondition::PrintCondition(void )
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGCondition::convert(void)
{
if (conditions.empty())
cout << " " << property1 << " " << conditional << " " << property2 << endl;
else
for (int i; i<conditions.size(); i++) conditions[i].convert();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print

View file

@ -72,6 +72,7 @@ public:
bool Evaluate(void);
void PrintCondition(void);
void convert(void);
private:
FGConfigFile* AC_cfg;
@ -86,6 +87,7 @@ private:
eComparison Comparison;
bool isGroup;
string conditional;
string property1, property2;
static string indent;

View file

@ -121,6 +121,33 @@ bool FGDeadBand::Run(void )
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGDeadBand::convert(void)
{
cout << endl;
cout << " <component name=\"" << Name << "\" type=\"" << Type << "\">" << endl;
cout << " <input>" << (InputNodes[0]->GetFullyQualifiedName()).substr(12) << "</input>" << endl;
if (gain != 1.0)
cout << " <gain>" << gain << "</gain>" << endl;
cout << " <width>" << width << "</width>" << endl;
if (clip) {
cout << " <clip>" << endl;
cout << " <min>" << clipmin << "</min>" << endl;
cout << " <max>" << clipmax << "</max>" << endl;
cout << " </clip>" << endl;
}
if (IsOutput)
cout << " <output>" << (OutputNode->GetFullyQualifiedName()).substr(12) << "</output>" << endl;
cout << " </component>" << endl;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print

View file

@ -88,6 +88,7 @@ public:
~FGDeadBand();
bool Run(void);
void convert(void);
private:
FGConfigFile* AC_cfg;

View file

@ -104,7 +104,7 @@ public:
inline string GetName(void) const {return Name;}
inline string GetType(void) const { return Type; }
virtual double GetOutputPct(void) const { return 0; }
virtual void convert(void) {};
virtual void bind();
FGPropertyManager* resolveSymbol(string token);

View file

@ -205,6 +205,30 @@ bool FGFilter::Run(void)
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGFilter::convert(void)
{
cout << endl;
cout << " <component name=\"" << Name << "\" type=\"" << Type << "\">" << endl;
cout << " <input>" << (InputNodes[0]->GetFullyQualifiedName()).substr(12) << "</input>" << endl;
if (C1 != 0) cout << " <c1>" << C1 << "</c1>" << endl;
if (C2 != 0) cout << " <c2>" << C2 << "</c2>" << endl;
if (C3 != 0) cout << " <c3>" << C3 << "</c3>" << endl;
if (C4 != 0) cout << " <c4>" << C4 << "</c4>" << endl;
if (C5 != 0) cout << " <c5>" << C5 << "</c5>" << endl;
if (C6 != 0) cout << " <c6>" << C6 << "</c6>" << endl;
if (Trigger != 0) cout << " <trigger>" << Trigger << "</trigger>" << endl;
if (IsOutput)
cout << " <output>" << (OutputNode->GetFullyQualifiedName()).substr(12) << "</output>" << endl;
cout << " </component>" << endl;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print

View file

@ -195,6 +195,7 @@ public:
/** When true, causes previous values to be set to current values. This
is particularly useful for first pass. */
bool Initialize;
void convert(void);
enum {eLag, eLeadLag, eOrder2, eWashout, eIntegrator, eUnknown} FilterType;

View file

@ -175,6 +175,40 @@ bool FGGain::Run(void )
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGGain::convert(void)
{
cout << endl;
cout << " <component name=\"" << Name << "\" type=\"" << Type << "\">" << endl;
cout << " <input>" << (InputNodes[0]->GetFullyQualifiedName()).substr(12) << "</input>" << endl;
if (Gain != 1.0)
cout << " <gain>" << Gain << "</gain>" << endl;
if (Type == "PURE_GAIN") { // PURE_GAIN
} else if (Type == "SCHEDULED_GAIN") { // SCHEDULED_GAIN
} else if (Type == "AEROSURFACE_SCALE") { // AEROSURFACE_SCALE
cout << " <limit>" << endl;
cout << " <min>" << Min << "</min>" << endl;
cout << " <max>" << Max << "</max>" << endl;
cout << " </limit>" << endl;
}
if (clip) {
cout << " <clip>" << endl;
cout << " <min>" << clipmin << "</min>" << endl;
cout << " <max>" << clipmax << "</max>" << endl;
cout << " </clip>" << endl;
}
if (IsOutput)
cout << " <output>" << (OutputNode->GetFullyQualifiedName()).substr(12) << "</output>" << endl;
cout << " </component>" << endl;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print

View file

@ -173,7 +173,7 @@ public:
~FGGain();
double GetOutputPct() const { return OutputPct; }
void convert(void);
bool Run (void);
private:

View file

@ -178,6 +178,30 @@ bool FGKinemat::Run(void )
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGKinemat::convert(void)
{
cout << endl;
cout << " <component name=\"" << Name << "\" type=\"" << Type << "\">" << endl;
cout << " <input>" << (InputNodes[0]->GetFullyQualifiedName()).substr(12) << "</input>" << endl;
cout << " <traverse>" << endl;
for (int i=0; i<Detents.size(); i++) {
cout << " <setting>" << endl;
cout << " <position>" << Detents[i] << "</position>" << endl;
cout << " <time>" << TransitionTimes[i] << "</time>" << endl;
cout << " </setting>" << endl;
}
cout << " </traverse>" << endl;
if (IsOutput)
cout << " <output>" << (OutputNode->GetFullyQualifiedName()).substr(12) << "</output>" << endl;
cout << " </component>" << endl;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print

View file

@ -101,6 +101,7 @@ public:
The routine doing the work.
*/
bool Run (void);
void convert(void);
private:
FGConfigFile* AC_cfg;

View file

@ -130,6 +130,37 @@ bool FGSummer::Run(void )
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGSummer::convert(void)
{
string sSign;
cout << endl;
cout << " <component name=\"" << Name << "\" type=\"" << Type << "\">" << endl;
for (int i=0; i<InputNodes.size(); i++) {
if (InputSigns[i] < 0.0) sSign = "-";
else sSign = "";
cout << " <input>" << sSign << (InputNodes[i]->GetFullyQualifiedName()).substr(12) << "</input>" << endl;
}
if (Bias != 0.0)
cout << " <bias>" << Bias << "</bias>" << endl;
if (clip) {
cout << " <clip>" << endl;
cout << " <min>" << clipmin << "</min>" << endl;
cout << " <max>" << clipmax << "</max>" << endl;
cout << " </clip>" << endl;
}
if (IsOutput)
cout << " <output>" << (OutputNode->GetFullyQualifiedName()).substr(12) << "</output>" << endl;
cout << " </component>" << endl;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print

View file

@ -115,6 +115,7 @@ public:
/// The execution method for this FCS component.
bool Run(void);
void convert(void);
private:
FGConfigFile* AC_cfg;

View file

@ -188,6 +188,44 @@ bool FGSwitch::Run(void )
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGSwitch::convert(void)
{
cout << endl;
cout << " <component name=\"" << Name << "\" type=\"" << Type << "\">" << endl;
// cout << " <input>" << InputNodes[0]->GetName() << "</input>" << endl;
for (int i=0; i<tests.size(); i++) {
if (tests[i].Logic == eDefault) {
if (tests[i].OutputProp == 0L)
cout << " <default value=\"" << tests[i].OutputVal << "\"/>" << endl;
else
cout << " <default value=\"" << (tests[i].OutputProp->GetFullyQualifiedName()).substr(12) << "\"/>" << endl;
} else if (tests[i].Logic == eAND) {
if (tests[i].OutputProp == 0L)
cout << " <test logic=\"AND\" value=\"" << tests[i].OutputVal << "\">" << endl;
else
cout << " <test logic=\"AND\" value=\"" << (tests[i].OutputProp->GetFullyQualifiedName()).substr(12) << "\">" << endl;
} else if (tests[i].Logic == eOR) {
if (tests[i].OutputProp == 0L)
cout << " <test logic=\"OR\" value=\"" << tests[i].OutputVal << "\">" << endl;
else
cout << " <test logic=\"OR\" value=\"" << (tests[i].OutputProp->GetFullyQualifiedName()).substr(12) << "\">" << endl;
}
for (int j=0; j<tests[i].conditions.size(); j++) {
tests[i].conditions[j].convert();
}
if (tests[i].Logic != eDefault) cout << " </test>" << endl;
}
if (IsOutput)
cout << " <output>" << (OutputNode->GetFullyQualifiedName()).substr(12) << "</output>" << endl;
cout << " </component>" << endl;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print

View file

@ -133,6 +133,7 @@ public:
~FGSwitch();
bool Run(void);
void convert(void);
enum eLogic {elUndef=0, eAND, eOR, eDefault};
enum eComparison {ecUndef=0, eEQ, eNE, eGT, eGE, eLT, eLE};