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);
} else { // skip Run() execution this time
}
return false; return false;
} else { // skip Run() execution this time
return true;
}
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

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

@ -115,8 +115,6 @@ FGFDMExec::FGFDMExec(FGPropertyManager* root)
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,6 +59,9 @@ 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();
@ -77,20 +80,11 @@ 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)
@ -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;
@ -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,19 +167,17 @@ 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();
@ -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;

View file

@ -82,6 +82,7 @@ FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec)
numTanks = numEngines = numThrusters = 0; numTanks = numEngines = numThrusters = 0;
numOxiTanks = numFuelTanks = 0; numOxiTanks = numFuelTanks = 0;
dt = 0.0; dt = 0.0;
ActiveEngine = -1; // -1: ALL, 0: Engine 1, 1: Engine 2 ...
bind(); bind();
Debug(0); Debug(0);
} }
@ -560,13 +561,67 @@ double FGPropulsion::GetTanksIxy(const FGColumnVector3& vXYZcg)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPropulsion::SetMagnetos(int setting)
{
if (ActiveEngine == -1) {
for (unsigned i=0; i<Engines.size(); i++) {
Engines[i]->SetMagnetos(setting);
}
} else {
Engines[ActiveEngine]->SetMagnetos(setting);
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPropulsion::SetStarter(int setting)
{
if (ActiveEngine == -1) {
for (unsigned i=0; i<Engines.size(); i++) {
Engines[i]->SetStarter(setting);
}
} else {
if (setting == 0)
Engines[ActiveEngine]->SetStarter(false);
else
Engines[ActiveEngine]->SetStarter(true);
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPropulsion::SetActiveEngine(int engine)
{
if ( unsigned(engine) > Engines.size())
ActiveEngine = -1;
else
ActiveEngine = engine;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPropulsion::bind(void) void FGPropulsion::bind(void)
{ {
typedef double (FGPropulsion::*PMF)(int) const; typedef double (FGPropulsion::*PMF)(int) const;
typedef int (FGPropulsion::*iPMF)(void) const;
/* PropertyManager->Tie("propulsion/num-engines", this, /* PropertyManager->Tie("propulsion/num-engines", this,
&FGPropulsion::GetNumEngines); &FGPropulsion::GetNumEngines);
PropertyManager->Tie("propulsion/num-tanks", this, PropertyManager->Tie("propulsion/num-tanks", this,
&FGPropulsion::GetNumTanks); */ &FGPropulsion::GetNumTanks); */
PropertyManager->Tie("propulsion/magneto_cmd", this,
(iPMF)0,
&FGPropulsion::SetMagnetos,
true);
PropertyManager->Tie("propulsion/starter_cmd", this,
(iPMF)0,
&FGPropulsion::SetStarter,
true);
PropertyManager->Tie("propulsion/active_engine", this,
(iPMF)0,
&FGPropulsion::SetActiveEngine,
true);
PropertyManager->Tie("propulsion/num-sel-fuel-tanks", this, PropertyManager->Tie("propulsion/num-sel-fuel-tanks", this,
&FGPropulsion::GetnumSelectedFuelTanks); &FGPropulsion::GetnumSelectedFuelTanks);
PropertyManager->Tie("propulsion/num-sel-ox-tanks", this, PropertyManager->Tie("propulsion/num-sel-ox-tanks", this,
@ -595,6 +650,9 @@ void FGPropulsion::unbind(void)
PropertyManager->Untie("propulsion/num-tanks"); */ PropertyManager->Untie("propulsion/num-tanks"); */
PropertyManager->Untie("propulsion/num-sel-fuel-tanks"); PropertyManager->Untie("propulsion/num-sel-fuel-tanks");
PropertyManager->Untie("propulsion/num-sel-ox-tanks"); PropertyManager->Untie("propulsion/num-sel-ox-tanks");
PropertyManager->Untie("propulsion/magneto_cmd");
PropertyManager->Untie("propulsion/starter_cmd");
PropertyManager->Untie("propulsion/active_engine");
PropertyManager->Untie("forces/fbx-prop-lbs"); PropertyManager->Untie("forces/fbx-prop-lbs");
PropertyManager->Untie("forces/fby-prop-lbs"); PropertyManager->Untie("forces/fby-prop-lbs");
PropertyManager->Untie("forces/fbz-prop-lbs"); PropertyManager->Untie("forces/fbz-prop-lbs");

View file

@ -192,6 +192,10 @@ public:
double GetTanksIxz(const FGColumnVector3& vXYZcg); double GetTanksIxz(const FGColumnVector3& vXYZcg);
double GetTanksIxy(const FGColumnVector3& vXYZcg); double GetTanksIxy(const FGColumnVector3& vXYZcg);
void SetMagnetos(int setting);
void SetStarter(int setting);
void SetActiveEngine(int engine);
void bind(); void bind();
void unbind(); void unbind();
@ -207,6 +211,7 @@ private:
unsigned int numEngines; unsigned int numEngines;
unsigned int numTanks; unsigned int numTanks;
unsigned int numThrusters; unsigned int numThrusters;
int ActiveEngine;
double dt; double dt;
FGColumnVector3 vForces; FGColumnVector3 vForces;
FGColumnVector3 vMoments; FGColumnVector3 vMoments;

View file

@ -83,6 +83,11 @@ FGRotation::FGRotation(FGFDMExec* fdmex) : FGModel(fdmex)
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

@ -230,6 +230,77 @@ public:
*/ */
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,7 +128,7 @@ 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;
@ -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);
}; };