1
0
Fork 0
flightgear/src/FDM/JSBSim/FGPropulsion.cpp

641 lines
22 KiB
C++
Raw Normal View History

2000-11-03 23:02:47 +00:00
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2000-10-02 23:07:30 +00:00
Module: FGPropulsion.cpp
Author: Jon S. Berndt
Date started: 08/20/00
Purpose: Encapsulates the set of engines, tanks, and thrusters associated
with this aircraft
------------- Copyright (C) 2000 Jon S. Berndt (jsb@hal-pc.org) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA.
Further information about the GNU General Public License can also be found on
the world wide web at http://www.gnu.org.
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
The Propulsion class is the container for the entire propulsion system, which is
comprised of engines, tanks, and "thrusters" (the device that transforms the
engine power into a force that acts on the aircraft, such as a nozzle or
propeller). Once the Propulsion class gets the config file, it reads in
information which is specific to a type of engine. Then:
1) The appropriate engine type instance is created
2001-03-30 01:04:50 +00:00
2) A thruster object is instantiated, and is linked to the engine
2000-10-02 23:07:30 +00:00
3) At least one tank object is created, and is linked to an engine.
At Run time each engines Calculate() method is called to return the excess power
generated during that iteration. The drag from the previous iteration is sub-
tracted to give the excess power available for thrust this pass. That quantity
is passed to the thrusters associated with a particular engine - perhaps with a
scaling mechanism (gearing?) to allow the engine to give its associated thrust-
ers specific distributed portions of the excess power.
HISTORY
--------------------------------------------------------------------------------
08/20/00 JSB Created
2000-11-03 23:02:47 +00:00
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2000-10-02 23:07:30 +00:00
INCLUDES
2000-11-03 23:02:47 +00:00
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
2000-10-02 23:07:30 +00:00
#include "FGPropulsion.h"
#include "FGPropertyManager.h"
2000-10-02 23:07:30 +00:00
2001-03-30 01:04:50 +00:00
static const char *IdSrc = "$Id$";
static const char *IdHdr = ID_PROPULSION;
2000-11-03 23:02:47 +00:00
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
2000-10-02 23:07:30 +00:00
2001-12-07 17:10:17 +00:00
FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec)
2000-10-02 23:07:30 +00:00
{
2001-03-30 01:04:50 +00:00
Name = "FGPropulsion";
numSelectedFuelTanks = numSelectedOxiTanks = 0;
numTanks = numEngines = numThrusters = 0;
numOxiTanks = numFuelTanks = 0;
dt = 0.0;
bind();
2001-12-13 04:48:34 +00:00
Debug(0);
2001-03-30 01:04:50 +00:00
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2000-10-02 23:07:30 +00:00
2001-03-30 01:04:50 +00:00
FGPropulsion::~FGPropulsion()
{
for (unsigned int i=0; i<Engines.size(); i++) delete Engines[i];
Engines.clear();
unbind();
2001-12-13 04:48:34 +00:00
Debug(1);
2000-10-02 23:07:30 +00:00
}
2001-03-30 01:04:50 +00:00
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2000-10-02 23:07:30 +00:00
2001-11-20 22:34:24 +00:00
bool FGPropulsion::Run(void)
{
double PowerAvailable;
2001-03-30 01:04:50 +00:00
dt = State->Getdt();
2001-12-07 17:10:17 +00:00
vForces.InitMatrix();
vMoments.InitMatrix();
2000-10-02 23:07:30 +00:00
if (!FGModel::Run()) {
2001-03-30 01:04:50 +00:00
for (unsigned int i=0; i<numEngines; i++) {
Thrusters[i]->SetdeltaT(dt*rate);
PowerAvailable = Engines[i]->Calculate(Thrusters[i]->GetPowerRequired());
Thrusters[i]->Calculate(PowerAvailable);
2001-12-07 17:10:17 +00:00
vForces += Thrusters[i]->GetBodyForces(); // sum body frame forces
vMoments += Thrusters[i]->GetMoments(); // sum body frame moments
2001-03-30 01:04:50 +00:00
}
2000-10-02 23:07:30 +00:00
return false;
} else {
return true;
}
}
2001-03-30 01:04:50 +00:00
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2001-11-30 17:49:37 +00:00
bool FGPropulsion::GetSteadyState(void)
{
2001-11-20 22:34:24 +00:00
double PowerAvailable;
double currentThrust = 0, lastThrust=-1;
2001-03-30 01:04:50 +00:00
dt = State->Getdt();
2001-11-06 22:33:05 +00:00
int steady_count,j=0;
bool steady=false;
2001-03-30 01:04:50 +00:00
2001-12-07 17:10:17 +00:00
vForces.InitMatrix();
vMoments.InitMatrix();
2001-03-30 01:04:50 +00:00
if (!FGModel::Run()) {
for (unsigned int i=0; i<numEngines; i++) {
Engines[i]->SetTrimMode(true);
Thrusters[i]->SetdeltaT(dt*rate);
2001-11-06 22:33:05 +00:00
steady=false;
2001-12-03 22:17:03 +00:00
steady_count=0;
2001-11-06 22:33:05 +00:00
while (!steady && j < 6000) {
2001-03-30 01:04:50 +00:00
PowerAvailable = Engines[i]->Calculate(Thrusters[i]->GetPowerRequired());
lastThrust = currentThrust;
currentThrust = Thrusters[i]->Calculate(PowerAvailable);
2002-04-16 13:15:29 +00:00
if (fabs(lastThrust-currentThrust) < 0.0001) {
2001-11-06 22:33:05 +00:00
steady_count++;
2002-04-16 13:15:29 +00:00
if (steady_count > 120) { steady=true; }
2001-11-06 22:33:05 +00:00
} else {
steady_count=0;
}
j++;
2001-03-30 01:04:50 +00:00
}
2001-12-07 17:10:17 +00:00
vForces += Thrusters[i]->GetBodyForces(); // sum body frame forces
vMoments += Thrusters[i]->GetMoments(); // sum body frame moments
2001-03-30 01:04:50 +00:00
Engines[i]->SetTrimMode(false);
}
return false;
} else {
return true;
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2000-10-02 23:07:30 +00:00
2001-11-30 17:49:37 +00:00
bool FGPropulsion::ICEngineStart(void)
{
2001-11-20 22:34:24 +00:00
double PowerAvailable;
2001-11-06 22:33:05 +00:00
int j;
dt = State->Getdt();
2001-12-07 17:10:17 +00:00
vForces.InitMatrix();
vMoments.InitMatrix();
2001-11-06 22:33:05 +00:00
for (unsigned int i=0; i<numEngines; i++) {
Engines[i]->SetTrimMode(true);
Thrusters[i]->SetdeltaT(dt*rate);
j=0;
while (!Engines[i]->GetRunning() && j < 2000) {
PowerAvailable = Engines[i]->Calculate(Thrusters[i]->GetPowerRequired());
Thrusters[i]->Calculate(PowerAvailable);
j++;
}
2001-12-07 17:10:17 +00:00
vForces += Thrusters[i]->GetBodyForces(); // sum body frame forces
vMoments += Thrusters[i]->GetMoments(); // sum body frame moments
2001-11-06 22:33:05 +00:00
Engines[i]->SetTrimMode(false);
}
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2001-07-10 15:56:38 +00:00
bool FGPropulsion::Load(FGConfigFile* AC_cfg)
2000-10-02 23:07:30 +00:00
{
2001-03-30 01:04:50 +00:00
string token, fullpath;
string engineFileName, engType;
string thrusterFileName, thrType;
2000-10-02 23:07:30 +00:00
string parameter;
2001-03-30 01:04:50 +00:00
string enginePath = FDMExec->GetEnginePath();
2001-11-09 04:38:53 +00:00
double xLoc, yLoc, zLoc, Pitch, Yaw;
double P_Factor = 0, Sense = 0.0;
2001-03-30 01:04:50 +00:00
int Feed;
2001-07-12 17:55:27 +00:00
bool ThrottleAdded = false;
2001-03-30 01:04:50 +00:00
# ifndef macintosh
fullpath = enginePath + "/";
# else
fullpath = enginePath + ";";
# endif
2000-10-02 23:07:30 +00:00
AC_cfg->GetNextConfigLine();
2001-11-20 22:34:24 +00:00
while ((token = AC_cfg->GetValue()) != string("/PROPULSION")) {
2000-10-02 23:07:30 +00:00
2001-03-30 01:04:50 +00:00
if (token == "AC_ENGINE") { // ============ READING ENGINES
engineFileName = AC_cfg->GetValue("FILE");
2000-10-02 23:07:30 +00:00
if (debug_lvl > 0) cout << "\n Reading engine from file: " << fullpath
+ engineFileName + ".xml"<< endl;
2001-03-30 01:04:50 +00:00
FGConfigFile Eng_cfg(fullpath + engineFileName + ".xml");
2000-10-02 23:07:30 +00:00
2001-03-30 01:04:50 +00:00
if (Eng_cfg.IsOpen()) {
Eng_cfg.GetNextConfigLine();
engType = Eng_cfg.GetValue();
2000-10-02 23:07:30 +00:00
2001-03-30 01:04:50 +00:00
FCS->AddThrottle();
2001-07-12 17:55:27 +00:00
ThrottleAdded = true;
2001-03-30 01:04:50 +00:00
if (engType == "FG_ROCKET") {
Engines.push_back(new FGRocket(FDMExec, &Eng_cfg));
} else if (engType == "FG_PISTON") {
Engines.push_back(new FGPiston(FDMExec, &Eng_cfg));
} else if (engType == "FG_TURBOJET") {
Engines.push_back(new FGTurboJet(FDMExec, &Eng_cfg));
} else if (engType == "FG_TURBOSHAFT") {
Engines.push_back(new FGTurboShaft(FDMExec, &Eng_cfg));
} else if (engType == "FG_TURBOPROP") {
Engines.push_back(new FGTurboProp(FDMExec, &Eng_cfg));
} else {
2001-12-01 04:03:57 +00:00
cerr << fgred << " Unrecognized engine type: " << underon << engType
<< underoff << " found in config file." << fgdef << endl;
return false;
2001-03-30 01:04:50 +00:00
}
AC_cfg->GetNextConfigLine();
2001-11-20 22:34:24 +00:00
while ((token = AC_cfg->GetValue()) != string("/AC_ENGINE")) {
2001-03-30 01:04:50 +00:00
*AC_cfg >> token;
if (token == "XLOC") { *AC_cfg >> xLoc; }
else if (token == "YLOC") { *AC_cfg >> yLoc; }
else if (token == "ZLOC") { *AC_cfg >> zLoc; }
else if (token == "PITCH") { *AC_cfg >> Pitch;}
else if (token == "YAW") { *AC_cfg >> Yaw;}
else if (token == "FEED") {
2001-03-30 01:04:50 +00:00
*AC_cfg >> Feed;
Engines[numEngines]->AddFeedTank(Feed);
if (debug_lvl > 0) cout << " Feed tank: " << Feed << endl;
2001-03-30 01:04:50 +00:00
} else cerr << "Unknown identifier: " << token << " in engine file: "
<< engineFileName << endl;
}
2001-04-02 03:12:38 +00:00
if (debug_lvl > 0) {
cout << " X = " << xLoc << endl;
cout << " Y = " << yLoc << endl;
cout << " Z = " << zLoc << endl;
cout << " Pitch = " << Pitch << endl;
cout << " Yaw = " << Yaw << endl;
2001-07-12 17:55:27 +00:00
}
2001-12-05 03:10:20 +00:00
2001-03-30 01:04:50 +00:00
Engines[numEngines]->SetPlacement(xLoc, yLoc, zLoc, Pitch, Yaw);
2001-11-30 17:49:37 +00:00
Engines[numEngines]->SetEngineNumber(numEngines);
2001-03-30 01:04:50 +00:00
numEngines++;
} else {
2001-04-02 03:12:38 +00:00
2001-12-01 04:03:57 +00:00
cerr << fgred << "\n Could not read engine config file: " << underon <<
fullpath + engineFileName + ".xml" << underoff << fgdef << endl;
2001-03-30 01:04:50 +00:00
return false;
}
} else if (token == "AC_TANK") { // ============== READING TANKS
if (debug_lvl > 0) cout << "\n Reading tank definition" << endl;
2001-03-30 01:04:50 +00:00
Tanks.push_back(new FGTank(AC_cfg));
switch(Tanks[numTanks]->GetType()) {
2000-10-02 23:07:30 +00:00
case FGTank::ttFUEL:
2001-03-30 01:04:50 +00:00
numSelectedFuelTanks++;
numFuelTanks++;
2000-10-02 23:07:30 +00:00
break;
case FGTank::ttOXIDIZER:
2001-03-30 01:04:50 +00:00
numSelectedOxiTanks++;
numOxiTanks++;
2000-10-02 23:07:30 +00:00
break;
}
2001-04-02 03:12:38 +00:00
2000-10-02 23:07:30 +00:00
numTanks++;
2001-03-30 01:04:50 +00:00
} else if (token == "AC_THRUSTER") { // ========== READING THRUSTERS
thrusterFileName = AC_cfg->GetValue("FILE");
if (debug_lvl > 0) cout << "\n Reading thruster from file: " <<
fullpath + thrusterFileName + ".xml" << endl;
2001-03-30 01:04:50 +00:00
FGConfigFile Thruster_cfg(fullpath + thrusterFileName + ".xml");
if (Thruster_cfg.IsOpen()) {
Thruster_cfg.GetNextConfigLine();
thrType = Thruster_cfg.GetValue();
if (thrType == "FG_PROPELLER") {
Thrusters.push_back(new FGPropeller(FDMExec, &Thruster_cfg));
} else if (thrType == "FG_NOZZLE") {
Thrusters.push_back(new FGNozzle(FDMExec, &Thruster_cfg));
}
AC_cfg->GetNextConfigLine();
2001-11-20 22:34:24 +00:00
while ((token = AC_cfg->GetValue()) != string("/AC_THRUSTER")) {
2001-03-30 01:04:50 +00:00
*AC_cfg >> token;
if (token == "XLOC") *AC_cfg >> xLoc;
else if (token == "YLOC") *AC_cfg >> yLoc;
else if (token == "ZLOC") *AC_cfg >> zLoc;
else if (token == "PITCH") *AC_cfg >> Pitch;
else if (token == "YAW") *AC_cfg >> Yaw;
2001-11-09 04:38:53 +00:00
else if (token == "P_FACTOR") *AC_cfg >> P_Factor;
else if (token == "SENSE") *AC_cfg >> Sense;
2001-03-30 01:04:50 +00:00
else cerr << "Unknown identifier: " << token << " in engine file: "
<< engineFileName << endl;
}
Thrusters[numThrusters]->SetLocation(xLoc, yLoc, zLoc);
Thrusters[numThrusters]->SetAnglesToBody(0, Pitch, Yaw);
2001-11-09 04:38:53 +00:00
if (thrType == "FG_PROPELLER" && P_Factor > 0.001) {
((FGPropeller*)Thrusters[numThrusters])->SetPFactor(P_Factor);
2001-12-13 04:48:34 +00:00
if (debug_lvl > 0) cout << " P-Factor: " << P_Factor << endl;
2001-12-14 23:57:05 +00:00
((FGPropeller*)Thrusters[numThrusters])->SetSense(fabs(Sense)/Sense);
2001-12-13 04:48:34 +00:00
if (debug_lvl > 0) cout << " Sense: " << Sense << endl;
2001-11-09 04:38:53 +00:00
}
2001-03-30 01:04:50 +00:00
Thrusters[numThrusters]->SetdeltaT(dt*rate);
2001-12-05 03:10:20 +00:00
Thrusters[numThrusters]->SetThrusterNumber(numThrusters);
2001-03-30 01:04:50 +00:00
numThrusters++;
} else {
cerr << "Could not read thruster config file: " << fullpath
+ thrusterFileName + ".xml" << endl;
return false;
}
2000-10-02 23:07:30 +00:00
}
2001-03-30 01:04:50 +00:00
AC_cfg->GetNextConfigLine();
2000-10-02 23:07:30 +00:00
}
2001-03-30 01:04:50 +00:00
2001-07-12 17:55:27 +00:00
if (!ThrottleAdded) FCS->AddThrottle(); // need to have at least one throttle
2001-03-30 01:04:50 +00:00
return true;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2001-04-02 03:12:38 +00:00
string FGPropulsion::GetPropulsionStrings(void)
{
string PropulsionStrings = "";
bool firstime = true;
2001-12-01 04:03:57 +00:00
char buffer[5];
2001-04-02 03:12:38 +00:00
for (unsigned int i=0;i<Engines.size();i++) {
2001-12-01 04:03:57 +00:00
if (firstime) firstime = false;
else PropulsionStrings += ", ";
sprintf(buffer, "%d", i);
2001-04-06 22:59:31 +00:00
switch(Engines[i]->GetType()) {
case FGEngine::etPiston:
2001-12-01 04:03:57 +00:00
PropulsionStrings += (Engines[i]->GetName() + "_PwrAvail[" + buffer + "]");
2001-04-06 22:59:31 +00:00
break;
case FGEngine::etRocket:
2001-12-01 04:03:57 +00:00
PropulsionStrings += (Engines[i]->GetName() + "_ChamberPress[" + buffer + "]");
2001-04-02 03:12:38 +00:00
break;
2001-04-06 22:59:31 +00:00
case FGEngine::etTurboJet:
case FGEngine::etTurboProp:
case FGEngine::etTurboShaft:
2001-04-02 03:12:38 +00:00
break;
2001-04-06 22:59:31 +00:00
default:
PropulsionStrings += "INVALID ENGINE TYPE";
2001-04-02 03:12:38 +00:00
break;
}
2001-04-06 22:59:31 +00:00
PropulsionStrings += ", ";
2001-12-13 04:48:34 +00:00
FGPropeller* Propeller = (FGPropeller*)Thrusters[i];
2001-04-06 22:59:31 +00:00
switch(Thrusters[i]->GetType()) {
case FGThruster::ttNozzle:
2001-12-01 04:03:57 +00:00
PropulsionStrings += (Thrusters[i]->GetName() + "_Thrust[" + buffer + "]");
2001-04-02 03:12:38 +00:00
break;
2001-04-06 22:59:31 +00:00
case FGThruster::ttRotor:
2001-04-02 03:12:38 +00:00
break;
2001-04-06 22:59:31 +00:00
case FGThruster::ttPropeller:
2001-12-01 04:03:57 +00:00
PropulsionStrings += (Thrusters[i]->GetName() + "_Torque[" + buffer + "], ");
2001-12-13 04:48:34 +00:00
PropulsionStrings += (Thrusters[i]->GetName() + "_PFactor_Roll[" + buffer + "], ");
PropulsionStrings += (Thrusters[i]->GetName() + "_PFactor_Pitch[" + buffer + "], ");
PropulsionStrings += (Thrusters[i]->GetName() + "_PFactor_Yaw[" + buffer + "], ");
2001-12-01 04:03:57 +00:00
PropulsionStrings += (Thrusters[i]->GetName() + "_Thrust[" + buffer + "], ");
2001-12-13 04:48:34 +00:00
if (Propeller->IsVPitch())
PropulsionStrings += (Thrusters[i]->GetName() + "_Pitch[" + buffer + "], ");
2001-12-01 04:03:57 +00:00
PropulsionStrings += (Thrusters[i]->GetName() + "_RPM[" + buffer + "]");
2001-04-02 03:12:38 +00:00
break;
2001-04-06 22:59:31 +00:00
default:
PropulsionStrings += "INVALID THRUSTER TYPE";
break;
}
2001-04-02 03:12:38 +00:00
}
return PropulsionStrings;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
string FGPropulsion::GetPropulsionValues(void)
{
char buff[20];
string PropulsionValues = "";
bool firstime = true;
for (unsigned int i=0;i<Engines.size();i++) {
2001-12-01 04:03:57 +00:00
if (firstime) firstime = false;
else PropulsionValues += ", ";
2001-04-06 22:59:31 +00:00
switch(Engines[i]->GetType()) {
case FGEngine::etPiston:
2001-11-30 17:49:37 +00:00
PropulsionValues += (string(gcvt(((FGPiston*)Engines[i])->GetPowerAvailable(), 10, buff)));
2001-04-02 03:12:38 +00:00
break;
2001-04-06 22:59:31 +00:00
case FGEngine::etRocket:
PropulsionValues += (string(gcvt(((FGRocket*)Engines[i])->GetChamberPressure(), 10, buff)));
2001-04-02 03:12:38 +00:00
break;
2001-04-06 22:59:31 +00:00
case FGEngine::etTurboJet:
case FGEngine::etTurboProp:
case FGEngine::etTurboShaft:
2001-04-02 03:12:38 +00:00
break;
}
2001-04-06 22:59:31 +00:00
PropulsionValues += ", ";
switch(Thrusters[i]->GetType()) {
case FGThruster::ttNozzle:
PropulsionValues += (string(gcvt(((FGNozzle*)Thrusters[i])->GetThrust(), 10, buff)));
2001-04-02 03:12:38 +00:00
break;
2001-04-06 22:59:31 +00:00
case FGThruster::ttRotor:
2001-04-02 03:12:38 +00:00
break;
2001-04-06 22:59:31 +00:00
case FGThruster::ttPropeller:
2001-12-13 04:48:34 +00:00
FGPropeller* Propeller = (FGPropeller*)Thrusters[i];
FGColumnVector3 vPFactor = Propeller->GetPFactor();
PropulsionValues += string(gcvt(Propeller->GetTorque(), 10, buff)) + ", ";
PropulsionValues += string(gcvt(vPFactor(eRoll), 10, buff)) + ", ";
PropulsionValues += string(gcvt(vPFactor(ePitch), 10, buff)) + ", ";
PropulsionValues += string(gcvt(vPFactor(eYaw), 10, buff)) + ", ";
PropulsionValues += string(gcvt(Propeller->GetThrust(), 10, buff)) + ", ";
if (Propeller->IsVPitch())
PropulsionValues += string(gcvt(Propeller->GetPitch(), 10, buff)) + ", ";
PropulsionValues += string(gcvt(Propeller->GetRPM(), 10, buff));
2001-04-02 03:12:38 +00:00
break;
}
}
return PropulsionValues;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGColumnVector3& FGPropulsion::GetTanksCG(void)
{
iTank = Tanks.begin();
vXYZtank.InitMatrix();
while (iTank < Tanks.end()) {
vXYZtank(eX) += (*iTank)->GetX()*(*iTank)->GetContents();
vXYZtank(eY) += (*iTank)->GetY()*(*iTank)->GetContents();
vXYZtank(eZ) += (*iTank)->GetZ()*(*iTank)->GetContents();
iTank++;
}
return vXYZtank;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2001-11-20 22:34:24 +00:00
double FGPropulsion::GetTanksWeight(void)
{
2001-11-20 22:34:24 +00:00
double Tw = 0.0;
iTank = Tanks.begin();
while (iTank < Tanks.end()) {
Tw += (*iTank)->GetContents();
iTank++;
}
return Tw;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2001-11-20 22:34:24 +00:00
double FGPropulsion::GetTanksIxx(const FGColumnVector3& vXYZcg)
{
2001-11-20 22:34:24 +00:00
double I = 0.0;
iTank = Tanks.begin();
while (iTank < Tanks.end()) {
2001-11-12 16:06:29 +00:00
I += ((*iTank)->GetX() - vXYZcg(eX))*((*iTank)->GetX() - vXYZcg(eX)) * (*iTank)->GetContents()/(144.0*Inertial->gravity());
iTank++;
}
return I;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2001-11-20 22:34:24 +00:00
double FGPropulsion::GetTanksIyy(const FGColumnVector3& vXYZcg)
{
2001-11-20 22:34:24 +00:00
double I = 0.0;
iTank = Tanks.begin();
while (iTank < Tanks.end()) {
2001-11-12 16:06:29 +00:00
I += ((*iTank)->GetY() - vXYZcg(eY))*((*iTank)->GetY() - vXYZcg(eY)) * (*iTank)->GetContents()/(144.0*Inertial->gravity());
iTank++;
}
return I;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2001-11-20 22:34:24 +00:00
double FGPropulsion::GetTanksIzz(const FGColumnVector3& vXYZcg)
{
2001-11-20 22:34:24 +00:00
double I = 0.0;
iTank = Tanks.begin();
while (iTank < Tanks.end()) {
2001-11-12 16:06:29 +00:00
I += ((*iTank)->GetZ() - vXYZcg(eZ))*((*iTank)->GetZ() - vXYZcg(eZ)) * (*iTank)->GetContents()/(144.0*Inertial->gravity());
iTank++;
}
return I;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2001-11-20 22:34:24 +00:00
double FGPropulsion::GetTanksIxz(const FGColumnVector3& vXYZcg)
{
2001-11-20 22:34:24 +00:00
double I = 0.0;
iTank = Tanks.begin();
while (iTank < Tanks.end()) {
2001-11-12 16:06:29 +00:00
I += ((*iTank)->GetX() - vXYZcg(eX))*((*iTank)->GetZ() - vXYZcg(eZ)) * (*iTank)->GetContents()/(144.0*Inertial->gravity());
iTank++;
}
return I;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2001-11-20 22:34:24 +00:00
double FGPropulsion::GetTanksIxy(const FGColumnVector3& vXYZcg)
{
2001-11-20 22:34:24 +00:00
double I = 0.0;
iTank = Tanks.begin();
while (iTank != Tanks.end()) {
2001-11-12 16:06:29 +00:00
I += ((*iTank)->GetX() - vXYZcg(eX))*((*iTank)->GetY() - vXYZcg(eY)) * (*iTank)->GetContents()/(144.0*Inertial->gravity());
iTank++;
}
return I;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2002-04-16 13:15:29 +00:00
void FGPropulsion::bind(void)
{
typedef double (FGPropulsion::*PMF)(int) const;
/* PropertyManager->Tie("propulsion/num-engines", this,
&FGPropulsion::GetNumEngines);
PropertyManager->Tie("propulsion/num-tanks", this,
&FGPropulsion::GetNumTanks); */
PropertyManager->Tie("propulsion/num-sel-fuel-tanks", this,
&FGPropulsion::GetnumSelectedFuelTanks);
PropertyManager->Tie("propulsion/num-sel-ox-tanks", this,
&FGPropulsion::GetnumSelectedOxiTanks);
PropertyManager->Tie("forces/fbx-prop-lbs", this,1,
(PMF)&FGPropulsion::GetForces);
PropertyManager->Tie("forces/fby-prop-lbs", this,2,
(PMF)&FGPropulsion::GetForces);
PropertyManager->Tie("forces/fbz-prop-lbs", this,3,
(PMF)&FGPropulsion::GetForces);
PropertyManager->Tie("moments/l-prop-lbsft", this,1,
(PMF)&FGPropulsion::GetMoments);
PropertyManager->Tie("moments/m-prop-lbsft", this,2,
(PMF)&FGPropulsion::GetMoments);
PropertyManager->Tie("moments/n-prop-lbsft", this,3,
(PMF)&FGPropulsion::GetMoments);
//PropertyManager->Tie("propulsion/tanks-weight-lbs", this,
// &FGPropulsion::GetTanksWeight);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2002-04-16 13:15:29 +00:00
void FGPropulsion::unbind(void)
{
/* PropertyManager->Untie("propulsion/num-engines");
PropertyManager->Untie("propulsion/num-tanks"); */
PropertyManager->Untie("propulsion/num-sel-fuel-tanks");
PropertyManager->Untie("propulsion/num-sel-ox-tanks");
PropertyManager->Untie("forces/fbx-prop-lbs");
PropertyManager->Untie("forces/fby-prop-lbs");
PropertyManager->Untie("forces/fbz-prop-lbs");
PropertyManager->Untie("moments/l-prop-lbsft");
PropertyManager->Untie("moments/m-prop-lbsft");
PropertyManager->Untie("moments/n-prop-lbsft");
//PropertyManager->Untie("propulsion/tanks-weight-lbs");
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2001-12-13 04:48:34 +00:00
// The bitmasked value choices are as follows:
// unset: In this case (the default) JSBSim would only print
// out the normally expected messages, essentially echoing
// the config files as they are read. If the environment
// variable is not set, debug_lvl is set to 1 internally
// 0: This requests JSBSim not to output any messages
// whatsoever.
// 1: This value explicity requests the normal JSBSim
// startup messages
// 2: This value asks for a message to be printed out when
// a class is instantiated
// 4: When this value is set, a message is displayed when a
// FGModel object executes its Run() method
// 8: When this value is set, various runtime state variables
// are printed out periodically
// 16: When set various parameters are sanity checked and
// a message is printed out when they go out of bounds
void FGPropulsion::Debug(int from)
2001-03-30 01:04:50 +00:00
{
2001-12-13 04:48:34 +00:00
if (debug_lvl <= 0) return;
if (debug_lvl & 1) { // Standard console startup message output
if (from == 0) { // Constructor
}
}
if (debug_lvl & 2 ) { // Instantiation/Destruction notification
if (from == 0) cout << "Instantiated: FGPropulsion" << endl;
if (from == 1) cout << "Destroyed: FGPropulsion" << endl;
}
if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
}
if (debug_lvl & 8 ) { // Runtime state variables
}
if (debug_lvl & 16) { // Sanity checking
}
2001-12-24 13:54:55 +00:00
if (debug_lvl & 64) {
if (from == 0) { // Constructor
cout << IdSrc << endl;
cout << IdHdr << endl;
}
}
2000-10-02 23:07:30 +00:00
}