namespace JSBSim {
-static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.79 2010/07/25 13:52:20 jberndt Exp $";
+static const char *IdSrc = "$Id: FGFDMExec.cpp,v 1.91 2011/04/05 20:20:21 andgi Exp $";
static const char *IdHdr = ID_FDMEXEC;
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-GLOBAL DECLARATIONS
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-
-unsigned int FGFDMExec::FDMctr = 0;
-FGPropertyManager* FGFDMExec::master=0;
-
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
CLASS IMPLEMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-void checkTied ( FGPropertyManager *node )
-{
- int N = node->nChildren();
- string name;
-
- for (int i=0; i<N; i++) {
- if (node->getChild(i)->nChildren() ) {
- checkTied( (FGPropertyManager*)node->getChild(i) );
- }
- if ( node->getChild(i)->isTied() ) {
- name = ((FGPropertyManager*)node->getChild(i))->GetFullyQualifiedName();
- node->Untie(name);
- }
- }
-}
-
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// Constructor
-FGFDMExec::FGFDMExec(FGPropertyManager* root) : Root(root)
+FGFDMExec::FGFDMExec(FGPropertyManager* root, unsigned int* fdmctr) : Root(root), FDMctr(fdmctr)
{
Frame = 0;
IsChild = false;
holding = false;
Terminate = false;
+ StandAlone = false;
sim_time = 0.0;
dT = 1.0/120.0; // a default timestep size. This is needed for when JSBSim is
// run in standalone mode with no initialization file.
- IdFDM = FDMctr; // The main (parent) JSBSim instance is always the "zeroth"
- FDMctr++; // instance. "child" instances are loaded last.
+ AircraftPath = "aircraft";
+ EnginePath = "engine";
+ SystemsPath = "systems";
try {
char* num = getenv("JSBSIM_DEBUG");
if (num) debug_lvl = atoi(num); // set debug level
- } catch (...) { // if error set to 1
+ } catch (...) { // if error set to 1
debug_lvl = 1;
}
- if (Root == 0) {
- if (master == 0)
- master = new FGPropertyManager;
- Root = master;
+ if (Root == 0) { // Then this is the root FDM
+ Root = new FGPropertyManager; // Create the property manager
+ StandAlone = true;
}
+ if (FDMctr == 0) {
+ FDMctr = new unsigned int; // Create and initialize the child FDM counter
+ (*FDMctr) = 0;
+ }
+
+ // Store this FDM's ID
+ IdFDM = (*FDMctr); // The main (parent) JSBSim instance is always the "zeroth"
+
+ // Prepare FDMctr for the next child FDM id
+ (*FDMctr)++; // instance. "child" instances are loaded last.
+
instance = Root->GetNode("/fdm/jsbsim",IdFDM,true);
Debug(0);
// this is to catch errors in binding member functions to the property tree.
Constructing = true;
typedef int (FGFDMExec::*iPMF)(void) const;
-// instance->Tie("simulation/do_trim_analysis", this, (iPMF)0, &FGFDMExec::DoTrimAnalysis);
- instance->Tie("simulation/do_simple_trim", this, (iPMF)0, &FGFDMExec::DoTrim);
- instance->Tie("simulation/reset", this, (iPMF)0, &FGFDMExec::ResetToInitialConditions);
+// instance->Tie("simulation/do_trim_analysis", this, (iPMF)0, &FGFDMExec::DoTrimAnalysis, false);
+ instance->Tie("simulation/do_simple_trim", this, (iPMF)0, &FGFDMExec::DoTrim, false);
+ instance->Tie("simulation/reset", this, (iPMF)0, &FGFDMExec::ResetToInitialConditions, false);
instance->Tie("simulation/terminate", (int *)&Terminate);
instance->Tie("simulation/sim-time-sec", this, &FGFDMExec::GetSimTime);
instance->Tie("simulation/jsbsim-debug", this, &FGFDMExec::GetDebugLevel, &FGFDMExec::SetDebugLevel);
+ instance->Tie("simulation/frame", (int *)&Frame, false);
Constructing = false;
}
FGFDMExec::~FGFDMExec()
{
try {
- checkTied( instance );
+ Unbind();
DeAllocate();
- if (Root == 0) delete master;
+
+ if (IdFDM == 0) { // Meaning this is no child FDM
+ if(Root != 0) {
+ if(StandAlone)
+ delete Root;
+ Root = 0;
+ }
+ if(FDMctr != 0) {
+ delete FDMctr;
+ FDMctr = 0;
+ }
+ }
} catch ( string msg ) {
cout << "Caught error: " << msg << endl;
}
void FGFDMExec::Initialize(FGInitialCondition *FGIC)
{
+ Setsim_time(0.0);
+
Propagate->SetInitialState( FGIC );
Atmosphere->Run();
FGIC->GetWindDFpsIC() );
FGColumnVector3 vAeroUVW;
+
+ //ToDo: move this to the Auxiliary class !?
+
vAeroUVW = Propagate->GetUVW() + Propagate->GetTl2b()*Atmosphere->GetTotalWindNED();
double alpha, beta;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-bool FGFDMExec::LoadScript(string script, double deltaT)
+bool FGFDMExec::LoadScript(const string& script, double deltaT)
{
bool result;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-bool FGFDMExec::LoadModel(string AircraftPath, string EnginePath, string SystemsPath,
- string model, bool addModelToPath)
+bool FGFDMExec::LoadModel(const string& AircraftPath, const string& EnginePath, const string& SystemsPath,
+ const string& model, bool addModelToPath)
{
FGFDMExec::AircraftPath = RootDir + AircraftPath;
FGFDMExec::EnginePath = RootDir + EnginePath;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-bool FGFDMExec::LoadModel(string model, bool addModelToPath)
+bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
{
string token;
string aircraftCfgFileName;
// Process the output element[s]. This element is OPTIONAL, and there may be more than one.
unsigned int idx=0;
- typedef int (FGOutput::*iOPMF)(void) const;
+ typedef double (FGOutput::*iOPMF)(void) const;
+ typedef int (FGFDMExec::*iOPV)(void) const;
+ typedef void (FGFDMExec::*vOPI)(int) const;
element = document->FindElement("output");
while (element) {
if (debug_lvl > 0) cout << endl << " Output data set: " << idx << " ";
} else {
Outputs.push_back(Output);
string outputProp = CreateIndexedPropertyName("simulation/output",idx);
- instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate);
+ instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate, false);
+ instance->Tie("simulation/force-output", this, (iOPV)0, &FGFDMExec::ForceOutput, false);
idx++;
}
element = document->FindNextElement("output");
<< fgdef << endl;
}
- struct PropertyCatalogStructure masterPCS;
- masterPCS.base_string = "";
- masterPCS.node = (FGPropertyManager*)Root;
-
- BuildPropertyCatalog(&masterPCS);
+ if (result) {
+ struct PropertyCatalogStructure masterPCS;
+ masterPCS.base_string = "";
+ masterPCS.node = (FGPropertyManager*)Root;
+ BuildPropertyCatalog(&masterPCS);
+ }
return result;
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-string FGFDMExec::QueryPropertyCatalog(string in)
+string FGFDMExec::QueryPropertyCatalog(const string& in)
{
string results="";
for (unsigned i=0; i<PropertyCatalog.size(); i++) {
struct childData* child = new childData;
- child->exec = new FGFDMExec();
+ child->exec = new FGFDMExec(Root, FDMctr);
child->exec->SetChild(true);
string childAircraft = el->GetAttributeValue("name");
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-bool FGFDMExec::SetOutputDirectives(string fname)
+void FGFDMExec::ForceOutput(int idx)
+{
+ if (idx >= 0 && idx < Outputs.size()) Outputs[idx]->Print();
+}
+
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+bool FGFDMExec::SetOutputDirectives(const string& fname)
{
bool result;
if (result) {
Outputs.push_back(Output);
- typedef int (FGOutput::*iOPMF)(void) const;
+ typedef double (FGOutput::*iOPMF)(void) const;
string outputProp = CreateIndexedPropertyName("simulation/output",Outputs.size()-1);
- instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate);
+ instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate, false);
}
return result;