1
0
Fork 0

Latest JSBSim updates.

This commit is contained in:
david 2002-08-05 20:13:34 +00:00
parent f71e09be69
commit 844a55c3d1
20 changed files with 1151 additions and 979 deletions

View file

@ -152,10 +152,10 @@ bool FGAtmosphere::Run(void)
Debug(2); Debug(2);
return false;
} else { // skip Run() execution this time } else { // skip Run() execution this time
return true;
} }
return false;
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -120,10 +120,11 @@ bool FGFCS::Run(void)
for (i=0; i<PropAdvance.size(); i++) PropAdvance[i] = PropAdvanceCmd[i]; for (i=0; i<PropAdvance.size(); i++) PropAdvance[i] = PropAdvanceCmd[i];
for (i=0; i<Components.size(); i++) Components[i]->Run(); for (i=0; i<Components.size(); i++) Components[i]->Run();
if (DoNormalize) Normalize(); if (DoNormalize) Normalize();
} else {
}
return false; return false;
} else {
return true;
}
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -114,9 +114,7 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root)
frozen = false; frozen = false;
modelLoaded = false; modelLoaded = false;
IsSlave = false; IsSlave = false;
cout << "FGFDMExec::FGFDMExec, FDMctr: " << FDMctr << endl;
IdFDM = FDMctr; IdFDM = FDMctr;
FDMctr++; FDMctr++;
@ -132,6 +130,7 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root)
else master = root; else master = root;
instance = master->GetNode("/fdm/jsbsim",IdFDM,true); instance = master->GetNode("/fdm/jsbsim",IdFDM,true);
instance->SetDouble("zero",0);
Debug(0); Debug(0);
@ -157,8 +156,7 @@ FGFDMExec::~FGFDMExec()
for (unsigned int i=1; i<SlaveFDMList.size(); i++) delete SlaveFDMList[i]->exec; for (unsigned int i=1; i<SlaveFDMList.size(); i++) delete SlaveFDMList[i]->exec;
SlaveFDMList.clear(); SlaveFDMList.clear();
cout << "FGFDMExec::~FGFDMExec, FDMctr: " << FDMctr << endl;
FDMctr--;
Debug(1); Debug(1);
} }
@ -339,9 +337,9 @@ bool FGFDMExec::Run(void)
// Run(i) // Run(i)
} }
while (!model_iterator->Run()) { while (model_iterator != 0L) {
model_iterator->Run();
model_iterator = model_iterator->NextModel; model_iterator = model_iterator->NextModel;
if (model_iterator == 0L) break;
} }
frame = Frame++; frame = Frame++;

View file

@ -134,6 +134,8 @@ string FGGroundReactions::GetGroundReactionStrings(void)
GroundReactionStrings += (lGear[i].GetName() + "_strokeVel, "); GroundReactionStrings += (lGear[i].GetName() + "_strokeVel, ");
GroundReactionStrings += (lGear[i].GetName() + "_CompressForce, "); GroundReactionStrings += (lGear[i].GetName() + "_CompressForce, ");
GroundReactionStrings += (lGear[i].GetName() + "_WhlSideForce, "); GroundReactionStrings += (lGear[i].GetName() + "_WhlSideForce, ");
GroundReactionStrings += (lGear[i].GetName() + "_WhlVelVecX, ");
GroundReactionStrings += (lGear[i].GetName() + "_WhlVelVecY, ");
GroundReactionStrings += (lGear[i].GetName() + "_WhlRollForce, "); GroundReactionStrings += (lGear[i].GetName() + "_WhlRollForce, ");
GroundReactionStrings += (lGear[i].GetName() + "_BodyXForce, "); GroundReactionStrings += (lGear[i].GetName() + "_BodyXForce, ");
GroundReactionStrings += (lGear[i].GetName() + "_BodyYForce, "); GroundReactionStrings += (lGear[i].GetName() + "_BodyYForce, ");
@ -142,6 +144,13 @@ string FGGroundReactions::GetGroundReactionStrings(void)
firstime = false; firstime = false;
} }
GroundReactionStrings += ", TotalGearForce_X, ";
GroundReactionStrings += "TotalGearForce_Y, ";
GroundReactionStrings += "TotalGearForce_Z, ";
GroundReactionStrings += "TotalGearMoment_L, ";
GroundReactionStrings += "TotalGearMoment_M, ";
GroundReactionStrings += "TotalGearMoment_N";
return GroundReactionStrings; return GroundReactionStrings;
} }
@ -160,6 +169,8 @@ string FGGroundReactions::GetGroundReactionValues(void)
GroundReactionValues += (string(gcvt(lGear[i].GetCompLen(), 5, buff)) + ", "); GroundReactionValues += (string(gcvt(lGear[i].GetCompLen(), 5, buff)) + ", ");
GroundReactionValues += (string(gcvt(lGear[i].GetCompVel(), 6, buff)) + ", "); GroundReactionValues += (string(gcvt(lGear[i].GetCompVel(), 6, buff)) + ", ");
GroundReactionValues += (string(gcvt(lGear[i].GetCompForce(), 10, buff)) + ", "); GroundReactionValues += (string(gcvt(lGear[i].GetCompForce(), 10, buff)) + ", ");
GroundReactionValues += (string(gcvt(lGear[i].GetWheelVel(eX), 6, buff)) + ", ");
GroundReactionValues += (string(gcvt(lGear[i].GetWheelVel(eY), 6, buff)) + ", ");
GroundReactionValues += (string(gcvt(lGear[i].GetWheelSideForce(), 6, buff)) + ", "); GroundReactionValues += (string(gcvt(lGear[i].GetWheelSideForce(), 6, buff)) + ", ");
GroundReactionValues += (string(gcvt(lGear[i].GetWheelRollForce(), 6, buff)) + ", "); GroundReactionValues += (string(gcvt(lGear[i].GetWheelRollForce(), 6, buff)) + ", ");
GroundReactionValues += (string(gcvt(lGear[i].GetBodyXForce(), 6, buff)) + ", "); GroundReactionValues += (string(gcvt(lGear[i].GetBodyXForce(), 6, buff)) + ", ");
@ -169,6 +180,13 @@ string FGGroundReactions::GetGroundReactionValues(void)
firstime = false; firstime = false;
} }
GroundReactionValues += (", " + string(gcvt(vForces(eX), 6, buff)) + ", ");
GroundReactionValues += (string(gcvt(vForces(eY), 6, buff)) + ", ");
GroundReactionValues += (string(gcvt(vForces(eZ), 6, buff)) + ", ");
GroundReactionValues += (string(gcvt(vMoments(eX), 6, buff)) + ", ");
GroundReactionValues += (string(gcvt(vMoments(eY), 6, buff)) + ", ");
GroundReactionValues += (string(gcvt(vMoments(eZ), 6, buff)));
return GroundReactionValues; return GroundReactionValues;
} }

View file

@ -59,7 +59,10 @@ FGInertial::FGInertial(FGFDMExec* fgex) : FGModel(fgex)
RadiusReference = 20925650.00; RadiusReference = 20925650.00;
gAccelReference = GM/(RadiusReference*RadiusReference); gAccelReference = GM/(RadiusReference*RadiusReference);
gAccel = GM/(RadiusReference*RadiusReference); gAccel = GM/(RadiusReference*RadiusReference);
vCoriolis.InitMatrix();
vCentrifugal.InitMatrix();
vGravity.InitMatrix();
bind(); bind();
Debug(0); Debug(0);
@ -77,21 +80,12 @@ FGInertial::~FGInertial(void)
bool FGInertial::Run(void) bool FGInertial::Run(void)
{ {
double stht, ctht, sphi, cphi;
if (!FGModel::Run()) { if (!FGModel::Run()) {
gAccel = GM / (Position->GetRadius()*Position->GetRadius()); gAccel = GM / (Position->GetRadius()*Position->GetRadius());
stht = sin(Rotation->GetEuler(eTht)); vGravity(eDown) = gAccel;
ctht = cos(Rotation->GetEuler(eTht));
sphi = sin(Rotation->GetEuler(ePhi));
cphi = cos(Rotation->GetEuler(ePhi));
vGravity(eX) = vForces(eX) = -gravity()*stht;
vGravity(eY) = vForces(eY) = gravity()*sphi*ctht;
vGravity(eZ) = vForces(eZ) = gravity()*cphi*ctht;
// The following equation for vOmegaLocal terms shows the angular velocity // The following equation for vOmegaLocal terms shows the angular velocity
// calculation _for_the_local_frame_ given the earth's rotation (first set) // calculation _for_the_local_frame_ given the earth's rotation (first set)
// at the current latitude, and also the component due to the aircraft // at the current latitude, and also the component due to the aircraft
@ -105,12 +99,17 @@ bool FGInertial::Run(void)
vOmegaLocal(eY) += -Position->GetVn() / Position->GetRadius(); vOmegaLocal(eY) += -Position->GetVn() / Position->GetRadius();
vOmegaLocal(eZ) += 0.00; vOmegaLocal(eZ) += 0.00;
// vForces = State->GetTl2b()*(-2.0*vOmegaLocal * Position->GetVel()); // Coriolis acceleration is normally written: -2w*dr/dt, but due to the axis
// conventions used here the sign is reversed: 2w*dr/dt. The same is true for
// Centrifugal acceleration.
vRadius(3) = Position->GetRadius(); vCoriolis(eEast) = 2.0*omega() * (Position->GetVd()*cos(Position->GetLatitude()) +
vForces += State->GetTl2b()*(vOmegaLocal * (vOmegaLocal * vRadius)); Position->GetVn()*sin(Position->GetLatitude()));
vForces *= MassBalance->GetMass(); // IMPORTANT !!!!!!!!!!!!!!!!!!!!!!!!!!!! vRadius(eDown) = Position->GetRadius();
vCentrifugal(eDown) = -vOmegaLocal.Magnitude() * vOmegaLocal.Magnitude() * vRadius(eDown);
vForces = State->GetTl2b() * MassBalance->GetMass() * (vCoriolis + vCentrifugal + vGravity);
return false; return false;
} else { } else {

View file

@ -75,6 +75,8 @@ public:
bool Run(void); bool Run(void);
FGColumnVector3& GetForces(void) {return vForces;} FGColumnVector3& GetForces(void) {return vForces;}
FGColumnVector3& GetGravity(void) {return vGravity;} FGColumnVector3& GetGravity(void) {return vGravity;}
FGColumnVector3& GetCoriolis(void) {return vCoriolis;}
FGColumnVector3& GetCentrifugal(void) {return vCentrifugal;}
double GetForces(int n) const {return vForces(n);} double GetForces(int n) const {return vForces(n);}
bool LoadInertial(FGConfigFile* AC_cfg); bool LoadInertial(FGConfigFile* AC_cfg);
double SLgravity(void) const {return gAccelReference;} double SLgravity(void) const {return gAccelReference;}
@ -91,6 +93,8 @@ private:
FGColumnVector3 vForces; FGColumnVector3 vForces;
FGColumnVector3 vRadius; FGColumnVector3 vRadius;
FGColumnVector3 vGravity; FGColumnVector3 vGravity;
FGColumnVector3 vCoriolis;
FGColumnVector3 vCentrifugal;
double gAccel; double gAccel;
double gAccelReference; double gAccelReference;
double RadiusReference; double RadiusReference;

View file

@ -110,7 +110,6 @@ FGInitialCondition::~FGInitialCondition()
void FGInitialCondition::SetVcalibratedKtsIC(double tt) { void FGInitialCondition::SetVcalibratedKtsIC(double tt) {
if(getMachFromVcas(&mach,tt*ktstofps)) { if(getMachFromVcas(&mach,tt*ktstofps)) {
//cout << "Mach: " << mach << endl; //cout << "Mach: " << mach << endl;
lastSpeedSet=setvc; lastSpeedSet=setvc;
vc=tt*ktstofps; vc=tt*ktstofps;

View file

@ -104,7 +104,7 @@ FGLGear::FGLGear(FGConfigFile* AC_cfg, FGFDMExec* fdmex) : Exec(fdmex)
FCS = Exec->GetFCS(); FCS = Exec->GetFCS();
MassBalance = Exec->GetMassBalance(); MassBalance = Exec->GetMassBalance();
WOW = lastWOW = false; WOW = lastWOW = true; // should the value be initialized to true?
ReportEnable = true; ReportEnable = true;
FirstContact = false; FirstContact = false;
Reported = false; Reported = false;
@ -115,7 +115,7 @@ FGLGear::FGLGear(FGConfigFile* AC_cfg, FGFDMExec* fdmex) : Exec(fdmex)
vWhlBodyVec = (vXYZ - MassBalance->GetXYZcg()) / 12.0; vWhlBodyVec = (vXYZ - MassBalance->GetXYZcg()) / 12.0;
vWhlBodyVec(eX) = -vWhlBodyVec(eX); vWhlBodyVec(eX) = -vWhlBodyVec(eX);
vWhlBodyVec(eZ) = -vWhlBodyVec(eZ); vWhlBodyVec(eZ) = -vWhlBodyVec(eZ);
vLocalGear = State->GetTb2l() * vWhlBodyVec; vLocalGear = State->GetTb2l() * vWhlBodyVec;
compressLength = 0.0; compressLength = 0.0;
@ -123,6 +123,13 @@ FGLGear::FGLGear(FGConfigFile* AC_cfg, FGFDMExec* fdmex) : Exec(fdmex)
brakePct = 0.0; brakePct = 0.0;
maxCompLen = 0.0; maxCompLen = 0.0;
WheelSlip = lastWheelSlip = 0.0;
compressLength = 0.0;
compressSpeed = 0.0;
brakePct = 0.0;
maxCompLen = 0.0;
Debug(0); Debug(0);
} }
@ -173,6 +180,8 @@ FGLGear::FGLGear(const FGLGear& lgear)
isRetractable = lgear.isRetractable; isRetractable = lgear.isRetractable;
GearUp = lgear.GearUp; GearUp = lgear.GearUp;
GearDown = lgear.GearDown; GearDown = lgear.GearDown;
WheelSlip = lgear.WheelSlip;
lastWheelSlip = lgear.lastWheelSlip;
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -266,17 +275,17 @@ FGColumnVector3& FGLGear::Force(void)
switch (eBrakeGrp) { switch (eBrakeGrp) {
case bgLeft: case bgLeft:
SteerGain = -0.10; SteerGain = 0.10;
BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgLeft)) + BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgLeft)) +
staticFCoeff*FCS->GetBrake(bgLeft); staticFCoeff*FCS->GetBrake(bgLeft);
break; break;
case bgRight: case bgRight:
SteerGain = -0.10; SteerGain = 0.10;
BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgRight)) + BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgRight)) +
staticFCoeff*FCS->GetBrake(bgRight); staticFCoeff*FCS->GetBrake(bgRight);
break; break;
case bgCenter: case bgCenter:
SteerGain = -0.10; SteerGain = 0.10;
BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgCenter)) + BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgCenter)) +
staticFCoeff*FCS->GetBrake(bgCenter); staticFCoeff*FCS->GetBrake(bgCenter);
break; break;
@ -289,7 +298,7 @@ FGColumnVector3& FGLGear::Force(void)
BrakeFCoeff = rollingFCoeff; BrakeFCoeff = rollingFCoeff;
break; break;
case bgNone: case bgNone:
SteerGain = -0.10; SteerGain = 0.0;
BrakeFCoeff = rollingFCoeff; BrakeFCoeff = rollingFCoeff;
break; break;
default: default:
@ -326,17 +335,31 @@ FGColumnVector3& FGLGear::Force(void)
if (RollingWhlVel == 0.0 && SideWhlVel == 0.0) { if (RollingWhlVel == 0.0 && SideWhlVel == 0.0) {
WheelSlip = 0.0; WheelSlip = 0.0;
} else if (fabs(RollingWhlVel) < 0.10) {
WheelSlip = 0.05*radtodeg*atan2(SideWhlVel, RollingWhlVel) + 0.95*WheelSlip;
} else { } else {
WheelSlip = radtodeg*atan2(SideWhlVel, RollingWhlVel); WheelSlip = radtodeg*atan2(SideWhlVel, RollingWhlVel);
} }
if ((WheelSlip < 0.0 && lastWheelSlip > 0.0) ||
(WheelSlip > 0.0 && lastWheelSlip < 0.0))
{
WheelSlip = 0.0;
}
lastWheelSlip = WheelSlip;
// Compute the sideforce coefficients using similar assumptions to LaRCSim for now. // Compute the sideforce coefficients using similar assumptions to LaRCSim for now.
// Allow a maximum of 10 degrees tire slip angle before wheel slides. At that point, // Allow a maximum of 10 degrees tire slip angle before wheel slides. At that point,
// transition from static to dynamic friction. There are more complicated formulations // transition from static to dynamic friction. There are more complicated formulations
// of this that avoid the discrete jump. Will fix this later. // of this that avoid the discrete jump. Will fix this later.
if (fabs(WheelSlip) <= 10.0) { if (fabs(WheelSlip) <= 20.0) {
FCoeff = staticFCoeff*WheelSlip/10.0; FCoeff = staticFCoeff*WheelSlip/20.0;
} else if (fabs(WheelSlip) <= 40.0) {
// FCoeff = dynamicFCoeff*fabs(WheelSlip)/WheelSlip;
FCoeff = (dynamicFCoeff*(fabs(WheelSlip) - 20.0)/20.0 +
staticFCoeff*(40.0 - fabs(WheelSlip))/20.0)*fabs(WheelSlip)/WheelSlip;
} else { } else {
FCoeff = dynamicFCoeff*fabs(WheelSlip)/WheelSlip; FCoeff = dynamicFCoeff*fabs(WheelSlip)/WheelSlip;
} }
@ -406,7 +429,7 @@ FGColumnVector3& FGLGear::Force(void)
} }
if (lastWOW != WOW) { if (lastWOW != WOW) {
PutMessage("GEAR_CONTACT", WOW); PutMessage("GEAR_CONTACT: " + name, WOW);
} }
lastWOW = WOW; lastWOW = WOW;

View file

@ -244,6 +244,7 @@ public:
inline double GetBodyXForce(void) { return vLocalForce(eX); } inline double GetBodyXForce(void) { return vLocalForce(eX); }
inline double GetBodyYForce(void) { return vLocalForce(eY); } inline double GetBodyYForce(void) { return vLocalForce(eY); }
inline double GetWheelSlipAngle(void) { return WheelSlip; } inline double GetWheelSlipAngle(void) { return WheelSlip; }
double GetWheelVel(int axis) { return vWhlVelVec(axis);}
private: private:
FGColumnVector3 vXYZ; FGColumnVector3 vXYZ;
@ -270,6 +271,7 @@ private:
double SideWhlVel, RollingWhlVel; double SideWhlVel, RollingWhlVel;
double RollingForce, SideForce, FCoeff; double RollingForce, SideForce, FCoeff;
double WheelSlip; double WheelSlip;
double lastWheelSlip;
bool WOW; bool WOW;
bool lastWOW; bool lastWOW;
bool FirstContact; bool FirstContact;

View file

@ -98,8 +98,9 @@ bool FGOutput::Run(void)
} else { } else {
// Not a valid type of output // Not a valid type of output
} }
return false;
} else { } else {
return true;
} }
} }
return false; return false;
@ -172,7 +173,10 @@ void FGOutput::DelimitedOutput(string fname)
outstream << ", "; outstream << ", ";
outstream << "Drag, Side, Lift, "; outstream << "Drag, Side, Lift, ";
outstream << "L/D, "; outstream << "L/D, ";
outstream << "Xforce, Yforce, Zforce"; outstream << "Xforce, Yforce, Zforce, ";
outstream << "xGravity, yGravity, zGravity, ";
outstream << "xCoriolis, yCoriolis, zCoriolis, ";
outstream << "xCentrifugal, yCentrifugal, zCentrifugal";
} }
if (SubSystems & ssMoments) { if (SubSystems & ssMoments) {
outstream << ", "; outstream << ", ";
@ -252,7 +256,10 @@ void FGOutput::DelimitedOutput(string fname)
outstream << ", "; outstream << ", ";
outstream << Aerodynamics->GetvFs() << ", "; outstream << Aerodynamics->GetvFs() << ", ";
outstream << Aerodynamics->GetLoD() << ", "; outstream << Aerodynamics->GetLoD() << ", ";
outstream << Aircraft->GetForces(); outstream << Aircraft->GetForces() << ", ";
outstream << Inertial->GetGravity() << ", ";
outstream << Inertial->GetCoriolis() << ", ";
outstream << Inertial->GetCentrifugal();
} }
if (SubSystems & ssMoments) { if (SubSystems & ssMoments) {
outstream << ", "; outstream << ", ";

View file

@ -101,7 +101,13 @@ FGPosition::FGPosition(FGFDMExec* fdmex) : FGModel(fdmex)
{ {
Name = "FGPosition"; Name = "FGPosition";
LongitudeDot = LatitudeDot = RadiusDot = 0.0; LongitudeDot = LatitudeDot = RadiusDot = 0.0;
lastLongitudeDot = lastLatitudeDot = lastRadiusDot = 0.0;
for (int i=0;i<3;i++) {
LatitudeDot_prev[i] = 0.0;
LongitudeDot_prev[i] = 0.0;
RadiusDot_prev[i] = 0.0;
}
Longitude = Latitude = 0.0; Longitude = Latitude = 0.0;
gamma = Vt = Vground = 0.0; gamma = Vt = Vground = 0.0;
hoverbmac = hoverbcg = 0.0; hoverbmac = hoverbcg = 0.0;
@ -143,7 +149,8 @@ Notes: [TP] Make sure that -Vt <= hdot <= Vt, which, of course, should always
In FGFS, SeaLevelRadius is stuffed from FGJSBSim in JSBSim.cxx each pass. In FGFS, SeaLevelRadius is stuffed from FGJSBSim in JSBSim.cxx each pass.
*/ */
bool FGPosition::Run(void) { bool FGPosition::Run(void)
{
double cosLat; double cosLat;
double hdot_Vt; double hdot_Vt;
FGColumnVector3 vMac; FGColumnVector3 vMac;
@ -160,22 +167,20 @@ bool FGPosition::Run(void) {
cosLat = cos(Latitude); cosLat = cos(Latitude);
if (cosLat != 0) LongitudeDot = vVel(eEast) / (Radius * cosLat); if (cosLat != 0) LongitudeDot = vVel(eEast) / (Radius * cosLat);
LatitudeDot = vVel(eNorth) / Radius; LatitudeDot = vVel(eNorth) / Radius;
RadiusDot = -vVel(eDown); RadiusDot = -vVel(eDown);
Longitude += 0.5*dt*rate*(LongitudeDot + lastLongitudeDot); Longitude += State->Integrate(FGState::TRAPZ, dt*rate, LongitudeDot, LongitudeDot_prev);
Latitude += 0.5*dt*rate*(LatitudeDot + lastLatitudeDot); Latitude += State->Integrate(FGState::TRAPZ, dt*rate, LatitudeDot, LatitudeDot_prev);
Radius += 0.5*dt*rate*(RadiusDot + lastRadiusDot); Radius += State->Integrate(FGState::TRAPZ, dt*rate, RadiusDot, RadiusDot_prev);
h = Radius - SeaLevelRadius; // Geocentric h = Radius - SeaLevelRadius; // Geocentric
DistanceAGL = Radius - RunwayRadius; // Geocentric DistanceAGL = Radius - RunwayRadius; // Geocentric
hoverbcg = DistanceAGL/b; hoverbcg = DistanceAGL/b;
vMac=State->GetTb2l()*Aircraft->GetXYZrp(); vMac = State->GetTb2l()*Aircraft->GetXYZrp();
vMac *= inchtoft; vMac *= inchtoft;
hoverbmac = (DistanceAGL + vMac(3))/b; hoverbmac = (DistanceAGL + vMac(3))/b;
@ -187,10 +192,6 @@ bool FGPosition::Run(void) {
gamma = 0.0; gamma = 0.0;
} }
lastLatitudeDot = LatitudeDot;
lastLongitudeDot = LongitudeDot;
lastRadiusDot = RadiusDot;
return false; return false;
} else { } else {
@ -200,7 +201,8 @@ bool FGPosition::Run(void) {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPosition::GetState(void) { void FGPosition::GetState(void)
{
dt = State->Getdt(); dt = State->Getdt();
Vt = Translation->GetVt(); Vt = Translation->GetVt();
@ -212,7 +214,8 @@ void FGPosition::GetState(void) {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPosition::Seth(double tt) { void FGPosition::Seth(double tt)
{
h = tt; h = tt;
Radius = h + SeaLevelRadius; Radius = h + SeaLevelRadius;
DistanceAGL = Radius - RunwayRadius; // Geocentric DistanceAGL = Radius - RunwayRadius; // Geocentric
@ -221,7 +224,8 @@ void FGPosition::Seth(double tt) {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPosition::SetDistanceAGL(double tt) { void FGPosition::SetDistanceAGL(double tt)
{
DistanceAGL=tt; DistanceAGL=tt;
Radius = RunwayRadius + DistanceAGL; Radius = RunwayRadius + DistanceAGL;
h = Radius - SeaLevelRadius; h = Radius - SeaLevelRadius;

View file

@ -79,6 +79,7 @@ public:
/** Constructor /** Constructor
@param Executive a pointer to the parent executive object */ @param Executive a pointer to the parent executive object */
FGPosition(FGFDMExec*); FGPosition(FGFDMExec*);
/// Destructor /// Destructor
~FGPosition(); ~FGPosition();
@ -132,7 +133,7 @@ private:
double Radius, h; double Radius, h;
double LatitudeDot, LongitudeDot, RadiusDot; double LatitudeDot, LongitudeDot, RadiusDot;
double lastLatitudeDot, lastLongitudeDot, lastRadiusDot; double LatitudeDot_prev[3], LongitudeDot_prev[3], RadiusDot_prev[3];
double Longitude, Latitude; double Longitude, Latitude;
double dt; double dt;
double RunwayRadius; double RunwayRadius;

File diff suppressed because it is too large Load diff

View file

@ -1,219 +1,224 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGPropulsion.h Header: FGPropulsion.h
Author: Jon S. Berndt Author: Jon S. Berndt
Date started: 08/20/00 Date started: 08/20/00
------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) ------------- ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under 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 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 Foundation; either version 2 of the License, or (at your option) any later
version. version.
This program is distributed in the hope that it will be useful, but WITHOUT 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 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details. details.
You should have received a copy of the GNU General Public License along with 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 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA. Place - Suite 330, Boston, MA 02111-1307, USA.
Further information about the GNU General Public License can also be found on Further information about the GNU General Public License can also be found on
the world wide web at http://www.gnu.org. the world wide web at http://www.gnu.org.
HISTORY HISTORY
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
08/20/00 JSB Created 08/20/00 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGPROPULSION_H #ifndef FGPROPULSION_H
#define FGPROPULSION_H #define FGPROPULSION_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef FGFS #ifdef FGFS
# include <simgear/compiler.h> # include <simgear/compiler.h>
# ifdef SG_HAVE_STD_INCLUDES # ifdef SG_HAVE_STD_INCLUDES
# include <vector> # include <vector>
# include <iterator> # include <iterator>
# else # else
# include <vector.h> # include <vector.h>
# include <iterator.h> # include <iterator.h>
# endif # endif
#else #else
# include <vector> # include <vector>
# include <iterator> # include <iterator>
#endif #endif
#include "FGModel.h" #include "FGModel.h"
#include "FGRocket.h" #include "FGRocket.h"
#include "FGPiston.h" #include "FGPiston.h"
#include "FGTurboShaft.h" #include "FGTurboShaft.h"
#include "FGTurboJet.h" #include "FGTurboJet.h"
#include "FGTurboProp.h" #include "FGTurboProp.h"
#include "FGTank.h" #include "FGTank.h"
#include "FGPropeller.h" #include "FGPropeller.h"
#include "FGNozzle.h" #include "FGNozzle.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_PROPULSION "$Id$" #define ID_PROPULSION "$Id$"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs] COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Propulsion management class. /** Propulsion management class.
FGPropulsion manages all aspects of propulsive force generation, including FGPropulsion manages all aspects of propulsive force generation, including
containment of engines, tanks, and thruster class instances in STL vectors, containment of engines, tanks, and thruster class instances in STL vectors,
and the interaction and communication between them. and the interaction and communication between them.
@author Jon S. Berndt @author Jon S. Berndt
@version $Id$ @version $Id$
@see FGEngine @see FGEngine
@see FGTank @see FGTank
@see FGThruster @see FGThruster
@see <a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/jsbsim/JSBSim/FGPropulsion.h?rev=HEAD&content-type=text/vnd.viewcvs-markup"> @see <a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/jsbsim/JSBSim/FGPropulsion.h?rev=HEAD&content-type=text/vnd.viewcvs-markup">
Header File </a> Header File </a>
@see <a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/jsbsim/JSBSim/FGPropulsion.cpp?rev=HEAD&content-type=text/vnd.viewcvs-markup"> @see <a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/jsbsim/JSBSim/FGPropulsion.cpp?rev=HEAD&content-type=text/vnd.viewcvs-markup">
Source File </a> Source File </a>
*/ */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGPropulsion : public FGModel class FGPropulsion : public FGModel
{ {
public: public:
/// Constructor /// Constructor
FGPropulsion(FGFDMExec*); FGPropulsion(FGFDMExec*);
/// Destructor /// Destructor
~FGPropulsion(); ~FGPropulsion();
/** Executes the propulsion model. /** Executes the propulsion model.
The initial plan for the FGPropulsion class calls for Run() to be executed, The initial plan for the FGPropulsion class calls for Run() to be executed,
performing the following tasks: performing the following tasks:
<ol> <ol>
<li>Determine the drag - or power required - for the attached thrust effector <li>Determine the drag - or power required - for the attached thrust effector
for this engine so that any feedback to the engine can be performed. This for this engine so that any feedback to the engine can be performed. This
is done by calling FGThruster::CalculatePReq()</li> is done by calling FGThruster::CalculatePReq()</li>
<li>Given 1, above, calculate the power available from the engine. This is <li>Given 1, above, calculate the power available from the engine. This is
done by calling FGEngine::CalculatePAvail()</li> done by calling FGEngine::CalculatePAvail()</li>
<li>Next, calculate the thrust output from the thruster model given the power <li>Next, calculate the thrust output from the thruster model given the power
available and the power required. This may also result in new performance available and the power required. This may also result in new performance
numbers for the thruster in the case of the propeller, at least. This numbers for the thruster in the case of the propeller, at least. This
result is returned from a call to Calculate().</li></ol> result is returned from a call to Calculate().</li></ol>
[Note: Should we be checking the Starved flag here?] */ [Note: Should we be checking the Starved flag here?] */
bool Run(void); bool Run(void);
/** Loads the propulsion system (engine[s], tank[s], thruster[s]). /** Loads the propulsion system (engine[s], tank[s], thruster[s]).
Characteristics of the propulsion system are read in from the config file. Characteristics of the propulsion system are read in from the config file.
@param AC_cfg pointer to the config file instance that describes the @param AC_cfg pointer to the config file instance that describes the
aircraft being modeled. aircraft being modeled.
@return true if successfully loaded, otherwise false */ @return true if successfully loaded, otherwise false */
bool Load(FGConfigFile* AC_cfg); bool Load(FGConfigFile* AC_cfg);
/// Retrieves the number of engines defined for the aircraft. /// Retrieves the number of engines defined for the aircraft.
inline unsigned int GetNumEngines(void) const {return Engines.size();} inline unsigned int GetNumEngines(void) const {return Engines.size();}
/** Retrieves an engine object pointer from the list of engines. /** Retrieves an engine object pointer from the list of engines.
@param index the engine index within the vector container @param index the engine index within the vector container
@return the address of the specific engine, or zero if no such engine is @return the address of the specific engine, or zero if no such engine is
available */ available */
inline FGEngine* GetEngine(unsigned int index) { inline FGEngine* GetEngine(unsigned int index) {
if (index <= Engines.size()-1) return Engines[index]; if (index <= Engines.size()-1) return Engines[index];
else return 0L; } else return 0L; }
// Retrieves the number of tanks defined for the aircraft. // Retrieves the number of tanks defined for the aircraft.
inline unsigned int GetNumTanks(void) const {return Tanks.size();} inline unsigned int GetNumTanks(void) const {return Tanks.size();}
/** Retrieves a tank object pointer from the list of tanks. /** Retrieves a tank object pointer from the list of tanks.
@param index the tank index within the vector container @param index the tank index within the vector container
@return the address of the specific tank, or zero if no such tank is @return the address of the specific tank, or zero if no such tank is
available */ available */
inline FGTank* GetTank(unsigned int index) { inline FGTank* GetTank(unsigned int index) {
if (index <= Tanks.size()-1) return Tanks[index]; if (index <= Tanks.size()-1) return Tanks[index];
else return 0L; } else return 0L; }
/** Retrieves a thruster object pointer from the list of thrusters. /** Retrieves a thruster object pointer from the list of thrusters.
@param index the thruster index within the vector container @param index the thruster index within the vector container
@return the address of the specific thruster, or zero if no such thruster is @return the address of the specific thruster, or zero if no such thruster is
available */ available */
inline FGThruster* GetThruster(unsigned int index) { inline FGThruster* GetThruster(unsigned int index) {
if (index <= Thrusters.size()-1) return Thrusters[index]; if (index <= Thrusters.size()-1) return Thrusters[index];
else return 0L; } else return 0L; }
/** Returns the number of fuel tanks currently actively supplying fuel */ /** Returns the number of fuel tanks currently actively supplying fuel */
inline int GetnumSelectedFuelTanks(void) const {return numSelectedFuelTanks;} inline int GetnumSelectedFuelTanks(void) const {return numSelectedFuelTanks;}
/** Returns the number of oxidizer tanks currently actively supplying oxidizer */ /** Returns the number of oxidizer tanks currently actively supplying oxidizer */
inline int GetnumSelectedOxiTanks(void) const {return numSelectedOxiTanks;} inline int GetnumSelectedOxiTanks(void) const {return numSelectedOxiTanks;}
/** Loops the engines/thrusters until thrust output steady (used for trimming) */ /** Loops the engines/thrusters until thrust output steady (used for trimming) */
bool GetSteadyState(void); bool GetSteadyState(void);
/** starts the engines in IC mode (dt=0). All engine-specific setup must /** starts the engines in IC mode (dt=0). All engine-specific setup must
be done before calling this (i.e. magnetos, starter engage, etc.) */ be done before calling this (i.e. magnetos, starter engage, etc.) */
bool ICEngineStart(void); bool ICEngineStart(void);
string GetPropulsionStrings(void); string GetPropulsionStrings(void);
string GetPropulsionValues(void); string GetPropulsionValues(void);
inline FGColumnVector3& GetForces(void) {return vForces; } inline FGColumnVector3& GetForces(void) {return vForces; }
inline double GetForces(int n) const { return vForces(n);} inline double GetForces(int n) const { return vForces(n);}
inline FGColumnVector3& GetMoments(void) {return vMoments;} inline FGColumnVector3& GetMoments(void) {return vMoments;}
inline double GetMoments(int n) const {return vMoments(n);} inline double GetMoments(int n) const {return vMoments(n);}
FGColumnVector3& GetTanksMoment(void); FGColumnVector3& GetTanksMoment(void);
double GetTanksWeight(void); double GetTanksWeight(void);
double GetTanksIxx(const FGColumnVector3& vXYZcg); double GetTanksIxx(const FGColumnVector3& vXYZcg);
double GetTanksIyy(const FGColumnVector3& vXYZcg); double GetTanksIyy(const FGColumnVector3& vXYZcg);
double GetTanksIzz(const FGColumnVector3& vXYZcg); double GetTanksIzz(const FGColumnVector3& vXYZcg);
double GetTanksIxz(const FGColumnVector3& vXYZcg); double GetTanksIxz(const FGColumnVector3& vXYZcg);
double GetTanksIxy(const FGColumnVector3& vXYZcg); double GetTanksIxy(const FGColumnVector3& vXYZcg);
void bind(); void SetMagnetos(int setting);
void unbind(); void SetStarter(int setting);
void SetActiveEngine(int engine);
private:
vector <FGEngine*> Engines; void bind();
vector <FGTank*> Tanks; void unbind();
vector <FGTank*>::iterator iTank;
vector <FGThruster*> Thrusters; private:
unsigned int numSelectedFuelTanks; vector <FGEngine*> Engines;
unsigned int numSelectedOxiTanks; vector <FGTank*> Tanks;
unsigned int numFuelTanks; vector <FGTank*>::iterator iTank;
unsigned int numOxiTanks; vector <FGThruster*> Thrusters;
unsigned int numEngines; unsigned int numSelectedFuelTanks;
unsigned int numTanks; unsigned int numSelectedOxiTanks;
unsigned int numThrusters; unsigned int numFuelTanks;
double dt; unsigned int numOxiTanks;
FGColumnVector3 vForces; unsigned int numEngines;
FGColumnVector3 vMoments; unsigned int numTanks;
FGColumnVector3 vXYZtank; unsigned int numThrusters;
void Debug(int from); int ActiveEngine;
}; double dt;
FGColumnVector3 vForces;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% FGColumnVector3 vMoments;
#endif FGColumnVector3 vXYZtank;
void Debug(int from);
};
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif

View file

@ -80,9 +80,14 @@ CLASS IMPLEMENTATION
FGRotation::FGRotation(FGFDMExec* fdmex) : FGModel(fdmex) FGRotation::FGRotation(FGFDMExec* fdmex) : FGModel(fdmex)
{ {
Name = "FGRotation"; Name = "FGRotation";
cTht=cPhi=cPsi=1.0; cTht = cPhi = cPsi = 1.0;
sTht=sPhi=sPsi=0.0; sTht = sPhi = sPsi = 0.0;
vPQRdot.InitMatrix();
vPQRdot_prev[0].InitMatrix();
vPQRdot_prev[1].InitMatrix();
vPQRdot_prev[2].InitMatrix();
bind(); bind();
Debug(0); Debug(0);
@ -110,10 +115,12 @@ bool FGRotation::Run(void)
N1 = vMoments(eN) - (Iyy-Ixx)*vPQR(eP)*vPQR(eQ) - Ixz*vPQR(eR)*vPQR(eQ); N1 = vMoments(eN) - (Iyy-Ixx)*vPQR(eP)*vPQR(eQ) - Ixz*vPQR(eR)*vPQR(eQ);
vPQRdot(eP) = (L2*Izz - N1*Ixz) / (Ixx*Izz - Ixz*Ixz); vPQRdot(eP) = (L2*Izz - N1*Ixz) / (Ixx*Izz - Ixz*Ixz);
vPQRdot(eQ) = (vMoments(eM) - (Ixx-Izz)*vPQR(eP)*vPQR(eR) - Ixz*(vPQR(eP)*vPQR(eP) - vPQR(eR)*vPQR(eR)))/Iyy; vPQRdot(eQ) = (vMoments(eM) - (Ixx-Izz)*vPQR(eP)*vPQR(eR)
- Ixz*(vPQR(eP)*vPQR(eP) - vPQR(eR)*vPQR(eR)))/Iyy;
vPQRdot(eR) = (N1*Ixx + L2*Ixz) / (Ixx*Izz - Ixz*Ixz); vPQRdot(eR) = (N1*Ixx + L2*Ixz) / (Ixx*Izz - Ixz*Ixz);
vPQR += dt*rate*(vlastPQRdot + vPQRdot)/2.0; vPQR += State->Integrate(FGState::TRAPZ, dt*rate, vPQRdot, vPQRdot_prev);
vAeroPQR = vPQR + Atmosphere->GetTurbPQR(); vAeroPQR = vPQR + Atmosphere->GetTurbPQR();
State->IntegrateQuat(vPQR, rate); State->IntegrateQuat(vPQR, rate);
@ -131,8 +138,6 @@ bool FGRotation::Run(void)
vEulerRates(ePsi) = (vPQR(2)*sPhi + vPQR(3)*cPhi)/cTht; vEulerRates(ePsi) = (vPQR(2)*sPhi + vPQR(3)*cPhi)/cTht;
} }
vlastPQRdot = vPQRdot;
if (debug_lvl > 1) Debug(2); if (debug_lvl > 1) Debug(2);
return false; return false;

View file

@ -121,15 +121,14 @@ public:
void bind(void); void bind(void);
void unbind(void); void unbind(void);
private: private:
FGColumnVector3 vPQR; FGColumnVector3 vPQR;
FGColumnVector3 vAeroPQR; FGColumnVector3 vAeroPQR;
FGColumnVector3 vPQRdot; FGColumnVector3 vPQRdot;
FGColumnVector3 vPQRdot_prev[3];
FGColumnVector3 vMoments; FGColumnVector3 vMoments;
FGColumnVector3 vEuler; FGColumnVector3 vEuler;
FGColumnVector3 vEulerRates; FGColumnVector3 vEulerRates;
FGColumnVector3 vlastPQRdot;
double cTht,sTht; double cTht,sTht;
double cPhi,sPhi; double cPhi,sPhi;

View file

@ -64,13 +64,6 @@ MACROS
CLASS IMPLEMENTATION CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//
// For every term registered here there must be a corresponding handler in
// GetParameter() below that retrieves that parameter. Also, there must be an
// 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) FGState::FGState(FGFDMExec* fdex)
{ {
FDMExec = fdex; FDMExec = fdex;
@ -78,7 +71,6 @@ FGState::FGState(FGFDMExec* fdex)
a = 1000.0; a = 1000.0;
sim_time = 0.0; sim_time = 0.0;
dt = 1.0/120.0; dt = 1.0/120.0;
ActiveEngine = -1;
Aircraft = FDMExec->GetAircraft(); Aircraft = FDMExec->GetAircraft();
Translation = FDMExec->GetTranslation(); Translation = FDMExec->GetTranslation();
@ -92,6 +84,8 @@ FGState::FGState(FGFDMExec* fdex)
Propulsion = FDMExec->GetPropulsion(); Propulsion = FDMExec->GetPropulsion();
PropertyManager = FDMExec->GetPropertyManager(); PropertyManager = FDMExec->GetPropertyManager();
for(int i=0;i<3;i++) vQdot_prev[i].InitMatrix();
InitPropertyMaps(); InitPropertyMaps();
bind(); bind();
@ -159,7 +153,6 @@ bool FGState::Reset(string path, string acname, string fname)
resetfile >> token; resetfile >> token;
} }
Position->SetLatitude(latitude*degtorad); Position->SetLatitude(latitude*degtorad);
Position->SetLongitude(longitude*degtorad); Position->SetLongitude(longitude*degtorad);
Position->Seth(h); Position->Seth(h);
@ -336,11 +329,10 @@ void FGState::IntegrateQuat(FGColumnVector3 vPQR, int rate)
vQdot(2) = 0.5*(vQtrn(1)*vPQR(eP) + vQtrn(3)*vPQR(eR) - vQtrn(4)*vPQR(eQ)); vQdot(2) = 0.5*(vQtrn(1)*vPQR(eP) + vQtrn(3)*vPQR(eR) - vQtrn(4)*vPQR(eQ));
vQdot(3) = 0.5*(vQtrn(1)*vPQR(eQ) + vQtrn(4)*vPQR(eP) - vQtrn(2)*vPQR(eR)); vQdot(3) = 0.5*(vQtrn(1)*vPQR(eQ) + vQtrn(4)*vPQR(eP) - vQtrn(2)*vPQR(eR));
vQdot(4) = 0.5*(vQtrn(1)*vPQR(eR) + vQtrn(2)*vPQR(eQ) - vQtrn(3)*vPQR(eP)); vQdot(4) = 0.5*(vQtrn(1)*vPQR(eR) + vQtrn(2)*vPQR(eQ) - vQtrn(3)*vPQR(eP));
vQtrn += 0.5*dt*rate*(vlastQdot + vQdot);
vQtrn += Integrate(TRAPZ, dt*rate, vQdot, vQdot_prev);
vQtrn.Normalize(); vQtrn.Normalize();
vlastQdot = vQdot;
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -553,17 +545,17 @@ void FGState::InitPropertyMaps(void)
ParamNameToProp[ "FG_THROTTLE_POS" ]="fcs/throttle-pos-norm"; ParamNameToProp[ "FG_THROTTLE_POS" ]="fcs/throttle-pos-norm";
ParamNameToProp[ "FG_MIXTURE_CMD" ]="fcs/mixture-cmd-norm"; ParamNameToProp[ "FG_MIXTURE_CMD" ]="fcs/mixture-cmd-norm";
ParamNameToProp[ "FG_MIXTURE_POS" ]="fcs/mixture-pos-norm"; ParamNameToProp[ "FG_MIXTURE_POS" ]="fcs/mixture-pos-norm";
ParamNameToProp[ "FG_MAGNETO_CMD" ]="zero"; ParamNameToProp[ "FG_MAGNETO_CMD" ]="propulsion/magneto_cmd";
ParamNameToProp[ "FG_STARTER_CMD" ]="zero"; ParamNameToProp[ "FG_STARTER_CMD" ]="propulsion/starter_cmd";
ParamNameToProp[ "FG_ACTIVE_ENGINE" ]="zero"; ParamNameToProp[ "FG_ACTIVE_ENGINE" ]="propulsion/active_engine";
ParamNameToProp[ "FG_HOVERB" ]="aero/h_b-mac-ft"; ParamNameToProp[ "FG_HOVERB" ]="aero/h_b-mac-ft";
ParamNameToProp[ "FG_PITCH_TRIM_CMD" ]="fcs/pitch-trim-cmd-norm"; ParamNameToProp[ "FG_PITCH_TRIM_CMD" ]="fcs/pitch-trim-cmd-norm";
ParamNameToProp[ "FG_YAW_TRIM_CMD" ]="fcs/yaw-trim-cmd-norm"; ParamNameToProp[ "FG_YAW_TRIM_CMD" ]="fcs/yaw-trim-cmd-norm";
ParamNameToProp[ "FG_ROLL_TRIM_CMD" ]="fcs/roll-trim-cmd-norm"; ParamNameToProp[ "FG_ROLL_TRIM_CMD" ]="fcs/roll-trim-cmd-norm";
ParamNameToProp[ "FG_LEFT_BRAKE_CMD" ]="zero"; ParamNameToProp[ "FG_LEFT_BRAKE_CMD" ]="fcs/left_brake";
ParamNameToProp[ "FG_CENTER_BRAKE_CMD" ]="zero"; ParamNameToProp[ "FG_CENTER_BRAKE_CMD" ]="fcs/center_brake";
ParamNameToProp[ "FG_RIGHT_BRAKE_CMD" ]="zero"; ParamNameToProp[ "FG_RIGHT_BRAKE_CMD" ]="fcs/right_brake";
ParamNameToProp[ "FG_SET_LOGGING" ]="zero"; ParamNameToProp[ "FG_SET_LOGGING" ]="sim/set_logging";
ParamNameToProp[ "FG_ALPHAH" ]="aero/alpha-rad"; ParamNameToProp[ "FG_ALPHAH" ]="aero/alpha-rad";
ParamNameToProp[ "FG_ALPHAW" ]="aero/alpha-wing-rad"; ParamNameToProp[ "FG_ALPHAW" ]="aero/alpha-wing-rad";
ParamNameToProp[ "FG_LBARH" ]="metrics/lh-norm"; ParamNameToProp[ "FG_LBARH" ]="metrics/lh-norm";

View file

@ -229,6 +229,77 @@ public:
@param rate the integration rate in seconds. @param rate the integration rate in seconds.
*/ */
void IntegrateQuat(FGColumnVector3 vPQR, int rate); void IntegrateQuat(FGColumnVector3 vPQR, int rate);
// ======================================= General Purpose INTEGRATOR
enum iType {AB4, AB3, AB2, AM3, EULER, TRAPZ};
/** Multi-method integrator.
@param type Type of intergation scheme to use. Can be one of:
<ul>
<li>AB4 - Adams-Bashforth, fourth order</li>
<li>AB3 - Adams-Bashforth, third order</li>
<li>AB2 - Adams-Bashforth, second order</li>
<li>AM3 - Adams Moulton, third order</li>
<li>EULER - Euler</li>
<li>TRAPZ - Trapezoidal</li>
</ul>
@param delta_t the integration time step in seconds
@param vTDeriv a reference to the current value of the time derivative of
the quantity being integrated (i.e. if vUVW is being integrated
vTDeriv is the current value of vUVWdot)
@param vLastArray an array of previously calculated and saved values of
the quantity being integrated (i.e. if vUVW is being integrated
vLastArray[0] is the past value of vUVWdot, vLastArray[1] is the value of
vUVWdot prior to that, etc.)
@return the current, incremental value of the item integrated to add to the
previous value. */
template <class T> T Integrate(iType type, double delta_t, T& vTDeriv, T *vLastArray)
{
T vResult;
switch (type) {
case AB4:
vResult = (delta_t/24.0)*( 55.0 * vTDeriv
- 59.0 * vLastArray[0]
+ 37.0 * vLastArray[1]
- 9.0 * vLastArray[2] );
vLastArray[2] = vLastArray[1];
vLastArray[1] = vLastArray[0];
vLastArray[0] = vTDeriv;
break;
case AB3:
vResult = (delta_t/12.0)*( 23.0 * vTDeriv
- 16.0 * vLastArray[0]
+ 5.0 * vLastArray[1] );
vLastArray[1] = vLastArray[0];
vLastArray[0] = vTDeriv;
break;
case AB2:
vResult = (delta_t/2.0)*( 3.0 * vTDeriv - vLastArray[0] );
vLastArray[0] = vTDeriv;
break;
case AM3:
vResult = (delta_t/12.0)*( 5.0 * vTDeriv
+ 8.0 * vLastArray[0]
- 1.0 * vLastArray[1] );
vLastArray[1] = vLastArray[0];
vLastArray[0] = vTDeriv;
break;
case EULER:
vResult = delta_t * vTDeriv;
break;
case TRAPZ:
vResult = (delta_t*0.5) * (vTDeriv + vLastArray[0]);
vLastArray[0] = vTDeriv;
break;
}
return vResult;
}
// =======================================
/** Calculates Euler angles from the local-to-body matrix. /** Calculates Euler angles from the local-to-body matrix.
@return a reference to the vEuler column vector. @return a reference to the vEuler column vector.
@ -275,8 +346,6 @@ public:
void ReportState(void); void ReportState(void);
inline string GetPropertyName(string prm) { return ParamNameToProp[prm]; } inline string GetPropertyName(string prm) { return ParamNameToProp[prm]; }
//inline string GetPropertyName(eParam prm) { return ParamIdxToProp[prm]; }
//inline eParam GetParam(string property) { return PropToParam[property]; }
void bind(); void bind();
void unbind(); void unbind();
@ -292,7 +361,7 @@ private:
FGMatrix33 mTs2b; FGMatrix33 mTs2b;
FGMatrix33 mTb2s; FGMatrix33 mTb2s;
FGColumnVector4 vQtrn; FGColumnVector4 vQtrn;
FGColumnVector4 vlastQdot; FGColumnVector4 vQdot_prev[3];
FGColumnVector4 vQdot; FGColumnVector4 vQdot;
FGColumnVector3 vUVW; FGColumnVector3 vUVW;
FGColumnVector3 vLocalVelNED; FGColumnVector3 vLocalVelNED;
@ -313,22 +382,9 @@ private:
FGPropulsion* Propulsion; FGPropulsion* Propulsion;
FGPropertyManager* PropertyManager; FGPropertyManager* PropertyManager;
/* typedef map<string, eParam> CoeffMap;
CoeffMap coeffdef;
typedef map<eParam, string> ParamMap;
//ParamMap paramdef; */
typedef map<string,string> ParamNameMap; typedef map<string,string> ParamNameMap;
ParamNameMap ParamNameToProp; ParamNameMap ParamNameToProp;
typedef map<eParam,string> ParamIdxMap;
ParamIdxMap ParamIdxToProp;
//CoeffMap PropToParam;
int ActiveEngine;
void InitPropertyMaps(void); void InitPropertyMaps(void);
void Debug(int from); void Debug(int from);

View file

@ -88,6 +88,12 @@ FGTranslation::FGTranslation(FGFDMExec* fdmex) : FGModel(fdmex)
Mach = 0.0; Mach = 0.0;
alpha = beta = 0.0; alpha = beta = 0.0;
adot = bdot = 0.0; adot = bdot = 0.0;
vUVWdot.InitMatrix();
vUVWdot_prev[0].InitMatrix();
vUVWdot_prev[1].InitMatrix();
vUVWdot_prev[2].InitMatrix();
bind(); bind();
Debug(0); Debug(0);
} }
@ -104,8 +110,6 @@ FGTranslation::~FGTranslation(void)
bool FGTranslation::Run(void) bool FGTranslation::Run(void)
{ {
double Tc = 0.5*State->Getdt()*rate;
if (!FGModel::Run()) { if (!FGModel::Run()) {
mVel(1,1) = 0.0; mVel(1,1) = 0.0;
@ -120,7 +124,7 @@ bool FGTranslation::Run(void)
vUVWdot = mVel*Rotation->GetPQR() + Aircraft->GetBodyAccel(); vUVWdot = mVel*Rotation->GetPQR() + Aircraft->GetBodyAccel();
vUVW += Tc*(vUVWdot + vlastUVWdot); vUVW += State->Integrate(FGState::TRAPZ, State->Getdt()*rate, vUVWdot, vUVWdot_prev);
vAeroUVW = vUVW + State->GetTl2b()*Atmosphere->GetWindNED(); vAeroUVW = vUVW + State->GetTl2b()*Atmosphere->GetWindNED();
@ -155,8 +159,6 @@ bool FGTranslation::Run(void)
qbarUV = 0.5*Atmosphere->GetDensity()*(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eV)*vAeroUVW(eV)); qbarUV = 0.5*Atmosphere->GetDensity()*(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eV)*vAeroUVW(eV));
Mach = Vt / State->Geta(); Mach = Vt / State->Geta();
vlastUVWdot = vUVWdot;
if (debug_lvl > 1) Debug(1); if (debug_lvl > 1) Debug(1);
return false; return false;

View file

@ -128,8 +128,8 @@ public:
private: private:
FGColumnVector3 vUVW; FGColumnVector3 vUVW;
FGColumnVector3 vUVWdot; FGColumnVector3 vUVWdot;
FGColumnVector3 vlastUVWdot; FGColumnVector3 vUVWdot_prev[3];
FGMatrix33 mVel; FGMatrix33 mVel;
FGColumnVector3 vAeroUVW; FGColumnVector3 vAeroUVW;
double Vt, Mach; double Vt, Mach;
@ -137,7 +137,6 @@ private:
double dt; double dt;
double alpha, beta; double alpha, beta;
double adot,bdot; double adot,bdot;
void Debug(int from); void Debug(int from);
}; };