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);
return false;
} 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<Components.size(); i++) Components[i]->Run();
if (DoNormalize) Normalize();
} else {
}
return false;
return false;
} else {
return true;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

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

View file

@ -134,6 +134,8 @@ string FGGroundReactions::GetGroundReactionStrings(void)
GroundReactionStrings += (lGear[i].GetName() + "_strokeVel, ");
GroundReactionStrings += (lGear[i].GetName() + "_CompressForce, ");
GroundReactionStrings += (lGear[i].GetName() + "_WhlSideForce, ");
GroundReactionStrings += (lGear[i].GetName() + "_WhlVelVecX, ");
GroundReactionStrings += (lGear[i].GetName() + "_WhlVelVecY, ");
GroundReactionStrings += (lGear[i].GetName() + "_WhlRollForce, ");
GroundReactionStrings += (lGear[i].GetName() + "_BodyXForce, ");
GroundReactionStrings += (lGear[i].GetName() + "_BodyYForce, ");
@ -142,6 +144,13 @@ string FGGroundReactions::GetGroundReactionStrings(void)
firstime = false;
}
GroundReactionStrings += ", TotalGearForce_X, ";
GroundReactionStrings += "TotalGearForce_Y, ";
GroundReactionStrings += "TotalGearForce_Z, ";
GroundReactionStrings += "TotalGearMoment_L, ";
GroundReactionStrings += "TotalGearMoment_M, ";
GroundReactionStrings += "TotalGearMoment_N";
return GroundReactionStrings;
}
@ -160,6 +169,8 @@ string FGGroundReactions::GetGroundReactionValues(void)
GroundReactionValues += (string(gcvt(lGear[i].GetCompLen(), 5, buff)) + ", ");
GroundReactionValues += (string(gcvt(lGear[i].GetCompVel(), 6, 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].GetWheelRollForce(), 6, buff)) + ", ");
GroundReactionValues += (string(gcvt(lGear[i].GetBodyXForce(), 6, buff)) + ", ");
@ -169,6 +180,13 @@ string FGGroundReactions::GetGroundReactionValues(void)
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;
}

View file

@ -59,7 +59,10 @@ FGInertial::FGInertial(FGFDMExec* fgex) : FGModel(fgex)
RadiusReference = 20925650.00;
gAccelReference = GM/(RadiusReference*RadiusReference);
gAccel = GM/(RadiusReference*RadiusReference);
vCoriolis.InitMatrix();
vCentrifugal.InitMatrix();
vGravity.InitMatrix();
bind();
Debug(0);
@ -77,21 +80,12 @@ FGInertial::~FGInertial(void)
bool FGInertial::Run(void)
{
double stht, ctht, sphi, cphi;
if (!FGModel::Run()) {
gAccel = GM / (Position->GetRadius()*Position->GetRadius());
stht = sin(Rotation->GetEuler(eTht));
ctht = cos(Rotation->GetEuler(eTht));
sphi = sin(Rotation->GetEuler(ePhi));
cphi = cos(Rotation->GetEuler(ePhi));
vGravity(eDown) = gAccel;
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
// calculation _for_the_local_frame_ given the earth's rotation (first set)
// 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(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();
vForces += State->GetTl2b()*(vOmegaLocal * (vOmegaLocal * vRadius));
vCoriolis(eEast) = 2.0*omega() * (Position->GetVd()*cos(Position->GetLatitude()) +
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;
} else {

View file

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

View file

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

View file

@ -104,7 +104,7 @@ FGLGear::FGLGear(FGConfigFile* AC_cfg, FGFDMExec* fdmex) : Exec(fdmex)
FCS = Exec->GetFCS();
MassBalance = Exec->GetMassBalance();
WOW = lastWOW = false;
WOW = lastWOW = true; // should the value be initialized to true?
ReportEnable = true;
FirstContact = false;
Reported = false;
@ -115,7 +115,7 @@ FGLGear::FGLGear(FGConfigFile* AC_cfg, FGFDMExec* fdmex) : Exec(fdmex)
vWhlBodyVec = (vXYZ - MassBalance->GetXYZcg()) / 12.0;
vWhlBodyVec(eX) = -vWhlBodyVec(eX);
vWhlBodyVec(eZ) = -vWhlBodyVec(eZ);
vLocalGear = State->GetTb2l() * vWhlBodyVec;
compressLength = 0.0;
@ -123,6 +123,13 @@ FGLGear::FGLGear(FGConfigFile* AC_cfg, FGFDMExec* fdmex) : Exec(fdmex)
brakePct = 0.0;
maxCompLen = 0.0;
WheelSlip = lastWheelSlip = 0.0;
compressLength = 0.0;
compressSpeed = 0.0;
brakePct = 0.0;
maxCompLen = 0.0;
Debug(0);
}
@ -173,6 +180,8 @@ FGLGear::FGLGear(const FGLGear& lgear)
isRetractable = lgear.isRetractable;
GearUp = lgear.GearUp;
GearDown = lgear.GearDown;
WheelSlip = lgear.WheelSlip;
lastWheelSlip = lgear.lastWheelSlip;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -266,17 +275,17 @@ FGColumnVector3& FGLGear::Force(void)
switch (eBrakeGrp) {
case bgLeft:
SteerGain = -0.10;
SteerGain = 0.10;
BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgLeft)) +
staticFCoeff*FCS->GetBrake(bgLeft);
break;
case bgRight:
SteerGain = -0.10;
SteerGain = 0.10;
BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgRight)) +
staticFCoeff*FCS->GetBrake(bgRight);
break;
case bgCenter:
SteerGain = -0.10;
SteerGain = 0.10;
BrakeFCoeff = rollingFCoeff*(1.0 - FCS->GetBrake(bgCenter)) +
staticFCoeff*FCS->GetBrake(bgCenter);
break;
@ -289,7 +298,7 @@ FGColumnVector3& FGLGear::Force(void)
BrakeFCoeff = rollingFCoeff;
break;
case bgNone:
SteerGain = -0.10;
SteerGain = 0.0;
BrakeFCoeff = rollingFCoeff;
break;
default:
@ -326,17 +335,31 @@ FGColumnVector3& FGLGear::Force(void)
if (RollingWhlVel == 0.0 && SideWhlVel == 0.0) {
WheelSlip = 0.0;
} else if (fabs(RollingWhlVel) < 0.10) {
WheelSlip = 0.05*radtodeg*atan2(SideWhlVel, RollingWhlVel) + 0.95*WheelSlip;
} else {
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.
// 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
// of this that avoid the discrete jump. Will fix this later.
if (fabs(WheelSlip) <= 10.0) {
FCoeff = staticFCoeff*WheelSlip/10.0;
if (fabs(WheelSlip) <= 20.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 {
FCoeff = dynamicFCoeff*fabs(WheelSlip)/WheelSlip;
}
@ -406,7 +429,7 @@ FGColumnVector3& FGLGear::Force(void)
}
if (lastWOW != WOW) {
PutMessage("GEAR_CONTACT", WOW);
PutMessage("GEAR_CONTACT: " + name, WOW);
}
lastWOW = WOW;

View file

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

View file

@ -98,8 +98,9 @@ bool FGOutput::Run(void)
} else {
// Not a valid type of output
}
return false;
} else {
return true;
}
}
return false;
@ -172,7 +173,10 @@ void FGOutput::DelimitedOutput(string fname)
outstream << ", ";
outstream << "Drag, Side, Lift, ";
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) {
outstream << ", ";
@ -252,7 +256,10 @@ void FGOutput::DelimitedOutput(string fname)
outstream << ", ";
outstream << Aerodynamics->GetvFs() << ", ";
outstream << Aerodynamics->GetLoD() << ", ";
outstream << Aircraft->GetForces();
outstream << Aircraft->GetForces() << ", ";
outstream << Inertial->GetGravity() << ", ";
outstream << Inertial->GetCoriolis() << ", ";
outstream << Inertial->GetCentrifugal();
}
if (SubSystems & ssMoments) {
outstream << ", ";

View file

@ -101,7 +101,13 @@ FGPosition::FGPosition(FGFDMExec* fdmex) : FGModel(fdmex)
{
Name = "FGPosition";
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;
gamma = Vt = Vground = 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.
*/
bool FGPosition::Run(void) {
bool FGPosition::Run(void)
{
double cosLat;
double hdot_Vt;
FGColumnVector3 vMac;
@ -160,22 +167,20 @@ bool FGPosition::Run(void) {
cosLat = cos(Latitude);
if (cosLat != 0) LongitudeDot = vVel(eEast) / (Radius * cosLat);
LatitudeDot = vVel(eNorth) / Radius;
RadiusDot = -vVel(eDown);
Longitude += 0.5*dt*rate*(LongitudeDot + lastLongitudeDot);
Latitude += 0.5*dt*rate*(LatitudeDot + lastLatitudeDot);
Radius += 0.5*dt*rate*(RadiusDot + lastRadiusDot);
Longitude += State->Integrate(FGState::TRAPZ, dt*rate, LongitudeDot, LongitudeDot_prev);
Latitude += State->Integrate(FGState::TRAPZ, dt*rate, LatitudeDot, LatitudeDot_prev);
Radius += State->Integrate(FGState::TRAPZ, dt*rate, RadiusDot, RadiusDot_prev);
h = Radius - SeaLevelRadius; // Geocentric
DistanceAGL = Radius - RunwayRadius; // Geocentric
hoverbcg = DistanceAGL/b;
vMac=State->GetTb2l()*Aircraft->GetXYZrp();
vMac = State->GetTb2l()*Aircraft->GetXYZrp();
vMac *= inchtoft;
hoverbmac = (DistanceAGL + vMac(3))/b;
@ -187,10 +192,6 @@ bool FGPosition::Run(void) {
gamma = 0.0;
}
lastLatitudeDot = LatitudeDot;
lastLongitudeDot = LongitudeDot;
lastRadiusDot = RadiusDot;
return false;
} else {
@ -200,7 +201,8 @@ bool FGPosition::Run(void) {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPosition::GetState(void) {
void FGPosition::GetState(void)
{
dt = State->Getdt();
Vt = Translation->GetVt();
@ -212,7 +214,8 @@ void FGPosition::GetState(void) {
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGPosition::Seth(double tt) {
void FGPosition::Seth(double tt)
{
h = tt;
Radius = h + SeaLevelRadius;
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;
Radius = RunwayRadius + DistanceAGL;
h = Radius - SeaLevelRadius;

View file

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

File diff suppressed because it is too large Load diff

View file

@ -1,219 +1,224 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGPropulsion.h
Author: Jon S. Berndt
Date started: 08/20/00
------------- 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.
HISTORY
--------------------------------------------------------------------------------
08/20/00 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGPROPULSION_H
#define FGPROPULSION_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef FGFS
# include <simgear/compiler.h>
# ifdef SG_HAVE_STD_INCLUDES
# include <vector>
# include <iterator>
# else
# include <vector.h>
# include <iterator.h>
# endif
#else
# include <vector>
# include <iterator>
#endif
#include "FGModel.h"
#include "FGRocket.h"
#include "FGPiston.h"
#include "FGTurboShaft.h"
#include "FGTurboJet.h"
#include "FGTurboProp.h"
#include "FGTank.h"
#include "FGPropeller.h"
#include "FGNozzle.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_PROPULSION "$Id$"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Propulsion management class.
FGPropulsion manages all aspects of propulsive force generation, including
containment of engines, tanks, and thruster class instances in STL vectors,
and the interaction and communication between them.
@author Jon S. Berndt
@version $Id$
@see FGEngine
@see FGTank
@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">
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">
Source File </a>
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGPropulsion : public FGModel
{
public:
/// Constructor
FGPropulsion(FGFDMExec*);
/// Destructor
~FGPropulsion();
/** Executes the propulsion model.
The initial plan for the FGPropulsion class calls for Run() to be executed,
performing the following tasks:
<ol>
<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
is done by calling FGThruster::CalculatePReq()</li>
<li>Given 1, above, calculate the power available from the engine. This is
done by calling FGEngine::CalculatePAvail()</li>
<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
numbers for the thruster in the case of the propeller, at least. This
result is returned from a call to Calculate().</li></ol>
[Note: Should we be checking the Starved flag here?] */
bool Run(void);
/** Loads the propulsion system (engine[s], tank[s], thruster[s]).
Characteristics of the propulsion system are read in from the config file.
@param AC_cfg pointer to the config file instance that describes the
aircraft being modeled.
@return true if successfully loaded, otherwise false */
bool Load(FGConfigFile* AC_cfg);
/// Retrieves the number of engines defined for the aircraft.
inline unsigned int GetNumEngines(void) const {return Engines.size();}
/** Retrieves an engine object pointer from the list of engines.
@param index the engine index within the vector container
@return the address of the specific engine, or zero if no such engine is
available */
inline FGEngine* GetEngine(unsigned int index) {
if (index <= Engines.size()-1) return Engines[index];
else return 0L; }
// Retrieves the number of tanks defined for the aircraft.
inline unsigned int GetNumTanks(void) const {return Tanks.size();}
/** Retrieves a tank object pointer from the list of tanks.
@param index the tank index within the vector container
@return the address of the specific tank, or zero if no such tank is
available */
inline FGTank* GetTank(unsigned int index) {
if (index <= Tanks.size()-1) return Tanks[index];
else return 0L; }
/** Retrieves a thruster object pointer from the list of thrusters.
@param index the thruster index within the vector container
@return the address of the specific thruster, or zero if no such thruster is
available */
inline FGThruster* GetThruster(unsigned int index) {
if (index <= Thrusters.size()-1) return Thrusters[index];
else return 0L; }
/** Returns the number of fuel tanks currently actively supplying fuel */
inline int GetnumSelectedFuelTanks(void) const {return numSelectedFuelTanks;}
/** Returns the number of oxidizer tanks currently actively supplying oxidizer */
inline int GetnumSelectedOxiTanks(void) const {return numSelectedOxiTanks;}
/** Loops the engines/thrusters until thrust output steady (used for trimming) */
bool GetSteadyState(void);
/** starts the engines in IC mode (dt=0). All engine-specific setup must
be done before calling this (i.e. magnetos, starter engage, etc.) */
bool ICEngineStart(void);
string GetPropulsionStrings(void);
string GetPropulsionValues(void);
inline FGColumnVector3& GetForces(void) {return vForces; }
inline double GetForces(int n) const { return vForces(n);}
inline FGColumnVector3& GetMoments(void) {return vMoments;}
inline double GetMoments(int n) const {return vMoments(n);}
FGColumnVector3& GetTanksMoment(void);
double GetTanksWeight(void);
double GetTanksIxx(const FGColumnVector3& vXYZcg);
double GetTanksIyy(const FGColumnVector3& vXYZcg);
double GetTanksIzz(const FGColumnVector3& vXYZcg);
double GetTanksIxz(const FGColumnVector3& vXYZcg);
double GetTanksIxy(const FGColumnVector3& vXYZcg);
void bind();
void unbind();
private:
vector <FGEngine*> Engines;
vector <FGTank*> Tanks;
vector <FGTank*>::iterator iTank;
vector <FGThruster*> Thrusters;
unsigned int numSelectedFuelTanks;
unsigned int numSelectedOxiTanks;
unsigned int numFuelTanks;
unsigned int numOxiTanks;
unsigned int numEngines;
unsigned int numTanks;
unsigned int numThrusters;
double dt;
FGColumnVector3 vForces;
FGColumnVector3 vMoments;
FGColumnVector3 vXYZtank;
void Debug(int from);
};
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGPropulsion.h
Author: Jon S. Berndt
Date started: 08/20/00
------------- 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.
HISTORY
--------------------------------------------------------------------------------
08/20/00 JSB Created
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGPROPULSION_H
#define FGPROPULSION_H
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef FGFS
# include <simgear/compiler.h>
# ifdef SG_HAVE_STD_INCLUDES
# include <vector>
# include <iterator>
# else
# include <vector.h>
# include <iterator.h>
# endif
#else
# include <vector>
# include <iterator>
#endif
#include "FGModel.h"
#include "FGRocket.h"
#include "FGPiston.h"
#include "FGTurboShaft.h"
#include "FGTurboJet.h"
#include "FGTurboProp.h"
#include "FGTank.h"
#include "FGPropeller.h"
#include "FGNozzle.h"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
DEFINITIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#define ID_PROPULSION "$Id$"
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FORWARD DECLARATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Propulsion management class.
FGPropulsion manages all aspects of propulsive force generation, including
containment of engines, tanks, and thruster class instances in STL vectors,
and the interaction and communication between them.
@author Jon S. Berndt
@version $Id$
@see FGEngine
@see FGTank
@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">
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">
Source File </a>
*/
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS DECLARATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
class FGPropulsion : public FGModel
{
public:
/// Constructor
FGPropulsion(FGFDMExec*);
/// Destructor
~FGPropulsion();
/** Executes the propulsion model.
The initial plan for the FGPropulsion class calls for Run() to be executed,
performing the following tasks:
<ol>
<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
is done by calling FGThruster::CalculatePReq()</li>
<li>Given 1, above, calculate the power available from the engine. This is
done by calling FGEngine::CalculatePAvail()</li>
<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
numbers for the thruster in the case of the propeller, at least. This
result is returned from a call to Calculate().</li></ol>
[Note: Should we be checking the Starved flag here?] */
bool Run(void);
/** Loads the propulsion system (engine[s], tank[s], thruster[s]).
Characteristics of the propulsion system are read in from the config file.
@param AC_cfg pointer to the config file instance that describes the
aircraft being modeled.
@return true if successfully loaded, otherwise false */
bool Load(FGConfigFile* AC_cfg);
/// Retrieves the number of engines defined for the aircraft.
inline unsigned int GetNumEngines(void) const {return Engines.size();}
/** Retrieves an engine object pointer from the list of engines.
@param index the engine index within the vector container
@return the address of the specific engine, or zero if no such engine is
available */
inline FGEngine* GetEngine(unsigned int index) {
if (index <= Engines.size()-1) return Engines[index];
else return 0L; }
// Retrieves the number of tanks defined for the aircraft.
inline unsigned int GetNumTanks(void) const {return Tanks.size();}
/** Retrieves a tank object pointer from the list of tanks.
@param index the tank index within the vector container
@return the address of the specific tank, or zero if no such tank is
available */
inline FGTank* GetTank(unsigned int index) {
if (index <= Tanks.size()-1) return Tanks[index];
else return 0L; }
/** Retrieves a thruster object pointer from the list of thrusters.
@param index the thruster index within the vector container
@return the address of the specific thruster, or zero if no such thruster is
available */
inline FGThruster* GetThruster(unsigned int index) {
if (index <= Thrusters.size()-1) return Thrusters[index];
else return 0L; }
/** Returns the number of fuel tanks currently actively supplying fuel */
inline int GetnumSelectedFuelTanks(void) const {return numSelectedFuelTanks;}
/** Returns the number of oxidizer tanks currently actively supplying oxidizer */
inline int GetnumSelectedOxiTanks(void) const {return numSelectedOxiTanks;}
/** Loops the engines/thrusters until thrust output steady (used for trimming) */
bool GetSteadyState(void);
/** starts the engines in IC mode (dt=0). All engine-specific setup must
be done before calling this (i.e. magnetos, starter engage, etc.) */
bool ICEngineStart(void);
string GetPropulsionStrings(void);
string GetPropulsionValues(void);
inline FGColumnVector3& GetForces(void) {return vForces; }
inline double GetForces(int n) const { return vForces(n);}
inline FGColumnVector3& GetMoments(void) {return vMoments;}
inline double GetMoments(int n) const {return vMoments(n);}
FGColumnVector3& GetTanksMoment(void);
double GetTanksWeight(void);
double GetTanksIxx(const FGColumnVector3& vXYZcg);
double GetTanksIyy(const FGColumnVector3& vXYZcg);
double GetTanksIzz(const FGColumnVector3& vXYZcg);
double GetTanksIxz(const FGColumnVector3& vXYZcg);
double GetTanksIxy(const FGColumnVector3& vXYZcg);
void SetMagnetos(int setting);
void SetStarter(int setting);
void SetActiveEngine(int engine);
void bind();
void unbind();
private:
vector <FGEngine*> Engines;
vector <FGTank*> Tanks;
vector <FGTank*>::iterator iTank;
vector <FGThruster*> Thrusters;
unsigned int numSelectedFuelTanks;
unsigned int numSelectedOxiTanks;
unsigned int numFuelTanks;
unsigned int numOxiTanks;
unsigned int numEngines;
unsigned int numTanks;
unsigned int numThrusters;
int ActiveEngine;
double dt;
FGColumnVector3 vForces;
FGColumnVector3 vMoments;
FGColumnVector3 vXYZtank;
void Debug(int from);
};
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#endif

View file

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

View file

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

View file

@ -64,13 +64,6 @@ MACROS
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)
{
FDMExec = fdex;
@ -78,7 +71,6 @@ FGState::FGState(FGFDMExec* fdex)
a = 1000.0;
sim_time = 0.0;
dt = 1.0/120.0;
ActiveEngine = -1;
Aircraft = FDMExec->GetAircraft();
Translation = FDMExec->GetTranslation();
@ -92,6 +84,8 @@ FGState::FGState(FGFDMExec* fdex)
Propulsion = FDMExec->GetPropulsion();
PropertyManager = FDMExec->GetPropertyManager();
for(int i=0;i<3;i++) vQdot_prev[i].InitMatrix();
InitPropertyMaps();
bind();
@ -159,7 +153,6 @@ bool FGState::Reset(string path, string acname, string fname)
resetfile >> token;
}
Position->SetLatitude(latitude*degtorad);
Position->SetLongitude(longitude*degtorad);
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(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));
vQtrn += 0.5*dt*rate*(vlastQdot + vQdot);
vQtrn += Integrate(TRAPZ, dt*rate, vQdot, vQdot_prev);
vQtrn.Normalize();
vlastQdot = vQdot;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -553,17 +545,17 @@ void FGState::InitPropertyMaps(void)
ParamNameToProp[ "FG_THROTTLE_POS" ]="fcs/throttle-pos-norm";
ParamNameToProp[ "FG_MIXTURE_CMD" ]="fcs/mixture-cmd-norm";
ParamNameToProp[ "FG_MIXTURE_POS" ]="fcs/mixture-pos-norm";
ParamNameToProp[ "FG_MAGNETO_CMD" ]="zero";
ParamNameToProp[ "FG_STARTER_CMD" ]="zero";
ParamNameToProp[ "FG_ACTIVE_ENGINE" ]="zero";
ParamNameToProp[ "FG_MAGNETO_CMD" ]="propulsion/magneto_cmd";
ParamNameToProp[ "FG_STARTER_CMD" ]="propulsion/starter_cmd";
ParamNameToProp[ "FG_ACTIVE_ENGINE" ]="propulsion/active_engine";
ParamNameToProp[ "FG_HOVERB" ]="aero/h_b-mac-ft";
ParamNameToProp[ "FG_PITCH_TRIM_CMD" ]="fcs/pitch-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_LEFT_BRAKE_CMD" ]="zero";
ParamNameToProp[ "FG_CENTER_BRAKE_CMD" ]="zero";
ParamNameToProp[ "FG_RIGHT_BRAKE_CMD" ]="zero";
ParamNameToProp[ "FG_SET_LOGGING" ]="zero";
ParamNameToProp[ "FG_LEFT_BRAKE_CMD" ]="fcs/left_brake";
ParamNameToProp[ "FG_CENTER_BRAKE_CMD" ]="fcs/center_brake";
ParamNameToProp[ "FG_RIGHT_BRAKE_CMD" ]="fcs/right_brake";
ParamNameToProp[ "FG_SET_LOGGING" ]="sim/set_logging";
ParamNameToProp[ "FG_ALPHAH" ]="aero/alpha-rad";
ParamNameToProp[ "FG_ALPHAW" ]="aero/alpha-wing-rad";
ParamNameToProp[ "FG_LBARH" ]="metrics/lh-norm";

View file

@ -229,6 +229,77 @@ public:
@param rate the integration rate in seconds.
*/
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.
@return a reference to the vEuler column vector.
@ -275,8 +346,6 @@ public:
void ReportState(void);
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 unbind();
@ -292,7 +361,7 @@ private:
FGMatrix33 mTs2b;
FGMatrix33 mTb2s;
FGColumnVector4 vQtrn;
FGColumnVector4 vlastQdot;
FGColumnVector4 vQdot_prev[3];
FGColumnVector4 vQdot;
FGColumnVector3 vUVW;
FGColumnVector3 vLocalVelNED;
@ -313,22 +382,9 @@ private:
FGPropulsion* Propulsion;
FGPropertyManager* PropertyManager;
/* typedef map<string, eParam> CoeffMap;
CoeffMap coeffdef;
typedef map<eParam, string> ParamMap;
//ParamMap paramdef; */
typedef map<string,string> ParamNameMap;
ParamNameMap ParamNameToProp;
typedef map<eParam,string> ParamIdxMap;
ParamIdxMap ParamIdxToProp;
//CoeffMap PropToParam;
int ActiveEngine;
void InitPropertyMaps(void);
void Debug(int from);

View file

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

View file

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