#include <FDM/JSBSim/FGAtmosphere.h>
#include <FDM/JSBSim/FGMassBalance.h>
#include <FDM/JSBSim/FGAerodynamics.h>
+#include <FDM/JSBSim/FGLGear.h>
#include "JSBSim.hxx"
/******************************************************************************/
SG_LOG( SG_FLIGHT, SG_INFO, "Finished initializing JSBSim" );
+ SG_LOG( SG_FLIGHT, SG_INFO, "FGControls::get_gear_down()= " <<
+ globals->get_controls()->get_gear_down() );
+
}
msg = fdmex->ProcessMessage();
switch (msg->type) {
case FGJSBBase::Message::eText:
- cout << msg->messageId << ": " << msg->text << endl;
+ SG_LOG( SG_FLIGHT, SG_INFO, msg->messageId << ": " << msg->text );
break;
case FGJSBBase::Message::eBool:
- cout << msg->messageId << ": " << msg->text << " " << msg->bVal << endl;
+ SG_LOG( SG_FLIGHT, SG_INFO, msg->messageId << ": " << msg->text << " " << msg->bVal );
break;
case FGJSBBase::Message::eInteger:
- cout << msg->messageId << ": " << msg->text << " " << msg->iVal << endl;
+ SG_LOG( SG_FLIGHT, SG_INFO, msg->messageId << ": " << msg->text << " " << msg->iVal );
break;
case FGJSBBase::Message::eDouble:
- cout << msg->messageId << ": " << msg->text << " " << msg->dVal << endl;
+ SG_LOG( SG_FLIGHT, SG_INFO, msg->messageId << ": " << msg->text << " " << msg->dVal );
break;
default:
- cerr << "Unrecognized message type." << endl;
- break;
+ SG_LOG( SG_FLIGHT, SG_INFO, "Unrecognized message type." );
+ break;
}
}
FCS->SetLBrake( globals->get_controls()->get_brake( 0 ) );
FCS->SetRBrake( globals->get_controls()->get_brake( 1 ) );
FCS->SetCBrake( globals->get_controls()->get_brake( 2 ) );
+ FCS->SetGearCmd( globals->get_controls()->get_gear_down());
for (int i = 0; i < get_num_engines(); i++) {
FCS->SetThrottleCmd(i, globals->get_controls()->get_throttle(i));
FCS->SetMixtureCmd(i, globals->get_controls()->get_mixture(i));
+ FCS->SetPropPitchCmd(i, globals->get_controls()->get_prop_advance(i));
}
Position->SetSeaLevelRadius( get_Sea_level_radius() );
if ( gr->GetGearUnit(i)->GetBrakeGroup() > 0 ) {
gear->SetBrake(true);
}
- if ( gr->GetGearUp() ) {
- gear->SetPosition( 0.0 );
- }
+ if ( gr->GetGearUnit(i)->GetRetractable() ) {
+ gear->SetPosition( FCS->GetGearPos() );
+ } else {
+ gear->SetPosition( 1.0 );
+ }
}
}
for (int i=0;i<Ngear;i++) {
gear=get_gear_unit(i);
gear->SetWoW( gr->GetGearUnit(i)->GetWOW() );
- if ( gr->GetGearUp() ) {
- gear->SetPosition( 0.0 );
- }
+ if ( gr->GetGearUnit(i)->GetRetractable() ) {
+ gear->SetPosition( FCS->GetGearPos() );
+ }
}
}
FGAerodynamics::FGAerodynamics(FGFDMExec* FDMExec) : FGModel(FDMExec),
- vMoments(3),
- vForces(3),
vFs(3),
+ vForces(3),
+ vMoments(3),
vLastFs(3),
vDXYZcg(3)
{
string FGAerodynamics::GetCoefficientValues(void)
{
string SDValues = "";
- char buffer[10];
bool firstime = true;
for (unsigned int axis = 0; axis < 6; axis++) {
double FGAerodynamics::GetLoD(void)
{
- double LoD;
-
if (vFs(1) != 0.00) return vFs(3)/vFs(1);
else return 0.00;
}
FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex),
- vWindNED(3),
vDirectiondAccelDt(3),
vDirectionAccel(3),
vDirection(3),
vTurbulence(3),
vTurbulenceGrad(3),
vBodyTurbGrad(3),
- vTurbPQR(3)
+ vTurbPQR(3),
+ vWindNED(3)
{
Name = "FGAtmosphere";
lastIndex=0;
{
double slope, reftemp, refpress;
int i = 0;
- bool lookup = false;
i = lastIndex;
if (altitude < htab[lastIndex]) {
}
switch(i) {
- case 0: // sea level
- slope = -0.00356616; // R/ft.
- reftemp = 518.67; // R
- refpress = 2116.22; // psf
- //refdens = 0.00237767; // slugs/cubic ft.
- break;
case 1: // 36089 ft.
slope = 0;
reftemp = 389.97;
refpress = 0.000122276;
//refdens = 2.19541e-10;
break;
+ case 0:
+ default: // sea level
+ slope = -0.00356616; // R/ft.
+ reftemp = 518.67; // R
+ refpress = 2116.22; // psf
+ //refdens = 0.00237767; // slugs/cubic ft.
+ break;
+
}
if (slope == 0) {
string FGConfigFile::GetNextConfigLine(void)
{
- int deblank, not_found = string::npos;
+
int comment_starts_at;
int comment_ends_at;
int comment_length;
#include "filtersjb/FGGradient.h"
#include "filtersjb/FGSwitch.h"
#include "filtersjb/FGSummer.h"
-#include "filtersjb/FGFlaps.h"
+#include "filtersjb/FGKinemat.h"
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_FCS;
DaCmd = DeCmd = DrCmd = DfCmd = DsbCmd = DspCmd = PTrimCmd = 0.0;
DaPos = DePos = DrPos = DfPos = DsbPos = DspPos = 0.0;
+ GearCmd = GearPos = 1; // default to gear down
LeftBrake = RightBrake = CenterBrake = 0.0;
if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
ThrottlePos.clear();
MixtureCmd.clear();
MixturePos.clear();
+ PropPitchCmd.clear();
+ PropPitchPos.clear();
unsigned int i;
if (!FGModel::Run()) {
for (i=0; i<ThrottlePos.size(); i++) ThrottlePos[i] = ThrottleCmd[i];
for (i=0; i<MixturePos.size(); i++) MixturePos[i] = MixtureCmd[i];
+ for (i=0; i<PropPitchPos.size(); i++) PropPitchPos[i] = PropPitchCmd[i];
for (i=0; i<Components.size(); i++) Components[i]->Run();
} else {
}
<< " engines exist, but throttle setting for engine " << engineNum
<< " is selected" << endl;
}
+ return 0.0;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
<< " engines exist, but attempted throttle position setting is for engine "
<< engineNum << endl;
}
+ return 0.0;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+void FGFCS::SetPropPitchCmd(int engineNum, double setting)
+{
+ unsigned int ctr;
+
+ if (engineNum < (int)ThrottlePos.size()) {
+ if (engineNum < 0) {
+ for (ctr=0;ctr<PropPitchCmd.size();ctr++) PropPitchCmd[ctr] = setting;
+ } else {
+ PropPitchCmd[engineNum] = setting;
+ }
+ }
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+void FGFCS::SetPropPitchPos(int engineNum, double setting)
+{
+ unsigned int ctr;
+
+ if (engineNum < (int)ThrottlePos.size()) {
+ if (engineNum < 0) {
+ for (ctr=0;ctr<=PropPitchCmd.size();ctr++) PropPitchPos[ctr] = PropPitchCmd[ctr];
+ } else {
+ PropPitchPos[engineNum] = setting;
+ }
+ }
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
bool FGFCS::Load(FGConfigFile* AC_cfg)
{
string token;
Components.push_back(new FGGradient(this, AC_cfg));
} else if (token == "SWITCH") {
Components.push_back(new FGSwitch(this, AC_cfg));
- } else if (token == "FLAPS") {
- Components.push_back(new FGFlaps(this, AC_cfg));
+ } else if (token == "KINEMAT") {
+ Components.push_back(new FGKinemat(this, AC_cfg));
} else {
cerr << "Unknown token [" << token << "] in FCS portion of config file" << endl;
return false;
ThrottlePos.push_back(0.0);
MixtureCmd.push_back(0.0); // assume throttle and mixture are coupled
MixturePos.push_back(0.0);
+ PropPitchCmd.push_back(0.0); // assume throttle and prop pitch are coupled
+ PropPitchPos.push_back(0.0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@return mixture command in percent ( 0 - 100) for the given engine */
inline double GetMixtureCmd(int engine) { return MixtureCmd[engine]; }
+ /** Gets the prop pitch command.
+ @param engine engine ID number
+ @return pitch command in percent ( 0.0 - 1.0) for the given engine */
+ inline double GetPropPitchCmd(int engine) { return PropPitchCmd[engine]; }
+
/** Gets the pitch trim command.
@return pitch trim command in radians */
inline double GetPitchTrimCmd(void) { return PTrimCmd; }
+
+ /** Get the gear extend/retract command. 0 commands gear up, 1 down.
+ defaults to down.
+ @return the current value of the gear extend/retract command*/
+ inline double GetGearCmd(void) { return GearCmd; }
//@}
/// @name Aerosurface position retrieval
@param engine engine ID number
@return mixture position for the given engine in percent ( 0 - 100)*/
inline double GetMixturePos(int engine) { return MixturePos[engine]; }
+
+ /** Gets the gear position (0 up, 1 down), defaults to down
+ @return gear position (0 up, 1 down) */
+ inline double GetGearPos(void) { return GearPos; }
+
+ /** Gets the prop pitch position.
+ @param engine engine ID number
+ @return prop pitch position for the given engine in percent ( 0.0-1.0)*/
+ inline double GetPropPitchPos(int engine) { return PropPitchPos[engine]; }
//@}
/** Retrieves the State object pointer.
@param engine engine ID number
@param cmd mixture command in percent (0 - 100)*/
void SetMixtureCmd(int engine, double cmd);
+
+ /** Set the gear extend/retract command, defaults to down
+ @param gear command 0 for up, 1 for down */
+ void SetGearCmd(double gearcmd) { GearCmd = gearcmd; }
+
+ /** Sets the propeller pitch command for the specified engine
+ @param engine engine ID number
+ @param cmd mixture command in percent (0.0 - 1.0)*/
+ void SetPropPitchCmd(int engine, double cmd);
//@}
/// @name Aerosurface position setting
@param engine engine ID number
@param cmd mixture setting in percent (0 - 100)*/
void SetMixturePos(int engine, double cmd);
+
+ /** Set the gear extend/retract position, defaults to down
+ @param gear position 0 up, 1 down */
+ void SetGearPos(double gearpos) { GearPos = gearpos; }
+
+
+ /** Sets the actual prop pitch setting for the specified engine
+ @param engine engine ID number
+ @param cmd prop pitch setting in percent (0.0 - 1.0)*/
+ void SetPropPitchPos(int engine, double cmd);
//@}
/// @name Landing Gear brakes
vector <double> ThrottlePos;
vector <double> MixtureCmd;
vector <double> MixturePos;
+ vector <double> PropPitchCmd;
+ vector <double> PropPitchPos;
double LeftBrake, RightBrake, CenterBrake; // Brake settings
+ double GearCmd,GearPos;
vector <FGFCSComponent*> Components;
void Debug(void);
string initialize="";
bool result=false;
double dt=0.0;
- int i;
+ unsigned i;
struct condition *newCondition;
if (!Script.IsOpen()) return false;
void FGFDMExec::RunScript(void)
{
vector <struct condition>::iterator iC = Conditions.begin();
- bool truth;
- bool WholeTruth;
- int i;
-
- int count=0;
+ bool truth = false;
+ bool WholeTruth = false;
+ unsigned i;
double currentTime = State->Getsim_time();
- double newSetValue;
+ double newSetValue = 0;
while (iC < Conditions.end()) {
// determine whether the set of conditional tests for this condition equate
FGFactorGroup::~FGFactorGroup()
{
- int i;
+ unsigned i;
for (i=0; i<sum.size(); i++) {
delete sum[i];
}
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
double FGFactorGroup::TotalValue(void) {
- int i;
+ unsigned i;
double totalsum=0;
SDtotal=0.0;
for(i=0;i<sum.size();i++) {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGForce::FGForce(FGFDMExec *FDMExec) :
+ ttype(tNone),
+ fdmex(FDMExec),
vFn(3),
vMn(3),
- fdmex(FDMExec),
+ vH(3),
vFb(3),
vM(3),
vXYZn(3),
vDXYZ(3),
- mT(3,3),
- vH(3),
vSense(3),
- ttype(tNone)
+ mT(3,3)
+
{
mT(1,1) = 1; //identity matrix
mT(2,2) = 1;
FGMatrix33 Transform(void);
protected:
+ FGFDMExec *fdmex;
FGColumnVector3 vFn;
FGColumnVector3 vMn;
FGColumnVector3 vH;
- FGFDMExec *fdmex;
+
virtual void Debug(void);
private:
{
Name = "FGGroundReactions";
- GearUp = false;
if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
}
vMoments.InitMatrix();
// Only execute gear force code below 300 feet
- if ( !GearUp && Position->GetDistanceAGL() < 300.0 ) {
+ if ( Position->GetDistanceAGL() < 300.0 ) {
vector <FGLGear>::iterator iGear = lGear.begin();
// Sum forces and moments for all gear, here.
// Some optimizations may be made here - or rather in the gear code itself.
FGColumnVector3& GetMoments(void) {return vMoments;}
string GetGroundReactionStrings(void);
string GetGroundReactionValues(void);
-
- /** Gets the gear status
- @return true if gear is not deployed */
- inline bool GetGearUp(void) { return GearUp; }
- /** Gets the number of gear units defined for the aircraft
- @return number of gear units defined */
+
inline int GetNumGearUnits(void) { return lGear.size(); }
/** Gets a gear instance
@param gear index of gear instance
@return a pointer to the FGLGear instance of the gear unit requested */
+
+
inline FGLGear* GetGearUnit(int gear) { return &(lGear[gear]); }
- inline void SetGear(bool tt) { GearUp = tt; }
- inline void SetGearUp(void) { GearUp = true; }
- inline void SetGearDown(bool tt) { GearUp = false; }
private:
vector <FGLGear> lGear;
- bool GearUp;
FGColumnVector3 vForces;
FGColumnVector3 vMoments;
FGColumnVector3 vMaxStaticGrip;
FGInertial::FGInertial(FGFDMExec* fgex) : FGModel(fgex),
- vForces(3),
vOmegaLocal(3),
+ vForces(3),
vRadius(3),
vGravity(3)
{
//******************************************************************************
double FGInitialCondition::GammaEqOfTheta(double Theta) {
- double a,b,c,d;
+ double a,b,c;
double sTheta,cTheta;
//theta=Theta; stheta=sin(theta); ctheta=cos(theta);
//******************************************************************************
double FGInitialCondition::GammaEqOfAlpha(double Alpha) {
- double a,b,c,d;
+ double a,b,c;
double sAlpha,cAlpha;
sAlpha=sin(Alpha); cAlpha=cos(Alpha);
//initializations
d=1;
-
+ x2 = 0;
x1=xlo;x3=xhi;
f1=(this->*sfunc)(x1)-x;
f3=(this->*sfunc)(x3)-x;
const double FGJSBBase::inchtoft = 0.08333333;
const double FGJSBBase::Reng = 1716.0;
const double FGJSBBase::SHRatio = 1.40;
-const string FGJSBBase::needed_cfg_version = "1.56";
+const string FGJSBBase::needed_cfg_version = "1.57";
const string FGJSBBase::JSBSim_version = "0.9.1";
queue <FGJSBBase::Message*> FGJSBBase::Messages;
FG_HTAILAREA,
FG_VTAILAREA,
FG_VBARH, //horizontal tail volume
- FG_VBARV //vertical tail volume
+ FG_VBARV, //vertical tail volume
+ FG_GEAR_CMD,
+ FG_GEAR_POS
};
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Exec(fdmex)
{
string tmp;
+ string Retractable;
+
*AC_cfg >> tmp >> name >> vXYZ(1) >> vXYZ(2) >> vXYZ(3)
>> kSpring >> bDamp>> dynamicFCoeff >> staticFCoeff
- >> rollingFCoeff >> sSteerType >> sBrakeGroup >> maxSteerAngle;
+ >> rollingFCoeff >> sSteerType >> sBrakeGroup
+ >> maxSteerAngle >> Retractable;
if (debug_lvl > 0) {
cout << " Name: " << name << endl;
cout << " Steering Type: " << sSteerType << endl;
cout << " Grouping: " << sBrakeGroup << endl;
cout << " Max Steer Angle: " << maxSteerAngle << endl;
+ cout << " Retractable: " << Retractable << endl;
}
if (sBrakeGroup == "LEFT" ) eBrakeGrp = bgLeft;
cerr << "Improper steering type specification in config file: "
<< sSteerType << " is undefined." << endl;
}
+
+ if( Retractable == "RETRACT" ) {
+ isRetractable=true;
+ } else {
+ isRetractable=false;
+ }
+
+ GearUp=false; GearDown=true;
// Add some AI here to determine if gear is located properly according to its
// brake group type ??
sBrakeGroup = lgear.sBrakeGroup;
eBrakeGrp = lgear.eBrakeGrp;
maxSteerAngle = lgear.maxSteerAngle;
+ isRetractable = lgear.isRetractable;
+ GearUp = lgear.GearUp;
+ GearDown = lgear.GearDown;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGColumnVector3& FGLGear::Force(void)
{
- double SteerGain;
- double SinWheel, CosWheel, SideWhlVel, RollingWhlVel;
- double RudderPedal, RollingForce, SideForce, FCoeff;
- double WheelSlip;
-
- vWhlBodyVec = (vXYZ - MassBalance->GetXYZcg()) / 12.0;
- vWhlBodyVec(eX) = -vWhlBodyVec(eX);
- vWhlBodyVec(eZ) = -vWhlBodyVec(eZ);
+ vForce.InitMatrix();
+ vMoment.InitMatrix();
+ if(isRetractable ) {
+ if( FCS->GetGearPos() < 0.01 ) {
+ GearUp=true;GearDown=false;
+ } else if(FCS->GetGearPos() > 0.99) {
+ GearDown=true;GearUp=false;
+ } else {
+ GearUp=false; GearDown=false;
+ }
+ } else {
+ GearUp=false; GearDown=true;
+ }
+
+ if( GearDown ) {
+ double SteerGain = 0;
+ double SinWheel, CosWheel, SideWhlVel, RollingWhlVel;
+ double RollingForce, SideForce, FCoeff;
+ double WheelSlip;
+
+ vWhlBodyVec = (vXYZ - MassBalance->GetXYZcg()) / 12.0;
+ vWhlBodyVec(eX) = -vWhlBodyVec(eX);
+ vWhlBodyVec(eZ) = -vWhlBodyVec(eZ);
// vWhlBodyVec now stores the vector from the cg to this wheel
- vLocalGear = State->GetTb2l() * vWhlBodyVec;
+ vLocalGear = State->GetTb2l() * vWhlBodyVec;
// vLocalGear now stores the vector from the cg to the wheel in local coords.
- compressLength = vLocalGear(eZ) - Position->GetDistanceAGL();
+ compressLength = vLocalGear(eZ) - Position->GetDistanceAGL();
// 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
// "hangs down" below the CG greater than the altitude, then the compressLength
// will be positive - i.e. the gear will have made contact.
- if (compressLength > 0.00) {
+ if (compressLength > 0.00) {
- WOW = true; // Weight-On-Wheels is true
+ WOW = true;// Weight-On-Wheels is true
// The next equation should really use the vector to the contact patch of the tire
// including the strut compression and not vWhlBodyVec. Will fix this later.
// (used for calculating damping force) is found by taking the Z-component of the
// wheel velocity.
- vWhlVelVec = State->GetTb2l() * (Rotation->GetPQR() * vWhlBodyVec);
+ vWhlVelVec = State->GetTb2l() * (Rotation->GetPQR() * vWhlBodyVec);
- vWhlVelVec += Position->GetVel();
+ vWhlVelVec += Position->GetVel();
- compressSpeed = vWhlVelVec(eZ);
+ compressSpeed = vWhlVelVec(eZ);
// If this is the first time the wheel has made contact, remember some values
// for later printout.
- if (!FirstContact) {
- FirstContact = true;
- SinkRate = compressSpeed;
- GroundSpeed = Position->GetVel().Magnitude();
- }
+ if (!FirstContact) {
+ FirstContact = true;
+ SinkRate = compressSpeed;
+ GroundSpeed = Position->GetVel().Magnitude();
+ }
// The following needs work regarding friction coefficients and braking and
// steering The BrakeFCoeff formula assumes that an anti-skid system is used.
// [JSB] The braking force coefficients include normal rolling coefficient +
// a percentage of the static friction coefficient based on braking applied.
- switch (eBrakeGrp) {
- case bgLeft:
- SteerGain = -0.10;
- BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgLeft)) +
- staticFCoeff*FCS->GetBrake(bgLeft);
- break;
- case bgRight:
- SteerGain = -0.10;
- BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgRight)) +
- staticFCoeff*FCS->GetBrake(bgRight);
- break;
- case bgCenter:
- SteerGain = -0.10;
- BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgCenter)) +
- staticFCoeff*FCS->GetBrake(bgCenter);
- break;
- case bgNose:
- SteerGain = 0.10;
- BrakeFCoeff = rollingFCoeff;
- break;
- case bgTail:
- SteerGain = -0.10;
- BrakeFCoeff = rollingFCoeff;
- break;
- case bgNone:
- SteerGain = -0.10;
- BrakeFCoeff = rollingFCoeff;
- break;
- default:
- cerr << "Improper brake group membership detected for this gear." << endl;
- break;
- }
-
- switch (eSteerType) {
- case stSteer:
- SteerAngle = SteerGain*FCS->GetDrPos();
- break;
- case stFixed:
- SteerAngle = 0.0;
- break;
- case stCaster:
- // Note to Jon: This is not correct for castering gear. I'll fix it later.
- SteerAngle = 0.0;
- break;
- default:
- cerr << "Improper steering type membership detected for this gear." << endl;
- break;
- }
+ switch (eBrakeGrp) {
+ case bgLeft:
+ SteerGain = -0.10;
+ BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgLeft)) +
+ staticFCoeff*FCS->GetBrake(bgLeft);
+ break;
+ case bgRight:
+ SteerGain = -0.10;
+ BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgRight)) +
+ staticFCoeff*FCS->GetBrake(bgRight);
+ break;
+ case bgCenter:
+ SteerGain = -0.10;
+ BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgCenter)) +
+ staticFCoeff*FCS->GetBrake(bgCenter);
+ break;
+ case bgNose:
+ SteerGain = 0.10;
+ BrakeFCoeff = rollingFCoeff;
+ break;
+ case bgTail:
+ SteerGain = -0.10;
+ BrakeFCoeff = rollingFCoeff;
+ break;
+ case bgNone:
+ SteerGain = -0.10;
+ BrakeFCoeff = rollingFCoeff;
+ break;
+ default:
+ cerr << "Improper brake group membership detected for this gear." << endl;
+ break;
+ }
+
+ switch (eSteerType) {
+ case stSteer:
+ SteerAngle = SteerGain*FCS->GetDrPos();
+ break;
+ case stFixed:
+ SteerAngle = 0.0;
+ break;
+ case stCaster:
+// Note to Jon: This is not correct for castering gear. I'll fix it later.
+ SteerAngle = 0.0;
+ break;
+ default:
+ cerr << "Improper steering type membership detected for this gear." << endl;
+ break;
+ }
// Transform the wheel velocities from the local axis system to the wheel axis system.
// For now, steering angle is assumed to happen in the Local Z axis,
// not the strut axis as it should be. Will fix this later.
- SinWheel = sin(Rotation->Getpsi() + SteerAngle);
- CosWheel = cos(Rotation->Getpsi() + SteerAngle);
- RollingWhlVel = vWhlVelVec(eX)*CosWheel + vWhlVelVec(eY)*SinWheel;
- SideWhlVel = vWhlVelVec(eY)*CosWheel - vWhlVelVec(eX)*SinWheel;
+ SinWheel = sin(Rotation->Getpsi() + SteerAngle);
+ CosWheel = cos(Rotation->Getpsi() + SteerAngle);
+ RollingWhlVel = vWhlVelVec(eX)*CosWheel + vWhlVelVec(eY)*SinWheel;
+ SideWhlVel = vWhlVelVec(eY)*CosWheel - vWhlVelVec(eX)*SinWheel;
// Calculate tire slip angle.
- if (RollingWhlVel == 0.0 && SideWhlVel == 0.0) {
- WheelSlip = 0.0;
- } else {
- WheelSlip = radtodeg*atan2(SideWhlVel, RollingWhlVel);
- }
+ if (RollingWhlVel == 0.0 && SideWhlVel == 0.0) {
+ WheelSlip = 0.0;
+ } else {
+ WheelSlip = radtodeg*atan2(SideWhlVel, RollingWhlVel);
+ }
// The following code normalizes the wheel velocity vector, reverses it, and zeroes out
// the z component of the velocity. The question is, should the Z axis velocity be zeroed
// transition from static to dynamic friction. There are more complicated formulations
// of this that avoid the discrete jump. Will fix this later.
- if (fabs(WheelSlip) <= 10.0) {
- FCoeff = staticFCoeff*WheelSlip/10.0;
- } else {
- FCoeff = dynamicFCoeff*fabs(WheelSlip)/WheelSlip;
- }
+ if (fabs(WheelSlip) <= 10.0) {
+ FCoeff = staticFCoeff*WheelSlip/10.0;
+ } else {
+ FCoeff = dynamicFCoeff*fabs(WheelSlip)/WheelSlip;
+ }
// Compute the vertical force on the wheel using square-law damping (per comment
// in paper AIAA-2000-4303 - see header prologue comments). We might consider
// possibly give a "rebound damping factor" that differs from the compression
// case. NOTE: SQUARE LAW DAMPING NO GOOD!
- vLocalForce(eZ) = min(-compressLength * kSpring
- - compressSpeed * bDamp, (double)0.0);
+ vLocalForce(eZ) = min(-compressLength * kSpring
+ - compressSpeed * bDamp, (double)0.0);
- MaximumStrutForce = max(MaximumStrutForce, fabs(vLocalForce(eZ)));
- MaximumStrutTravel = max(MaximumStrutTravel, fabs(compressLength));
+ MaximumStrutForce = max(MaximumStrutForce, fabs(vLocalForce(eZ)));
+ MaximumStrutTravel = max(MaximumStrutTravel, fabs(compressLength));
// Compute the forces in the wheel ground plane.
- RollingForce = 0;
- if (fabs(RollingWhlVel) > 1E-3) {
- RollingForce = vLocalForce(eZ) * BrakeFCoeff * fabs(RollingWhlVel)/RollingWhlVel;
- }
- SideForce = vLocalForce(eZ) * FCoeff;
+ RollingForce = 0;
+ if (fabs(RollingWhlVel) > 1E-3) {
+ RollingForce = vLocalForce(eZ) * BrakeFCoeff * fabs(RollingWhlVel)/RollingWhlVel;
+ }
+ SideForce = vLocalForce(eZ) * FCoeff;
// Transform these forces back to the local reference frame.
- vLocalForce(eX) = RollingForce*CosWheel - SideForce*SinWheel;
- vLocalForce(eY) = SideForce*CosWheel + RollingForce*SinWheel;
+ vLocalForce(eX) = RollingForce*CosWheel - SideForce*SinWheel;
+ vLocalForce(eY) = SideForce*CosWheel + RollingForce*SinWheel;
// Note to Jon: At this point the forces will be too big when the airplane is
// stopped or rolling to a stop. We need to make sure that the gear forces just
// Transform the forces back to the body frame and compute the moment.
- vForce = State->GetTl2b() * vLocalForce;
- vMoment = vWhlBodyVec * vForce;
+ vForce = State->GetTl2b() * vLocalForce;
+ vMoment = vWhlBodyVec * vForce;
- } else {
+ } else {
- WOW = false;
+ WOW = false;
- if (Position->GetDistanceAGL() > 200.0) {
- FirstContact = false;
- Reported = false;
- DistanceTraveled = 0.0;
- MaximumStrutForce = MaximumStrutTravel = 0.0;
- }
+ if (Position->GetDistanceAGL() > 200.0) {
+ FirstContact = false;
+ Reported = false;
+ DistanceTraveled = 0.0;
+ MaximumStrutForce = MaximumStrutTravel = 0.0;
+ }
- compressLength = 0.0; // reset compressLength to zero for data output validity
+ compressLength = 0.0;// reset compressLength to zero for data output validity
- vForce.InitMatrix();
- vMoment.InitMatrix();
- }
+
+ }
- if (FirstContact) {
- DistanceTraveled += Position->GetVel().Magnitude()*State->Getdt()*Aircraft->GetRate();
- }
+ if (FirstContact) {
+ DistanceTraveled += Position->GetVel().Magnitude()*State->Getdt()*Aircraft->GetRate();
+ }
+
+ if (ReportEnable && Position->GetVel().Magnitude() <= 0.05 && !Reported) {
+ if (debug_lvl > 0) Report();
+ }
- if (ReportEnable && Position->GetVel().Magnitude() <= 0.05 && !Reported) {
- if (debug_lvl > 0) Report();
- }
+ if (lastWOW != WOW) {
+ PutMessage("GEAR_CONTACT", WOW);
+ }
- if (lastWOW != WOW) {
- PutMessage("GEAR_CONTACT", WOW);
- }
+ lastWOW = WOW;
- lastWOW = WOW;
+// Crash detection logic (really out-of-bounds detection)
- // Crash detection logic (really out-of-bounds detection)
-
- if (compressLength > 500.0 ||
- vForce.Magnitude() > 100000000.0 ||
- vMoment.Magnitude() > 5000000000.0 ||
- SinkRate > 1.4666*30)
- {
- PutMessage("Crash Detected");
- Exec->Freeze();
- }
+ if (compressLength > 500.0 ||
+ vForce.Magnitude() > 100000000.0 ||
+ vMoment.Magnitude() > 5000000000.0 ||
+ SinkRate > 1.4666*30)
+ {
+ PutMessage("Crash Detected");
+ Exec->Freeze();
+ }
- return vForce;
+
+ }
+ return vForce;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
inline int GetBrakeGroup(void) { return (int)eBrakeGrp; }
inline int GetSteerType(void) { return (int)eSteerType; }
-
+
+ inline bool GetRetractable(void) { return isRetractable; }
+ inline bool GetGearUnitUp(void) { return GearUp; }
+ inline bool GetGearUnitDown(void) { return GearDown; }
+
private:
FGColumnVector3 vXYZ;
FGColumnVector3 vMoment;
bool FirstContact;
bool Reported;
bool ReportEnable;
+ bool isRetractable;
+ bool GearUp, GearDown;
string name;
string sSteerType;
string sBrakeGroup;
+
BrakeGroup eBrakeGrp;
SteerType eSteerType;
double maxSteerAngle;
FGPiston::FGPiston(FGFDMExec* exec, FGConfigFile* Eng_cfg)
: FGEngine(exec),
- MinManifoldPressure_inHg(6.5),
- MaxManifoldPressure_inHg(28.5),
- Displacement(360),
- MaxHP(200),
- Cycles(2),
- IdleRPM(600),
- // Set constants
- CONVERT_CUBIC_INCHES_TO_METERS_CUBED(1.638706e-5),
- R_air(287.3),
- rho_fuel(800), // estimate
- calorific_value_fuel(47.3e6),
- Cp_air(1005),
- Cp_fuel(1700)
+ //these must be initialized this way as they are declared const
+ CONVERT_CUBIC_INCHES_TO_METERS_CUBED(1.638706e-5),
+ R_air(287.3),
+ rho_fuel(800), // estimate
+ calorific_value_fuel(47.3e6),
+ Cp_air(1005),
+ Cp_fuel(1700)
{
+
string token;
+ MinManifoldPressure_inHg=6.5;
+ MaxManifoldPressure_inHg=28.5;
+ Displacement=360;
+ MaxHP=200;
+ Cycles=2;
+ IdleRPM=600;
+ // Set constants
+
+
+
Name = Eng_cfg->GetValue("NAME");
Eng_cfg->GetNextConfigLine();
while (Eng_cfg->GetValue() != string("/FG_PISTON")) {
double FGPiston::Calculate(double PowerRequired)
{
- double h,EngineMaxPower;
// FIXME: calculate from actual fuel flow
ConsumeFuel();
double FGRocket::Calculate(double pe)
{
- double Cf;
+ double Cf=0;
ConsumeFuel();
FGRotation::FGRotation(FGFDMExec* fdmex) : FGModel(fdmex),
vPQR(3),
+ vAeroPQR(3),
vPQRdot(3),
vMoments(3),
vEuler(3),
vEulerRates(3),
- vlastPQRdot(3),
- vAeroPQR(3)
+ vlastPQRdot(3)
{
Name = "FGRotation";
cTht=cPhi=cPsi=1.0;
// entry in the enum eParam definition in FGJSBBase.h. The ID is what must be used
// in any config file entry which references that item.
-FGState::FGState(FGFDMExec* fdex) : mTb2l(3,3),
+FGState::FGState(FGFDMExec* fdex) :
+ mTb2l(3,3),
mTl2b(3,3),
mTs2b(3,3),
mTb2s(3,3),
vQtrn(4),
vlastQdot(4),
vQdot(4),
- vTmp(4),
- vEuler(3),
vUVW(3),
vLocalVelNED(3),
- vLocalEuler(3)
+ vLocalEuler(3),
+ vTmp(4),
+ vEuler(3)
{
FDMExec = fdex;
RegisterVariable(FG_SPDBRAKE_POS, " speedbrake_pos " );
RegisterVariable(FG_SPOILERS_POS, " spoiler_pos " );
RegisterVariable(FG_FLAPS_POS, " flaps_pos " );
+ RegisterVariable(FG_GEAR_POS, " gear_pos " );
RegisterVariable(FG_ELEVATOR_CMD, " elevator_cmd " );
RegisterVariable(FG_AILERON_CMD, " aileron_cmd " );
RegisterVariable(FG_RUDDER_CMD, " rudder_cmd " );
RegisterVariable(FG_SPOILERS_CMD, " spoiler_cmd " );
RegisterVariable(FG_FLAPS_CMD, " flaps_cmd " );
RegisterVariable(FG_THROTTLE_CMD, " throttle_cmd " );
+ RegisterVariable(FG_GEAR_CMD, " gear_cmd " );
RegisterVariable(FG_THROTTLE_POS, " throttle_pos " );
- RegisterVariable(FG_MIXTURE_CMD, " mixture_cmd " );
- RegisterVariable(FG_MIXTURE_POS, " mixture_pos " );
- RegisterVariable(FG_MAGNETO_CMD, " magneto_cmd " );
- RegisterVariable(FG_STARTER_CMD, " starter_cmd " );
+ RegisterVariable(FG_MIXTURE_CMD, " mixture_cmd " );
+ RegisterVariable(FG_MIXTURE_POS, " mixture_pos " );
+ RegisterVariable(FG_MAGNETO_CMD, " magneto_cmd " );
+ RegisterVariable(FG_STARTER_CMD, " starter_cmd " );
RegisterVariable(FG_ACTIVE_ENGINE, " active_engine " );
RegisterVariable(FG_HOVERB, " height/span " );
RegisterVariable(FG_PITCH_TRIM_CMD, " pitch_trim_cmd " );
return Position->GetHOverBMAC();
case FG_PITCH_TRIM_CMD:
return FCS->GetPitchTrimCmd();
+ case FG_GEAR_CMD:
+ return FCS->GetGearCmd();
+ case FG_GEAR_POS:
+ return FCS->GetGearPos();
default:
cerr << "FGState::GetParameter() - No handler for parameter " << paramdef[val_idx] << endl;
return 0.0;
FCS->SetMixtureCmd(ActiveEngine,val);
break;
case FG_MAGNETO_CMD:
- Propulsion->GetEngine(ActiveEngine)->SetMagnetos(val); // need to account for -1
+ Propulsion->GetEngine(ActiveEngine)->SetMagnetos((int)val); // need to account for -1
break;
case FG_STARTER_CMD:
if (val < 0.001)
case FG_RIGHT_BRAKE_CMD:
FCS->SetRBrake(val);
break;
-
+ case FG_GEAR_CMD:
+ FCS->SetGearCmd(val);
+ break;
+ case FG_GEAR_POS:
+ FCS->SetGearPos(val);
+ break;
case FG_SET_LOGGING:
if (val < -0.01) Output->Disable();
else if (val > 0.01) Output->Enable();
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGState::ReportState(void) {
- char out[80], flap[10], gear[10];
+ char out[80], flap[10], gear[12];
cout << endl << " JSBSim State" << endl;
snprintf(out,80," Weight: %7.0f lbs. CG: %5.1f, %5.1f, %5.1f inches\n",
snprintf(flap,10,"Up");
else
snprintf(flap,10,"%2.0f",FCS->GetDfPos());
- if(GroundReactions->GetGearUp() == true)
- snprintf(gear,10,"Up");
+ if(FCS->GetGearPos() < 0.01)
+ snprintf(gear,12,"Up");
+ else if(FCS->GetGearPos() > 0.99)
+ snprintf(gear,12,"Down");
else
- snprintf(gear,10,"Down");
- snprintf(out,80, " Flaps: %3s Gear: %4s\n",flap,gear);
+ snprintf(gear,12,"In Transit");
+ snprintf(out,80, " Flaps: %3s Gear: %12s\n",flap,gear);
cout << out;
snprintf(out,80, " Speed: %4.0f KCAS Mach: %5.2f\n",
FDMExec->GetAuxiliary()->GetVcalibratedKTS(),
FGMatrix33 mTb2s;
FGColumnVector4 vQtrn;
FGColumnVector4 vlastQdot;
+ FGColumnVector4 vQdot;
FGColumnVector3 vUVW;
FGColumnVector3 vLocalVelNED;
FGColumnVector3 vLocalEuler;
- FGColumnVector4 vQdot;
+
FGColumnVector4 vTmp;
FGColumnVector3 vEuler;
enum type {tt1D, tt2D} Type;
double** Data;
int nRows, nCols;
- unsigned int colCounter;
- unsigned int rowCounter;
+ int colCounter;
+ int rowCounter;
double** Allocate(void);
void Debug(void);
};
private:
vector<FGTrimAxis*> TrimAxes;
- int current_axis;
+ unsigned int current_axis;
int N, Nsub;
TrimMode mode;
int DebugLevel, Debug;
bool trimudot;
bool gamma_fallback;
bool trim_failed;
- int axis_count;
+ unsigned int axis_count;
int solutionDomain;
double xlo,xhi,alo,ahi;
double targetNlf;
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-\r
- Module: JSBSim.cpp\r
- Author: Jon S. Berndt\r
- Date started: 08/17/99\r
- Purpose: Standalone version of JSBSim.\r
- Called by: The USER.\r
-\r
- ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------\r
-\r
- This program is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License as published by the Free Software\r
- Foundation; either version 2 of the License, or (at your option) any later\r
- version.\r
-\r
- This program is distributed in the hope that it will be useful, but WITHOUT\r
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\r
- details.\r
-\r
- You should have received a copy of the GNU General Public License along with\r
- this program; if not, write to the Free Software Foundation, Inc., 59 Temple\r
- Place - Suite 330, Boston, MA 02111-1307, USA.\r
-\r
- Further information about the GNU General Public License can also be found on\r
- the world wide web at http://www.gnu.org.\r
-\r
-FUNCTIONAL DESCRIPTION\r
---------------------------------------------------------------------------------\r
-\r
-This class Handles calling JSBSim standalone. It is set up for compilation under\r
-Borland C+Builder or other compiler.\r
-\r
-HISTORY\r
---------------------------------------------------------------------------------\r
-08/17/99 JSB Created\r
-\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-INCLUDES\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
-\r
-#include "FGFDMExec.h"\r
-#include "FGRotation.h"\r
-#include "FGAtmosphere.h"\r
-#include "FGState.h"\r
-#include "FGFCS.h"\r
-#include "FGAircraft.h"\r
-#include "FGTranslation.h"\r
-#include "FGPosition.h"\r
-#include "FGAuxiliary.h"\r
-#include "FGOutput.h"\r
-#include "FGConfigFile.h"\r
-\r
-#ifdef FGFS\r
-#include <simgear/compiler.h>\r
-#include STL_IOSTREAM\r
-# ifdef SG_HAVE_STD_INCLUDES\r
-# include <ctime>\r
-# else\r
-# include <time.h>\r
-# endif\r
-#else\r
-# if defined(sgi) && !defined(__GNUC__)\r
-# include <iostream.h>\r
-# include <time.h>\r
-# else\r
-# include <iostream>\r
-# include <ctime>\r
-# endif\r
-#endif\r
-\r
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-DEFINITIONS\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
-\r
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-GLOBAL DATA\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
-\r
-static const char *IdSrc = "$Id$";\r
-\r
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
-\r
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-DOCUMENTATION\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
-\r
-/** Standalone JSBSim main program\r
- This is the wrapper program used to instantiate the JSBSim system and control\r
- it. Use this program to build a version of JSBSim that can be run from the\r
- command line. To get any use out of this, you will have to create a script\r
- to run a test case and specify what kind of output you would like.\r
- @author Jon S. Berndt\r
- @version $Id$\r
- @see -\r
-*/\r
-\r
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-IMPLEMENTATION\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
-\r
-int main(int argc, char** argv)\r
-{\r
- FGFDMExec* FDMExec;\r
- float cmd = 0.0;\r
- bool result = false;\r
- bool scripted = false;\r
-\r
- if (argc == 2) {\r
- FGConfigFile testFile(argv[1]);\r
-\r
- if (!testFile.IsOpen()) {\r
- cout << "Script file not opened" << endl;\r
- exit(-1); \r
- }\r
-\r
- testFile.GetNextConfigLine();\r
- if (testFile.GetValue("runscript").length() <= 0) {\r
- cout << "File: " << argv[1] << " is not a script file" << endl;\r
- exit(-1); \r
- }\r
- scripted = true;\r
- } else if (argc != 3) {\r
- cout << endl\r
- << " You must enter the name of a registered aircraft and reset point:"\r
- << endl << endl << " FDM <aircraft name> <reset file>" << endl;\r
- cout << endl << " Alternatively, you may specify only the name of a script file:"\r
- << endl << endl << " FDM <script file>" << endl << endl;\r
- exit(0);\r
- }\r
-\r
- FDMExec = new FGFDMExec();\r
-\r
- if (scripted) { // form jsbsim <scriptfile>\r
- result = FDMExec->LoadScript(argv[1]);\r
- if (!result) {\r
- cerr << "Script file " << argv[1] << " was not successfully loaded" << endl;\r
- exit(-1);\r
- }\r
- } else { // form jsbsim <acname> <resetfile>\r
- if ( ! FDMExec->LoadModel("aircraft", "engine", string(argv[1]))) {\r
- cerr << " JSBSim could not be started" << endl << endl;\r
- exit(-1);\r
- } \r
-\r
- FGInitialCondition IC(FDMExec);\r
- if ( ! IC.Load("aircraft",string(argv[1]),string(argv[2]))) {\r
- cerr << "Initialization unsuccessful" << endl;\r
- exit(-1);\r
- }\r
- }\r
-\r
- FGJSBBase::Message* msg;\r
- while (FDMExec->Run()) {\r
- while (FDMExec->ReadMessage()) {\r
- msg = FDMExec->ProcessMessage();\r
- switch (msg->type) {\r
- case FGJSBBase::Message::eText:\r
- cout << msg->messageId << ": " << msg->text << endl;\r
- break;\r
- case FGJSBBase::Message::eBool:\r
- cout << msg->messageId << ": " << msg->text << " " << msg->bVal << endl;\r
- break;\r
- case FGJSBBase::Message::eInteger:\r
- cout << msg->messageId << ": " << msg->text << " " << msg->iVal << endl;\r
- break;\r
- case FGJSBBase::Message::eDouble:\r
- cout << msg->messageId << ": " << msg->text << " " << msg->dVal << endl;\r
- break;\r
- default:\r
- cerr << "Unrecognized message type." << endl;\r
- break;\r
- }\r
- }\r
- }\r
-\r
- delete FDMExec;\r
-\r
- return 0;\r
-}\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ Module: JSBSim.cpp
+ Author: Jon S. Berndt
+ Date started: 08/17/99
+ Purpose: Standalone version of JSBSim.
+ Called by: The USER.
+
+ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
+
+ 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.
+
+FUNCTIONAL DESCRIPTION
+--------------------------------------------------------------------------------
+
+This class Handles calling JSBSim standalone. It is set up for compilation under
+Borland C+Builder or other compiler.
+
+HISTORY
+--------------------------------------------------------------------------------
+08/17/99 JSB Created
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+INCLUDES
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#include "FGFDMExec.h"
+#include "FGRotation.h"
+#include "FGAtmosphere.h"
+#include "FGState.h"
+#include "FGFCS.h"
+#include "FGAircraft.h"
+#include "FGTranslation.h"
+#include "FGPosition.h"
+#include "FGAuxiliary.h"
+#include "FGOutput.h"
+#include "FGConfigFile.h"
+
+#ifdef FGFS
+#include <simgear/compiler.h>
+#include STL_IOSTREAM
+# ifdef SG_HAVE_STD_INCLUDES
+# include <ctime>
+# else
+# include <time.h>
+# endif
+#else
+# if defined(sgi) && !defined(__GNUC__)
+# include <iostream.h>
+# include <time.h>
+# else
+# include <iostream>
+# include <ctime>
+# endif
+#endif
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+DEFINITIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+GLOBAL DATA
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+static const char *IdSrc = "$Id$";
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+DOCUMENTATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/** Standalone JSBSim main program
+ This is the wrapper program used to instantiate the JSBSim system and control
+ it. Use this program to build a version of JSBSim that can be run from the
+ command line. To get any use out of this, you will have to create a script
+ to run a test case and specify what kind of output you would like.
+ @author Jon S. Berndt
+ @version $Id$
+ @see -
+*/
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+IMPLEMENTATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+int main(int argc, char** argv)
+{
+ FGFDMExec* FDMExec;
+ float cmd = 0.0;
+ bool result = false;
+ bool scripted = false;
+
+ if (argc == 2) {
+ FGConfigFile testFile(argv[1]);
+
+ if (!testFile.IsOpen()) {
+ cout << "Script file not opened" << endl;
+ exit(-1);
+ }
+
+ testFile.GetNextConfigLine();
+ if (testFile.GetValue("runscript").length() <= 0) {
+ cout << "File: " << argv[1] << " is not a script file" << endl;
+ exit(-1);
+ }
+ scripted = true;
+ } else if (argc != 3) {
+ cout << endl
+ << " You must enter the name of a registered aircraft and reset point:"
+ << endl << endl << " FDM <aircraft name> <reset file>" << endl;
+ cout << endl << " Alternatively, you may specify only the name of a script file:"
+ << endl << endl << " FDM <script file>" << endl << endl;
+ exit(0);
+ }
+
+ FDMExec = new FGFDMExec();
+
+ if (scripted) { // form jsbsim <scriptfile>
+ result = FDMExec->LoadScript(argv[1]);
+ if (!result) {
+ cerr << "Script file " << argv[1] << " was not successfully loaded" << endl;
+ exit(-1);
+ }
+ } else { // form jsbsim <acname> <resetfile>
+ if ( ! FDMExec->LoadModel("aircraft", "engine", string(argv[1]))) {
+ cerr << " JSBSim could not be started" << endl << endl;
+ exit(-1);
+ }
+
+ FGInitialCondition IC(FDMExec);
+ if ( ! IC.Load("aircraft",string(argv[1]),string(argv[2]))) {
+ cerr << "Initialization unsuccessful" << endl;
+ exit(-1);
+ }
+ }
+
+ FGJSBBase::Message* msg;
+ while (FDMExec->Run()) {
+ while (FDMExec->ReadMessage()) {
+ msg = FDMExec->ProcessMessage();
+ switch (msg->type) {
+ case FGJSBBase::Message::eText:
+ cout << msg->messageId << ": " << msg->text << endl;
+ break;
+ case FGJSBBase::Message::eBool:
+ cout << msg->messageId << ": " << msg->text << " " << msg->bVal << endl;
+ break;
+ case FGJSBBase::Message::eInteger:
+ cout << msg->messageId << ": " << msg->text << " " << msg->iVal << endl;
+ break;
+ case FGJSBBase::Message::eDouble:
+ cout << msg->messageId << ": " << msg->text << " " << msg->dVal << endl;
+ break;
+ default:
+ cerr << "Unrecognized message type." << endl;
+ break;
+ }
+ }
+ }
+
+ delete FDMExec;
+
+ return 0;
+}
+++ /dev/null
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- Module: FGFlap.cpp
- Author: Tony Peden, for flight control system authored by Jon S. Berndt
- Date started: 5/11/00
-
- ------------- Copyright (C) 2000 Anthony K. Peden -------------
-
- 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.
-
-FUNCTIONAL DESCRIPTION
---------------------------------------------------------------------------------
-
-HISTORY
---------------------------------------------------------------------------------
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-COMMENTS, REFERENCES, and NOTES
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-INCLUDES
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-#include "FGFlaps.h"
-
-static const char *IdSrc = "$Id$";
-static const char *IdHdr = ID_FLAPS;
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-CLASS IMPLEMENTATION
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-FGFlaps::FGFlaps(FGFCS* fcs, FGConfigFile* AC_cfg) : FGFCSComponent(fcs),
-AC_cfg(AC_cfg) {
- string token;
- double tmpDetent;
- double tmpTime;
-
- Detents.clear();
- TransitionTimes.clear();
-
- Type = AC_cfg->GetValue("TYPE");
- Name = AC_cfg->GetValue("NAME");
- AC_cfg->GetNextConfigLine();
-
- while ((token = AC_cfg->GetValue()) != string("/COMPONENT")) {
- *AC_cfg >> token;
- if (token == "ID") {
- *AC_cfg >> ID;
- } else if (token == "INPUT") {
- token = AC_cfg->GetValue("INPUT");
- if (token.find("FG_") != token.npos) {
- *AC_cfg >> token;
- InputIdx = fcs->GetState()->GetParameterIndex(token);
- InputType = itPilotAC;
- }
- } else if ( token == "DETENTS" ) {
- *AC_cfg >> NumDetents;
- for(int i=0;i<NumDetents;i++) {
- *AC_cfg >> tmpDetent;
- *AC_cfg >> tmpTime;
- Detents.push_back(tmpDetent);
- TransitionTimes.push_back(tmpTime);
- }
- } else if (token == "OUTPUT") {
-
- IsOutput = true;
- *AC_cfg >> sOutputIdx;
- OutputIdx = fcs->GetState()->GetParameterIndex(sOutputIdx);
- }
- }
-
- if (debug_lvl > 1) {
- cout << " ID: " << ID << endl;
- cout << " INPUT: " << InputIdx << endl;
- cout << " DETENTS: " << NumDetents << endl;
- for(int i=0;i<NumDetents;i++) {
- cout << " " << Detents[i] << " " << TransitionTimes[i] << endl;
- }
- if (IsOutput) cout << " OUTPUT: " <<sOutputIdx << endl;
- }
-
- if (debug_lvl & 2) cout << "Instantiated: FGFlaps" << endl;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-FGFlaps::~FGFlaps()
-{
- if (debug_lvl & 2) cout << "Destroyed: FGFlaps" << endl;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-bool FGFlaps::Run(void ) {
- double dt=fcs->GetState()->Getdt();
- double flap_transit_rate=0;
-
- FGFCSComponent::Run(); // call the base class for initialization of Input
- Flap_Handle = Input*Detents[NumDetents-1];
- Flap_Position = fcs->GetState()->GetParameter(OutputIdx);
-
- if(Flap_Handle < Detents[0]) {
- fi=0;
- Flap_Handle=Detents[0];
- lastFlapHandle=Flap_Handle;
- Flap_Position=Detents[0];
- Output=Flap_Position;
- } else if(Flap_Handle > Detents[NumDetents-1]) {
- fi=NumDetents-1;
- Flap_Handle=Detents[fi];
- lastFlapHandle=Flap_Handle;
- Flap_Position=Detents[fi];
- Output=Flap_Position;
- } else {
- //cout << "FGFlaps::Run Handle: " << Flap_Handle << " Position: " << Flap_Position << endl;
- if(dt <= 0)
- Flap_Position=Flap_Handle;
- else {
- if(Flap_Handle != lastFlapHandle) {
-
- Flaps_In_Transit=1;
- }
- if(Flaps_In_Transit) {
-
- //fprintf(stderr,"Flap_Handle: %g, Flap_Position: %g\n",Flap_Handle,Flap_Position);
- fi=0;
- while(Detents[fi] < Flap_Handle) {
- fi++;
- }
- if(Flap_Position < Flap_Handle) {
- if(TransitionTimes[fi] > 0)
- flap_transit_rate=(Detents[fi] - Detents[fi-1])/TransitionTimes[fi];
- else
- flap_transit_rate=(Detents[fi] - Detents[fi-1])/5;
- } else {
- if(TransitionTimes[fi+1] > 0)
- flap_transit_rate=(Detents[fi] - Detents[fi+1])/TransitionTimes[fi+1];
- else
- flap_transit_rate=(Detents[fi] - Detents[fi+1])/5;
- }
- if(fabs(Flap_Position - Flap_Handle) > dt*flap_transit_rate)
- Flap_Position+=flap_transit_rate*dt;
- else {
- Flaps_In_Transit=0;
- Flap_Position=Flap_Handle;
- }
- }
- }
- lastFlapHandle=Flap_Handle;
- Output=Flap_Position;
- }
- //cout << "FGFlaps::Run Handle: " << Flap_Handle << " Position: " << Flap_Position << " Output: " << Output << endl;
- if (IsOutput) {
- //cout << "Calling SetOutput()" << endl;
- SetOutput();
- }
- //cout << "Out FGFlap::Run" << endl;
- return true;
-}
-
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGFlaps::Debug(void)
-{
- //TODO: Add your source code here
-}
-
+++ /dev/null
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- Header: FGFlaps.h
- Author: Tony Peden, for flight control system authored by Jon S. Berndt
- Date started: 5/11/00
-
- ------------- Copyright (C) Anthony K. Peden -------------
-
- 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
---------------------------------------------------------------------------------
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-COMMENTS, REFERENCES, and NOTES
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-SENTRY
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-#ifndef FGFLAPS_H
-#define FGFLAPS_H
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-INCLUDES
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-#ifdef FGFS
-# include <simgear/compiler.h>
-# ifdef SG_HAVE_STD_INCLUDES
-# include <vector>
-# else
-# include <vector.h>
-# endif
-#else
-# include <vector>
-#endif
-
-#include <string>
-#include "FGFCSComponent.h"
-#include "../FGConfigFile.h"
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-DEFINES
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-#define ID_FLAPS "$Id$"
-
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-CLASS DECLARATION
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-class FGFlaps : public FGFCSComponent {
-public:
- FGFlaps(FGFCS* fcs, FGConfigFile* AC_cfg);
- ~FGFlaps();
- bool Run (void );
-
-private:
- FGConfigFile* AC_cfg;
- vector<double> Detents;
- vector<double> TransitionTimes;
- int NumDetents,fi;
- double lastFlapHandle;
- double Flap_Handle;
- double Flap_Position;
- bool Flaps_In_Transit;
-
- void Debug(void);
-};
-
-#endif
if (debug_lvl > 0) {
cout << " ID: " << ID << endl;
cout << " INPUTS: " << endl;
- for (int i=0;i<InputIndices.size();i++) {
+ for (unsigned i=0;i<InputIndices.size();i++) {
cout << " " << InputIndices[i] << endl;
}
if (clipmax > clipmin) cout << " CLIPTO: " << clipmin
FGDeadBand.cpp FGDeadBand.h \
FGFCSComponent.cpp FGFCSComponent.h \
FGFilter.cpp FGFilter.h \
- FGFlaps.cpp FGFlaps.h \
FGGain.cpp FGGain.h \
FGGradient.cpp FGGradient.h \
+ FGKinemat.cpp FGKinemat.h \
FGSummer.cpp FGSummer.h \
FGSwitch.cpp FGSwitch.h