Sync with latest JSBSim changes.
This commit is contained in:
parent
c167c60de9
commit
71a562b695
31 changed files with 774 additions and 475 deletions
|
@ -198,7 +198,7 @@ void FGJSBsim::init() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
stall_warning->setBoolValue(false);
|
stall_warning->setDoubleValue(0);
|
||||||
|
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, " Bank Angle: "
|
SG_LOG( SG_FLIGHT, SG_INFO, " Bank Angle: "
|
||||||
<< Rotation->Getphi()*RADTODEG << " deg" );
|
<< Rotation->Getphi()*RADTODEG << " deg" );
|
||||||
|
@ -382,7 +382,7 @@ bool FGJSBsim::copy_from_JSBsim() {
|
||||||
// Auxiliary->GetNpilot(2)/32.1739,
|
// Auxiliary->GetNpilot(2)/32.1739,
|
||||||
// Auxiliary->GetNpilot(3)/32.1739 );
|
// Auxiliary->GetNpilot(3)/32.1739 );
|
||||||
|
|
||||||
_set_Nlf( Aerodynamics->GetNlf() );
|
_set_Nlf( Aircraft->GetNlf() );
|
||||||
|
|
||||||
// Velocities
|
// Velocities
|
||||||
|
|
||||||
|
|
56
src/FDM/JSBSim/AUTHORS
Normal file
56
src/FDM/JSBSim/AUTHORS
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
AUTHORS
|
||||||
|
-------
|
||||||
|
|
||||||
|
Jon S. Berndt
|
||||||
|
primary architect and coordinator
|
||||||
|
jsb@hal-pc.org
|
||||||
|
CVS access as developer (r/w)
|
||||||
|
|
||||||
|
|
||||||
|
Tony Peden
|
||||||
|
additional architecture support
|
||||||
|
trimming and aerodynamics
|
||||||
|
interface with flightgear
|
||||||
|
apeden@earthlink.net
|
||||||
|
CVS access as developer (r/w)
|
||||||
|
|
||||||
|
|
||||||
|
Additional support (programming, bug fixes, aircraft models)
|
||||||
|
by the FlightGear team and others as listed:
|
||||||
|
|
||||||
|
Curt Olson
|
||||||
|
wrote initial interface with flightgear
|
||||||
|
works flightgear/jsbsim issues
|
||||||
|
curt@flightgear.org
|
||||||
|
|
||||||
|
Norman Vine
|
||||||
|
matrix math class optimization support
|
||||||
|
general C++ suggestions, debugging, and support
|
||||||
|
nhv@cape.com
|
||||||
|
|
||||||
|
Christian Mayer
|
||||||
|
JSBSim compatibility with MSVC
|
||||||
|
mail@ChristianMayer.de
|
||||||
|
|
||||||
|
Erik Hofman
|
||||||
|
JSBSim compatibility with IRIX
|
||||||
|
erik@ehofman.com
|
||||||
|
|
||||||
|
David Megginson
|
||||||
|
ported Dave Luff's piston engine model initially to JSBSim
|
||||||
|
creation of multi-engine C-310 model and testing/debugging
|
||||||
|
general C++ suggestions, debugging, and support
|
||||||
|
david@megginson.com
|
||||||
|
|
||||||
|
Ross Golder
|
||||||
|
improvements to the build process and auto* files
|
||||||
|
ross@golder.org
|
||||||
|
|
||||||
|
Dave Luff
|
||||||
|
wrote the piston engine model used by LaRCSim and is ported to JSBSim
|
||||||
|
eazdluf@nottingham.ac.uk
|
||||||
|
|
||||||
|
Norman Princen
|
||||||
|
provided an improved gear model
|
||||||
|
nprincen@hotmail.com
|
||||||
|
|
|
@ -100,7 +100,10 @@ bool FGAerodynamics::Run(void)
|
||||||
vFs(axis_ctr+1) += Coeff[axis_ctr][ctr]->TotalValue();
|
vFs(axis_ctr+1) += Coeff[axis_ctr][ctr]->TotalValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//correct signs of drag and lift to wind axes convention
|
||||||
|
//positive forward, right, down
|
||||||
|
vFs(1)*=-1; vFs(3)*=-1;
|
||||||
|
//cout << "Aircraft::vFs: " << vFs << endl;
|
||||||
vForces = State->GetTs2b()*vFs;
|
vForces = State->GetTs2b()*vFs;
|
||||||
|
|
||||||
vDXYZcg(eX) = -(Aircraft->GetXYZrp(eX)
|
vDXYZcg(eX) = -(Aircraft->GetXYZrp(eX)
|
||||||
|
@ -198,17 +201,6 @@ string FGAerodynamics::GetCoefficientValues(void)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
double FGAerodynamics::GetNlf(void)
|
|
||||||
{
|
|
||||||
if (fabs(Position->GetGamma()) < 1.57) {
|
|
||||||
return (vFs(eZ)/(MassBalance->GetWeight()*cos(Position->GetGamma())));
|
|
||||||
} else {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
double FGAerodynamics::GetLoD(void)
|
double FGAerodynamics::GetLoD(void)
|
||||||
{
|
{
|
||||||
double LoD;
|
double LoD;
|
||||||
|
|
|
@ -134,8 +134,6 @@ public:
|
||||||
coefficients */
|
coefficients */
|
||||||
string GetCoefficientValues(void);
|
string GetCoefficientValues(void);
|
||||||
|
|
||||||
/// Gets the Normal Load Factor
|
|
||||||
double GetNlf(void);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef map<string,int> AxisIndex;
|
typedef map<string,int> AxisIndex;
|
||||||
|
|
|
@ -105,7 +105,8 @@ FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex),
|
||||||
vXYZep(3),
|
vXYZep(3),
|
||||||
vDXYZcg(3),
|
vDXYZcg(3),
|
||||||
vBodyAccel(3),
|
vBodyAccel(3),
|
||||||
vNcg(3)
|
vNcg(3),
|
||||||
|
vNwcg(3)
|
||||||
{
|
{
|
||||||
Name = "FGAircraft";
|
Name = "FGAircraft";
|
||||||
alphaclmin = alphaclmax = 0;
|
alphaclmin = alphaclmax = 0;
|
||||||
|
@ -180,6 +181,9 @@ bool FGAircraft::Run(void)
|
||||||
|
|
||||||
vNcg = vBodyAccel/Inertial->gravity();
|
vNcg = vBodyAccel/Inertial->gravity();
|
||||||
|
|
||||||
|
vNwcg = State->GetTb2s() * vNcg;
|
||||||
|
vNwcg(3) = -1*vNwcg(3) + 1;
|
||||||
|
|
||||||
if (alphaclmax != 0) {
|
if (alphaclmax != 0) {
|
||||||
if (Translation->Getalpha() > 0.85*alphaclmax) {
|
if (Translation->Getalpha() > 0.85*alphaclmax) {
|
||||||
impending_stall = 10*(Translation->Getalpha()/alphaclmax - 0.85);
|
impending_stall = 10*(Translation->Getalpha()/alphaclmax - 0.85);
|
||||||
|
@ -196,6 +200,13 @@ bool FGAircraft::Run(void)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
float FGAircraft::GetNlf(void)
|
||||||
|
{
|
||||||
|
return vNwcg(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
void FGAircraft::ReadPrologue(FGConfigFile* AC_cfg)
|
void FGAircraft::ReadPrologue(FGConfigFile* AC_cfg)
|
||||||
{
|
{
|
||||||
string token = AC_cfg->GetValue();
|
string token = AC_cfg->GetValue();
|
||||||
|
|
|
@ -200,7 +200,11 @@ public:
|
||||||
inline void SetAlphaCLMax(double tt) { alphaclmax=tt; }
|
inline void SetAlphaCLMax(double tt) { alphaclmax=tt; }
|
||||||
inline void SetAlphaCLMin(double tt) { alphaclmin=tt; }
|
inline void SetAlphaCLMin(double tt) { alphaclmin=tt; }
|
||||||
|
|
||||||
inline bool GetStallWarn(void) { return impending_stall; }
|
inline double GetStallWarn(void) { return impending_stall; }
|
||||||
|
|
||||||
|
float GetNlf(void);
|
||||||
|
|
||||||
|
inline FGColumnVector3& GetNwcg(void) { return vNwcg; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FGColumnVector3 vMoments;
|
FGColumnVector3 vMoments;
|
||||||
|
@ -211,6 +215,7 @@ private:
|
||||||
FGColumnVector3 vDXYZcg;
|
FGColumnVector3 vDXYZcg;
|
||||||
FGColumnVector3 vBodyAccel;
|
FGColumnVector3 vBodyAccel;
|
||||||
FGColumnVector3 vNcg;
|
FGColumnVector3 vNcg;
|
||||||
|
FGColumnVector3 vNwcg;
|
||||||
|
|
||||||
double WingArea, WingSpan, cbar, WingIncidence;
|
double WingArea, WingSpan, cbar, WingIncidence;
|
||||||
double HTailArea, VTailArea, HTailArm, VTailArm;
|
double HTailArea, VTailArea, HTailArm, VTailArm;
|
||||||
|
|
|
@ -145,6 +145,7 @@ public:
|
||||||
inline void SetTurbGain(double tt) {TurbGain = tt;}
|
inline void SetTurbGain(double tt) {TurbGain = tt;}
|
||||||
|
|
||||||
inline double GetTurbPQR(int idx) {return vTurbPQR(idx);}
|
inline double GetTurbPQR(int idx) {return vTurbPQR(idx);}
|
||||||
|
inline FGColumnVector3& GetTurbPQR(void) {return vTurbPQR;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double rho;
|
double rho;
|
||||||
|
|
|
@ -64,7 +64,8 @@ CLASS IMPLEMENTATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
|
||||||
FGEngine::FGEngine(FGFDMExec* exec) {
|
FGEngine::FGEngine(FGFDMExec* exec)
|
||||||
|
{
|
||||||
FDMExec = exec;
|
FDMExec = exec;
|
||||||
State = FDMExec->GetState();
|
State = FDMExec->GetState();
|
||||||
Atmosphere = FDMExec->GetAtmosphere();
|
Atmosphere = FDMExec->GetAtmosphere();
|
||||||
|
@ -101,7 +102,8 @@ FGEngine::~FGEngine()
|
||||||
// This base class method removes fuel from the fuel tanks as appropriate,
|
// This base class method removes fuel from the fuel tanks as appropriate,
|
||||||
// and sets the starved flag if necessary.
|
// and sets the starved flag if necessary.
|
||||||
|
|
||||||
void FGEngine::ConsumeFuel(void) {
|
void FGEngine::ConsumeFuel(void)
|
||||||
|
{
|
||||||
double Fshortage, Oshortage;
|
double Fshortage, Oshortage;
|
||||||
FGTank* Tank;
|
FGTank* Tank;
|
||||||
|
|
||||||
|
|
|
@ -182,6 +182,9 @@ public:
|
||||||
/// Sets engine placement information
|
/// Sets engine placement information
|
||||||
void SetPlacement(double x, double y, double z, double pitch, double yaw);
|
void SetPlacement(double x, double y, double z, double pitch, double yaw);
|
||||||
|
|
||||||
|
/// Sets the engine number
|
||||||
|
void SetEngineNumber(int nn) {EngineNumber = nn;}
|
||||||
|
|
||||||
virtual double GetPowerAvailable(void) {return 0.0;};
|
virtual double GetPowerAvailable(void) {return 0.0;};
|
||||||
|
|
||||||
bool GetTrimMode(void) {return TrimMode;}
|
bool GetTrimMode(void) {return TrimMode;}
|
||||||
|
|
|
@ -67,8 +67,8 @@ const double FGJSBBase::SHRatio = 1.40;
|
||||||
const string FGJSBBase::needed_cfg_version = "1.55";
|
const string FGJSBBase::needed_cfg_version = "1.55";
|
||||||
const string FGJSBBase::JSBSim_version = "0.9.1";
|
const string FGJSBBase::JSBSim_version = "0.9.1";
|
||||||
|
|
||||||
queue <struct FGJSBBase::Message*> FGJSBBase::Messages;
|
queue <FGJSBBase::Message*> FGJSBBase::Messages;
|
||||||
struct FGJSBBase::Message FGJSBBase::localMsg;
|
FGJSBBase::Message FGJSBBase::localMsg;
|
||||||
unsigned int FGJSBBase::messageId = 0;
|
unsigned int FGJSBBase::messageId = 0;
|
||||||
unsigned int FGJSBBase::frame = 0;
|
unsigned int FGJSBBase::frame = 0;
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ FGJSBBase::FGJSBBase()
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
struct FGJSBBase::Message* FGJSBBase::PutMessage(struct Message* msg)
|
FGJSBBase::Message* FGJSBBase::PutMessage(Message* msg)
|
||||||
{
|
{
|
||||||
Messages.push(msg);
|
Messages.push(msg);
|
||||||
return msg;
|
return msg;
|
||||||
|
@ -90,9 +90,9 @@ struct FGJSBBase::Message* FGJSBBase::PutMessage(struct Message* msg)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
struct FGJSBBase::Message* FGJSBBase::PutMessage(string text)
|
FGJSBBase::Message* FGJSBBase::PutMessage(string text)
|
||||||
{
|
{
|
||||||
struct Message *msg = new Message();
|
Message *msg = new Message();
|
||||||
msg->text = text;
|
msg->text = text;
|
||||||
msg->messageId = messageId++;
|
msg->messageId = messageId++;
|
||||||
msg->subsystem = "FDM";
|
msg->subsystem = "FDM";
|
||||||
|
@ -103,9 +103,9 @@ struct FGJSBBase::Message* FGJSBBase::PutMessage(string text)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
struct FGJSBBase::Message* FGJSBBase::PutMessage(string text, bool bVal)
|
FGJSBBase::Message* FGJSBBase::PutMessage(string text, bool bVal)
|
||||||
{
|
{
|
||||||
struct Message *msg = new Message();
|
Message *msg = new Message();
|
||||||
msg->text = text;
|
msg->text = text;
|
||||||
msg->messageId = messageId++;
|
msg->messageId = messageId++;
|
||||||
msg->subsystem = "FDM";
|
msg->subsystem = "FDM";
|
||||||
|
@ -117,9 +117,9 @@ struct FGJSBBase::Message* FGJSBBase::PutMessage(string text, bool bVal)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
struct FGJSBBase::Message* FGJSBBase::PutMessage(string text, int iVal)
|
FGJSBBase::Message* FGJSBBase::PutMessage(string text, int iVal)
|
||||||
{
|
{
|
||||||
struct Message *msg = new Message();
|
Message *msg = new Message();
|
||||||
msg->text = text;
|
msg->text = text;
|
||||||
msg->messageId = messageId++;
|
msg->messageId = messageId++;
|
||||||
msg->subsystem = "FDM";
|
msg->subsystem = "FDM";
|
||||||
|
@ -131,9 +131,9 @@ struct FGJSBBase::Message* FGJSBBase::PutMessage(string text, int iVal)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
struct FGJSBBase::Message* FGJSBBase::PutMessage(string text, double dVal)
|
FGJSBBase::Message* FGJSBBase::PutMessage(string text, double dVal)
|
||||||
{
|
{
|
||||||
struct Message *msg = new Message();
|
Message *msg = new Message();
|
||||||
msg->text = text;
|
msg->text = text;
|
||||||
msg->messageId = messageId++;
|
msg->messageId = messageId++;
|
||||||
msg->subsystem = "FDM";
|
msg->subsystem = "FDM";
|
||||||
|
@ -145,7 +145,7 @@ struct FGJSBBase::Message* FGJSBBase::PutMessage(string text, double dVal)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
struct FGJSBBase::Message* FGJSBBase::ReadMessage(void)
|
FGJSBBase::Message* FGJSBBase::ReadMessage(void)
|
||||||
{
|
{
|
||||||
if (!Messages.empty()) return Messages.front();
|
if (!Messages.empty()) return Messages.front();
|
||||||
else return NULL;
|
else return NULL;
|
||||||
|
@ -153,7 +153,7 @@ struct FGJSBBase::Message* FGJSBBase::ReadMessage(void)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
struct FGJSBBase::Message* FGJSBBase::ProcessMessage(void)
|
FGJSBBase::Message* FGJSBBase::ProcessMessage(void)
|
||||||
{
|
{
|
||||||
if (!Messages.empty())
|
if (!Messages.empty())
|
||||||
localMsg = *(Messages.front());
|
localMsg = *(Messages.front());
|
||||||
|
|
|
@ -165,7 +165,7 @@ public:
|
||||||
virtual ~FGJSBBase() {};
|
virtual ~FGJSBBase() {};
|
||||||
|
|
||||||
/// JSBSim Message structure
|
/// JSBSim Message structure
|
||||||
struct Message {
|
typedef struct Msg {
|
||||||
unsigned int fdmId;
|
unsigned int fdmId;
|
||||||
unsigned int messageId;
|
unsigned int messageId;
|
||||||
string text;
|
string text;
|
||||||
|
@ -174,7 +174,7 @@ public:
|
||||||
bool bVal;
|
bool bVal;
|
||||||
int iVal;
|
int iVal;
|
||||||
double dVal;
|
double dVal;
|
||||||
};
|
} Message;
|
||||||
|
|
||||||
///@name JSBSim Enums.
|
///@name JSBSim Enums.
|
||||||
//@{
|
//@{
|
||||||
|
@ -227,38 +227,38 @@ public:
|
||||||
/** Places a Message structure on the Message queue.
|
/** Places a Message structure on the Message queue.
|
||||||
@param msg pointer to a Message structure
|
@param msg pointer to a Message structure
|
||||||
@return pointer to a Message structure */
|
@return pointer to a Message structure */
|
||||||
struct Message* PutMessage(struct Message* msg);
|
Message* PutMessage(Message* msg);
|
||||||
/** Creates a message with the given text and places it on the queue.
|
/** Creates a message with the given text and places it on the queue.
|
||||||
@param text message text
|
@param text message text
|
||||||
@return pointer to a Message structure */
|
@return pointer to a Message structure */
|
||||||
struct Message* PutMessage(string text);
|
Message* PutMessage(string text);
|
||||||
/** Creates a message with the given text and boolean value and places it on the queue.
|
/** Creates a message with the given text and boolean value and places it on the queue.
|
||||||
@param text message text
|
@param text message text
|
||||||
@param bVal boolean value associated with the message
|
@param bVal boolean value associated with the message
|
||||||
@return pointer to a Message structure */
|
@return pointer to a Message structure */
|
||||||
struct Message* PutMessage(string text, bool bVal);
|
Message* PutMessage(string text, bool bVal);
|
||||||
/** Creates a message with the given text and integer value and places it on the queue.
|
/** Creates a message with the given text and integer value and places it on the queue.
|
||||||
@param text message text
|
@param text message text
|
||||||
@param iVal integer value associated with the message
|
@param iVal integer value associated with the message
|
||||||
@return pointer to a Message structure */
|
@return pointer to a Message structure */
|
||||||
struct Message* PutMessage(string text, int iVal);
|
Message* PutMessage(string text, int iVal);
|
||||||
/** Creates a message with the given text and double value and places it on the queue.
|
/** Creates a message with the given text and double value and places it on the queue.
|
||||||
@param text message text
|
@param text message text
|
||||||
@param dVal double value associated with the message
|
@param dVal double value associated with the message
|
||||||
@return pointer to a Message structure */
|
@return pointer to a Message structure */
|
||||||
struct Message* PutMessage(string text, double dVal);
|
Message* PutMessage(string text, double dVal);
|
||||||
/** Reads the message on the queue (but does not delete it).
|
/** Reads the message on the queue (but does not delete it).
|
||||||
@return pointer to a Message structure (or NULL if no mesage) */
|
@return pointer to a Message structure (or NULL if no mesage) */
|
||||||
struct Message* ReadMessage(void);
|
Message* ReadMessage(void);
|
||||||
/** Reads the message on the queue and removes it from the queue.
|
/** Reads the message on the queue and removes it from the queue.
|
||||||
@return pointer to a Message structure (or NULL if no mesage) */
|
@return pointer to a Message structure (or NULL if no mesage) */
|
||||||
struct Message* ProcessMessage(void);
|
Message* ProcessMessage(void);
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static struct Message localMsg;
|
static Message localMsg;
|
||||||
|
|
||||||
static queue <struct Message*> Messages;
|
static queue <Message*> Messages;
|
||||||
|
|
||||||
virtual void Debug(void) {};
|
virtual void Debug(void) {};
|
||||||
|
|
||||||
|
|
|
@ -148,8 +148,6 @@ void FGOutput::DelimitedOutput(string fname)
|
||||||
}
|
}
|
||||||
if (SubSystems & ssAerosurfaces) {
|
if (SubSystems & ssAerosurfaces) {
|
||||||
outstream << ", ";
|
outstream << ", ";
|
||||||
outstream << "Throttle, ";
|
|
||||||
outstream << "Mixture, ";
|
|
||||||
outstream << "Aileron Cmd, ";
|
outstream << "Aileron Cmd, ";
|
||||||
outstream << "Elevator Cmd, ";
|
outstream << "Elevator Cmd, ";
|
||||||
outstream << "Rudder Cmd, ";
|
outstream << "Rudder Cmd, ";
|
||||||
|
@ -224,8 +222,6 @@ void FGOutput::DelimitedOutput(string fname)
|
||||||
}
|
}
|
||||||
if (SubSystems & ssAerosurfaces) {
|
if (SubSystems & ssAerosurfaces) {
|
||||||
outstream << ", ";
|
outstream << ", ";
|
||||||
outstream << FCS->GetThrottlePos(0) << ", ";
|
|
||||||
outstream << FCS->GetMixturePos(0) << ", ";
|
|
||||||
outstream << FCS->GetDaCmd() << ", ";
|
outstream << FCS->GetDaCmd() << ", ";
|
||||||
outstream << FCS->GetDeCmd() << ", ";
|
outstream << FCS->GetDeCmd() << ", ";
|
||||||
outstream << FCS->GetDrCmd() << ", ";
|
outstream << FCS->GetDrCmd() << ", ";
|
||||||
|
@ -242,7 +238,7 @@ void FGOutput::DelimitedOutput(string fname)
|
||||||
outstream << Translation->Getqbar() << ", ";
|
outstream << Translation->Getqbar() << ", ";
|
||||||
outstream << Translation->GetVt() << ", ";
|
outstream << Translation->GetVt() << ", ";
|
||||||
outstream << Translation->GetUVW() << ", ";
|
outstream << Translation->GetUVW() << ", ";
|
||||||
outstream << Translation->GetvAero() << ", ";
|
outstream << Translation->GetvAeroUVW() << ", ";
|
||||||
outstream << Position->GetVel();
|
outstream << Position->GetVel();
|
||||||
}
|
}
|
||||||
if (SubSystems & ssForces) {
|
if (SubSystems & ssForces) {
|
||||||
|
@ -360,9 +356,9 @@ void FGOutput::SocketOutput(void)
|
||||||
socket->Append(Translation->GetUVW(eU));
|
socket->Append(Translation->GetUVW(eU));
|
||||||
socket->Append(Translation->GetUVW(eV));
|
socket->Append(Translation->GetUVW(eV));
|
||||||
socket->Append(Translation->GetUVW(eW));
|
socket->Append(Translation->GetUVW(eW));
|
||||||
socket->Append(Translation->GetvAero(eU));
|
socket->Append(Translation->GetvAeroUVW(eU));
|
||||||
socket->Append(Translation->GetvAero(eV));
|
socket->Append(Translation->GetvAeroUVW(eV));
|
||||||
socket->Append(Translation->GetvAero(eW));
|
socket->Append(Translation->GetvAeroUVW(eW));
|
||||||
socket->Append(Position->GetVn());
|
socket->Append(Position->GetVn());
|
||||||
socket->Append(Position->GetVe());
|
socket->Append(Position->GetVe());
|
||||||
socket->Append(Position->GetVd());
|
socket->Append(Position->GetVd());
|
||||||
|
|
|
@ -144,6 +144,7 @@ Notes: [TP] Make sure that -Vt <= hdot <= Vt, which, of course, should always
|
||||||
bool FGPosition::Run(void) {
|
bool FGPosition::Run(void) {
|
||||||
double cosLat;
|
double cosLat;
|
||||||
double hdot_Vt;
|
double hdot_Vt;
|
||||||
|
FGColumnVector3 vMac;
|
||||||
|
|
||||||
if (!FGModel::Run()) {
|
if (!FGModel::Run()) {
|
||||||
GetState();
|
GetState();
|
||||||
|
@ -171,7 +172,13 @@ bool FGPosition::Run(void) {
|
||||||
|
|
||||||
DistanceAGL = Radius - RunwayRadius; // Geocentric
|
DistanceAGL = Radius - RunwayRadius; // Geocentric
|
||||||
|
|
||||||
hoverb = DistanceAGL/b;
|
|
||||||
|
hoverbcg = DistanceAGL/b;
|
||||||
|
|
||||||
|
vMac=State->GetTb2l()*Aircraft->GetXYZrp();
|
||||||
|
|
||||||
|
vMac *= inchtoft;
|
||||||
|
hoverbmac = (DistanceAGL + vMac(3))/b;
|
||||||
|
|
||||||
if (Vt > 0) {
|
if (Vt > 0) {
|
||||||
hdot_Vt = RadiusDot/Vt;
|
hdot_Vt = RadiusDot/Vt;
|
||||||
|
@ -209,7 +216,7 @@ void FGPosition::Seth(double tt) {
|
||||||
h = tt;
|
h = tt;
|
||||||
Radius = h + SeaLevelRadius;
|
Radius = h + SeaLevelRadius;
|
||||||
DistanceAGL = Radius - RunwayRadius; // Geocentric
|
DistanceAGL = Radius - RunwayRadius; // Geocentric
|
||||||
hoverb = DistanceAGL/b;
|
hoverbcg = DistanceAGL/b;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -218,7 +225,7 @@ void FGPosition::SetDistanceAGL(double tt) {
|
||||||
DistanceAGL=tt;
|
DistanceAGL=tt;
|
||||||
Radius = RunwayRadius + DistanceAGL;
|
Radius = RunwayRadius + DistanceAGL;
|
||||||
h = Radius - SeaLevelRadius;
|
h = Radius - SeaLevelRadius;
|
||||||
hoverb = DistanceAGL/b;
|
hoverbcg = DistanceAGL/b;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
|
@ -105,7 +105,8 @@ public:
|
||||||
|
|
||||||
inline double GetGamma(void) { return gamma; }
|
inline double GetGamma(void) { return gamma; }
|
||||||
inline void SetGamma(double tt) { gamma = tt; }
|
inline void SetGamma(double tt) { gamma = tt; }
|
||||||
inline double GetHOverB(void) { return hoverb; }
|
inline double GetHOverBCG(void) { return hoverbcg; }
|
||||||
|
inline double GetHOverBMAC(void){ return hoverbmac; }
|
||||||
void SetvVel(const FGColumnVector3& v) { vVel = v; }
|
void SetvVel(const FGColumnVector3& v) { vVel = v; }
|
||||||
void SetLatitude(double tt) { Latitude = tt; }
|
void SetLatitude(double tt) { Latitude = tt; }
|
||||||
void SetLongitude(double tt) { Longitude = tt; }
|
void SetLongitude(double tt) { Longitude = tt; }
|
||||||
|
@ -133,7 +134,7 @@ private:
|
||||||
double SeaLevelRadius;
|
double SeaLevelRadius;
|
||||||
double gamma;
|
double gamma;
|
||||||
double Vt, Vground;
|
double Vt, Vground;
|
||||||
double hoverb,b;
|
double hoverbcg,hoverbmac,b;
|
||||||
|
|
||||||
double psigt;
|
double psigt;
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ FGPropeller::FGPropeller(FGFDMExec* exec, FGConfigFile* Prop_cfg) : FGThruster(e
|
||||||
string token;
|
string token;
|
||||||
int rows, cols;
|
int rows, cols;
|
||||||
|
|
||||||
MaxPitch = MinPitch = P_Factor = Sense = 0.0;
|
MaxPitch = MinPitch = P_Factor = Sense = Pitch = 0.0;
|
||||||
|
|
||||||
Name = Prop_cfg->GetValue("NAME");
|
Name = Prop_cfg->GetValue("NAME");
|
||||||
Prop_cfg->GetNextConfigLine();
|
Prop_cfg->GetNextConfigLine();
|
||||||
|
@ -138,7 +138,7 @@ FGPropeller::~FGPropeller()
|
||||||
double FGPropeller::Calculate(double PowerAvailable)
|
double FGPropeller::Calculate(double PowerAvailable)
|
||||||
{
|
{
|
||||||
double J, C_Thrust, omega;
|
double J, C_Thrust, omega;
|
||||||
double Vel = (fdmex->GetTranslation()->GetvAero())(1);
|
double Vel = fdmex->GetTranslation()->GetvAeroUVW(eU);
|
||||||
double rho = fdmex->GetAtmosphere()->GetDensity();
|
double rho = fdmex->GetAtmosphere()->GetDensity();
|
||||||
double RPS = RPM/60.0;
|
double RPS = RPM/60.0;
|
||||||
double alpha, beta;
|
double alpha, beta;
|
||||||
|
@ -194,7 +194,7 @@ double FGPropeller::GetPowerRequired(void)
|
||||||
|
|
||||||
double cPReq, RPS = RPM / 60.0;
|
double cPReq, RPS = RPM / 60.0;
|
||||||
|
|
||||||
double J = (fdmex->GetTranslation()->GetvAero())(1) / (Diameter * RPS);
|
double J = fdmex->GetTranslation()->GetvAeroUVW(eU) / (Diameter * RPS);
|
||||||
double rho = fdmex->GetAtmosphere()->GetDensity();
|
double rho = fdmex->GetAtmosphere()->GetDensity();
|
||||||
|
|
||||||
if (MaxPitch == MinPitch) { // Fixed pitch prop
|
if (MaxPitch == MinPitch) { // Fixed pitch prop
|
||||||
|
|
|
@ -62,14 +62,14 @@ CLASS IMPLEMENTATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
|
||||||
FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec)
|
FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec),
|
||||||
|
Forces(3),
|
||||||
|
Moments(3)
|
||||||
{
|
{
|
||||||
Name = "FGPropulsion";
|
Name = "FGPropulsion";
|
||||||
numSelectedFuelTanks = numSelectedOxiTanks = 0;
|
numSelectedFuelTanks = numSelectedOxiTanks = 0;
|
||||||
numTanks = numEngines = numThrusters = 0;
|
numTanks = numEngines = numThrusters = 0;
|
||||||
numOxiTanks = numFuelTanks = 0;
|
numOxiTanks = numFuelTanks = 0;
|
||||||
Forces = new FGColumnVector3(3);
|
|
||||||
Moments = new FGColumnVector3(3);
|
|
||||||
|
|
||||||
if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
|
if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
|
||||||
}
|
}
|
||||||
|
@ -80,8 +80,6 @@ FGPropulsion::~FGPropulsion()
|
||||||
{
|
{
|
||||||
for (unsigned int i=0; i<Engines.size(); i++) delete Engines[i];
|
for (unsigned int i=0; i<Engines.size(); i++) delete Engines[i];
|
||||||
Engines.clear();
|
Engines.clear();
|
||||||
if (Forces) delete Forces;
|
|
||||||
if (Moments) delete Moments;
|
|
||||||
if (debug_lvl & 2) cout << "Destroyed: FGPropulsion" << endl;
|
if (debug_lvl & 2) cout << "Destroyed: FGPropulsion" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,16 +90,16 @@ bool FGPropulsion::Run(void)
|
||||||
double PowerAvailable;
|
double PowerAvailable;
|
||||||
dt = State->Getdt();
|
dt = State->Getdt();
|
||||||
|
|
||||||
Forces->InitMatrix();
|
Forces.InitMatrix();
|
||||||
Moments->InitMatrix();
|
Moments.InitMatrix();
|
||||||
|
|
||||||
if (!FGModel::Run()) {
|
if (!FGModel::Run()) {
|
||||||
for (unsigned int i=0; i<numEngines; i++) {
|
for (unsigned int i=0; i<numEngines; i++) {
|
||||||
Thrusters[i]->SetdeltaT(dt*rate);
|
Thrusters[i]->SetdeltaT(dt*rate);
|
||||||
PowerAvailable = Engines[i]->Calculate(Thrusters[i]->GetPowerRequired());
|
PowerAvailable = Engines[i]->Calculate(Thrusters[i]->GetPowerRequired());
|
||||||
Thrusters[i]->Calculate(PowerAvailable);
|
Thrusters[i]->Calculate(PowerAvailable);
|
||||||
*Forces += Thrusters[i]->GetBodyForces(); // sum body frame forces
|
Forces += Thrusters[i]->GetBodyForces(); // sum body frame forces
|
||||||
*Moments += Thrusters[i]->GetMoments(); // sum body frame moments
|
Moments += Thrusters[i]->GetMoments(); // sum body frame moments
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -111,15 +109,16 @@ bool FGPropulsion::Run(void)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
bool FGPropulsion::GetSteadyState(void) {
|
bool FGPropulsion::GetSteadyState(void)
|
||||||
|
{
|
||||||
double PowerAvailable;
|
double PowerAvailable;
|
||||||
double currentThrust = 0, lastThrust=-1;
|
double currentThrust = 0, lastThrust=-1;
|
||||||
dt = State->Getdt();
|
dt = State->Getdt();
|
||||||
int steady_count,j=0;
|
int steady_count,j=0;
|
||||||
bool steady=false;
|
bool steady=false;
|
||||||
|
|
||||||
Forces->InitMatrix();
|
Forces.InitMatrix();
|
||||||
Moments->InitMatrix();
|
Moments.InitMatrix();
|
||||||
|
|
||||||
if (!FGModel::Run()) {
|
if (!FGModel::Run()) {
|
||||||
for (unsigned int i=0; i<numEngines; i++) {
|
for (unsigned int i=0; i<numEngines; i++) {
|
||||||
|
@ -138,8 +137,8 @@ bool FGPropulsion::GetSteadyState(void) {
|
||||||
}
|
}
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
*Forces += Thrusters[i]->GetBodyForces(); // sum body frame forces
|
Forces += Thrusters[i]->GetBodyForces(); // sum body frame forces
|
||||||
*Moments += Thrusters[i]->GetMoments(); // sum body frame moments
|
Moments += Thrusters[i]->GetMoments(); // sum body frame moments
|
||||||
Engines[i]->SetTrimMode(false);
|
Engines[i]->SetTrimMode(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,13 +151,14 @@ bool FGPropulsion::GetSteadyState(void) {
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
|
||||||
bool FGPropulsion::ICEngineStart(void) {
|
bool FGPropulsion::ICEngineStart(void)
|
||||||
|
{
|
||||||
double PowerAvailable;
|
double PowerAvailable;
|
||||||
int j;
|
int j;
|
||||||
dt = State->Getdt();
|
dt = State->Getdt();
|
||||||
|
|
||||||
Forces->InitMatrix();
|
Forces.InitMatrix();
|
||||||
Moments->InitMatrix();
|
Moments.InitMatrix();
|
||||||
|
|
||||||
for (unsigned int i=0; i<numEngines; i++) {
|
for (unsigned int i=0; i<numEngines; i++) {
|
||||||
Engines[i]->SetTrimMode(true);
|
Engines[i]->SetTrimMode(true);
|
||||||
|
@ -169,8 +169,8 @@ bool FGPropulsion::ICEngineStart(void) {
|
||||||
Thrusters[i]->Calculate(PowerAvailable);
|
Thrusters[i]->Calculate(PowerAvailable);
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
*Forces += Thrusters[i]->GetBodyForces(); // sum body frame forces
|
Forces += Thrusters[i]->GetBodyForces(); // sum body frame forces
|
||||||
*Moments += Thrusters[i]->GetMoments(); // sum body frame moments
|
Moments += Thrusters[i]->GetMoments(); // sum body frame moments
|
||||||
Engines[i]->SetTrimMode(false);
|
Engines[i]->SetTrimMode(false);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -254,6 +254,7 @@ bool FGPropulsion::Load(FGConfigFile* AC_cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
Engines[numEngines]->SetPlacement(xLoc, yLoc, zLoc, Pitch, Yaw);
|
Engines[numEngines]->SetPlacement(xLoc, yLoc, zLoc, Pitch, Yaw);
|
||||||
|
Engines[numEngines]->SetEngineNumber(numEngines);
|
||||||
numEngines++;
|
numEngines++;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -406,7 +407,7 @@ string FGPropulsion::GetPropulsionValues(void)
|
||||||
|
|
||||||
switch(Engines[i]->GetType()) {
|
switch(Engines[i]->GetType()) {
|
||||||
case FGEngine::etPiston:
|
case FGEngine::etPiston:
|
||||||
PropulsionValues += (string(gcvt(((FGRocket*)Engines[i])->GetPowerAvailable(), 10, buff)));
|
PropulsionValues += (string(gcvt(((FGPiston*)Engines[i])->GetPowerAvailable(), 10, buff)));
|
||||||
break;
|
break;
|
||||||
case FGEngine::etRocket:
|
case FGEngine::etRocket:
|
||||||
PropulsionValues += (string(gcvt(((FGRocket*)Engines[i])->GetChamberPressure(), 10, buff)));
|
PropulsionValues += (string(gcvt(((FGRocket*)Engines[i])->GetChamberPressure(), 10, buff)));
|
||||||
|
|
|
@ -168,10 +168,10 @@ public:
|
||||||
string GetPropulsionStrings(void);
|
string GetPropulsionStrings(void);
|
||||||
string GetPropulsionValues(void);
|
string GetPropulsionValues(void);
|
||||||
|
|
||||||
inline FGColumnVector3& GetForces(void) {return *Forces; }
|
inline FGColumnVector3& GetForces(void) {return Forces; }
|
||||||
inline double GetForces(int n) { return (*Forces)(n);}
|
inline double GetForces(int n) { return Forces(n);}
|
||||||
inline FGColumnVector3& GetMoments(void) {return *Moments;}
|
inline FGColumnVector3& GetMoments(void) {return Moments;}
|
||||||
inline double GetMoments(int n) {return (*Moments)(n);}
|
inline double GetMoments(int n) {return Moments(n);}
|
||||||
|
|
||||||
FGColumnVector3& GetTanksCG(void);
|
FGColumnVector3& GetTanksCG(void);
|
||||||
double GetTanksWeight(void);
|
double GetTanksWeight(void);
|
||||||
|
@ -195,8 +195,8 @@ private:
|
||||||
unsigned int numTanks;
|
unsigned int numTanks;
|
||||||
unsigned int numThrusters;
|
unsigned int numThrusters;
|
||||||
double dt;
|
double dt;
|
||||||
FGColumnVector3 *Forces;
|
FGColumnVector3 Forces;
|
||||||
FGColumnVector3 *Moments;
|
FGColumnVector3 Moments;
|
||||||
FGColumnVector3 vXYZtank;
|
FGColumnVector3 vXYZtank;
|
||||||
void Debug(void);
|
void Debug(void);
|
||||||
};
|
};
|
||||||
|
|
|
@ -81,7 +81,8 @@ FGRotation::FGRotation(FGFDMExec* fdmex) : FGModel(fdmex),
|
||||||
vMoments(3),
|
vMoments(3),
|
||||||
vEuler(3),
|
vEuler(3),
|
||||||
vEulerRates(3),
|
vEulerRates(3),
|
||||||
vlastPQRdot(3)
|
vlastPQRdot(3),
|
||||||
|
vAeroPQR(3)
|
||||||
{
|
{
|
||||||
Name = "FGRotation";
|
Name = "FGRotation";
|
||||||
cTht=cPhi=cPsi=1.0;
|
cTht=cPhi=cPsi=1.0;
|
||||||
|
@ -115,6 +116,7 @@ bool FGRotation::Run(void)
|
||||||
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 += dt*rate*(vlastPQRdot + vPQRdot)/2.0;
|
||||||
|
vAeroPQR = vPQR + Atmosphere->GetTurbPQR();
|
||||||
|
|
||||||
State->IntegrateQuat(vPQR, rate);
|
State->IntegrateQuat(vPQR, rate);
|
||||||
State->CalcMatrices();
|
State->CalcMatrices();
|
||||||
|
|
|
@ -88,6 +88,8 @@ public:
|
||||||
|
|
||||||
inline FGColumnVector3& GetPQR(void) {return vPQR;}
|
inline FGColumnVector3& GetPQR(void) {return vPQR;}
|
||||||
inline double GetPQR(int axis) {return vPQR(axis);}
|
inline double GetPQR(int axis) {return vPQR(axis);}
|
||||||
|
inline FGColumnVector3& GetAeroPQR(void) {return vAeroPQR;}
|
||||||
|
inline double GetAeroPQR(int axis) {return vAeroPQR(axis);}
|
||||||
inline FGColumnVector3& GetPQRdot(void) {return vPQRdot;}
|
inline FGColumnVector3& GetPQRdot(void) {return vPQRdot;}
|
||||||
inline double GetPQRdot(int idx) {return vPQRdot(idx);}
|
inline double GetPQRdot(int idx) {return vPQRdot(idx);}
|
||||||
inline FGColumnVector3& GetEuler(void) {return vEuler;}
|
inline FGColumnVector3& GetEuler(void) {return vEuler;}
|
||||||
|
@ -111,6 +113,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FGColumnVector3 vPQR;
|
FGColumnVector3 vPQR;
|
||||||
|
FGColumnVector3 vAeroPQR;
|
||||||
FGColumnVector3 vPQRdot;
|
FGColumnVector3 vPQRdot;
|
||||||
FGColumnVector3 vMoments;
|
FGColumnVector3 vMoments;
|
||||||
FGColumnVector3 vEuler;
|
FGColumnVector3 vEuler;
|
||||||
|
|
|
@ -76,6 +76,7 @@ CLASS IMPLEMENTATION
|
||||||
FGState::FGState(FGFDMExec* fdex) : mTb2l(3,3),
|
FGState::FGState(FGFDMExec* fdex) : mTb2l(3,3),
|
||||||
mTl2b(3,3),
|
mTl2b(3,3),
|
||||||
mTs2b(3,3),
|
mTs2b(3,3),
|
||||||
|
mTb2s(3,3),
|
||||||
vQtrn(4),
|
vQtrn(4),
|
||||||
vlastQdot(4),
|
vlastQdot(4),
|
||||||
vQdot(4),
|
vQdot(4),
|
||||||
|
@ -223,12 +224,12 @@ double FGState::GetParameter(eParam val_idx) {
|
||||||
return Rotation->GetPQR(eP);
|
return Rotation->GetPQR(eP);
|
||||||
case FG_YAWRATE:
|
case FG_YAWRATE:
|
||||||
return Rotation->GetPQR(eR);
|
return Rotation->GetPQR(eR);
|
||||||
case FG_AEROQ:
|
|
||||||
return Rotation->GetPQR(eQ) + Atmosphere->GetTurbPQR(eQ); // add aero turbulence effects
|
|
||||||
case FG_AEROP:
|
case FG_AEROP:
|
||||||
return Rotation->GetPQR(eP) + Atmosphere->GetTurbPQR(eP); // add aero turbulence effects
|
return Rotation->GetAeroPQR(eP);
|
||||||
|
case FG_AEROQ:
|
||||||
|
return Rotation->GetAeroPQR(eQ);
|
||||||
case FG_AEROR:
|
case FG_AEROR:
|
||||||
return Rotation->GetPQR(eR) + Atmosphere->GetTurbPQR(eR); // add aero turbulence effects
|
return Rotation->GetAeroPQR(eR);
|
||||||
case FG_CL_SQRD:
|
case FG_CL_SQRD:
|
||||||
if (Translation->Getqbar() > 0.00)
|
if (Translation->Getqbar() > 0.00)
|
||||||
scratch = Aerodynamics->GetvLastFs(eLift)/(Aircraft->GetWingArea()*Translation->Getqbar());
|
scratch = Aerodynamics->GetvLastFs(eLift)/(Aircraft->GetWingArea()*Translation->Getqbar());
|
||||||
|
@ -297,7 +298,7 @@ double FGState::GetParameter(eParam val_idx) {
|
||||||
if (ActiveEngine < 0) return FCS->GetMixturePos(0);
|
if (ActiveEngine < 0) return FCS->GetMixturePos(0);
|
||||||
else return FCS->GetMixturePos(ActiveEngine);
|
else return FCS->GetMixturePos(ActiveEngine);
|
||||||
case FG_HOVERB:
|
case FG_HOVERB:
|
||||||
return Position->GetHOverB();
|
return Position->GetHOverBMAC();
|
||||||
case FG_PITCH_TRIM_CMD:
|
case FG_PITCH_TRIM_CMD:
|
||||||
return FCS->GetPitchTrimCmd();
|
return FCS->GetPitchTrimCmd();
|
||||||
default:
|
default:
|
||||||
|
@ -432,7 +433,7 @@ bool FGState::Reset(string path, string acname, string fname)
|
||||||
|
|
||||||
resetfile.GetNextConfigLine();
|
resetfile.GetNextConfigLine();
|
||||||
token = resetfile.GetValue();
|
token = resetfile.GetValue();
|
||||||
if (token != "initialize") {
|
if (token != string("initialize")) {
|
||||||
cerr << "The reset file " << resetDef
|
cerr << "The reset file " << resetDef
|
||||||
<< " does not appear to be a reset file" << endl;
|
<< " does not appear to be a reset file" << endl;
|
||||||
return false;
|
return false;
|
||||||
|
@ -440,7 +441,7 @@ bool FGState::Reset(string path, string acname, string fname)
|
||||||
|
|
||||||
resetfile.GetNextConfigLine();
|
resetfile.GetNextConfigLine();
|
||||||
resetfile >> token;
|
resetfile >> token;
|
||||||
while (token != "/initialize" && token != "EOF") {
|
while (token != string("/initialize") && token != string("EOF")) {
|
||||||
if (token == "UBODY") resetfile >> U;
|
if (token == "UBODY") resetfile >> U;
|
||||||
if (token == "VBODY") resetfile >> V;
|
if (token == "VBODY") resetfile >> V;
|
||||||
if (token == "WBODY") resetfile >> W;
|
if (token == "WBODY") resetfile >> W;
|
||||||
|
@ -482,7 +483,7 @@ void FGState::Initialize(double U, double V, double W,
|
||||||
{
|
{
|
||||||
double alpha, beta;
|
double alpha, beta;
|
||||||
double qbar, Vt;
|
double qbar, Vt;
|
||||||
FGColumnVector3 vAero;
|
FGColumnVector3 vAeroUVW;
|
||||||
|
|
||||||
Position->SetLatitude(Latitude);
|
Position->SetLatitude(Latitude);
|
||||||
Position->SetLongitude(Longitude);
|
Position->SetLongitude(Longitude);
|
||||||
|
@ -500,14 +501,14 @@ void FGState::Initialize(double U, double V, double W,
|
||||||
|
|
||||||
Atmosphere->SetWindNED(wnorth, weast, wdown);
|
Atmosphere->SetWindNED(wnorth, weast, wdown);
|
||||||
|
|
||||||
vAero = vUVW + mTl2b*Atmosphere->GetWindNED();
|
vAeroUVW = vUVW + mTl2b*Atmosphere->GetWindNED();
|
||||||
|
|
||||||
if (vAero(eW) != 0.0)
|
if (vAeroUVW(eW) != 0.0)
|
||||||
alpha = vAero(eU)*vAero(eU) > 0.0 ? atan2(vAero(eW), vAero(eU)) : 0.0;
|
alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0;
|
||||||
else
|
else
|
||||||
alpha = 0.0;
|
alpha = 0.0;
|
||||||
if (vAero(eV) != 0.0)
|
if (vAeroUVW(eV) != 0.0)
|
||||||
beta = vAero(eU)*vAero(eU)+vAero(eW)*vAero(eW) > 0.0 ? atan2(vAero(eV), (fabs(vAero(eU))/vAero(eU))*sqrt(vAero(eU)*vAero(eU) + vAero(eW)*vAero(eW))) : 0.0;
|
beta = vAeroUVW(eU)*vAeroUVW(eU)+vAeroUVW(eW)*vAeroUVW(eW) > 0.0 ? atan2(vAeroUVW(eV), (fabs(vAeroUVW(eU))/vAeroUVW(eU))*sqrt(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW))) : 0.0;
|
||||||
else
|
else
|
||||||
beta = 0.0;
|
beta = 0.0;
|
||||||
|
|
||||||
|
@ -689,19 +690,46 @@ FGMatrix33& FGState::GetTs2b(void)
|
||||||
cb = cos(beta);
|
cb = cos(beta);
|
||||||
sb = sin(beta);
|
sb = sin(beta);
|
||||||
|
|
||||||
mTs2b(1,1) = -ca*cb;
|
mTs2b(1,1) = ca*cb;
|
||||||
mTs2b(1,2) = -ca*sb;
|
mTs2b(1,2) = -ca*sb;
|
||||||
mTs2b(1,3) = sa;
|
mTs2b(1,3) = -sa;
|
||||||
mTs2b(2,1) = -sb;
|
mTs2b(2,1) = sb;
|
||||||
mTs2b(2,2) = cb;
|
mTs2b(2,2) = cb;
|
||||||
mTs2b(2,3) = 0.0;
|
mTs2b(2,3) = 0.0;
|
||||||
mTs2b(3,1) = -sa*cb;
|
mTs2b(3,1) = sa*cb;
|
||||||
mTs2b(3,2) = -sa*sb;
|
mTs2b(3,2) = -sa*sb;
|
||||||
mTs2b(3,3) = -ca;
|
mTs2b(3,3) = ca;
|
||||||
|
|
||||||
return mTs2b;
|
return mTs2b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
FGMatrix33& FGState::GetTb2s(void)
|
||||||
|
{
|
||||||
|
float alpha,beta;
|
||||||
|
float ca, cb, sa, sb;
|
||||||
|
|
||||||
|
alpha = Translation->Getalpha();
|
||||||
|
beta = Translation->Getbeta();
|
||||||
|
|
||||||
|
ca = cos(alpha);
|
||||||
|
sa = sin(alpha);
|
||||||
|
cb = cos(beta);
|
||||||
|
sb = sin(beta);
|
||||||
|
|
||||||
|
mTb2s(1,1) = ca*cb;
|
||||||
|
mTb2s(1,2) = sb;
|
||||||
|
mTb2s(1,3) = sa*cb;
|
||||||
|
mTb2s(2,1) = -ca*sb;
|
||||||
|
mTb2s(2,2) = cb;
|
||||||
|
mTb2s(2,3) = -sa*sb;
|
||||||
|
mTb2s(3,1) = -sa;
|
||||||
|
mTb2s(3,2) = 0.0;
|
||||||
|
mTb2s(3,3) = ca;
|
||||||
|
|
||||||
|
return mTb2s;
|
||||||
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
@ -742,7 +770,7 @@ void FGState::ReportState(void) {
|
||||||
Position->Gethdot()*60 );
|
Position->Gethdot()*60 );
|
||||||
cout << out;
|
cout << out;
|
||||||
snprintf(out,80, " Normal Load Factor: %4.2f g's Pitch Rate: %5.2f deg/s\n",
|
snprintf(out,80, " Normal Load Factor: %4.2f g's Pitch Rate: %5.2f deg/s\n",
|
||||||
Aerodynamics->GetNlf(),
|
Aircraft->GetNlf(),
|
||||||
GetParameter(FG_PITCHRATE)*radtodeg );
|
GetParameter(FG_PITCHRATE)*radtodeg );
|
||||||
cout << out;
|
cout << out;
|
||||||
snprintf(out,80, " Heading: %3.0f deg true Sideslip: %5.2f deg\n",
|
snprintf(out,80, " Heading: %3.0f deg true Sideslip: %5.2f deg\n",
|
||||||
|
|
|
@ -269,6 +269,11 @@ public:
|
||||||
*/
|
*/
|
||||||
FGMatrix33& GetTs2b(void);
|
FGMatrix33& GetTs2b(void);
|
||||||
|
|
||||||
|
/** Calculates and returns the body-to-stability axis transformation matrix.
|
||||||
|
@return a reference to the stability-to-body transformation matrix.
|
||||||
|
*/
|
||||||
|
FGMatrix33& GetTb2s(void);
|
||||||
|
|
||||||
/** Retrieves the local-to-body transformation matrix.
|
/** Retrieves the local-to-body transformation matrix.
|
||||||
@return a reference to the local-to-body transformation matrix.
|
@return a reference to the local-to-body transformation matrix.
|
||||||
*/
|
*/
|
||||||
|
@ -311,6 +316,7 @@ private:
|
||||||
FGMatrix33 mTb2l;
|
FGMatrix33 mTb2l;
|
||||||
FGMatrix33 mTl2b;
|
FGMatrix33 mTl2b;
|
||||||
FGMatrix33 mTs2b;
|
FGMatrix33 mTs2b;
|
||||||
|
FGMatrix33 mTb2s;
|
||||||
FGColumnVector4 vQtrn;
|
FGColumnVector4 vQtrn;
|
||||||
FGColumnVector4 vlastQdot;
|
FGColumnVector4 vlastQdot;
|
||||||
FGColumnVector3 vUVW;
|
FGColumnVector3 vUVW;
|
||||||
|
|
|
@ -82,7 +82,7 @@ FGTranslation::FGTranslation(FGFDMExec* fdmex) : FGModel(fdmex),
|
||||||
vUVWdot(3),
|
vUVWdot(3),
|
||||||
vlastUVWdot(3),
|
vlastUVWdot(3),
|
||||||
mVel(3,3),
|
mVel(3,3),
|
||||||
vAero(3)
|
vAeroUVW(3)
|
||||||
{
|
{
|
||||||
Name = "FGTranslation";
|
Name = "FGTranslation";
|
||||||
qbar = 0;
|
qbar = 0;
|
||||||
|
@ -122,29 +122,29 @@ bool FGTranslation::Run(void)
|
||||||
vUVWdot = mVel*Rotation->GetPQR() + Aircraft->GetBodyAccel();
|
vUVWdot = mVel*Rotation->GetPQR() + Aircraft->GetBodyAccel();
|
||||||
|
|
||||||
vUVW += Tc * (vlastUVWdot + vUVWdot);
|
vUVW += Tc * (vlastUVWdot + vUVWdot);
|
||||||
vAero = vUVW + State->GetTl2b()*Atmosphere->GetWindNED();
|
vAeroUVW = vUVW + State->GetTl2b()*Atmosphere->GetWindNED();
|
||||||
|
|
||||||
Vt = vAero.Magnitude();
|
Vt = vAeroUVW.Magnitude();
|
||||||
if ( Vt > 1) {
|
if ( Vt > 1) {
|
||||||
if (vAero(eW) != 0.0)
|
if (vAeroUVW(eW) != 0.0)
|
||||||
alpha = vAero(eU)*vAero(eU) > 0.0 ? atan2(vAero(eW), vAero(eU)) : 0.0;
|
alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0;
|
||||||
if (vAero(eV) != 0.0)
|
if (vAeroUVW(eV) != 0.0)
|
||||||
beta = vAero(eU)*vAero(eU)+vAero(eW)*vAero(eW) > 0.0 ? atan2(vAero(eV),
|
beta = vAeroUVW(eU)*vAeroUVW(eU)+vAeroUVW(eW)*vAeroUVW(eW) > 0.0 ? atan2(vAeroUVW(eV),
|
||||||
sqrt(vAero(eU)*vAero(eU) + vAero(eW)*vAero(eW))) : 0.0;
|
sqrt(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW))) : 0.0;
|
||||||
|
|
||||||
// stolen, quite shamelessly, from LaRCsim
|
// stolen, quite shamelessly, from LaRCsim
|
||||||
double mUW = (vAero(eU)*vAero(eU) + vAero(eW)*vAero(eW));
|
double mUW = (vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW));
|
||||||
double signU=1;
|
double signU=1;
|
||||||
if (vAero(eU) != 0.0)
|
if (vAeroUVW(eU) != 0.0)
|
||||||
signU = vAero(eU)/fabs(vAero(eU));
|
signU = vAeroUVW(eU)/fabs(vAeroUVW(eU));
|
||||||
|
|
||||||
if ( (mUW == 0.0) || (Vt == 0.0) ) {
|
if ( (mUW == 0.0) || (Vt == 0.0) ) {
|
||||||
adot = 0.0;
|
adot = 0.0;
|
||||||
bdot = 0.0;
|
bdot = 0.0;
|
||||||
} else {
|
} else {
|
||||||
adot = (vAero(eU)*vAero(eW) - vAero(eW)*vUVWdot(eU))/mUW;
|
adot = (vAeroUVW(eU)*vAeroUVW(eW) - vAeroUVW(eW)*vUVWdot(eU))/mUW;
|
||||||
bdot = (signU*mUW*vUVWdot(eV) - vAero(eV)*(vAero(eU)*vUVWdot(eU)
|
bdot = (signU*mUW*vUVWdot(eV) - vAeroUVW(eV)*(vAeroUVW(eU)*vUVWdot(eU)
|
||||||
+ vAero(eW)*vUVWdot(eW)))/(Vt*Vt*sqrt(mUW));
|
+ vAeroUVW(eW)*vUVWdot(eW)))/(Vt*Vt*sqrt(mUW));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alpha = beta = adot = bdot = 0;
|
alpha = beta = adot = bdot = 0;
|
||||||
|
|
|
@ -91,8 +91,8 @@ public:
|
||||||
inline double GetUVW (int idx) { return vUVW(idx); }
|
inline double GetUVW (int idx) { return vUVW(idx); }
|
||||||
inline FGColumnVector3& GetUVWdot(void) { return vUVWdot; }
|
inline FGColumnVector3& GetUVWdot(void) { return vUVWdot; }
|
||||||
inline double GetUVWdot(int idx) { return vUVWdot(idx); }
|
inline double GetUVWdot(int idx) { return vUVWdot(idx); }
|
||||||
inline FGColumnVector3& GetvAero (void) { return vAero; }
|
inline FGColumnVector3& GetvAeroUVW (void) { return vAeroUVW; }
|
||||||
inline double GetvAero (int idx) { return vAero(idx); }
|
inline double GetvAeroUVW (int idx) { return vAeroUVW(idx); }
|
||||||
|
|
||||||
inline double Getalpha(void) { return alpha; }
|
inline double Getalpha(void) { return alpha; }
|
||||||
inline double Getbeta (void) { return beta; }
|
inline double Getbeta (void) { return beta; }
|
||||||
|
@ -121,7 +121,7 @@ private:
|
||||||
FGColumnVector3 vUVWdot;
|
FGColumnVector3 vUVWdot;
|
||||||
FGColumnVector3 vlastUVWdot;
|
FGColumnVector3 vlastUVWdot;
|
||||||
FGMatrix33 mVel;
|
FGMatrix33 mVel;
|
||||||
FGColumnVector3 vAero;
|
FGColumnVector3 vAeroUVW;
|
||||||
|
|
||||||
double Vt, qbar, Mach;
|
double Vt, qbar, Mach;
|
||||||
double dt;
|
double dt;
|
||||||
|
|
|
@ -53,6 +53,7 @@ INCLUDES
|
||||||
#include "FGAircraft.h"
|
#include "FGAircraft.h"
|
||||||
#include "FGMassBalance.h"
|
#include "FGMassBalance.h"
|
||||||
#include "FGAerodynamics.h"
|
#include "FGAerodynamics.h"
|
||||||
|
#include "FGColumnVector3.h"
|
||||||
#if _MSC_VER
|
#if _MSC_VER
|
||||||
#pragma warning (disable : 4786 4788)
|
#pragma warning (disable : 4786 4788)
|
||||||
#endif
|
#endif
|
||||||
|
@ -70,7 +71,7 @@ FGTrim::FGTrim(FGFDMExec *FDMExec,FGInitialCondition *FGIC, TrimMode tt ) {
|
||||||
Tolerance=1E-3;
|
Tolerance=1E-3;
|
||||||
A_Tolerance = Tolerance / 10;
|
A_Tolerance = Tolerance / 10;
|
||||||
|
|
||||||
Debug=0;
|
Debug=0;DebugLevel=0;
|
||||||
fdmex=FDMExec;
|
fdmex=FDMExec;
|
||||||
fgic=FGIC;
|
fgic=FGIC;
|
||||||
total_its=0;
|
total_its=0;
|
||||||
|
@ -79,6 +80,8 @@ FGTrim::FGTrim(FGFDMExec *FDMExec,FGInitialCondition *FGIC, TrimMode tt ) {
|
||||||
axis_count=0;
|
axis_count=0;
|
||||||
mode=tt;
|
mode=tt;
|
||||||
xlo=xhi=alo=ahi;
|
xlo=xhi=alo=ahi;
|
||||||
|
targetNlf=1.0;
|
||||||
|
debug_axis=tAll;
|
||||||
switch(mode) {
|
switch(mode) {
|
||||||
case tFull:
|
case tFull:
|
||||||
cout << " Full Trim" << endl;
|
cout << " Full Trim" << endl;
|
||||||
|
@ -102,6 +105,24 @@ FGTrim::FGTrim(FGFDMExec *FDMExec,FGInitialCondition *FGIC, TrimMode tt ) {
|
||||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tTheta ));
|
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tTheta ));
|
||||||
//TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tPhi ));
|
//TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tPhi ));
|
||||||
break;
|
break;
|
||||||
|
case tPullup:
|
||||||
|
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tNlf,tAlpha ));
|
||||||
|
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle ));
|
||||||
|
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim ));
|
||||||
|
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tHmgt,tBeta ));
|
||||||
|
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tVdot,tPhi ));
|
||||||
|
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tAileron ));
|
||||||
|
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tRdot,tRudder ));
|
||||||
|
break;
|
||||||
|
case tTurn:
|
||||||
|
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tNlf,tAlpha ));
|
||||||
|
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle ));
|
||||||
|
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim ));
|
||||||
|
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tVdot,tBeta ));
|
||||||
|
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tPdot,tAileron ));
|
||||||
|
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tRdot,tRudder ));
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
//cout << "TrimAxes.size(): " << TrimAxes.size() << endl;
|
//cout << "TrimAxes.size(): " << TrimAxes.size() << endl;
|
||||||
sub_iterations=new double[TrimAxes.size()];
|
sub_iterations=new double[TrimAxes.size()];
|
||||||
|
@ -281,9 +302,24 @@ bool FGTrim::DoTrim(void) {
|
||||||
successful[current_axis]=0;
|
successful[current_axis]=0;
|
||||||
solution[current_axis]=false;
|
solution[current_axis]=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(mode == tPullup ) {
|
||||||
|
cout << "Setting pitch rate and nlf... " << endl;
|
||||||
|
setupPullup();
|
||||||
|
cout << "pitch rate done ... " << endl;
|
||||||
|
TrimAxes[0]->SetStateTarget(targetNlf);
|
||||||
|
cout << "nlf done" << endl;
|
||||||
|
} else if (mode == tTurn) {
|
||||||
|
setupTurn();
|
||||||
|
TrimAxes[0]->SetStateTarget(targetNlf);
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
axis_count=0;
|
axis_count=0;
|
||||||
for(current_axis=0;current_axis<TrimAxes.size();current_axis++) {
|
for(current_axis=0;current_axis<TrimAxes.size();current_axis++) {
|
||||||
|
setDebug();
|
||||||
|
|
||||||
Nsub=0;
|
Nsub=0;
|
||||||
if(!solution[current_axis]) {
|
if(!solution[current_axis]) {
|
||||||
if(checkLimits()) {
|
if(checkLimits()) {
|
||||||
|
@ -550,5 +586,50 @@ bool FGTrim::checkLimits(void) {
|
||||||
return solutionExists;
|
return solutionExists;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FGTrim::setupPullup() {
|
||||||
|
float g,q,cgamma;
|
||||||
|
FGColumnVector3 vPQR;
|
||||||
|
g=fdmex->GetInertial()->gravity();
|
||||||
|
cgamma=cos(fgic->GetFlightPathAngleRadIC());
|
||||||
|
cout << "setPitchRateInPullup(): " << g << ", " << cgamma << ", "
|
||||||
|
<< fgic->GetVtrueFpsIC() << endl;
|
||||||
|
q=g*(targetNlf-cgamma)/fgic->GetVtrueFpsIC();
|
||||||
|
cout << targetNlf << ", " << q << endl;
|
||||||
|
vPQR.InitMatrix();
|
||||||
|
vPQR(2)=q;
|
||||||
|
cout << vPQR << endl;
|
||||||
|
fdmex->GetRotation()->SetPQR(vPQR);
|
||||||
|
cout << "setPitchRateInPullup() complete" << endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FGTrim::setupTurn(void){
|
||||||
|
FGColumnVector3 vPQR;
|
||||||
|
float g,q,r,phi, psidot;
|
||||||
|
phi = fgic->GetRollAngleRadIC();
|
||||||
|
if( fabs(phi) > 0.01 && fabs(phi) < 1.56 ) {
|
||||||
|
targetNlf = 1 / cos(phi);
|
||||||
|
g = fdmex->GetInertial()->gravity();
|
||||||
|
psidot = g*tan(phi) / fgic->GetVtrueFpsIC();
|
||||||
|
q = psidot*sin(phi);
|
||||||
|
r = psidot*cos(phi);
|
||||||
|
vPQR(1)=0;vPQR(2)=q;vPQR(3)=r;
|
||||||
|
fdmex->GetRotation()->SetPQR(vPQR);
|
||||||
|
cout << targetNlf << ", " << vPQR*57.29577 << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FGTrim::setDebug(void) {
|
||||||
|
if(debug_axis == tAll ||
|
||||||
|
TrimAxes[current_axis]->GetStateType() == debug_axis ) {
|
||||||
|
Debug=DebugLevel;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
Debug=0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//YOU WERE WARNED, BUT YOU DID IT ANYWAY.
|
//YOU WERE WARNED, BUT YOU DID IT ANYWAY.
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,9 @@ DEFINITIONS
|
||||||
|
|
||||||
#define ID_TRIM "$Id$"
|
#define ID_TRIM "$Id$"
|
||||||
|
|
||||||
typedef enum { tLongitudinal, tFull, tGround, tCustom, tNone } TrimMode;
|
typedef enum { tLongitudinal, tFull, tGround, tPullup,
|
||||||
|
tCustom, tNone, tTurn
|
||||||
|
} TrimMode;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
|
@ -148,7 +150,7 @@ private:
|
||||||
int current_axis;
|
int current_axis;
|
||||||
int N, Nsub;
|
int N, Nsub;
|
||||||
TrimMode mode;
|
TrimMode mode;
|
||||||
int Debug;
|
int DebugLevel, Debug;
|
||||||
double Tolerance, A_Tolerance;
|
double Tolerance, A_Tolerance;
|
||||||
double wdot,udot,qdot;
|
double wdot,udot,qdot;
|
||||||
double dth;
|
double dth;
|
||||||
|
@ -164,6 +166,8 @@ private:
|
||||||
int axis_count;
|
int axis_count;
|
||||||
int solutionDomain;
|
int solutionDomain;
|
||||||
double xlo,xhi,alo,ahi;
|
double xlo,xhi,alo,ahi;
|
||||||
|
double targetNlf;
|
||||||
|
int debug_axis;
|
||||||
|
|
||||||
FGFDMExec* fdmex;
|
FGFDMExec* fdmex;
|
||||||
FGInitialCondition* fgic;
|
FGInitialCondition* fgic;
|
||||||
|
@ -181,6 +185,11 @@ private:
|
||||||
|
|
||||||
bool checkLimits(void);
|
bool checkLimits(void);
|
||||||
|
|
||||||
|
void setupPullup(void);
|
||||||
|
void setupTurn(void);
|
||||||
|
|
||||||
|
void setDebug(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Initializes the trimming class
|
/** Initializes the trimming class
|
||||||
@param FDMExec pointer to a JSBSim executive object.
|
@param FDMExec pointer to a JSBSim executive object.
|
||||||
|
@ -270,10 +279,21 @@ public:
|
||||||
A_Tolerance = tt / 10;
|
A_Tolerance = tt / 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Debug level 1 shows results of each top-level iteration
|
/**
|
||||||
//Debug level 2 shows level 1 & results of each per-axis iteration
|
Debug level 1 shows results of each top-level iteration
|
||||||
inline void SetDebug(int level) { Debug = level; }
|
Debug level 2 shows level 1 & results of each per-axis iteration
|
||||||
inline void ClearDebug(void) { Debug = 0; }
|
*/
|
||||||
|
inline void SetDebug(int level) { DebugLevel = level; }
|
||||||
|
inline void ClearDebug(void) { DebugLevel = 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
Output debug data for one of the axes
|
||||||
|
The State enum is defined in FGTrimAxis.h
|
||||||
|
*/
|
||||||
|
inline void DebugState(State state) { debug_axis=state; }
|
||||||
|
|
||||||
|
inline void SetTargetNlf(float nlf) { targetNlf=nlf; }
|
||||||
|
inline double GetTargetNlf(void) { return targetNlf; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@ FGTrimAxis::FGTrimAxis(FGFDMExec* fdex, FGInitialCondition* ic, State st,
|
||||||
state_convert=1.0;
|
state_convert=1.0;
|
||||||
control_convert=1.0;
|
control_convert=1.0;
|
||||||
state_value=0;
|
state_value=0;
|
||||||
|
state_target=0;
|
||||||
switch(state) {
|
switch(state) {
|
||||||
case tUdot: tolerance = DEFAULT_TOLERANCE; break;
|
case tUdot: tolerance = DEFAULT_TOLERANCE; break;
|
||||||
case tVdot: tolerance = DEFAULT_TOLERANCE; break;
|
case tVdot: tolerance = DEFAULT_TOLERANCE; break;
|
||||||
|
@ -70,6 +71,7 @@ FGTrimAxis::FGTrimAxis(FGFDMExec* fdex, FGInitialCondition* ic, State st,
|
||||||
case tPdot: tolerance = DEFAULT_TOLERANCE / 10; break;
|
case tPdot: tolerance = DEFAULT_TOLERANCE / 10; break;
|
||||||
case tRdot: tolerance = DEFAULT_TOLERANCE / 10; break;
|
case tRdot: tolerance = DEFAULT_TOLERANCE / 10; break;
|
||||||
case tHmgt: tolerance = 0.01; break;
|
case tHmgt: tolerance = 0.01; break;
|
||||||
|
case tNlf: state_target=1.0; tolerance = 1E-5; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
solver_eps=tolerance;
|
solver_eps=tolerance;
|
||||||
|
@ -151,13 +153,14 @@ FGTrimAxis::~FGTrimAxis()
|
||||||
|
|
||||||
void FGTrimAxis::getState(void) {
|
void FGTrimAxis::getState(void) {
|
||||||
switch(state) {
|
switch(state) {
|
||||||
case tUdot: state_value=fdmex->GetAircraft()->GetBodyAccel()(1); break;
|
case tUdot: state_value=fdmex->GetTranslation()->GetUVWdot()(1)-state_target; break;
|
||||||
case tVdot: state_value=fdmex->GetAircraft()->GetBodyAccel()(2); break;
|
case tVdot: state_value=fdmex->GetTranslation()->GetUVWdot()(2)-state_target; break;
|
||||||
case tWdot: state_value=fdmex->GetAircraft()->GetBodyAccel()(3); break;
|
case tWdot: state_value=fdmex->GetTranslation()->GetUVWdot()(3)-state_target; break;
|
||||||
case tQdot: state_value=fdmex->GetRotation()->GetPQRdot(2);break;
|
case tQdot: state_value=fdmex->GetRotation()->GetPQRdot(2)-state_target;break;
|
||||||
case tPdot: state_value=fdmex->GetRotation()->GetPQRdot(1); break;
|
case tPdot: state_value=fdmex->GetRotation()->GetPQRdot(1)-state_target; break;
|
||||||
case tRdot: state_value=fdmex->GetRotation()->GetPQRdot(3); break;
|
case tRdot: state_value=fdmex->GetRotation()->GetPQRdot(3)-state_target; break;
|
||||||
case tHmgt: state_value=computeHmgt(); break;
|
case tHmgt: state_value=computeHmgt()-state_target; break;
|
||||||
|
case tNlf: state_value=fdmex->GetAircraft()->GetNlf()-state_target; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,7 +415,7 @@ void FGTrimAxis::AxisReport(void) {
|
||||||
char out[80];
|
char out[80];
|
||||||
sprintf(out," %20s: %6.2f %5s: %9.2e Tolerance: %3.0e\n",
|
sprintf(out," %20s: %6.2f %5s: %9.2e Tolerance: %3.0e\n",
|
||||||
GetControlName().c_str(), GetControl()*control_convert,
|
GetControlName().c_str(), GetControl()*control_convert,
|
||||||
GetStateName().c_str(), GetState(), GetTolerance());
|
GetStateName().c_str(), GetState()+state_target, GetTolerance());
|
||||||
cout << out;
|
cout << out;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,9 @@ INCLUDES
|
||||||
|
|
||||||
#define DEFAULT_TOLERANCE 0.001
|
#define DEFAULT_TOLERANCE 0.001
|
||||||
|
|
||||||
const string StateNames[7]= { "udot","vdot","wdot","qdot","pdot","rdot","hmgt" };
|
const string StateNames[10]= { "all","udot","vdot","wdot","qdot","pdot","rdot",
|
||||||
|
"hmgt","nlf"
|
||||||
|
};
|
||||||
const string ControlNames[14]= { "Throttle","Sideslip","Angle of Attack",
|
const string ControlNames[14]= { "Throttle","Sideslip","Angle of Attack",
|
||||||
"Elevator","Ailerons","Rudder",
|
"Elevator","Ailerons","Rudder",
|
||||||
"Altitude AGL", "Pitch Angle",
|
"Altitude AGL", "Pitch Angle",
|
||||||
|
@ -69,7 +71,7 @@ const string ControlNames[14]= { "Throttle","Sideslip","Angle of Attack",
|
||||||
CLASS DECLARATION
|
CLASS DECLARATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
enum State { tUdot,tVdot,tWdot,tQdot,tPdot,tRdot,tHmgt };
|
enum State { tAll,tUdot,tVdot,tWdot,tQdot,tPdot,tRdot,tHmgt,tNlf };
|
||||||
enum Control { tThrottle, tBeta, tAlpha, tElevator, tAileron, tRudder, tAltAGL,
|
enum Control { tThrottle, tBeta, tAlpha, tElevator, tAileron, tRudder, tAltAGL,
|
||||||
tTheta, tPhi, tGamma, tPitchTrim, tRollTrim, tYawTrim, tHeading };
|
tTheta, tPhi, tGamma, tPitchTrim, tRollTrim, tYawTrim, tHeading };
|
||||||
|
|
||||||
|
@ -120,6 +122,9 @@ public:
|
||||||
void SetThetaOnGround(double ff);
|
void SetThetaOnGround(double ff);
|
||||||
void SetPhiOnGround(double ff);
|
void SetPhiOnGround(double ff);
|
||||||
|
|
||||||
|
inline void SetStateTarget(float target) { state_target=target; }
|
||||||
|
inline float GetStateTarget(void) { return state_target; }
|
||||||
|
|
||||||
bool initTheta(void);
|
bool initTheta(void);
|
||||||
|
|
||||||
void AxisReport(void);
|
void AxisReport(void);
|
||||||
|
@ -133,8 +138,10 @@ private:
|
||||||
State state;
|
State state;
|
||||||
Control control;
|
Control control;
|
||||||
|
|
||||||
double state_value;
|
float state_target;
|
||||||
double control_value;
|
|
||||||
|
float state_value;
|
||||||
|
float control_value;
|
||||||
|
|
||||||
double control_min;
|
double control_min;
|
||||||
double control_max;
|
double control_max;
|
||||||
|
|
|
@ -152,7 +152,7 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FGJSBBase::Message* msg;
|
FGJSBBase::Message* msg;
|
||||||
while (FDMExec->Run()) {
|
while (FDMExec->Run()) {
|
||||||
while (FDMExec->ReadMessage()) {
|
while (FDMExec->ReadMessage()) {
|
||||||
msg = FDMExec->ProcessMessage();
|
msg = FDMExec->ProcessMessage();
|
||||||
|
|
76
src/FDM/JSBSim/README
Normal file
76
src/FDM/JSBSim/README
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
Contents
|
||||||
|
--------
|
||||||
|
|
||||||
|
1) Introduction
|
||||||
|
2) Building with autoconf/automake
|
||||||
|
3) Contact
|
||||||
|
|
||||||
|
|
||||||
|
1) Introduction
|
||||||
|
---------------
|
||||||
|
|
||||||
|
JSBSim is a multi-platform, general purpose object-oriented Flight
|
||||||
|
Dynamics Model (FDM) written in C++. Jon Berndt and Tony Peden began
|
||||||
|
about mid-1998 writing JSBSim. As of this writing it is the default
|
||||||
|
FDM for FlightGear. JSBSim can also be run in a standalone batch mode
|
||||||
|
for testing and study. More information on JSBSim can be found at the
|
||||||
|
JSBSim home page here:
|
||||||
|
|
||||||
|
http://jsbsim.sourceforge.net
|
||||||
|
|
||||||
|
The standalone version of JSBSim can be easily built from the command
|
||||||
|
line of a unix or unix-like (CygWin/Linux/Unix/IRIX, etc.) system like
|
||||||
|
this:
|
||||||
|
|
||||||
|
make -fMakefile.solo
|
||||||
|
|
||||||
|
If you are on an IRIX machine you can use the Makefile.irix makefile.
|
||||||
|
Directions are also provided below for using traditional auto* utilities
|
||||||
|
also provided with JSBSim.
|
||||||
|
|
||||||
|
|
||||||
|
2) Building with autoconf/automake
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
Unpack the distribution tarball (if needed - CVS users will have
|
||||||
|
downloaded the code directly) using your preferred method, and change
|
||||||
|
to the working directory. For example :
|
||||||
|
|
||||||
|
$ tar xvfz JSBSim-0.1.2.tar.gz
|
||||||
|
$ cd JSBSim-0.1.2
|
||||||
|
|
||||||
|
NOTE for CVS users: If you are using JSBSim from a CVS checkout, or
|
||||||
|
snapshot, you will need to create the initial configure script. The
|
||||||
|
commands to do this have been included in the 'autogen.sh' script, so
|
||||||
|
just :
|
||||||
|
|
||||||
|
$ ./autogen.sh
|
||||||
|
|
||||||
|
If you wish to customise your version of JSBSim, use the following to
|
||||||
|
determine any build-time options you may be interested in.
|
||||||
|
|
||||||
|
$ ./configure --help
|
||||||
|
|
||||||
|
Then :
|
||||||
|
|
||||||
|
$ ./configure
|
||||||
|
|
||||||
|
This will check your system platform, compiler and other local
|
||||||
|
configuration variables needed to build JSBSim, and generates the
|
||||||
|
necessary Makefiles. Next :
|
||||||
|
|
||||||
|
$ make
|
||||||
|
|
||||||
|
Will compile the various classes, and link the library. Finally :
|
||||||
|
|
||||||
|
$ make install
|
||||||
|
|
||||||
|
Unless specified otherwise (with --prefix configure option), this will
|
||||||
|
install 'JSBSim.a' into '/usr/local/lib'.
|
||||||
|
|
||||||
|
|
||||||
|
3) Contact
|
||||||
|
----------
|
||||||
|
|
||||||
|
For more information on JSBSim contact Jon Berndt at jsbsim@hal-pc.org.
|
||||||
|
|
Loading…
Reference in a new issue