fgpropulsion.cpp
来自「6 DOF Missle Simulation」· C++ 代码 · 共 699 行 · 第 1/2 页
CPP
699 行
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Module: FGPropulsion.cpp Author: Jon S. Berndt Date started: 08/20/00 Purpose: Encapsulates the set of engines and tanks 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 Lesser 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser 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 Lesser 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 iscomprised of engines and tanks. 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 created2) At least one tank object is created, and is linked to an engine.At Run time each engines Calculate() method is called.HISTORY--------------------------------------------------------------------------------08/20/00 JSB Created%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%INCLUDES%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/#include "FGPropulsion.h"#include <models/propulsion/FGRocket.h>#include <models/propulsion/FGTurbine.h>#include <models/propulsion/FGPiston.h>#include <models/propulsion/FGElectric.h>#include <models/propulsion/FGTurboProp.h>#include <input_output/FGPropertyManager.h>#include <input_output/FGXMLParse.h>#include <math/FGColumnVector3.h>#include <sstream>namespace JSBSim {static const char *IdSrc = "$Id$";static const char *IdHdr = ID_PROPULSION;extern short debug_lvl;/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%CLASS IMPLEMENTATION%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/FGPropulsion::FGPropulsion(FGFDMExec* exec) : FGModel(exec){ Name = "FGPropulsion"; InitializedEngines = 0; numSelectedFuelTanks = numSelectedOxiTanks = 0; numTanks = numEngines = 0; numOxiTanks = numFuelTanks = 0; ActiveEngine = -1; // -1: ALL, 0: Engine 1, 1: Engine 2 ... tankJ.InitMatrix(); refuel = dump = false; DumpRate = 0.0; fuel_freeze = false; TotalFuelQuantity = 0.0; IsBound = HavePistonEngine = HaveTurbineEngine = HaveRocketEngine = HaveTurboPropEngine = HaveElectricEngine = false; HasInitializedEngines = false; Debug(0);}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%FGPropulsion::~FGPropulsion(){ for (unsigned int i=0; i<Engines.size(); i++) delete Engines[i]; Engines.clear(); for (unsigned int i=0; i<Tanks.size(); i++) delete Tanks[i]; Tanks.clear(); Debug(1);}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%bool FGPropulsion::InitModel(void){ if (!FGModel::InitModel()) return false; for (unsigned int i=0; i<numTanks; i++) Tanks[i]->ResetToIC(); for (unsigned int i=0; i<numEngines; i++) { switch (Engines[i]->GetType()) { case FGEngine::etPiston: ((FGPiston*)Engines[i])->ResetToIC(); if (HasInitializedEngines && (InitializedEngines & i)) InitRunning(i); break; case FGEngine::etTurbine: ((FGTurbine*)Engines[i])->ResetToIC(); if (HasInitializedEngines && (InitializedEngines & i)) InitRunning(i); break; default: break; } } return true;}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%bool FGPropulsion::Run(void){ unsigned int i; if (FGModel::Run()) return true; if (FDMExec->Holding()) return false; double dt = State->Getdt(); vForces.InitMatrix(); vMoments.InitMatrix(); for (i=0; i<numEngines; i++) { Engines[i]->Calculate(); vForces += Engines[i]->GetBodyForces(); // sum body frame forces vMoments += Engines[i]->GetMoments(); // sum body frame moments } TotalFuelQuantity = 0.0; for (i=0; i<numTanks; i++) { Tanks[i]->Calculate( dt * rate ); if (Tanks[i]->GetType() == FGTank::ttFUEL) { TotalFuelQuantity += Tanks[i]->GetContents(); } } if (refuel) DoRefuel( dt * rate ); if (dump) DumpFuel( dt * rate ); return false;}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%bool FGPropulsion::GetSteadyState(void){ double currentThrust = 0, lastThrust = -1; int steady_count = 0, j = 0; bool steady = false; vForces.InitMatrix(); vMoments.InitMatrix(); if (!FGModel::Run()) { for (unsigned int i=0; i<numEngines; i++) {// cout << " Finding steady state for engine " << i << endl; Engines[i]->SetTrimMode(true); steady=false; steady_count=0; j=0; while (!steady && j < 6000) { Engines[i]->Calculate(); lastThrust = currentThrust; currentThrust = Engines[i]->GetThrust(); if (fabs(lastThrust-currentThrust) < 0.0001) { steady_count++; if (steady_count > 120) { steady=true;// cout << " Steady state found at thrust: " << currentThrust << " lbs." << endl; } } else { steady_count=0; } j++; }// if (j >= 6000) {// cout << " Could not find a steady state for this engine." << endl;// } vForces += Engines[i]->GetBodyForces(); // sum body frame forces vMoments += Engines[i]->GetMoments(); // sum body frame moments Engines[i]->SetTrimMode(false); } return false; } else { return true; }}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%void FGPropulsion::InitRunning(int n){ if (n > 0) { // A specific engine is supposed to be initialized if (n >= GetNumEngines() ) { cerr << "Tried to initialize a non-existent engine!" << endl; throw; } FCS->SetThrottleCmd(n,1); FCS->SetMixtureCmd(n,1); GetEngine(n)->InitRunning(); GetSteadyState(); InitializedEngines = 1 << n; HasInitializedEngines = true; } else if (n < 0) { // -1 refers to "All Engines" for (unsigned int i=0; i<GetNumEngines(); i++) { FCS->SetThrottleCmd(i,1); FCS->SetMixtureCmd(i,1); GetEngine(i)->InitRunning(); } GetSteadyState(); InitializedEngines = -1; HasInitializedEngines = true; } else if (n == 0) { // No engines are to be initialized // Do nothing }}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%bool FGPropulsion::Load(Element* el){ string type, engine_filename; bool ThrottleAdded = false; Debug(2); Element* engine_element = el->FindElement("engine"); while (engine_element) { engine_filename = engine_element->GetAttributeValue("file"); if (engine_filename.empty()) { cerr << "Engine definition did not supply an engine file." << endl; return false; } engine_filename = FindEngineFullPathname(engine_filename); document = LoadXMLDocument(engine_filename); document->SetParent(engine_element); type = document->GetName(); if (type == "piston_engine") { HavePistonEngine = true; if (!IsBound) bind(); Engines.push_back(new FGPiston(FDMExec, document, numEngines)); } else if (type == "turbine_engine") { HaveTurbineEngine = true; if (!IsBound) bind(); Engines.push_back(new FGTurbine(FDMExec, document, numEngines)); } else if (type == "turboprop_engine") { HaveTurboPropEngine = true; if (!IsBound) bind(); Engines.push_back(new FGTurboProp(FDMExec, document, numEngines)); } else if (type == "rocket_engine") { HaveRocketEngine = true; if (!IsBound) bind(); Engines.push_back(new FGRocket(FDMExec, document, numEngines)); } else if (type == "electric_engine") { HaveElectricEngine = true; if (!IsBound) bind(); Engines.push_back(new FGElectric(FDMExec, document, numEngines)); } else { cerr << "Unknown engine type: " << type << endl; exit(-5); } FCS->AddThrottle(); ThrottleAdded = true; numEngines++; engine_element = el->FindNextElement("engine"); ResetParser(); } // Process tank definitions Element* tank_element = el->FindElement("tank"); while (tank_element) { Tanks.push_back(new FGTank(FDMExec, tank_element, numTanks)); if (Tanks.back()->GetType() == FGTank::ttFUEL) numFuelTanks++; else if (Tanks.back()->GetType() == FGTank::ttOXIDIZER) numOxiTanks++; else {cerr << "Unknown tank type specified." << endl; return false;} numTanks++; tank_element = el->FindNextElement("tank"); } numSelectedFuelTanks = numFuelTanks; numSelectedOxiTanks = numOxiTanks; CalculateTankInertias(); if (!ThrottleAdded) FCS->AddThrottle(); // need to have at least one throttle // Process fuel dump rate if (el->FindElement("dump-rate")) DumpRate = el->FindElementValueAsNumberConvertTo("dump-rate", "LBS/MIN"); return true;}//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%string FGPropulsion::FindEngineFullPathname(string engine_filename){ string fullpath, localpath; string enginePath = FDMExec->GetEnginePath(); string aircraftPath = FDMExec->GetFullAircraftPath(); ifstream engine_file; string separator = "/"; fullpath = enginePath + separator; localpath = aircraftPath + separator + "Engines" + separator; engine_file.open(string(fullpath + engine_filename + ".xml").c_str()); if ( !engine_file.is_open()) { engine_file.open(string(localpath + engine_filename + ".xml").c_str()); if ( !engine_file.is_open()) { cerr << " Could not open engine file: " << engine_filename << " in path " << fullpath << " or " << localpath << endl; return string(""); } else {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?