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
}
}
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+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
void bind(void);
void bindModel(void);
void unbind(void);
+ void convert(void);
private:
typedef map<string,int> AxisIndex;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-float FGAircraft::GetNlf(void)
+double FGAircraft::GetNlf(void)
{
return -1*Aerodynamics->GetvFs(3)/MassBalance->GetWeight();
}
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; }
FDMExec = fdex;
State = FDMExec->GetState();
Table = 0;
+ IsFactor = false;
PropertyManager = FDMExec->GetPropertyManager();
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
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;
{
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);
}
}
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;
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; }
/// 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;};
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;
}
}
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+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
void AddGear(void);
FGPropertyManager* GetPropertyManager(void) { return PropertyManager; }
+ void convert(void);
void bind(void);
void bindModel(void);
#include "FGState.h"
#include "FGAtmosphere.h"
#include "FGFCS.h"
+#include "FGGroundCallback.h"
#include "FGPropulsion.h"
#include "FGMassBalance.h"
#include "FGGroundReactions.h"
Inertial = 0;
GroundReactions = 0;
Aircraft = 0;
+ GroundCallback = 0;
Propagate = 0;
Auxiliary = 0;
Output = 0;
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);
delete IC;
delete Trim;
+ delete GroundCallback;
+
FirstModel = 0L;
Error = 0;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+void FGFDMExec::SetGroundCallback(FGGroundCallback* p) {
+ if (GroundCallback)
+ delete GroundCallback;
+ GroundCallback = p;
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
vector <string> FGFDMExec::EnumerateFDMs(void)
{
vector <string> FDMList;
return false;
}
- if (Release == "ALPHA") {
+ if (Release == "ALPHA" && debug_lvl > 0) {
#ifndef _MSC_VER
system("banner ALPHA");
#endif
<< " 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
#include "FGTrim.h"
#include "FGInitialCondition.h"
#include "FGJSBBase.h"
+#include "FGGroundCallback.h"
#include "FGPropertyManager.h"
+#include "FGPropagate.h"
#include <vector>
/// 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
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.
/// 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.
FGState* State;
FGAtmosphere* Atmosphere;
FGFCS* FCS;
+ FGGroundCallback* GroundCallback;
FGPropulsion* Propulsion;
FGMassBalance* MassBalance;
FGAerodynamics* Aerodynamics;
{
FDMExec = fdmex;
totalValue = 0;
+ IsFactor = true;
Debug(0);
}
void unbind(void);
private:
- typedef vector<FGCoefficient*> CoeffArray;
- CoeffArray sum;
+// typedef vector<FGCoefficient*> CoeffArray;
+// CoeffArray sum;
double SDtotal;
double totalValue;
string description;
--- /dev/null
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ 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;
+}
+
+}
--- /dev/null
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ 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
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;
//******************************************************************************
void FGInitialCondition::SetAltitudeAGLFtIC(double tt) {
- fdmex->GetPropagate()->SetDistanceAGL(tt);
- altitude=fdmex->GetPropagate()->Geth();
- SetAltitudeFtIC(altitude);
+ SetAltitudeFtIC(terrain_altitude + tt);
}
//******************************************************************************
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;
FGColumnVector3& FGLGear::Force(void)
{
double SinWheel, CosWheel;
- double deltaT = State->Getdt()*Aircraft->GetRate();
+ double deltaT = State->Getdt()*Exec->GetGroundReactions()->GetRate();
vForce.InitMatrix();
vMoment.InitMatrix();
}
if (GearDown) {
+ double t = Exec->GetState()->Getsim_time();
vWhlBodyVec = MassBalance->StructuralToBody(vXYZ);
// 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
// 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
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;
/// 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; }
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;
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
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);
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#include <stdio.h>
#include <sstream>
#include "FGNozzle.h"
MAP = Atmosphere->GetPressure() * 47.88; // psf to Pa
CylinderHeadTemp_degK = 0.0;
Displacement = 360;
- MaxHP = 200;
+ MaxHP = 0;
Cycles = 2;
IdleRPM = 600;
Magnetos = 0;
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();
std::ostringstream buf;
buf << PowerAvailable << delimeter << HP << delimeter
+ << equivalence_ratio << delimeter << MAP << delimeter
<< Thruster->GetThrusterValues(EngineNumber, delimeter);
return buf.str();
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(),
// Finaly make shure that the quaternion stays normalized.
VState.vQtrn.Normalize();
+
+ // Recompute the RunwayRadius level.
+ RecomputeRunwayRadius();
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
{
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
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+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 );
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+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 );
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);
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(); }
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);
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; }
return false;
}
+ Engines.back()->SetEngineFileName(engineFileName);
+
AC_cfg->GetNextConfigLine();
while ((token = AC_cfg->GetValue()) != string("/AC_ENGINE")) {
*AC_cfg >> token;
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;
}
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();
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-void FGTable::Print(void)
+void FGTable::Print(int spaces)
{
+ string tabspace;
int startRow=0;
int startCol=0;
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 << " ";
cout << Data[r][c] << " ";
if (Type == tt3D) {
cout << endl;
- Tables[r-1].Print();
+ Tables[r-1].Print(spaces);
}
}
}
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;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGTrim::setupPullup() {
- float g,q,cgamma;
+ double g,q,cgamma;
g=fdmex->GetInertial()->gravity();
cgamma=cos(fgic->GetFlightPathAngleRadIC());
cout << "setPitchRateInPullup(): " << g << ", " << cgamma << ", "
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();
*/
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; }
};
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);
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;
#endif
#include <simgear/compiler.h>
+#include <simgear/math/sg_geodesy.hxx>
#include <stdio.h> // size_t
#ifdef SG_MATH_EXCEPTION_CLASH
#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>
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;
+};
/******************************************************************************/
fdmex = new FGFDMExec( (FGPropertyManager*)globals->get_props() );
+ // Register ground callback.
+ fdmex->SetGroundCallback( new FGFSGroundCallback(this) );
+
State = fdmex->GetState();
Atmosphere = fdmex->GetAtmosphere();
FCS = fdmex->GetFCS();
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();
trimmed->setBoolValue(false);
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
}
- _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) );
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() );
_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),
&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;
}
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;
}
&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 );
FGGroundReactions *GroundReactions;
int runcount;
- float trim_elev;
- float trim_throttle;
+ double trim_elev;
+ double trim_throttle;
SGPropertyNode *startup_trim;
SGPropertyNode *trimmed;
FGLocation.cpp FGLocation.h \
FGQuaternion.cpp FGQuaternion.h \
FGElectric.cpp FGElectric.h \
+ FGGroundCallback.cpp FGGroundCallback.h \
JSBSim.cxx JSBSim.hxx
FGCondition::FGCondition(FGConfigFile* AC_cfg, FGPropertyManager* PropertyManager) :
PropertyManager(PropertyManager)
{
- string property1, property2;
-
mComparison["EQ"] = eEQ;
mComparison["NE"] = eNE;
mComparison["GT"] = eGT;
}
}
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+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
bool Evaluate(void);
void PrintCondition(void);
+ void convert(void);
private:
FGConfigFile* AC_cfg;
eComparison Comparison;
bool isGroup;
string conditional;
-
+ string property1, property2;
+
static string indent;
vector <FGCondition> conditions;
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
~FGDeadBand();
bool Run(void);
+ void convert(void);
private:
FGConfigFile* AC_cfg;
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);
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
/** 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;
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
~FGGain();
double GetOutputPct() const { return OutputPct; }
-
+ void convert(void);
bool Run (void);
private:
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
The routine doing the work.
*/
bool Run (void);
-
+ void convert(void);
+
private:
FGConfigFile* AC_cfg;
vector<double> Detents;
Module: FGSummer.cpp
Author: Jon S. Berndt
Date started: 4/2000
-
+
------------- Copyright (C) 2000 -------------
This program is free software; you can redistribute it and/or modify it under
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-#include "FGSummer.h"
+#include "FGSummer.h"
namespace JSBSim {
} else {
InputSigns.push_back( 1.0);
}
-
+
InputNodes.push_back( resolveSymbol(token) );
} else if (token == "BIAS") {
*AC_cfg >> Bias;
OutputNode = PropertyManager->GetNode(sOutputIdx, true);
}
}
-
+
FGFCSComponent::bind();
Debug(0);
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
cout << " " << InputNodes[i]->getName() << endl;
}
if (Bias != 0.0) cout << " Bias: " << Bias << endl;
- if (clip) cout << " CLIPTO: " << clipmin
+ if (clip) cout << " CLIPTO: " << clipmin
<< ", " << clipmax << endl;
if (IsOutput) cout << " OUTPUT: " <<OutputNode->getName() << endl;
}
/// The execution method for this FCS component.
bool Run(void);
+ void convert(void);
private:
FGConfigFile* AC_cfg;
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
~FGSwitch();
bool Run(void);
+ void convert(void);
enum eLogic {elUndef=0, eAND, eOR, eDefault};
enum eComparison {ecUndef=0, eEQ, eNE, eGT, eGE, eLT, eLE};