Update to the latest version of JSBSim
This commit is contained in:
parent
25a99a2417
commit
cf25f69d36
15 changed files with 125 additions and 25 deletions
|
@ -650,16 +650,23 @@ bool FGFDMExec::LoadModel(string model, bool addModelToPath)
|
|||
}
|
||||
|
||||
// Process the output element[s]. This element is OPTIONAL, and there may be more than one.
|
||||
unsigned int idx=0;
|
||||
typedef int (FGOutput::*iOPMF)(void) const;
|
||||
element = document->FindElement("output");
|
||||
while (element) {
|
||||
if (debug_lvl > 0) cout << endl << " Output data set: " << idx << " ";
|
||||
FGOutput* Output = new FGOutput(this);
|
||||
Output->InitModel();
|
||||
Schedule(Output, 1);
|
||||
result = Output->Load(element);
|
||||
Outputs.push_back(Output);
|
||||
if (!result) {
|
||||
cerr << endl << "Aircraft output element has problems in file " << aircraftCfgFileName << endl;
|
||||
return result;
|
||||
} else {
|
||||
Outputs.push_back(Output);
|
||||
string outputProp = CreateIndexedPropertyName("simulation/output",idx);
|
||||
instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate);
|
||||
idx++;
|
||||
}
|
||||
element = document->FindNextElement("output");
|
||||
}
|
||||
|
@ -931,6 +938,10 @@ bool FGFDMExec::SetOutputDirectives(string fname)
|
|||
result = Output->Load(0);
|
||||
Outputs.push_back(Output);
|
||||
|
||||
typedef int (FGOutput::*iOPMF)(void) const;
|
||||
string outputProp = CreateIndexedPropertyName("simulation/output",Outputs.size()-1);
|
||||
instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ INCLUDES
|
|||
#define BASE
|
||||
|
||||
#include "FGJSBBase.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace JSBSim {
|
||||
|
||||
|
@ -109,6 +110,10 @@ unsigned int FGJSBBase::messageId = 0;
|
|||
|
||||
short FGJSBBase::debug_lvl = 1;
|
||||
|
||||
using std::cerr;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGJSBBase::PutMessage(const Message& msg)
|
||||
|
@ -176,10 +181,43 @@ int FGJSBBase::SomeMessages(void)
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGJSBBase::Message* FGJSBBase::ProcessMessage(void)
|
||||
void FGJSBBase::ProcessMessage(void)
|
||||
{
|
||||
if (Messages.empty()) return;
|
||||
localMsg = Messages.front();
|
||||
|
||||
while (Messages.size() > 0) {
|
||||
switch (localMsg.type) {
|
||||
case JSBSim::FGJSBBase::Message::eText:
|
||||
cout << localMsg.messageId << ": " << localMsg.text << endl;
|
||||
break;
|
||||
case JSBSim::FGJSBBase::Message::eBool:
|
||||
cout << localMsg.messageId << ": " << localMsg.text << " " << localMsg.bVal << endl;
|
||||
break;
|
||||
case JSBSim::FGJSBBase::Message::eInteger:
|
||||
cout << localMsg.messageId << ": " << localMsg.text << " " << localMsg.iVal << endl;
|
||||
break;
|
||||
case JSBSim::FGJSBBase::Message::eDouble:
|
||||
cout << localMsg.messageId << ": " << localMsg.text << " " << localMsg.dVal << endl;
|
||||
break;
|
||||
default:
|
||||
cerr << "Unrecognized message type." << endl;
|
||||
break;
|
||||
}
|
||||
Messages.pop();
|
||||
if (Messages.size() > 0) localMsg = Messages.front();
|
||||
else break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
FGJSBBase::Message* FGJSBBase::ProcessNextMessage(void)
|
||||
{
|
||||
if (Messages.empty()) return NULL;
|
||||
localMsg = Messages.front();
|
||||
|
||||
Messages.pop();
|
||||
return &localMsg;
|
||||
}
|
||||
|
|
|
@ -182,8 +182,12 @@ public:
|
|||
@return 1 if some messages */
|
||||
int SomeMessages(void);
|
||||
/** Reads the message on the queue and removes it from the queue.
|
||||
@return pointer to a Message structure (or NULL if no mesage) */
|
||||
Message* ProcessMessage(void);
|
||||
This function also prints out the message.*/
|
||||
void ProcessMessage(void);
|
||||
/** Reads the next message on the queue and removes it from the queue.
|
||||
This function also prints out the message.
|
||||
@return a pointer to the message, or NULL if there are no messages.*/
|
||||
Message* ProcessNextMessage(void);
|
||||
//@}
|
||||
|
||||
/** Returns the version number of JSBSim.
|
||||
|
|
|
@ -489,8 +489,8 @@ void FGJSBsim::update( double dt )
|
|||
}
|
||||
|
||||
FGJSBBase::Message* msg;
|
||||
while (fdmex->SomeMessages()) {
|
||||
msg = fdmex->ProcessMessage();
|
||||
while (msg = fdmex->ProcessNextMessage()) {
|
||||
// msg = fdmex->ProcessNextMessage();
|
||||
switch (msg->type) {
|
||||
case FGJSBBase::Message::eText:
|
||||
if (msg->text == "Crash Detected: Simulation FREEZE.")
|
||||
|
|
|
@ -865,8 +865,14 @@ bool FGInitialCondition::Load(string rstfile, bool useStoredPath)
|
|||
SetLongitudeDegIC(document->FindElementValueAsNumberConvertTo("longitude", "DEG"));
|
||||
if (document->FindElement("elevation"))
|
||||
SetTerrainElevationFtIC(document->FindElementValueAsNumberConvertTo("elevation", "FT"));
|
||||
|
||||
if (document->FindElement("altitude")) // This is feet above ground level
|
||||
SetAltitudeAGLFtIC(document->FindElementValueAsNumberConvertTo("altitude", "FT"));
|
||||
else if (document->FindElement("altitudeAGL")) // This is feet above ground level
|
||||
SetAltitudeAGLFtIC(document->FindElementValueAsNumberConvertTo("altitudeAGL", "FT"));
|
||||
else if (document->FindElement("altitudeMSL")) // This is feet above sea level
|
||||
SetAltitudeASLFtIC(document->FindElementValueAsNumberConvertTo("altitudeMSL", "FT"));
|
||||
|
||||
if (document->FindElement("ubody"))
|
||||
SetUBodyFpsIC(document->FindElementValueAsNumberConvertTo("ubody", "FT/SEC"));
|
||||
if (document->FindElement("vbody"))
|
||||
|
|
|
@ -140,7 +140,10 @@ CLASS DOCUMENTATION
|
|||
- beta (angle, degrees)
|
||||
- gamma (angle, degrees)
|
||||
- roc (vertical velocity, ft/sec)
|
||||
- elevation (local terrain elevation, ft)
|
||||
- altitude (altitude AGL, ft)
|
||||
- altitudeAGL (altitude AGL, ft)
|
||||
- altitudeMSL (altitude MSL, ft)
|
||||
- winddir (wind from-angle, degrees)
|
||||
- vwind (magnitude wind speed, ft/sec)
|
||||
- hwind (headwind speed, knots)
|
||||
|
|
|
@ -35,14 +35,9 @@ SENTRY
|
|||
INCLUDES
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <simgear/props/props.hxx>
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
|
||||
#include "FGJSBBase.h"
|
||||
|
||||
|
|
|
@ -519,7 +519,7 @@ bool FGFCS::Load(Element* el, SystemType systype)
|
|||
{
|
||||
string name, file, fname="", interface_property_string, parent_name;
|
||||
vector <FGFCSComponent*> *Components;
|
||||
Element *component_element, *sensor_element;
|
||||
Element *component_element;
|
||||
Element *channel_element;
|
||||
|
||||
Components=0;
|
||||
|
|
|
@ -652,6 +652,10 @@ void FGLGear::bind(void)
|
|||
Exec->GetPropertyManager()->Tie( property_name.c_str(), &compressLength );
|
||||
property_name = base_property_name + "/side_friction_coeff";
|
||||
Exec->GetPropertyManager()->Tie( property_name.c_str(), &FCoeff );
|
||||
|
||||
property_name = base_property_name + "/static_friction_coeff";
|
||||
Exec->GetPropertyManager()->Tie( property_name.c_str(), &staticFCoeff );
|
||||
|
||||
}
|
||||
|
||||
if( isRetractable ) {
|
||||
|
|
|
@ -59,6 +59,9 @@ FGMassBalance::FGMassBalance(FGFDMExec* fdmex) : FGModel(fdmex)
|
|||
Weight = EmptyWeight = Mass = 0.0;
|
||||
|
||||
vbaseXYZcg.InitMatrix(0.0);
|
||||
vXYZcg.InitMatrix(0.0);
|
||||
vLastXYZcg.InitMatrix(0.0);
|
||||
vDeltaXYZcg.InitMatrix(0.0);
|
||||
baseJ.InitMatrix();
|
||||
mJ.InitMatrix();
|
||||
mJinv.InitMatrix();
|
||||
|
@ -85,6 +88,9 @@ bool FGMassBalance::InitModel(void)
|
|||
{
|
||||
if (!FGModel::InitModel()) return false;
|
||||
|
||||
vLastXYZcg.InitMatrix(0.0);
|
||||
vDeltaXYZcg.InitMatrix(0.0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -172,6 +178,14 @@ bool FGMassBalance::Run(void)
|
|||
+ GetPointMassMoment()
|
||||
+ BuoyantForces->GetGasMassMoment()) / Weight;
|
||||
|
||||
// Track frame-by-frame delta CG, and move the EOM-tracked location
|
||||
// by this amount.
|
||||
if (vLastXYZcg.Magnitude() == 0.0) vLastXYZcg = vXYZcg;
|
||||
vDeltaXYZcg = vXYZcg - vLastXYZcg;
|
||||
vDeltaXYZcgBody = StructuralToBody(vLastXYZcg) - StructuralToBody(vXYZcg);
|
||||
vLastXYZcg = vXYZcg;
|
||||
Propagate->NudgeBodyLocation(vDeltaXYZcgBody);
|
||||
|
||||
// Calculate new total moments of inertia
|
||||
|
||||
// At first it is the base configuration inertia matrix ...
|
||||
|
|
|
@ -107,10 +107,12 @@ public:
|
|||
bool InitModel(void);
|
||||
bool Run(void);
|
||||
|
||||
inline double GetMass(void) const {return Mass;}
|
||||
inline double GetWeight(void) const {return Weight;}
|
||||
inline FGColumnVector3& GetXYZcg(void) {return vXYZcg;}
|
||||
inline double GetXYZcg(int axis) const {return vXYZcg(axis);}
|
||||
double GetMass(void) const {return Mass;}
|
||||
double GetWeight(void) const {return Weight;}
|
||||
FGColumnVector3& GetXYZcg(void) {return vXYZcg;}
|
||||
double GetXYZcg(int axis) const {return vXYZcg(axis);}
|
||||
FGColumnVector3& GetDeltaXYZcg(void) {return vDeltaXYZcg;}
|
||||
double GetDeltaXYZcg(int axis) const {return vDeltaXYZcg(axis);}
|
||||
|
||||
/** Computes the inertia contribution of a pointmass.
|
||||
Computes and returns the inertia matrix of a pointmass of mass
|
||||
|
@ -166,6 +168,9 @@ private:
|
|||
FGMatrix33 pmJ;
|
||||
FGMatrix33 baseJ;
|
||||
FGColumnVector3 vXYZcg;
|
||||
FGColumnVector3 vLastXYZcg;
|
||||
FGColumnVector3 vDeltaXYZcg;
|
||||
FGColumnVector3 vDeltaXYZcgBody;
|
||||
FGColumnVector3 vXYZtank;
|
||||
FGColumnVector3 vbaseXYZcg;
|
||||
FGColumnVector3 vPMxyz;
|
||||
|
|
|
@ -465,9 +465,11 @@ void FGOutput::DelimitedOutput(string fname)
|
|||
outstream << Propulsion->GetPropulsionValues(delimeter);
|
||||
}
|
||||
|
||||
outstream.precision(18);
|
||||
for (unsigned int i=0;i<OutputProperties.size();i++) {
|
||||
outstream << delimeter << OutputProperties[i]->getDoubleValue();
|
||||
}
|
||||
outstream.precision(10);
|
||||
|
||||
outstream << endl;
|
||||
outstream.flush();
|
||||
|
@ -1016,14 +1018,27 @@ bool FGOutput::Load(Element* element)
|
|||
property_element = document->FindNextElement("property");
|
||||
}
|
||||
|
||||
OutRate = OutRate>1000?1000:(OutRate<0?0:OutRate);
|
||||
rate = (int)(0.5 + 1.0/(State->Getdt()*OutRate));
|
||||
SetRate(OutRate);
|
||||
|
||||
Debug(2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGOutput::SetRate(int rtHz)
|
||||
{
|
||||
rtHz = rtHz>1000?1000:(rtHz<0?0:rtHz);
|
||||
if (rtHz > 0) {
|
||||
rate = (int)(0.5 + 1.0/(State->Getdt()*rtHz));
|
||||
Enable();
|
||||
} else {
|
||||
rate = 1;
|
||||
Disable();
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// The bitmasked value choices are as follows:
|
||||
// unset: In this case (the default) JSBSim would only print
|
||||
|
|
|
@ -150,12 +150,13 @@ public:
|
|||
void SetType(string);
|
||||
void SetStartNewFile(bool tt) {StartNewFile = tt;}
|
||||
void SetSubsystems(int tt) {SubSystems = tt;}
|
||||
inline void Enable(void) { enabled = true; }
|
||||
inline void Disable(void) { enabled = false; }
|
||||
inline bool Toggle(void) {enabled = !enabled; return enabled;}
|
||||
void Enable(void) { enabled = true; }
|
||||
void Disable(void) { enabled = false; }
|
||||
bool Toggle(void) {enabled = !enabled; return enabled;}
|
||||
bool Load(Element* el);
|
||||
void SetOutputFileName(string fname) {Filename = fname;}
|
||||
void SetDirectivesFile(string fname) {DirectivesFile = fname;}
|
||||
void SetRate(int rt);
|
||||
string GetOutputFileName(void) const {return Filename;}
|
||||
|
||||
/// Subsystem types for specifying which will be output in the FDM data logging
|
||||
|
|
|
@ -487,6 +487,11 @@ public:
|
|||
void SetInitialState(const FGInitialCondition *);
|
||||
void RecomputeLocalTerrainRadius(void);
|
||||
|
||||
void NudgeBodyLocation(FGColumnVector3 deltaLoc) {
|
||||
vDeltaXYZEC = GetTb2ec()*deltaLoc;
|
||||
VState.vLocation -= vDeltaXYZEC;
|
||||
}
|
||||
|
||||
void CalculatePQRdot(void);
|
||||
void CalculateQuatdot(void);
|
||||
void CalculateLocationdot(void);
|
||||
|
@ -504,6 +509,7 @@ private:
|
|||
FGColumnVector3 vUVWdot, last_vUVWdot, last2_vUVWdot;
|
||||
FGColumnVector3 vLocationDot, last_vLocationDot, last2_vLocationDot;
|
||||
FGColumnVector3 vLocation;
|
||||
FGColumnVector3 vDeltaXYZEC;
|
||||
FGColumnVector3 vPQRi; // Inertial frame angular velocity
|
||||
FGColumnVector3 vOmega; // The Earth angular velocity vector
|
||||
FGColumnVector3 vOmegaLocal; // The local frame angular velocity vector
|
||||
|
|
|
@ -199,8 +199,6 @@ double FGPropeller::Calculate(double PowerAvailable)
|
|||
vH(eY) = 0.0;
|
||||
vH(eZ) = 0.0;
|
||||
|
||||
vH = Transform()*vH; // Transform rotational momentum to rotated frame (if any)
|
||||
|
||||
if (omega > 0.0) ExcessTorque = GearRatio * PowerAvailable / omega;
|
||||
else ExcessTorque = GearRatio * PowerAvailable / 1.0;
|
||||
|
||||
|
@ -208,9 +206,9 @@ double FGPropeller::Calculate(double PowerAvailable)
|
|||
|
||||
if (RPM < 1.0) RPM = 0; // Engine friction stops rotation arbitrarily at 1 RPM.
|
||||
|
||||
// Transform Torque and momentum prior to this equation, as PQR is used in this
|
||||
// Transform Torque and momentum first, as PQR is used in this
|
||||
// equation and cannot be transformed itself.
|
||||
vMn = fdmex->GetPropagate()->GetPQR()*vH + Transform()*vTorque;
|
||||
vMn = fdmex->GetPropagate()->GetPQR()*(Transform()*vH) + Transform()*vTorque;
|
||||
|
||||
return Thrust; // return thrust in pounds
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue