Sync. w. JSBSim CVS.
This commit is contained in:
parent
5a2ff68ffc
commit
5b340578ae
25 changed files with 374 additions and 217 deletions
|
@ -87,6 +87,8 @@ FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex)
|
||||||
TurbGain = 0.0;
|
TurbGain = 0.0;
|
||||||
TurbRate = 1.0;
|
TurbRate = 1.0;
|
||||||
|
|
||||||
|
T_dev_sl = T_dev = delta_T = 0.0;
|
||||||
|
|
||||||
bind();
|
bind();
|
||||||
Debug(0);
|
Debug(0);
|
||||||
}
|
}
|
||||||
|
@ -234,6 +236,17 @@ void FGAtmosphere::Calculate(double altitude)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
T_dev = 0.0;
|
||||||
|
if (delta_T != 0.0) {
|
||||||
|
T_dev = delta_T;
|
||||||
|
} else {
|
||||||
|
if ((h < 36089.239) && (T_dev_sl != 0.0)) {
|
||||||
|
T_dev = T_dev_sl * ( 1.0 - (h/36089.239));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
density_altitude = h + T_dev * 66.7;
|
||||||
|
|
||||||
|
reftemp+=T_dev;
|
||||||
if (slope == 0) {
|
if (slope == 0) {
|
||||||
intTemperature = reftemp;
|
intTemperature = reftemp;
|
||||||
intPressure = refpress*exp(-Inertial->SLgravity()/(reftemp*Reng)*(altitude-htab[i]));
|
intPressure = refpress*exp(-Inertial->SLgravity()/(reftemp*Reng)*(altitude-htab[i]));
|
||||||
|
@ -430,6 +443,12 @@ void FGAtmosphere::bind(void)
|
||||||
&FGAtmosphere::GetSoundSpeedRatio);
|
&FGAtmosphere::GetSoundSpeedRatio);
|
||||||
PropertyManager->Tie("atmosphere/psiw-rad", this,
|
PropertyManager->Tie("atmosphere/psiw-rad", this,
|
||||||
&FGAtmosphere::GetWindPsi);
|
&FGAtmosphere::GetWindPsi);
|
||||||
|
PropertyManager->Tie("atmosphere/delta-T", this,
|
||||||
|
&FGAtmosphere::GetDeltaT, &FGAtmosphere::SetDeltaT);
|
||||||
|
PropertyManager->Tie("atmosphere/T-sl-dev-F", this,
|
||||||
|
&FGAtmosphere::GetSLTempDev, &FGAtmosphere::SetSLTempDev);
|
||||||
|
PropertyManager->Tie("atmosphere/density-altitude", this,
|
||||||
|
&FGAtmosphere::GetDensityAltitude);
|
||||||
PropertyManager->Tie("atmosphere/p-turb-rad_sec", this,1,
|
PropertyManager->Tie("atmosphere/p-turb-rad_sec", this,1,
|
||||||
(PMF)&FGAtmosphere::GetTurbPQR);
|
(PMF)&FGAtmosphere::GetTurbPQR);
|
||||||
PropertyManager->Tie("atmosphere/q-turb-rad_sec", this,2,
|
PropertyManager->Tie("atmosphere/q-turb-rad_sec", this,2,
|
||||||
|
@ -450,6 +469,9 @@ void FGAtmosphere::unbind(void)
|
||||||
PropertyManager->Untie("atmosphere/rho-sl-slugs_ft3");
|
PropertyManager->Untie("atmosphere/rho-sl-slugs_ft3");
|
||||||
PropertyManager->Untie("atmosphere/P-sl-psf");
|
PropertyManager->Untie("atmosphere/P-sl-psf");
|
||||||
PropertyManager->Untie("atmosphere/a-sl-fps");
|
PropertyManager->Untie("atmosphere/a-sl-fps");
|
||||||
|
PropertyManager->Untie("atmosphere/delta-T");
|
||||||
|
PropertyManager->Untie("atmosphere/T-sl-dev-F");
|
||||||
|
PropertyManager->Untie("atmosphere/density-altitude");
|
||||||
PropertyManager->Untie("atmosphere/theta-norm");
|
PropertyManager->Untie("atmosphere/theta-norm");
|
||||||
PropertyManager->Untie("atmosphere/sigma-norm");
|
PropertyManager->Untie("atmosphere/sigma-norm");
|
||||||
PropertyManager->Untie("atmosphere/delta-norm");
|
PropertyManager->Untie("atmosphere/delta-norm");
|
||||||
|
|
|
@ -129,6 +129,19 @@ public:
|
||||||
/// Provides the external atmosphere model with an interface to set the pressure.
|
/// Provides the external atmosphere model with an interface to set the pressure.
|
||||||
inline void SetExPressure(double p) { exPressure=p; }
|
inline void SetExPressure(double p) { exPressure=p; }
|
||||||
|
|
||||||
|
/// Sets the temperature deviation at sea-level in degrees Fahrenheit
|
||||||
|
inline void SetSLTempDev(double d) { T_dev_sl = d; }
|
||||||
|
/// Gets the temperature deviation at sea-level in degrees Fahrenheit
|
||||||
|
inline double GetSLTempDev(void) const { return T_dev_sl; }
|
||||||
|
/// Sets the current delta-T in degrees Fahrenheit
|
||||||
|
inline void SetDeltaT(double d) { delta_T = d; }
|
||||||
|
/// Gets the current delta-T in degrees Fahrenheit
|
||||||
|
inline double GetDeltaT(void) const { return delta_T; }
|
||||||
|
/// Gets the at-altitude temperature deviation in degrees Fahrenheit
|
||||||
|
inline double GetTempDev(void) const { return T_dev; }
|
||||||
|
/// Gets the density altitude in feet
|
||||||
|
inline double GetDensityAltitude(void) const { return density_altitude; }
|
||||||
|
|
||||||
/// Sets the wind components in NED frame.
|
/// Sets the wind components in NED frame.
|
||||||
inline void SetWindNED(double wN, double wE, double wD) { vWindNED(1)=wN; vWindNED(2)=wE; vWindNED(3)=wD;}
|
inline void SetWindNED(double wN, double wE, double wD) { vWindNED(1)=wN; vWindNED(2)=wE; vWindNED(3)=wD;}
|
||||||
|
|
||||||
|
@ -164,6 +177,7 @@ protected:
|
||||||
bool useExternal;
|
bool useExternal;
|
||||||
double exTemperature,exDensity,exPressure;
|
double exTemperature,exDensity,exPressure;
|
||||||
double intTemperature, intDensity, intPressure;
|
double intTemperature, intDensity, intPressure;
|
||||||
|
double T_dev_sl, T_dev, delta_T, density_altitude;
|
||||||
|
|
||||||
double MagnitudedAccelDt, MagnitudeAccel, Magnitude;
|
double MagnitudedAccelDt, MagnitudeAccel, Magnitude;
|
||||||
double TurbGain;
|
double TurbGain;
|
||||||
|
|
|
@ -116,9 +116,9 @@ bool FGAuxiliary::Run()
|
||||||
|
|
||||||
// Rotation
|
// Rotation
|
||||||
|
|
||||||
double cTht = Propagate->GetCostht();
|
double cTht = Propagate->GetCosEuler(eTht);
|
||||||
double cPhi = Propagate->GetCosphi();
|
double cPhi = Propagate->GetCosEuler(ePhi);
|
||||||
double sPhi = Propagate->GetSinphi();
|
double sPhi = Propagate->GetSinEuler(ePhi);
|
||||||
|
|
||||||
vEulerRates(eTht) = vPQR(eQ)*cPhi - vPQR(eR)*sPhi;
|
vEulerRates(eTht) = vPQR(eQ)*cPhi - vPQR(eR)*sPhi;
|
||||||
if (cTht != 0.0) {
|
if (cTht != 0.0) {
|
||||||
|
@ -246,7 +246,7 @@ double FGAuxiliary::GetHeadWind(void)
|
||||||
psiw = Atmosphere->GetWindPsi();
|
psiw = Atmosphere->GetWindPsi();
|
||||||
vw = Atmosphere->GetWindNED().Magnitude();
|
vw = Atmosphere->GetWindNED().Magnitude();
|
||||||
|
|
||||||
return vw*cos(psiw - Propagate->Getpsi());
|
return vw*cos(psiw - Propagate->GetEuler(ePsi));
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -258,7 +258,7 @@ double FGAuxiliary::GetCrossWind(void)
|
||||||
psiw = Atmosphere->GetWindPsi();
|
psiw = Atmosphere->GetWindPsi();
|
||||||
vw = Atmosphere->GetWindNED().Magnitude();
|
vw = Atmosphere->GetWindNED().Magnitude();
|
||||||
|
|
||||||
return vw*sin(psiw - Propagate->Getpsi());
|
return vw*sin(psiw - Propagate->GetEuler(ePsi));
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
|
@ -299,6 +299,15 @@ public:
|
||||||
*/
|
*/
|
||||||
double Magnitude(void) const;
|
double Magnitude(void) const;
|
||||||
|
|
||||||
|
/** Length of the vector in a coordinate axis plane.
|
||||||
|
|
||||||
|
Compute and return the euclidean norm of this vector projected into
|
||||||
|
the coordinate axis plane idx1-idx2.
|
||||||
|
*/
|
||||||
|
double Magnitude(int idx1, int idx2) const {
|
||||||
|
return sqrt( Entry(idx1)*Entry(idx1) + Entry(idx2)*Entry(idx2) );
|
||||||
|
}
|
||||||
|
|
||||||
/** Normalize.
|
/** Normalize.
|
||||||
|
|
||||||
Normalize the vector to have the Magnitude() == 1.0. If the vector
|
Normalize the vector to have the Magnitude() == 1.0. If the vector
|
||||||
|
|
|
@ -236,11 +236,11 @@ bool FGEngine::LoadThruster(FGConfigFile* AC_cfg)
|
||||||
thrType = Cfg_ptr->GetValue();
|
thrType = Cfg_ptr->GetValue();
|
||||||
|
|
||||||
if (thrType == "FG_PROPELLER") {
|
if (thrType == "FG_PROPELLER") {
|
||||||
Thruster = new FGPropeller(FDMExec, Cfg_ptr);
|
Thruster = new FGPropeller(FDMExec, Cfg_ptr, EngineNumber);
|
||||||
} else if (thrType == "FG_NOZZLE") {
|
} else if (thrType == "FG_NOZZLE") {
|
||||||
Thruster = new FGNozzle(FDMExec, Cfg_ptr);
|
Thruster = new FGNozzle(FDMExec, Cfg_ptr, EngineNumber);
|
||||||
} else if (thrType == "FG_DIRECT") {
|
} else if (thrType == "FG_DIRECT") {
|
||||||
Thruster = new FGThruster( FDMExec, Cfg_ptr);
|
Thruster = new FGThruster( FDMExec, Cfg_ptr, EngineNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
AC_cfg->GetNextConfigLine();
|
AC_cfg->GetNextConfigLine();
|
||||||
|
|
|
@ -100,6 +100,7 @@ FGFCS::~FGFCS()
|
||||||
MixturePos.clear();
|
MixturePos.clear();
|
||||||
PropAdvanceCmd.clear();
|
PropAdvanceCmd.clear();
|
||||||
PropAdvance.clear();
|
PropAdvance.clear();
|
||||||
|
SteerPosDeg.clear();
|
||||||
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
@ -117,10 +118,17 @@ bool FGFCS::Run(void)
|
||||||
|
|
||||||
if (FGModel::Run()) return true; // fast exit if nothing to do
|
if (FGModel::Run()) return true; // fast exit if nothing to do
|
||||||
|
|
||||||
|
// Set the default engine commands
|
||||||
for (i=0; i<ThrottlePos.size(); i++) ThrottlePos[i] = ThrottleCmd[i];
|
for (i=0; i<ThrottlePos.size(); i++) ThrottlePos[i] = ThrottleCmd[i];
|
||||||
for (i=0; i<MixturePos.size(); i++) MixturePos[i] = MixtureCmd[i];
|
for (i=0; i<MixturePos.size(); i++) MixturePos[i] = MixtureCmd[i];
|
||||||
for (i=0; i<PropAdvance.size(); i++) PropAdvance[i] = PropAdvanceCmd[i];
|
for (i=0; i<PropAdvance.size(); i++) PropAdvance[i] = PropAdvanceCmd[i];
|
||||||
|
|
||||||
|
// Set the default steering angle
|
||||||
|
for (i=0; i<SteerPosDeg.size(); i++) {
|
||||||
|
FGLGear* gear = GroundReactions->GetGearUnit(i);
|
||||||
|
SteerPosDeg[i] = gear->GetDefaultSteerAngle( GetDsCmd() );
|
||||||
|
}
|
||||||
|
|
||||||
for (i=0; i<APComponents.size(); i++) APComponents[i]->Run(); // cycle AP components
|
for (i=0; i<APComponents.size(); i++) APComponents[i]->Run(); // cycle AP components
|
||||||
for (i=0; i<FCSComponents.size(); i++) FCSComponents[i]->Run(); // cycle FCS components
|
for (i=0; i<FCSComponents.size(); i++) FCSComponents[i]->Run(); // cycle FCS components
|
||||||
|
|
||||||
|
@ -473,6 +481,13 @@ void FGFCS::AddThrottle(void)
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
void FGFCS::AddGear(void)
|
||||||
|
{
|
||||||
|
SteerPosDeg.push_back(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
void FGFCS::Normalize(void) {
|
void FGFCS::Normalize(void) {
|
||||||
|
|
||||||
//not all of these are guaranteed to be defined for every model
|
//not all of these are guaranteed to be defined for every model
|
||||||
|
@ -533,6 +548,10 @@ void FGFCS::bind(void)
|
||||||
&FGFCS::GetDrCmd,
|
&FGFCS::GetDrCmd,
|
||||||
&FGFCS::SetDrCmd,
|
&FGFCS::SetDrCmd,
|
||||||
true);
|
true);
|
||||||
|
PropertyManager->Tie("fcs/steer-cmd-norm", this,
|
||||||
|
&FGFCS::GetDsCmd,
|
||||||
|
&FGFCS::SetDsCmd,
|
||||||
|
true);
|
||||||
PropertyManager->Tie("fcs/flap-cmd-norm", this,
|
PropertyManager->Tie("fcs/flap-cmd-norm", this,
|
||||||
&FGFCS::GetDfCmd,
|
&FGFCS::GetDfCmd,
|
||||||
&FGFCS::SetDfCmd,
|
&FGFCS::SetDfCmd,
|
||||||
|
@ -783,6 +802,16 @@ void FGFCS::bindModel(void)
|
||||||
true );
|
true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i=0; i<SteerPosDeg.size(); i++) {
|
||||||
|
if (GroundReactions->GetGearUnit(i)->GetSteerable()) {
|
||||||
|
snprintf(tmp,80,"fcs/steer-pos-deg[%u]",i);
|
||||||
|
PropertyManager->Tie( tmp, this, i,
|
||||||
|
&FGFCS::GetSteerPosDeg,
|
||||||
|
&FGFCS::SetSteerPosDeg,
|
||||||
|
true );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
|
@ -176,6 +176,10 @@ public:
|
||||||
@return rudder command in percent */
|
@return rudder command in percent */
|
||||||
inline double GetDrCmd(void) const { return DrCmd; }
|
inline double GetDrCmd(void) const { return DrCmd; }
|
||||||
|
|
||||||
|
/** Gets the steering command.
|
||||||
|
@return steering command in percent */
|
||||||
|
inline double GetDsCmd(void) const { return DsCmd; }
|
||||||
|
|
||||||
/** Gets the flaps command.
|
/** Gets the flaps command.
|
||||||
@return flaps command in percent */
|
@return flaps command in percent */
|
||||||
inline double GetDfCmd(void) const { return DfCmd; }
|
inline double GetDfCmd(void) const { return DfCmd; }
|
||||||
|
@ -402,6 +406,10 @@ public:
|
||||||
@return mixture position for the given engine in percent ( 0 - 100)*/
|
@return mixture position for the given engine in percent ( 0 - 100)*/
|
||||||
inline double GetMixturePos(int engine) const { return MixturePos[engine]; }
|
inline double GetMixturePos(int engine) const { return MixturePos[engine]; }
|
||||||
|
|
||||||
|
/** Gets the steering position.
|
||||||
|
@return steering position in degrees */
|
||||||
|
double GetSteerPosDeg(int gear) const { return SteerPosDeg[gear]; }
|
||||||
|
|
||||||
/** Gets the gear position (0 up, 1 down), defaults to down
|
/** Gets the gear position (0 up, 1 down), defaults to down
|
||||||
@return gear position (0 up, 1 down) */
|
@return gear position (0 up, 1 down) */
|
||||||
inline double GetGearPos(void) const { return GearPos; }
|
inline double GetGearPos(void) const { return GearPos; }
|
||||||
|
@ -437,6 +445,10 @@ public:
|
||||||
@param cmd rudder command in percent*/
|
@param cmd rudder command in percent*/
|
||||||
inline void SetDrCmd(double cmd) { DrCmd = cmd; }
|
inline void SetDrCmd(double cmd) { DrCmd = cmd; }
|
||||||
|
|
||||||
|
/** Sets the steering command
|
||||||
|
@param cmd steering command in percent*/
|
||||||
|
inline void SetDsCmd(double cmd) { DsCmd = cmd; }
|
||||||
|
|
||||||
/** Sets the flaps command
|
/** Sets the flaps command
|
||||||
@param cmd flaps command in percent*/
|
@param cmd flaps command in percent*/
|
||||||
inline void SetDfCmd(double cmd) { DfCmd = cmd; }
|
inline void SetDfCmd(double cmd) { DfCmd = cmd; }
|
||||||
|
@ -547,6 +559,10 @@ public:
|
||||||
@param cmd mixture setting in percent (0 - 100)*/
|
@param cmd mixture setting in percent (0 - 100)*/
|
||||||
void SetMixturePos(int engine, double cmd);
|
void SetMixturePos(int engine, double cmd);
|
||||||
|
|
||||||
|
/** Sets the steering position
|
||||||
|
@param cmd steering position in degrees*/
|
||||||
|
void SetSteerPosDeg(int gear, double pos) { SteerPosDeg[gear] = pos; }
|
||||||
|
|
||||||
/** Set the gear extend/retract position, defaults to down
|
/** Set the gear extend/retract position, defaults to down
|
||||||
@param gear position 0 up, 1 down */
|
@param gear position 0 up, 1 down */
|
||||||
void SetGearPos(double gearpos) { GearPos = gearpos; }
|
void SetGearPos(double gearpos) { GearPos = gearpos; }
|
||||||
|
@ -587,6 +603,7 @@ public:
|
||||||
bool Load(FGConfigFile* AC_cfg);
|
bool Load(FGConfigFile* AC_cfg);
|
||||||
|
|
||||||
void AddThrottle(void);
|
void AddThrottle(void);
|
||||||
|
void AddGear(void);
|
||||||
|
|
||||||
FGPropertyManager* GetPropertyManager(void) { return PropertyManager; }
|
FGPropertyManager* GetPropertyManager(void) { return PropertyManager; }
|
||||||
|
|
||||||
|
@ -595,7 +612,7 @@ public:
|
||||||
void unbind(FGPropertyManager *node);
|
void unbind(FGPropertyManager *node);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double DaCmd, DeCmd, DrCmd, DfCmd, DsbCmd, DspCmd;
|
double DaCmd, DeCmd, DrCmd, DsCmd, DfCmd, DsbCmd, DspCmd;
|
||||||
double AP_DaCmd, AP_DeCmd, AP_DrCmd, AP_ThrottleCmd;
|
double AP_DaCmd, AP_DeCmd, AP_DrCmd, AP_ThrottleCmd;
|
||||||
double DePos[NForms], DaLPos[NForms], DaRPos[NForms], DrPos[NForms];
|
double DePos[NForms], DaLPos[NForms], DaRPos[NForms], DrPos[NForms];
|
||||||
double DfPos[NForms], DsbPos[NForms], DspPos[NForms];
|
double DfPos[NForms], DsbPos[NForms], DspPos[NForms];
|
||||||
|
@ -606,6 +623,7 @@ private:
|
||||||
vector <double> MixturePos;
|
vector <double> MixturePos;
|
||||||
vector <double> PropAdvanceCmd;
|
vector <double> PropAdvanceCmd;
|
||||||
vector <double> PropAdvance;
|
vector <double> PropAdvance;
|
||||||
|
vector <double> SteerPosDeg;
|
||||||
double LeftBrake, RightBrake, CenterBrake; // Brake settings
|
double LeftBrake, RightBrake, CenterBrake; // Brake settings
|
||||||
double GearCmd,GearPos;
|
double GearCmd,GearPos;
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,9 @@ bool FGGroundReactions::Load(FGConfigFile* AC_cfg)
|
||||||
AC_cfg->GetNextConfigLine();
|
AC_cfg->GetNextConfigLine();
|
||||||
|
|
||||||
while ((token = AC_cfg->GetValue()) != string("/UNDERCARRIAGE")) {
|
while ((token = AC_cfg->GetValue()) != string("/UNDERCARRIAGE")) {
|
||||||
lGear.push_back(FGLGear(AC_cfg, FDMExec));
|
int num = lGear.size();
|
||||||
|
lGear.push_back(FGLGear(AC_cfg, FDMExec, num));
|
||||||
|
FCS->AddGear();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -57,10 +57,12 @@ static const char *IdHdr = ID_LGEAR;
|
||||||
CLASS IMPLEMENTATION
|
CLASS IMPLEMENTATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
FGLGear::FGLGear(FGConfigFile* AC_cfg, FGFDMExec* fdmex) : Exec(fdmex)
|
FGLGear::FGLGear(FGConfigFile* AC_cfg, FGFDMExec* fdmex, int number) : Exec(fdmex)
|
||||||
{
|
{
|
||||||
string tmp;
|
string tmp;
|
||||||
|
|
||||||
|
GearNumber = number;
|
||||||
|
|
||||||
*AC_cfg >> tmp >> name >> vXYZ(1) >> vXYZ(2) >> vXYZ(3)
|
*AC_cfg >> tmp >> name >> vXYZ(1) >> vXYZ(2) >> vXYZ(3)
|
||||||
>> kSpring >> bDamp>> dynamicFCoeff >> staticFCoeff
|
>> kSpring >> bDamp>> dynamicFCoeff >> staticFCoeff
|
||||||
>> rollingFCoeff >> sSteerType >> sBrakeGroup
|
>> rollingFCoeff >> sSteerType >> sBrakeGroup
|
||||||
|
@ -140,6 +142,8 @@ FGLGear::FGLGear(FGConfigFile* AC_cfg, FGFDMExec* fdmex) : Exec(fdmex)
|
||||||
|
|
||||||
FGLGear::FGLGear(const FGLGear& lgear)
|
FGLGear::FGLGear(const FGLGear& lgear)
|
||||||
{
|
{
|
||||||
|
GearNumber = lgear.GearNumber;
|
||||||
|
|
||||||
State = lgear.State;
|
State = lgear.State;
|
||||||
Aircraft = lgear.Aircraft;
|
Aircraft = lgear.Aircraft;
|
||||||
Propagate = lgear.Propagate;
|
Propagate = lgear.Propagate;
|
||||||
|
@ -207,7 +211,6 @@ FGLGear::~FGLGear()
|
||||||
FGColumnVector3& FGLGear::Force(void)
|
FGColumnVector3& FGLGear::Force(void)
|
||||||
{
|
{
|
||||||
double SinWheel, CosWheel;
|
double SinWheel, CosWheel;
|
||||||
double deltaSlip;
|
|
||||||
double deltaT = State->Getdt()*Aircraft->GetRate();
|
double deltaT = State->Getdt()*Aircraft->GetRate();
|
||||||
|
|
||||||
vForce.InitMatrix();
|
vForce.InitMatrix();
|
||||||
|
@ -229,6 +232,24 @@ FGColumnVector3& FGLGear::Force(void)
|
||||||
GearDown = true;
|
GearDown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute the steering angle in any case.
|
||||||
|
// Will make shure that animations will look right.
|
||||||
|
switch (eSteerType) {
|
||||||
|
case stSteer:
|
||||||
|
SteerAngle = degtorad * FCS->GetSteerPosDeg(GearNumber);
|
||||||
|
break;
|
||||||
|
case stFixed:
|
||||||
|
SteerAngle = 0.0;
|
||||||
|
break;
|
||||||
|
case stCaster:
|
||||||
|
// Note to Jon: This is not correct for castering gear. I'll fix it later.
|
||||||
|
SteerAngle = 0.0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cerr << "Improper steering type membership detected for this gear." << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (GearDown) {
|
if (GearDown) {
|
||||||
|
|
||||||
vWhlBodyVec = MassBalance->StructuralToBody(vXYZ);
|
vWhlBodyVec = MassBalance->StructuralToBody(vXYZ);
|
||||||
|
@ -323,28 +344,12 @@ FGColumnVector3& FGLGear::Force(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (eSteerType) {
|
|
||||||
case stSteer:
|
|
||||||
SteerAngle = -maxSteerAngle * FCS->GetDrCmd() * 0.01745;
|
|
||||||
break;
|
|
||||||
case stFixed:
|
|
||||||
SteerAngle = 0.0;
|
|
||||||
break;
|
|
||||||
case stCaster:
|
|
||||||
// Note to Jon: This is not correct for castering gear. I'll fix it later.
|
|
||||||
SteerAngle = 0.0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
cerr << "Improper steering type membership detected for this gear." << endl;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transform the wheel velocities from the local axis system to the wheel axis system.
|
// Transform the wheel velocities from the local axis system to the wheel axis system.
|
||||||
// For now, steering angle is assumed to happen in the Local Z axis,
|
// For now, steering angle is assumed to happen in the Local Z axis,
|
||||||
// not the strut axis as it should be. Will fix this later.
|
// not the strut axis as it should be. Will fix this later.
|
||||||
|
|
||||||
SinWheel = sin(Propagate->Getpsi() + SteerAngle);
|
SinWheel = sin(Propagate->GetEuler(ePsi) + SteerAngle);
|
||||||
CosWheel = cos(Propagate->Getpsi() + SteerAngle);
|
CosWheel = cos(Propagate->GetEuler(ePsi) + SteerAngle);
|
||||||
RollingWhlVel = vWhlVelVec(eX)*CosWheel + vWhlVelVec(eY)*SinWheel;
|
RollingWhlVel = vWhlVelVec(eX)*CosWheel + vWhlVelVec(eY)*SinWheel;
|
||||||
SideWhlVel = vWhlVelVec(eY)*CosWheel - vWhlVelVec(eX)*SinWheel;
|
SideWhlVel = vWhlVelVec(eY)*CosWheel - vWhlVelVec(eX)*SinWheel;
|
||||||
|
|
||||||
|
@ -447,6 +452,9 @@ FGColumnVector3& FGLGear::Force(void)
|
||||||
|
|
||||||
WOW = false;
|
WOW = false;
|
||||||
|
|
||||||
|
// Return to neutral position between 1.0 and 0.8 gear pos.
|
||||||
|
SteerAngle *= max(FCS->GetGearPos()-0.8, 0.0)/0.2;
|
||||||
|
|
||||||
if (Propagate->GetDistanceAGL() > 200.0) {
|
if (Propagate->GetDistanceAGL() > 200.0) {
|
||||||
FirstContact = false;
|
FirstContact = false;
|
||||||
StartedGroundRun = false;
|
StartedGroundRun = false;
|
||||||
|
|
|
@ -183,7 +183,7 @@ public:
|
||||||
/** Constructor
|
/** Constructor
|
||||||
@param Executive a pointer to the parent executive object
|
@param Executive a pointer to the parent executive object
|
||||||
@param File a pointer to the config file instance */
|
@param File a pointer to the config file instance */
|
||||||
FGLGear(FGConfigFile* File, FGFDMExec* Executive);
|
FGLGear(FGConfigFile* File, FGFDMExec* Executive, int number);
|
||||||
/** Constructor
|
/** Constructor
|
||||||
@param lgear a reference to an existing FGLGear object */
|
@param lgear a reference to an existing FGLGear object */
|
||||||
FGLGear(const FGLGear& lgear);
|
FGLGear(const FGLGear& lgear);
|
||||||
|
@ -229,12 +229,14 @@ public:
|
||||||
/** Get the console touchdown reporting feature
|
/** Get the console touchdown reporting feature
|
||||||
@return true if reporting is turned on */
|
@return true if reporting is turned on */
|
||||||
inline bool GetReport(void) { return ReportEnable; }
|
inline bool GetReport(void) { return ReportEnable; }
|
||||||
inline double GetSteerAngle(void) { return SteerAngle;}
|
double GetSteerNorm(void) const { return radtodeg/maxSteerAngle*SteerAngle; }
|
||||||
inline double GetstaticFCoeff(void) { return staticFCoeff;}
|
double GetDefaultSteerAngle(double cmd) const { return cmd*maxSteerAngle; }
|
||||||
|
double GetstaticFCoeff(void) { return staticFCoeff; }
|
||||||
|
|
||||||
inline int GetBrakeGroup(void) { return (int)eBrakeGrp; }
|
inline int GetBrakeGroup(void) { return (int)eBrakeGrp; }
|
||||||
inline int GetSteerType(void) { return (int)eSteerType; }
|
inline int GetSteerType(void) { return (int)eSteerType; }
|
||||||
|
|
||||||
|
bool GetSteerable(void) const { return eSteerType != stFixed; }
|
||||||
inline bool GetRetractable(void) { return isRetractable; }
|
inline bool GetRetractable(void) { return isRetractable; }
|
||||||
inline bool GetGearUnitUp(void) { return GearUp; }
|
inline bool GetGearUnitUp(void) { return GearUp; }
|
||||||
inline bool GetGearUnitDown(void) { return GearDown; }
|
inline bool GetGearUnitDown(void) { return GearDown; }
|
||||||
|
@ -246,6 +248,7 @@ public:
|
||||||
double GetWheelVel(int axis) { return vWhlVelVec(axis);}
|
double GetWheelVel(int axis) { return vWhlVelVec(axis);}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int GearNumber;
|
||||||
FGColumnVector3 vXYZ;
|
FGColumnVector3 vXYZ;
|
||||||
FGColumnVector3 vMoment;
|
FGColumnVector3 vMoment;
|
||||||
FGColumnVector3 vWhlBodyVec;
|
FGColumnVector3 vWhlBodyVec;
|
||||||
|
|
|
@ -82,15 +82,20 @@ FGLocation::FGLocation(double lon, double lat, double radius)
|
||||||
|
|
||||||
void FGLocation::SetLongitude(double longitude)
|
void FGLocation::SetLongitude(double longitude)
|
||||||
{
|
{
|
||||||
double rtmp = sqrt(mECLoc(eX)*mECLoc(eX) + mECLoc(eY)*mECLoc(eY));
|
double rtmp = mECLoc.Magnitude(eX, eY);
|
||||||
|
// Check if we have zero radius.
|
||||||
|
// If so set it to 1, so that we can set a position
|
||||||
|
if (0.0 == mECLoc.Magnitude())
|
||||||
|
rtmp = 1.0;
|
||||||
|
|
||||||
// Fast return if we are on the north or south pole ...
|
// Fast return if we are on the north or south pole ...
|
||||||
if (rtmp == 0.0)
|
if (rtmp == 0.0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mCacheValid = false;
|
mCacheValid = false;
|
||||||
|
|
||||||
mECLoc(eX) = rtmp*sin(longitude);
|
mECLoc(eX) = rtmp*cos(longitude);
|
||||||
mECLoc(eY) = rtmp*cos(longitude);
|
mECLoc(eY) = rtmp*sin(longitude);
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -105,7 +110,7 @@ void FGLocation::SetLatitude(double latitude)
|
||||||
r = 1.0;
|
r = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double rtmp = sqrt(mECLoc(eX)*mECLoc(eX) + mECLoc(eY)*mECLoc(eY));
|
double rtmp = mECLoc.Magnitude(eX, eY);
|
||||||
if (rtmp != 0.0) {
|
if (rtmp != 0.0) {
|
||||||
double fac = r/rtmp*cos(latitude);
|
double fac = r/rtmp*cos(latitude);
|
||||||
mECLoc(eX) *= fac;
|
mECLoc(eX) *= fac;
|
||||||
|
|
|
@ -50,7 +50,7 @@ CLASS IMPLEMENTATION
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||||
|
|
||||||
|
|
||||||
FGNozzle::FGNozzle(FGFDMExec* FDMExec, FGConfigFile* Nzl_cfg) : FGThruster(FDMExec)
|
FGNozzle::FGNozzle(FGFDMExec* FDMExec, FGConfigFile* Nzl_cfg, int num) : FGThruster(FDMExec)
|
||||||
{
|
{
|
||||||
string token;
|
string token;
|
||||||
|
|
||||||
|
@ -71,6 +71,10 @@ FGNozzle::FGNozzle(FGFDMExec* FDMExec, FGConfigFile* Nzl_cfg) : FGThruster(FDMEx
|
||||||
Area2 = (Diameter*Diameter/4.0)*M_PI;
|
Area2 = (Diameter*Diameter/4.0)*M_PI;
|
||||||
AreaT = Area2/ExpR;
|
AreaT = Area2/ExpR;
|
||||||
|
|
||||||
|
char property_name[80];
|
||||||
|
snprintf(property_name, 80, "propulsion/c-thrust[%u]", EngineNum);
|
||||||
|
PropertyManager->Tie( property_name, &ThrustCoeff );
|
||||||
|
|
||||||
Debug(0);
|
Debug(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +82,10 @@ FGNozzle::FGNozzle(FGFDMExec* FDMExec, FGConfigFile* Nzl_cfg) : FGThruster(FDMEx
|
||||||
|
|
||||||
FGNozzle::~FGNozzle()
|
FGNozzle::~FGNozzle()
|
||||||
{
|
{
|
||||||
|
char property_name[80];
|
||||||
|
snprintf(property_name, 80, "propulsion/c-thrust[%u]", EngineNum);
|
||||||
|
PropertyManager->Untie( property_name );
|
||||||
|
|
||||||
Debug(1);
|
Debug(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,6 +97,8 @@ double FGNozzle::Calculate(double CfPc)
|
||||||
Thrust = max((double)0.0, (CfPc * AreaT + (PE - pAtm)*Area2) * nzlEff);
|
Thrust = max((double)0.0, (CfPc * AreaT + (PE - pAtm)*Area2) * nzlEff);
|
||||||
vFn(1) = Thrust * cos(ReverserAngle);
|
vFn(1) = Thrust * cos(ReverserAngle);
|
||||||
|
|
||||||
|
ThrustCoeff = CfPc / ((pAtm - PE) * Area2);
|
||||||
|
|
||||||
return Thrust;
|
return Thrust;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ class FGNozzle : public FGThruster {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
FGNozzle(FGFDMExec* exec, FGConfigFile* AC_cfg);
|
FGNozzle(FGFDMExec* exec, FGConfigFile* AC_cfg, int num = 0);
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~FGNozzle();
|
~FGNozzle();
|
||||||
|
|
||||||
|
|
|
@ -381,9 +381,9 @@ void FGOutput::SocketOutput(void)
|
||||||
socket->Clear();
|
socket->Clear();
|
||||||
socket->Append(State->Getsim_time());
|
socket->Append(State->Getsim_time());
|
||||||
socket->Append(Propagate->Geth());
|
socket->Append(Propagate->Geth());
|
||||||
socket->Append(Propagate->Getphi());
|
socket->Append(Propagate->GetEuler(ePhi));
|
||||||
socket->Append(Propagate->Gettht());
|
socket->Append(Propagate->GetEuler(eTht));
|
||||||
socket->Append(Propagate->Getpsi());
|
socket->Append(Propagate->GetEuler(ePsi));
|
||||||
socket->Append(Atmosphere->GetDensity());
|
socket->Append(Atmosphere->GetDensity());
|
||||||
socket->Append(Auxiliary->GetVt());
|
socket->Append(Auxiliary->GetVt());
|
||||||
socket->Append(Propagate->GetUVW(eU));
|
socket->Append(Propagate->GetUVW(eU));
|
||||||
|
|
|
@ -152,6 +152,9 @@ void FGPropagate::SetInitialState(const FGInitialCondition *FGIC)
|
||||||
|
|
||||||
// Compute some derived values.
|
// Compute some derived values.
|
||||||
vVel = VState.vQtrn.GetTInv()*VState.vUVW;
|
vVel = VState.vQtrn.GetTInv()*VState.vUVW;
|
||||||
|
|
||||||
|
// Finaly make shure that the quaternion stays normalized.
|
||||||
|
VState.vQtrn.Normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -289,13 +292,13 @@ void FGPropagate::bind(void)
|
||||||
|
|
||||||
PropertyManager->Tie("metrics/runway-radius", this, &FGPropagate::GetRunwayRadius, &FGPropagate::SetRunwayRadius);
|
PropertyManager->Tie("metrics/runway-radius", this, &FGPropagate::GetRunwayRadius, &FGPropagate::SetRunwayRadius);
|
||||||
|
|
||||||
PropertyManager->Tie("attitude/phi-rad", this, &FGPropagate::Getphi);
|
PropertyManager->Tie("attitude/phi-rad", this, (int)ePhi, (PMF)&FGPropagate::GetEuler);
|
||||||
PropertyManager->Tie("attitude/theta-rad", this, &FGPropagate::Gettht);
|
PropertyManager->Tie("attitude/theta-rad", this, (int)eTht, (PMF)&FGPropagate::GetEuler);
|
||||||
PropertyManager->Tie("attitude/psi-rad", this, &FGPropagate::Getpsi);
|
PropertyManager->Tie("attitude/psi-rad", this, (int)ePsi, (PMF)&FGPropagate::GetEuler);
|
||||||
|
|
||||||
PropertyManager->Tie("attitude/roll-rad", this, &FGPropagate::Getphi);
|
PropertyManager->Tie("attitude/roll-rad", this, (int)ePhi, (PMF)&FGPropagate::GetEuler);
|
||||||
PropertyManager->Tie("attitude/pitch-rad", this, &FGPropagate::Gettht);
|
PropertyManager->Tie("attitude/pitch-rad", this, (int)eTht, (PMF)&FGPropagate::GetEuler);
|
||||||
PropertyManager->Tie("attitude/heading-true-rad", this, &FGPropagate::Getpsi);
|
PropertyManager->Tie("attitude/heading-true-rad", this, (int)ePsi, (PMF)&FGPropagate::GetEuler);
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
|
@ -106,7 +106,9 @@ public:
|
||||||
double Geth(void) const { return VState.vLocation.GetRadius() - SeaLevelRadius; }
|
double Geth(void) const { return VState.vLocation.GetRadius() - SeaLevelRadius; }
|
||||||
double GetPQR(int axis) const {return VState.vPQR(axis);}
|
double GetPQR(int axis) const {return VState.vPQR(axis);}
|
||||||
double GetPQRdot(int idx) const {return vPQRdot(idx);}
|
double GetPQRdot(int idx) const {return vPQRdot(idx);}
|
||||||
double GetEuler(int axis) const { return VState.vQtrn.GetEuler()(axis); }
|
double GetEuler(int axis) const { return VState.vQtrn.GetEuler(axis); }
|
||||||
|
double GetCosEuler(int idx) const { return VState.vQtrn.GetCosEuler(idx); }
|
||||||
|
double GetSinEuler(int idx) const { return VState.vQtrn.GetSinEuler(idx); }
|
||||||
double Gethdot(void) const { return -vVel(eDown); }
|
double Gethdot(void) const { return -vVel(eDown); }
|
||||||
|
|
||||||
/** Returns the "constant" RunwayRadius.
|
/** Returns the "constant" RunwayRadius.
|
||||||
|
@ -122,18 +124,6 @@ public:
|
||||||
double GetLatitude(void) const { return VState.vLocation.GetLatitude(); }
|
double GetLatitude(void) const { return VState.vLocation.GetLatitude(); }
|
||||||
const FGLocation& GetLocation(void) const { return VState.vLocation; }
|
const FGLocation& GetLocation(void) const { return VState.vLocation; }
|
||||||
|
|
||||||
double Getphi(void) const { return VState.vQtrn.GetEulerPhi(); }
|
|
||||||
double Gettht(void) const { return VState.vQtrn.GetEulerTheta(); }
|
|
||||||
double Getpsi(void) const { return VState.vQtrn.GetEulerPsi(); }
|
|
||||||
|
|
||||||
double GetCosphi(void) const { return VState.vQtrn.GetCosEulerPhi(); }
|
|
||||||
double GetCostht(void) const { return VState.vQtrn.GetCosEulerTheta(); }
|
|
||||||
double GetCospsi(void) const { return VState.vQtrn.GetCosEulerPsi(); }
|
|
||||||
|
|
||||||
double GetSinphi(void) const { return VState.vQtrn.GetSinEulerPhi(); }
|
|
||||||
double GetSintht(void) const { return VState.vQtrn.GetSinEulerTheta(); }
|
|
||||||
double GetSinpsi(void) const { return VState.vQtrn.GetSinEulerPsi(); }
|
|
||||||
|
|
||||||
/** 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. */
|
||||||
const FGMatrix33& GetTl2b(void) const { return VState.vQtrn.GetT(); }
|
const FGMatrix33& GetTl2b(void) const { return VState.vQtrn.GetT(); }
|
||||||
|
|
|
@ -56,7 +56,7 @@ CLASS IMPLEMENTATION
|
||||||
// not just the X-axis of the engine/propeller. This may or may not work for a
|
// not just the X-axis of the engine/propeller. This may or may not work for a
|
||||||
// helicopter.
|
// helicopter.
|
||||||
|
|
||||||
FGPropeller::FGPropeller(FGFDMExec* exec, FGConfigFile* Prop_cfg) : FGThruster(exec)
|
FGPropeller::FGPropeller(FGFDMExec* exec, FGConfigFile* Prop_cfg, int num) : FGThruster(exec)
|
||||||
{
|
{
|
||||||
string token;
|
string token;
|
||||||
int rows, cols;
|
int rows, cols;
|
||||||
|
@ -107,6 +107,10 @@ FGPropeller::FGPropeller(FGFDMExec* exec, FGConfigFile* Prop_cfg) : FGThruster(e
|
||||||
RPM = 0;
|
RPM = 0;
|
||||||
vTorque.InitMatrix();
|
vTorque.InitMatrix();
|
||||||
|
|
||||||
|
char property_name[80];
|
||||||
|
snprintf(property_name, 80, "propulsion/c-thrust[%u]", EngineNum);
|
||||||
|
PropertyManager->Tie( property_name, &ThrustCoeff );
|
||||||
|
|
||||||
Debug(0);
|
Debug(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,6 +120,11 @@ FGPropeller::~FGPropeller()
|
||||||
{
|
{
|
||||||
if (cThrust) delete cThrust;
|
if (cThrust) delete cThrust;
|
||||||
if (cPower) delete cPower;
|
if (cPower) delete cPower;
|
||||||
|
|
||||||
|
char property_name[80];
|
||||||
|
snprintf(property_name, 80, "propulsion/c-thrust[%u]", EngineNum);
|
||||||
|
PropertyManager->Untie( property_name );
|
||||||
|
|
||||||
Debug(1);
|
Debug(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +144,7 @@ FGPropeller::~FGPropeller()
|
||||||
|
|
||||||
double FGPropeller::Calculate(double PowerAvailable)
|
double FGPropeller::Calculate(double PowerAvailable)
|
||||||
{
|
{
|
||||||
double J, C_Thrust, omega;
|
double J, omega;
|
||||||
double Vel = fdmex->GetAuxiliary()->GetAeroUVW(eU);
|
double Vel = fdmex->GetAuxiliary()->GetAeroUVW(eU);
|
||||||
double rho = fdmex->GetAtmosphere()->GetDensity();
|
double rho = fdmex->GetAtmosphere()->GetDensity();
|
||||||
double RPS = RPM/60.0;
|
double RPS = RPM/60.0;
|
||||||
|
@ -148,9 +157,9 @@ double FGPropeller::Calculate(double PowerAvailable)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MaxPitch == MinPitch) { // Fixed pitch prop
|
if (MaxPitch == MinPitch) { // Fixed pitch prop
|
||||||
C_Thrust = cThrust->GetValue(J);
|
ThrustCoeff = cThrust->GetValue(J);
|
||||||
} else { // Variable pitch prop
|
} else { // Variable pitch prop
|
||||||
C_Thrust = cThrust->GetValue(J, Pitch);
|
ThrustCoeff = cThrust->GetValue(J, Pitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (P_Factor > 0.0001) {
|
if (P_Factor > 0.0001) {
|
||||||
|
@ -162,7 +171,7 @@ double FGPropeller::Calculate(double PowerAvailable)
|
||||||
cerr << "P-Factor value in config file must be greater than zero" << endl;
|
cerr << "P-Factor value in config file must be greater than zero" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thrust = C_Thrust*RPS*RPS*Diameter*Diameter*Diameter*Diameter*rho;
|
Thrust = ThrustCoeff*RPS*RPS*Diameter*Diameter*Diameter*Diameter*rho;
|
||||||
omega = RPS*2.0*M_PI;
|
omega = RPS*2.0*M_PI;
|
||||||
|
|
||||||
vFn(1) = Thrust;
|
vFn(1) = Thrust;
|
||||||
|
|
|
@ -89,7 +89,7 @@ public:
|
||||||
/** Constructor for FGPropeller.
|
/** Constructor for FGPropeller.
|
||||||
@param exec a pointer to the main executive object
|
@param exec a pointer to the main executive object
|
||||||
@param AC_cfg a pointer to the main aircraft config file object */
|
@param AC_cfg a pointer to the main aircraft config file object */
|
||||||
FGPropeller(FGFDMExec* exec, FGConfigFile* AC_cfg);
|
FGPropeller(FGFDMExec* exec, FGConfigFile* AC_cfg, int num = 0);
|
||||||
|
|
||||||
/// Destructor for FGPropeller - deletes the FGTable objects
|
/// Destructor for FGPropeller - deletes the FGTable objects
|
||||||
~FGPropeller();
|
~FGPropeller();
|
||||||
|
|
|
@ -130,12 +130,17 @@ FGQuaternion::FGQuaternion(double phi, double tht, double psi)
|
||||||
angular velocities PQR.
|
angular velocities PQR.
|
||||||
*/
|
*/
|
||||||
FGQuaternion FGQuaternion::GetQDot(const FGColumnVector3& PQR) const {
|
FGQuaternion FGQuaternion::GetQDot(const FGColumnVector3& PQR) const {
|
||||||
|
double norm = Magnitude();
|
||||||
|
if (norm == 0.0)
|
||||||
|
return FGQuaternion::zero();
|
||||||
|
double rnorm = 1.0/norm;
|
||||||
|
|
||||||
FGQuaternion QDot;
|
FGQuaternion QDot;
|
||||||
QDot(1) = -0.5*(Entry(2)*PQR(eP) + Entry(3)*PQR(eQ) + Entry(4)*PQR(eR));
|
QDot(1) = -0.5*(Entry(2)*PQR(eP) + Entry(3)*PQR(eQ) + Entry(4)*PQR(eR));
|
||||||
QDot(2) = 0.5*(Entry(1)*PQR(eP) + Entry(3)*PQR(eR) - Entry(4)*PQR(eQ));
|
QDot(2) = 0.5*(Entry(1)*PQR(eP) + Entry(3)*PQR(eR) - Entry(4)*PQR(eQ));
|
||||||
QDot(3) = 0.5*(Entry(1)*PQR(eQ) + Entry(4)*PQR(eP) - Entry(2)*PQR(eR));
|
QDot(3) = 0.5*(Entry(1)*PQR(eQ) + Entry(4)*PQR(eP) - Entry(2)*PQR(eR));
|
||||||
QDot(4) = 0.5*(Entry(1)*PQR(eR) + Entry(2)*PQR(eQ) - Entry(3)*PQR(eP));
|
QDot(4) = 0.5*(Entry(1)*PQR(eR) + Entry(2)*PQR(eQ) - Entry(3)*PQR(eP));
|
||||||
return QDot;
|
return rnorm*QDot;
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
|
@ -110,6 +110,39 @@ public:
|
||||||
@param psi The euler Z axis (heading) angle in radians */
|
@param psi The euler Z axis (heading) angle in radians */
|
||||||
FGQuaternion(double phi, double tht, double psi);
|
FGQuaternion(double phi, double tht, double psi);
|
||||||
|
|
||||||
|
/** Initializer by one euler angle.
|
||||||
|
Initialize the quaternion with the single euler angle where its index
|
||||||
|
is given in the first argument.
|
||||||
|
@param idx Index of the euler angle to initialize
|
||||||
|
@param angle The euler angle in radians */
|
||||||
|
FGQuaternion(int idx, double angle)
|
||||||
|
: mCacheValid(false) {
|
||||||
|
double angle2 = 0.5*angle;
|
||||||
|
|
||||||
|
double Sangle2 = sin(angle2);
|
||||||
|
double Cangle2 = cos(angle2);
|
||||||
|
|
||||||
|
if (idx == ePhi) {
|
||||||
|
Entry(1) = Cangle2;
|
||||||
|
Entry(2) = Sangle2;
|
||||||
|
Entry(3) = 0.0;
|
||||||
|
Entry(4) = 0.0;
|
||||||
|
|
||||||
|
} else if (idx == eTht) {
|
||||||
|
Entry(1) = Cangle2;
|
||||||
|
Entry(2) = 0.0;
|
||||||
|
Entry(3) = Sangle2;
|
||||||
|
Entry(4) = 0.0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Entry(1) = Cangle2;
|
||||||
|
Entry(2) = 0.0;
|
||||||
|
Entry(3) = 0.0;
|
||||||
|
Entry(4) = Sangle2;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Destructor.
|
/// Destructor.
|
||||||
~FGQuaternion() {}
|
~FGQuaternion() {}
|
||||||
|
|
||||||
|
@ -123,121 +156,56 @@ public:
|
||||||
/** Transformation matrix.
|
/** Transformation matrix.
|
||||||
@return a reference to the transformation/rotation matrix
|
@return a reference to the transformation/rotation matrix
|
||||||
corresponding to this quaternion rotation. */
|
corresponding to this quaternion rotation. */
|
||||||
const FGMatrix33& GetT() const { ComputeDerived(); return mT; }
|
const FGMatrix33& GetT(void) const { ComputeDerived(); return mT; }
|
||||||
|
|
||||||
/** Backward transformation matrix.
|
/** Backward transformation matrix.
|
||||||
@return a reference to the inverse transformation/rotation matrix
|
@return a reference to the inverse transformation/rotation matrix
|
||||||
corresponding to this quaternion rotation. */
|
corresponding to this quaternion rotation. */
|
||||||
const FGMatrix33& GetTInv() const { ComputeDerived(); return mTInv; }
|
const FGMatrix33& GetTInv(void) const { ComputeDerived(); return mTInv; }
|
||||||
|
|
||||||
/** Retrieves the Euler angles.
|
/** Retrieves the Euler angles.
|
||||||
@return a reference to the triad of euler angles corresponding
|
@return a reference to the triad of euler angles corresponding
|
||||||
to this quaternion rotation.
|
to this quaternion rotation.
|
||||||
@units radians */
|
@units radians */
|
||||||
const FGColumnVector3& GetEuler() const {
|
const FGColumnVector3& GetEuler(void) const {
|
||||||
ComputeDerived();
|
ComputeDerived();
|
||||||
return mEulerAngles;
|
return mEulerAngles;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Euler angle theta.
|
/** Retrieves the Euler angles.
|
||||||
@return the euler angle theta (pitch attitude) corresponding to this
|
@param i the euler angle index.
|
||||||
quaternion rotation.
|
@return a reference to the i-th euler angles corresponding
|
||||||
|
to this quaternion rotation.
|
||||||
@units radians */
|
@units radians */
|
||||||
double GetEulerTheta() const {
|
double GetEuler(int i) const {
|
||||||
ComputeDerived();
|
ComputeDerived();
|
||||||
return mEulerAngles(eTht);
|
return mEulerAngles(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Euler angle theta.
|
/** Retrieves the Euler angles.
|
||||||
@return the euler angle theta (pitch attitude) corresponding to
|
@param i the euler angle index.
|
||||||
this quaternion rotation.
|
@return a reference to the i-th euler angles corresponding
|
||||||
|
to this quaternion rotation.
|
||||||
@units degrees */
|
@units degrees */
|
||||||
double GetEulerThetaDeg() const {
|
double GetEulerDeg(int i) const {
|
||||||
ComputeDerived();
|
ComputeDerived();
|
||||||
return radtodeg*mEulerAngles(eTht);
|
return radtodeg*mEulerAngles(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Euler angle psi.
|
/** Retrieves sine of the given euler angle.
|
||||||
@return the heading euler angle (psi) corresponding to this quaternion
|
|
||||||
rotation.
|
|
||||||
@units radians */
|
|
||||||
double GetEulerPsi() const {
|
|
||||||
ComputeDerived();
|
|
||||||
return mEulerAngles(ePsi);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Retrieves the heading angle.
|
|
||||||
@return the Euler angle psi (heading) corresponding to this quaternion
|
|
||||||
rotation.
|
|
||||||
@units degrees */
|
|
||||||
double GetEulerPsiDeg() const {
|
|
||||||
ComputeDerived();
|
|
||||||
return radtodeg*mEulerAngles(ePsi);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Retrieves the roll angle.
|
|
||||||
@return the euler angle phi (roll) corresponding to this quaternion
|
|
||||||
rotation.
|
|
||||||
@units radians */
|
|
||||||
double GetEulerPhi() const {
|
|
||||||
ComputeDerived();
|
|
||||||
return mEulerAngles(ePhi);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Retrieves the roll angle.
|
|
||||||
Returns the Euler angle phi (roll) corresponding to this quaternion rotation.
|
|
||||||
@units degrees */
|
|
||||||
double GetEulerPhiDeg() const {
|
|
||||||
ComputeDerived();
|
|
||||||
return radtodeg*mEulerAngles(ePhi);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Retrieves sine theta.
|
|
||||||
@return the sine of the Euler angle theta (pitch attitude) corresponding
|
@return the sine of the Euler angle theta (pitch attitude) corresponding
|
||||||
to this quaternion rotation. */
|
to this quaternion rotation. */
|
||||||
double GetSinEulerTheta() const {
|
double GetSinEuler(int i) const {
|
||||||
ComputeDerived();
|
ComputeDerived();
|
||||||
return mEulerSines(eTht);
|
return mEulerSines(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Retrieves sine psi.
|
/** Retrieves cosine of the given euler angle.
|
||||||
@return the sine of the Euler angle psi (heading) corresponding to this
|
@return the sine of the Euler angle theta (pitch attitude) corresponding
|
||||||
quaternion rotation. */
|
to this quaternion rotation. */
|
||||||
double GetSinEulerPsi() const {
|
double GetCosEuler(int i) const {
|
||||||
ComputeDerived();
|
ComputeDerived();
|
||||||
return mEulerSines(ePsi);
|
return mEulerCosines(i);
|
||||||
}
|
|
||||||
|
|
||||||
/** Sine of euler angle phi.
|
|
||||||
@return the sine of the Euler angle phi (roll) corresponding to this
|
|
||||||
quaternion rotation. */
|
|
||||||
double GetSinEulerPhi() const {
|
|
||||||
ComputeDerived();
|
|
||||||
return mEulerSines(ePhi);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Cosine of euler angle theta.
|
|
||||||
@return the cosine of the Euler angle theta (pitch) corresponding to this
|
|
||||||
quaternion rotation. */
|
|
||||||
double GetCosEulerTheta() const {
|
|
||||||
ComputeDerived();
|
|
||||||
return mEulerCosines(eTht);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Cosine of euler angle psi.
|
|
||||||
@return the cosine of the Euler angle psi (heading) corresponding to this
|
|
||||||
quaternion rotation. */
|
|
||||||
double GetCosEulerPsi() const {
|
|
||||||
ComputeDerived();
|
|
||||||
return mEulerCosines(ePsi);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Cosine of euler angle phi.
|
|
||||||
@return the cosine of the Euler angle phi (roll) corresponding to this
|
|
||||||
quaternion rotation. */
|
|
||||||
double GetCosEulerPhi() const {
|
|
||||||
ComputeDerived();
|
|
||||||
return mEulerCosines(ePhi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Read access the entries of the vector.
|
/** Read access the entries of the vector.
|
||||||
|
@ -413,19 +381,43 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Inverse of the quaternion.
|
||||||
|
|
||||||
|
Compute and return the inverse of the quaternion so that the orientation
|
||||||
|
represented with *this multiplied with the returned value is equal to
|
||||||
|
the identity orientation.
|
||||||
|
*/
|
||||||
|
FGQuaternion Inverse(void) const {
|
||||||
|
double norm = Magnitude();
|
||||||
|
if (norm == 0.0)
|
||||||
|
return *this;
|
||||||
|
double rNorm = 1.0/norm;
|
||||||
|
return FGQuaternion( Entry(1)*rNorm, -Entry(2)*rNorm,
|
||||||
|
-Entry(3)*rNorm, -Entry(4)*rNorm );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Conjugate of the quaternion.
|
||||||
|
|
||||||
|
Compute and return the conjugate of the quaternion. This one is equal
|
||||||
|
to the inverse iff the quaternion is normalized.
|
||||||
|
*/
|
||||||
|
FGQuaternion Conjugate(void) const {
|
||||||
|
return FGQuaternion( Entry(1), -Entry(2), -Entry(3), -Entry(4) );
|
||||||
|
}
|
||||||
|
|
||||||
friend FGQuaternion operator*(double, const FGQuaternion&);
|
friend FGQuaternion operator*(double, const FGQuaternion&);
|
||||||
|
|
||||||
/** Length of the vector.
|
/** Length of the vector.
|
||||||
|
|
||||||
Compute and return the euclidean norm of this vector.
|
Compute and return the euclidean norm of this vector.
|
||||||
*/
|
*/
|
||||||
double Magnitude() const { return sqrt(SqrMagnitude()); }
|
double Magnitude(void) const { return sqrt(SqrMagnitude()); }
|
||||||
|
|
||||||
/** Square of the length of the vector.
|
/** Square of the length of the vector.
|
||||||
|
|
||||||
Compute and return the square of the euclidean norm of this vector.
|
Compute and return the square of the euclidean norm of this vector.
|
||||||
*/
|
*/
|
||||||
double SqrMagnitude() const {
|
double SqrMagnitude(void) const {
|
||||||
return Entry(1)*Entry(1)+Entry(2)*Entry(2)
|
return Entry(1)*Entry(1)+Entry(2)*Entry(2)
|
||||||
+Entry(3)*Entry(3)+Entry(4)*Entry(4);
|
+Entry(3)*Entry(3)+Entry(4)*Entry(4);
|
||||||
}
|
}
|
||||||
|
@ -435,7 +427,7 @@ public:
|
||||||
Normalize the vector to have the Magnitude() == 1.0. If the vector
|
Normalize the vector to have the Magnitude() == 1.0. If the vector
|
||||||
is equal to zero it is left untouched.
|
is equal to zero it is left untouched.
|
||||||
*/
|
*/
|
||||||
void Normalize();
|
void Normalize(void);
|
||||||
|
|
||||||
/** Zero quaternion vector. Does not represent any orientation.
|
/** Zero quaternion vector. Does not represent any orientation.
|
||||||
Useful for initialization of increments */
|
Useful for initialization of increments */
|
||||||
|
@ -454,7 +446,10 @@ private:
|
||||||
/** Computation of derived values.
|
/** Computation of derived values.
|
||||||
This function checks if the derived values like euler angles and
|
This function checks if the derived values like euler angles and
|
||||||
transformation matrices are already computed. If so, it
|
transformation matrices are already computed. If so, it
|
||||||
returns. If they need to be computed this is done here. */
|
returns. If they need to be computed the real worker routine
|
||||||
|
\ref FGQuaternion::ComputeDerivedUnconditional(void) const
|
||||||
|
is called.
|
||||||
|
This function is inlined to avoid function calls in the fast path. */
|
||||||
void ComputeDerived(void) const {
|
void ComputeDerived(void) const {
|
||||||
if (!mCacheValid)
|
if (!mCacheValid)
|
||||||
ComputeDerivedUnconditional();
|
ComputeDerivedUnconditional();
|
||||||
|
|
|
@ -54,18 +54,30 @@ FGThruster::FGThruster(FGFDMExec *FDMExec) : FGForce(FDMExec)
|
||||||
Type = ttDirect;
|
Type = ttDirect;
|
||||||
SetTransformType(FGForce::tCustom);
|
SetTransformType(FGForce::tCustom);
|
||||||
|
|
||||||
|
EngineNum = 0;
|
||||||
|
PropertyManager = FDMExec->GetPropertyManager();
|
||||||
|
|
||||||
Debug(0);
|
Debug(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
FGThruster::FGThruster(FGFDMExec *FDMExec,
|
FGThruster::FGThruster(FGFDMExec *FDMExec,
|
||||||
FGConfigFile *Eng_cfg ): FGForce(FDMExec)
|
FGConfigFile *Eng_cfg, int num ): FGForce(FDMExec)
|
||||||
{
|
{
|
||||||
Type = ttDirect;
|
Type = ttDirect;
|
||||||
SetTransformType(FGForce::tCustom);
|
SetTransformType(FGForce::tCustom);
|
||||||
Name = Eng_cfg->GetValue();
|
Name = Eng_cfg->GetValue();
|
||||||
GearRatio = 1.0;
|
GearRatio = 1.0;
|
||||||
|
|
||||||
|
EngineNum = num;
|
||||||
|
ThrustCoeff = 0.0;
|
||||||
|
PropertyManager = FDMExec->GetPropertyManager();
|
||||||
|
|
||||||
|
char property_name[80];
|
||||||
|
snprintf(property_name, 80, "propulsion/c-thrust[%u]", EngineNum);
|
||||||
|
PropertyManager->Tie( property_name, &ThrustCoeff );
|
||||||
|
|
||||||
Debug(0);
|
Debug(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +85,10 @@ FGThruster::FGThruster(FGFDMExec *FDMExec,
|
||||||
|
|
||||||
FGThruster::~FGThruster()
|
FGThruster::~FGThruster()
|
||||||
{
|
{
|
||||||
|
char property_name[80];
|
||||||
|
snprintf(property_name, 80, "propulsion/c-thrust[%u]", EngineNum);
|
||||||
|
PropertyManager->Untie( property_name );
|
||||||
|
|
||||||
Debug(1);
|
Debug(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ INCLUDES
|
||||||
|
|
||||||
#include "FGForce.h"
|
#include "FGForce.h"
|
||||||
#include "FGConfigFile.h"
|
#include "FGConfigFile.h"
|
||||||
|
#include "FGPropertyManager.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -72,13 +73,16 @@ class FGThruster : public FGForce {
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
FGThruster(FGFDMExec *FDMExec);
|
FGThruster(FGFDMExec *FDMExec);
|
||||||
FGThruster(FGFDMExec *FDMExec, FGConfigFile *Eng_cfg );
|
FGThruster(FGFDMExec *FDMExec, FGConfigFile *Eng_cfg, int num );
|
||||||
/// Destructor
|
/// Destructor
|
||||||
virtual ~FGThruster();
|
virtual ~FGThruster();
|
||||||
|
|
||||||
enum eType {ttNozzle, ttRotor, ttPropeller, ttDirect};
|
enum eType {ttNozzle, ttRotor, ttPropeller, ttDirect};
|
||||||
|
|
||||||
virtual double Calculate(double tt) { Thrust = tt; vFn(1) = Thrust; return 0.0; }
|
virtual double Calculate(double tt) {
|
||||||
|
Thrust = tt; vFn(1) = Thrust;
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
void SetName(string name) {Name = name;}
|
void SetName(string name) {Name = name;}
|
||||||
virtual void SetRPM(double rpm) {};
|
virtual void SetRPM(double rpm) {};
|
||||||
virtual double GetPowerRequired(void) {return 0.0;}
|
virtual double GetPowerRequired(void) {return 0.0;}
|
||||||
|
@ -98,6 +102,9 @@ protected:
|
||||||
double PowerRequired;
|
double PowerRequired;
|
||||||
double deltaT;
|
double deltaT;
|
||||||
double GearRatio;
|
double GearRatio;
|
||||||
|
double ThrustCoeff;
|
||||||
|
int EngineNum;
|
||||||
|
FGPropertyManager* PropertyManager;
|
||||||
virtual void Debug(int from);
|
virtual void Debug(int from);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,13 +124,13 @@ FGTrimAxis::FGTrimAxis(FGFDMExec* fdex, FGInitialCondition* ic, State st,
|
||||||
solver_eps=tolerance/100;
|
solver_eps=tolerance/100;
|
||||||
break;
|
break;
|
||||||
case tTheta:
|
case tTheta:
|
||||||
control_min=fdmex->GetPropagate()->Gettht() - 5*degtorad;
|
control_min=fdmex->GetPropagate()->GetEuler(eTht) - 5*degtorad;
|
||||||
control_max=fdmex->GetPropagate()->Gettht() + 5*degtorad;
|
control_max=fdmex->GetPropagate()->GetEuler(eTht) + 5*degtorad;
|
||||||
state_convert=radtodeg;
|
state_convert=radtodeg;
|
||||||
break;
|
break;
|
||||||
case tPhi:
|
case tPhi:
|
||||||
control_min=fdmex->GetPropagate()->Getphi() - 30*degtorad;
|
control_min=fdmex->GetPropagate()->GetEuler(ePhi) - 30*degtorad;
|
||||||
control_max=fdmex->GetPropagate()->Getphi() + 30*degtorad;
|
control_max=fdmex->GetPropagate()->GetEuler(ePhi) + 30*degtorad;
|
||||||
state_convert=radtodeg;
|
state_convert=radtodeg;
|
||||||
control_convert=radtodeg;
|
control_convert=radtodeg;
|
||||||
break;
|
break;
|
||||||
|
@ -141,8 +141,8 @@ FGTrimAxis::FGTrimAxis(FGFDMExec* fdex, FGInitialCondition* ic, State st,
|
||||||
control_convert=radtodeg;
|
control_convert=radtodeg;
|
||||||
break;
|
break;
|
||||||
case tHeading:
|
case tHeading:
|
||||||
control_min=fdmex->GetPropagate()->Getpsi() - 30*degtorad;
|
control_min=fdmex->GetPropagate()->GetEuler(ePsi) - 30*degtorad;
|
||||||
control_max=fdmex->GetPropagate()->Getpsi() + 30*degtorad;
|
control_max=fdmex->GetPropagate()->GetEuler(ePsi) + 30*degtorad;
|
||||||
state_convert=radtodeg;
|
state_convert=radtodeg;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -190,10 +190,10 @@ void FGTrimAxis::getControl(void) {
|
||||||
case tYawTrim:
|
case tYawTrim:
|
||||||
case tRudder: control_value=fdmex->GetFCS() -> GetDrCmd(); break;
|
case tRudder: control_value=fdmex->GetFCS() -> GetDrCmd(); break;
|
||||||
case tAltAGL: control_value=fdmex->GetPropagate()->GetDistanceAGL();break;
|
case tAltAGL: control_value=fdmex->GetPropagate()->GetDistanceAGL();break;
|
||||||
case tTheta: control_value=fdmex->GetPropagate()->Gettht(); break;
|
case tTheta: control_value=fdmex->GetPropagate()->GetEuler(eTht); break;
|
||||||
case tPhi: control_value=fdmex->GetPropagate()->Getphi(); break;
|
case tPhi: control_value=fdmex->GetPropagate()->GetEuler(ePhi); break;
|
||||||
case tGamma: control_value=fdmex->GetAuxiliary()->GetGamma();break;
|
case tGamma: control_value=fdmex->GetAuxiliary()->GetGamma();break;
|
||||||
case tHeading: control_value=fdmex->GetPropagate()->Getpsi(); break;
|
case tHeading: control_value=fdmex->GetPropagate()->GetEuler(ePsi); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ void FGTrimAxis::getControl(void) {
|
||||||
double FGTrimAxis::computeHmgt(void) {
|
double FGTrimAxis::computeHmgt(void) {
|
||||||
double diff;
|
double diff;
|
||||||
|
|
||||||
diff = fdmex->GetPropagate()->Getpsi() -
|
diff = fdmex->GetPropagate()->GetEuler(ePsi) -
|
||||||
fdmex->GetAuxiliary()->GetGroundTrack();
|
fdmex->GetAuxiliary()->GetGroundTrack();
|
||||||
|
|
||||||
if( diff < -M_PI ) {
|
if( diff < -M_PI ) {
|
||||||
|
@ -270,8 +270,8 @@ void FGTrimAxis::SetThetaOnGround(double ff) {
|
||||||
}
|
}
|
||||||
cout << "SetThetaOnGround ref gear: " << ref << endl;
|
cout << "SetThetaOnGround ref gear: " << ref << endl;
|
||||||
if(ref >= 0) {
|
if(ref >= 0) {
|
||||||
double sp = fdmex->GetPropagate()->GetSinphi();
|
double sp = fdmex->GetPropagate()->GetSinEuler(ePhi);
|
||||||
double cp = fdmex->GetPropagate()->GetCosphi();
|
double cp = fdmex->GetPropagate()->GetCosEuler(ePhi);
|
||||||
double lx = fdmex->GetGroundReactions()->GetGearUnit(ref)->GetBodyLocation(1);
|
double lx = fdmex->GetGroundReactions()->GetGearUnit(ref)->GetBodyLocation(1);
|
||||||
double ly = fdmex->GetGroundReactions()->GetGearUnit(ref)->GetBodyLocation(2);
|
double ly = fdmex->GetGroundReactions()->GetGearUnit(ref)->GetBodyLocation(2);
|
||||||
double lz = fdmex->GetGroundReactions()->GetGearUnit(ref)->GetBodyLocation(3);
|
double lz = fdmex->GetGroundReactions()->GetGearUnit(ref)->GetBodyLocation(3);
|
||||||
|
@ -344,7 +344,7 @@ bool FGTrimAxis::initTheta(void) {
|
||||||
}
|
}
|
||||||
//cout << i << endl;
|
//cout << i << endl;
|
||||||
if (debug_lvl > 0) {
|
if (debug_lvl > 0) {
|
||||||
cout << " Initial Theta: " << fdmex->GetPropagate()->Gettht()*radtodeg << endl;
|
cout << " Initial Theta: " << fdmex->GetPropagate()->GetEuler(eTht)*radtodeg << endl;
|
||||||
cout << " Used gear unit " << iAft << " as aft and " << iForward << " as forward" << endl;
|
cout << " Used gear unit " << iAft << " as aft and " << iForward << " as forward" << endl;
|
||||||
}
|
}
|
||||||
control_min=(theta+5)*degtorad;
|
control_min=(theta+5)*degtorad;
|
||||||
|
@ -370,8 +370,8 @@ void FGTrimAxis::SetPhiOnGround(double ff) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (ref >= 0) {
|
if (ref >= 0) {
|
||||||
double st = sin(fdmex->GetPropagate()->Gettht());
|
double st = fdmex->GetPropagate()->GetSinEuler(eTht);
|
||||||
double ct = cos(fdmex->GetPropagate()->Gettht());
|
double ct = fdmex->GetPropagate()->GetCosEuler(eTht);
|
||||||
double lx = fdmex->GetGroundReactions()->GetGearUnit(ref)->GetBodyLocation(1);
|
double lx = fdmex->GetGroundReactions()->GetGearUnit(ref)->GetBodyLocation(1);
|
||||||
double ly = fdmex->GetGroundReactions()->GetGearUnit(ref)->GetBodyLocation(2);
|
double ly = fdmex->GetGroundReactions()->GetGearUnit(ref)->GetBodyLocation(2);
|
||||||
double lz = fdmex->GetGroundReactions()->GetGearUnit(ref)->GetBodyLocation(3);
|
double lz = fdmex->GetGroundReactions()->GetGearUnit(ref)->GetBodyLocation(3);
|
||||||
|
@ -431,11 +431,16 @@ void FGTrimAxis::setThrottlesPct(void) {
|
||||||
void FGTrimAxis::AxisReport(void) {
|
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",
|
||||||
GetControlName().c_str(), GetControl()*control_convert,
|
GetControlName().c_str(), GetControl()*control_convert,
|
||||||
GetStateName().c_str(), GetState()+state_target, GetTolerance());
|
GetStateName().c_str(), GetState()+state_target, GetTolerance());
|
||||||
cout << out;
|
cout << out;
|
||||||
|
|
||||||
|
if( abs(GetState()+state_target) < abs(GetTolerance()) )
|
||||||
|
cout << " Passed" << endl;
|
||||||
|
else
|
||||||
|
cout << " Failed" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -396,6 +396,7 @@ bool FGTurbine::Load(FGConfigFile *Eng_cfg)
|
||||||
ThrustTables.back()->Load(Eng_cfg);
|
ThrustTables.back()->Load(Eng_cfg);
|
||||||
}
|
}
|
||||||
else cerr << "Unhandled token in Engine config file: " << token << endl;
|
else cerr << "Unhandled token in Engine config file: " << token << endl;
|
||||||
|
if (token == "EOF") return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pre-calculations and initializations
|
// Pre-calculations and initializations
|
||||||
|
|
|
@ -314,11 +314,11 @@ void FGJSBsim::init()
|
||||||
stall_warning->setDoubleValue(0);
|
stall_warning->setDoubleValue(0);
|
||||||
|
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, " Bank Angle: "
|
SG_LOG( SG_FLIGHT, SG_INFO, " Bank Angle: "
|
||||||
<< Propagate->Getphi()*RADTODEG << " deg" );
|
<< Propagate->GetEuler(ePhi)*RADTODEG << " deg" );
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, " Pitch Angle: "
|
SG_LOG( SG_FLIGHT, SG_INFO, " Pitch Angle: "
|
||||||
<< Propagate->Gettht()*RADTODEG << " deg" );
|
<< Propagate->GetEuler(eTht)*RADTODEG << " deg" );
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, " True Heading: "
|
SG_LOG( SG_FLIGHT, SG_INFO, " True Heading: "
|
||||||
<< Propagate->Getpsi()*RADTODEG << " deg" );
|
<< Propagate->GetEuler(ePsi)*RADTODEG << " deg" );
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, " Latitude: "
|
SG_LOG( SG_FLIGHT, SG_INFO, " Latitude: "
|
||||||
<< Propagate->GetLocation().GetLatitudeDeg() << " deg" );
|
<< Propagate->GetLocation().GetLatitudeDeg() << " deg" );
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, " Longitude: "
|
SG_LOG( SG_FLIGHT, SG_INFO, " Longitude: "
|
||||||
|
@ -415,6 +415,9 @@ bool FGJSBsim::copy_to_JSBsim()
|
||||||
FCS->SetPitchTrimCmd( globals->get_controls()->get_elevator_trim() );
|
FCS->SetPitchTrimCmd( globals->get_controls()->get_elevator_trim() );
|
||||||
FCS->SetDrCmd( -globals->get_controls()->get_rudder() );
|
FCS->SetDrCmd( -globals->get_controls()->get_rudder() );
|
||||||
FCS->SetYawTrimCmd( -globals->get_controls()->get_rudder_trim() );
|
FCS->SetYawTrimCmd( -globals->get_controls()->get_rudder_trim() );
|
||||||
|
// FIXME: make that get_steering work
|
||||||
|
// FCS->SetDsCmd( globals->get_controls()->get_steering()/80.0 );
|
||||||
|
FCS->SetDsCmd( globals->get_controls()->get_rudder() );
|
||||||
FCS->SetDfCmd( globals->get_controls()->get_flaps() );
|
FCS->SetDfCmd( globals->get_controls()->get_flaps() );
|
||||||
FCS->SetDsbCmd( globals->get_controls()->get_speedbrake() );
|
FCS->SetDsbCmd( globals->get_controls()->get_speedbrake() );
|
||||||
FCS->SetDspCmd( globals->get_controls()->get_spoilers() );
|
FCS->SetDspCmd( globals->get_controls()->get_spoilers() );
|
||||||
|
@ -576,9 +579,9 @@ bool FGJSBsim::copy_from_JSBsim()
|
||||||
|
|
||||||
_set_Altitude_AGL( Propagate->GetDistanceAGL() );
|
_set_Altitude_AGL( Propagate->GetDistanceAGL() );
|
||||||
|
|
||||||
_set_Euler_Angles( Propagate->Getphi(),
|
_set_Euler_Angles( Propagate->GetEuler(ePhi),
|
||||||
Propagate->Gettht(),
|
Propagate->GetEuler(eTht),
|
||||||
Propagate->Getpsi() );
|
Propagate->GetEuler(ePsi) );
|
||||||
|
|
||||||
_set_Alpha( Auxiliary->Getalpha() );
|
_set_Alpha( Auxiliary->Getalpha() );
|
||||||
_set_Beta( Auxiliary->Getbeta() );
|
_set_Beta( Auxiliary->Getbeta() );
|
||||||
|
@ -914,17 +917,17 @@ void FGJSBsim::init_gear(void )
|
||||||
FGGroundReactions* gr=fdmex->GetGroundReactions();
|
FGGroundReactions* gr=fdmex->GetGroundReactions();
|
||||||
int Ngear=GroundReactions->GetNumGearUnits();
|
int Ngear=GroundReactions->GetNumGearUnits();
|
||||||
for (int i=0;i<Ngear;i++) {
|
for (int i=0;i<Ngear;i++) {
|
||||||
|
FGLGear *gear = gr->GetGearUnit(i);
|
||||||
SGPropertyNode * node = fgGetNode("gear/gear", i, true);
|
SGPropertyNode * node = fgGetNode("gear/gear", i, true);
|
||||||
node->setDoubleValue("xoffset-in",
|
node->setDoubleValue("xoffset-in", gear->GetBodyLocation()(1));
|
||||||
gr->GetGearUnit(i)->GetBodyLocation()(1));
|
node->setDoubleValue("yoffset-in", gear->GetBodyLocation()(2));
|
||||||
node->setDoubleValue("yoffset-in",
|
node->setDoubleValue("zoffset-in", gear->GetBodyLocation()(3));
|
||||||
gr->GetGearUnit(i)->GetBodyLocation()(2));
|
node->setBoolValue("wow", gear->GetWOW());
|
||||||
node->setDoubleValue("zoffset-in",
|
node->setBoolValue("has-brake", gear->GetBrakeGroup() > 0);
|
||||||
gr->GetGearUnit(i)->GetBodyLocation()(3));
|
|
||||||
node->setBoolValue("wow", gr->GetGearUnit(i)->GetWOW());
|
|
||||||
node->setBoolValue("has-brake", gr->GetGearUnit(i)->GetBrakeGroup() > 0);
|
|
||||||
node->setDoubleValue("position-norm", FCS->GetGearPos());
|
node->setDoubleValue("position-norm", FCS->GetGearPos());
|
||||||
node->setDoubleValue("tire-pressure-norm", gr->GetGearUnit(i)->GetTirePressure());
|
node->setDoubleValue("tire-pressure-norm", gear->GetTirePressure());
|
||||||
|
if ( gear->GetSteerable() )
|
||||||
|
node->setDoubleValue("steering-norm", gear->GetSteerNorm());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -933,10 +936,13 @@ void FGJSBsim::update_gear(void)
|
||||||
FGGroundReactions* gr=fdmex->GetGroundReactions();
|
FGGroundReactions* gr=fdmex->GetGroundReactions();
|
||||||
int Ngear=GroundReactions->GetNumGearUnits();
|
int Ngear=GroundReactions->GetNumGearUnits();
|
||||||
for (int i=0;i<Ngear;i++) {
|
for (int i=0;i<Ngear;i++) {
|
||||||
|
FGLGear *gear = gr->GetGearUnit(i);
|
||||||
SGPropertyNode * node = fgGetNode("gear/gear", i, true);
|
SGPropertyNode * node = fgGetNode("gear/gear", i, true);
|
||||||
node->getChild("wow", 0, true)->setBoolValue(gr->GetGearUnit(i)->GetWOW());
|
node->getChild("wow", 0, true)->setBoolValue( gear->GetWOW());
|
||||||
node->getChild("position-norm", 0, true)->setDoubleValue(FCS->GetGearPos());
|
node->getChild("position-norm", 0, true)->setDoubleValue(FCS->GetGearPos());
|
||||||
gr->GetGearUnit(i)->SetTirePressure(node->getDoubleValue("tire-pressure-norm"));
|
gear->SetTirePressure(node->getDoubleValue("tire-pressure-norm"));
|
||||||
|
if ( gear->GetSteerable() )
|
||||||
|
node->setDoubleValue("steering-norm", gear->GetSteerNorm());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue