Esempio n. 1
0
void FGFDMExec::Initialize(FGInitialCondition *FGIC)
{
  Setsim_time(0.0);

  Propagate->SetInitialState( FGIC );
  LoadInputs(eAccelerations);
  Accelerations->Run(false);
  LoadInputs(ePropagate);
  Propagate->InitializeDerivatives();
  LoadInputs(eAtmosphere);
  Atmosphere->Run(false);
  Winds->SetWindNED(FGIC->GetWindNEDFpsIC());
  Auxiliary->Run(false);
}
Esempio n. 2
0
void FGFDMExec::Initialize(FGInitialCondition *FGIC)
{
  Setsim_time(0.0);

  Propagate->SetInitialState( FGIC );
  LoadInputs(eInertial);
  Inertial->Run(false);
  LoadInputs(eAccelerations);
  Accelerations->Run(false);
  LoadInputs(ePropagate);
  Propagate->InitializeDerivatives();
  Winds->SetWindNED(FGIC->GetWindNEDFpsIC());
  LoadInputs(eMassBalance);
  MassBalance->Run(false);
}
Esempio n. 3
0
bool FGFDMExec::Run(void)
{
  bool success=true;

  Debug(2);

  for (unsigned int i=1; i<ChildFDMList.size(); i++) {
    ChildFDMList[i]->AssignState( (FGPropagate*)Models[ePropagate] ); // Transfer state to the child FDM
    ChildFDMList[i]->Run();
  }

  if (firstPass && !IntegrationSuspended()) {
    // Outputs the initial conditions
    for (unsigned int i = 0; i < Outputs.size(); i++)
      Outputs[i]->Run(holding);

    firstPass = false;
  }

  IncrTime();

  // returns true if success, false if complete
  if (Script != 0 && !IntegrationSuspended()) success = Script->RunScript();

  for (unsigned int i = 0; i < Models.size(); i++) {
    LoadInputs(i);
    Models[i]->Run(holding);
  }

  if (Terminate) success = false;

  return (success);
}
Esempio n. 4
0
bool FGFDMExec::Run(void)
{
  bool success=true;

  Debug(2);

  for (unsigned int i=1; i<ChildFDMList.size(); i++) {
    ChildFDMList[i]->AssignState( (FGPropagate*)Models[ePropagate] ); // Transfer state to the child FDM
    ChildFDMList[i]->Run();
  }

  IncrTime();

  // returns true if success, false if complete
  if (Script != 0 && !IntegrationSuspended()) success = Script->RunScript();

  for (unsigned int i = 0; i < Models.size(); i++) {
    LoadInputs(i);
    Models[i]->Run(holding);
  }

  if (ResetMode) {
    unsigned int mode = ResetMode;

    ResetMode = 0;
    ResetToInitialConditions(mode);
  }

  if (Terminate) success = false;

  return success;
}
Esempio n. 5
0
bool FGFDMExec::Allocate(void)
{
  bool result=true;

  Models.resize(eNumStandardModels);

  // See the eModels enum specification in the header file. The order of the enums
  // specifies the order of execution. The Models[] vector is the primary
  // storage array for the list of models.
  Models[ePropagate]         = new FGPropagate(this);
  Models[eInput]             = new FGInput(this);
  Models[eInertial]          = new FGInertial(this);
  Models[eAtmosphere]        = new FGStandardAtmosphere(this);
  Models[eWinds]             = new FGWinds(this);
  Models[eAuxiliary]         = new FGAuxiliary(this);
  Models[eSystems]           = new FGFCS(this);
  Models[ePropulsion]        = new FGPropulsion(this);
  Models[eAerodynamics]      = new FGAerodynamics (this);

  GetGroundCallback()->SetSeaLevelRadius(((FGInertial*)Models[eInertial])->GetRefRadius());

  Models[eGroundReactions]   = new FGGroundReactions(this);
  Models[eExternalReactions] = new FGExternalReactions(this);
  Models[eBuoyantForces]     = new FGBuoyantForces(this);
  Models[eMassBalance]       = new FGMassBalance(this);
  Models[eAircraft]          = new FGAircraft(this);
  Models[eAccelerations]     = new FGAccelerations(this);

  // Assign the Model shortcuts for internal executive use only.
  Propagate = (FGPropagate*)Models[ePropagate];
  Inertial = (FGInertial*)Models[eInertial];
  Atmosphere = (FGAtmosphere*)Models[eAtmosphere];
  Winds = (FGWinds*)Models[eWinds];
  Auxiliary = (FGAuxiliary*)Models[eAuxiliary];
  FCS = (FGFCS*)Models[eSystems];
  Propulsion = (FGPropulsion*)Models[ePropulsion];
  Aerodynamics = (FGAerodynamics*)Models[eAerodynamics];
  GroundReactions = (FGGroundReactions*)Models[eGroundReactions];
  ExternalReactions = (FGExternalReactions*)Models[eExternalReactions];
  BuoyantForces = (FGBuoyantForces*)Models[eBuoyantForces];
  MassBalance = (FGMassBalance*)Models[eMassBalance];
  Aircraft = (FGAircraft*)Models[eAircraft];
  Accelerations = (FGAccelerations*)Models[eAccelerations];

  // Initialize planet (environment) constants
  LoadPlanetConstants();

  // Initialize models
  for (unsigned int i = 0; i < Models.size(); i++) {
    LoadInputs(i);
    Models[i]->InitModel();
  }

  IC = new FGInitialCondition(this);

  modelLoaded = false;

  return result;
}
Esempio n. 6
0
void FGFDMExec::ResetToInitialConditions(int mode)
{
  if (Constructing) return;

  if (mode == 1) Output->SetStartNewOutput();

  for (unsigned int i = 0; i < Models.size(); i++) {
    // The Input/Output models will be initialized during the RunIC() execution
    if (i == eInput || i == eOutput) continue;

    LoadInputs(i);
    Models[i]->InitModel();
  }

  if (Script) Script->ResetEvents();

  RunIC();
}
Esempio n. 7
0
bool FGFDMExec::LoadModel(const string& model, bool addModelToPath)
{
  string token;
  string aircraftCfgFileName;
  Element* element = 0L;
  bool result = false; // initialize result to false, indicating input file not yet read

  modelName = model; // Set the class modelName attribute

  if( AircraftPath.empty() || EnginePath.empty() || SystemsPath.empty()) {
    cerr << "Error: attempted to load aircraft with undefined ";
    cerr << "aircraft, engine, and system paths" << endl;
    return false;
  }

  FullAircraftPath = AircraftPath;
  if (addModelToPath) FullAircraftPath += "/" + model;
  aircraftCfgFileName = FullAircraftPath + "/" + model + ".xml";

  if (modelLoaded) {
    DeAllocate();
    Allocate();
  }

  int saved_debug_lvl = debug_lvl;

  document = LoadXMLDocument(aircraftCfgFileName); // "document" is a class member
  if (document) {
    if (IsChild) debug_lvl = 0;

    ReadPrologue(document);

    if (IsChild) debug_lvl = saved_debug_lvl;

    // Process the fileheader element in the aircraft config file. This element is OPTIONAL.
    element = document->FindElement("fileheader");
    if (element) {
      result = ReadFileHeader(element);
      if (!result) {
        cerr << endl << "Aircraft fileheader element has problems in file " << aircraftCfgFileName << endl;
        return result;
      }
    }

    if (IsChild) debug_lvl = 0;

    // Process the metrics element. This element is REQUIRED.
    element = document->FindElement("metrics");
    if (element) {
      result = ((FGAircraft*)Models[eAircraft])->Load(element);
      if (!result) {
        cerr << endl << "Aircraft metrics element has problems in file " << aircraftCfgFileName << endl;
        return result;
      }
    } else {
      cerr << endl << "No metrics element was found in the aircraft config file." << endl;
      return false;
    }

    // Process the mass_balance element. This element is REQUIRED.
    element = document->FindElement("mass_balance");
    if (element) {
      result = ((FGMassBalance*)Models[eMassBalance])->Load(element);
      if (!result) {
        cerr << endl << "Aircraft mass_balance element has problems in file " << aircraftCfgFileName << endl;
        return result;
      }
    } else {
      cerr << endl << "No mass_balance element was found in the aircraft config file." << endl;
      return false;
    }

    // Process the ground_reactions element. This element is REQUIRED.
    element = document->FindElement("ground_reactions");
    if (element) {
      result = ((FGGroundReactions*)Models[eGroundReactions])->Load(element);
      if (!result) {
        cerr << endl << "Aircraft ground_reactions element has problems in file " << aircraftCfgFileName << endl;
        return result;
      }
      ((FGFCS*)Models[eSystems])->AddGear(((FGGroundReactions*)Models[eGroundReactions])->GetNumGearUnits());
    } else {
      cerr << endl << "No ground_reactions element was found in the aircraft config file." << endl;
      return false;
    }

    // Process the external_reactions element. This element is OPTIONAL.
    element = document->FindElement("external_reactions");
    if (element) {
      result = ((FGExternalReactions*)Models[eExternalReactions])->Load(element);
      if (!result) {
        cerr << endl << "Aircraft external_reactions element has problems in file " << aircraftCfgFileName << endl;
        return result;
      }
    }

    // Process the buoyant_forces element. This element is OPTIONAL.
    element = document->FindElement("buoyant_forces");
    if (element) {
      result = ((FGBuoyantForces*)Models[eBuoyantForces])->Load(element);
      if (!result) {
        cerr << endl << "Aircraft buoyant_forces element has problems in file " << aircraftCfgFileName << endl;
        return result;
      }
    }

    // Process the propulsion element. This element is OPTIONAL.
    element = document->FindElement("propulsion");
    if (element) {
      result = ((FGPropulsion*)Models[ePropulsion])->Load(element);
      if (!result) {
        cerr << endl << "Aircraft propulsion element has problems in file " << aircraftCfgFileName << endl;
        return result;
      }
      for (unsigned int i=0; i<((FGPropulsion*)Models[ePropulsion])->GetNumEngines(); i++)
        ((FGFCS*)Models[eSystems])->AddThrottle();
    }

    // Process the system element[s]. This element is OPTIONAL, and there may be more than one.
    element = document->FindElement("system");
    while (element) {
      result = ((FGFCS*)Models[eSystems])->Load(element, FGFCS::stSystem);
      if (!result) {
        cerr << endl << "Aircraft system element has problems in file " << aircraftCfgFileName << endl;
        return result;
      }
      element = document->FindNextElement("system");
    }

    // Process the autopilot element. This element is OPTIONAL.
    element = document->FindElement("autopilot");
    if (element) {
      result = ((FGFCS*)Models[eSystems])->Load(element, FGFCS::stAutoPilot);
      if (!result) {
        cerr << endl << "Aircraft autopilot element has problems in file " << aircraftCfgFileName << endl;
        return result;
      }
    }

    // Process the flight_control element. This element is OPTIONAL.
    element = document->FindElement("flight_control");
    if (element) {
      result = ((FGFCS*)Models[eSystems])->Load(element, FGFCS::stFCS);
      if (!result) {
        cerr << endl << "Aircraft flight_control element has problems in file " << aircraftCfgFileName << endl;
        return result;
      }
    }

    // Process the aerodynamics element. This element is OPTIONAL, but almost always expected.
    element = document->FindElement("aerodynamics");
    if (element) {
      result = ((FGAerodynamics*)Models[eAerodynamics])->Load(element);
      if (!result) {
        cerr << endl << "Aircraft aerodynamics element has problems in file " << aircraftCfgFileName << endl;
        return result;
      }
    } else {
      cerr << endl << "No expected aerodynamics element was found in the aircraft config file." << endl;
    }

    // Process the input element. This element is OPTIONAL.
    element = document->FindElement("input");
    if (element) {
      result = ((FGInput*)Models[eInput])->Load(element);
      if (!result) {
        cerr << endl << "Aircraft input element has problems in file " << aircraftCfgFileName << endl;
        return result;
      }
    }

    // Process the output element[s]. This element is OPTIONAL, and there may be more than one.
    unsigned int idx=0;
    typedef double (FGOutput::*iOPMF)(void) const;
    typedef int (FGFDMExec::*iOPV)(void) const;
    element = document->FindElement("output");
    while (element) {
      if (debug_lvl > 0) cout << endl << "  Output data set: " << idx << "  ";
      FGOutput* Output = new FGOutput(this);
      Output->InitModel();
      Schedule(Output);
      result = Output->Load(element);
      if (!result) {
        cerr << endl << "Aircraft output element has problems in file " << aircraftCfgFileName << endl;
        return result;
      } else {
        Outputs.push_back(Output);
        string outputProp = CreateIndexedPropertyName("simulation/output",idx);
        instance->Tie(outputProp+"/log_rate_hz", Output, (iOPMF)0, &FGOutput::SetRate, false);
        instance->Tie("simulation/force-output", this, (iOPV)0, &FGFDMExec::ForceOutput, false);
        idx++;
      }
      element = document->FindNextElement("output");
    }

    // Lastly, process the child element. This element is OPTIONAL - and NOT YET SUPPORTED.
    element = document->FindElement("child");
    if (element) {
      result = ReadChild(element);
      if (!result) {
        cerr << endl << "Aircraft child element has problems in file " << aircraftCfgFileName << endl;
        return result;
      }
    }

    // Since all vehicle characteristics have been loaded, place the values in the Inputs
    // structure for the FGModel-derived classes.
    LoadModelConstants();

    modelLoaded = true;

    if (debug_lvl > 0) {
      LoadInputs(eMassBalance); // Update all input mass properties for the report.
      Models[eMassBalance]->Run(false);  // Update all mass properties for the report.
      ((FGMassBalance*)Models[eMassBalance])->GetMassPropertiesReport();

      cout << endl << fgblue << highint
           << "End of vehicle configuration loading." << endl
           << "-------------------------------------------------------------------------------"
           << reset << endl;
    }

    if (IsChild) debug_lvl = saved_debug_lvl;

  } else {
    cerr << fgred
         << "  JSBSim failed to open the configuration file: " << aircraftCfgFileName
         << fgdef << endl;
  }

  for (unsigned int i=0; i< Models.size(); i++) LoadInputs(i);

  if (result) {
    struct PropertyCatalogStructure masterPCS;
    masterPCS.base_string = "";
    masterPCS.node = (FGPropertyManager*)Root;
    BuildPropertyCatalog(&masterPCS);
  }

  return result;
}
Esempio n. 8
0
bool FGFDMExec::Allocate(void)
{
  bool result=true;

  Models.resize(eNumStandardModels);

  // First build the inertial model since some other models are relying on
  // the inertial model and the ground callback to build themselves.
  // Note that this does not affect the order in which the models will be
  // executed later.
  Models[eInertial]          = new FGInertial(this);
  SetGroundCallback(new FGDefaultGroundCallback(static_cast<FGInertial*>(Models[eInertial])->GetRefRadius()));

  // See the eModels enum specification in the header file. The order of the
  // enums specifies the order of execution. The Models[] vector is the primary
  // storage array for the list of models.
  Models[ePropagate]         = new FGPropagate(this);
  Models[eInput]             = new FGInput(this);
  Models[eAtmosphere]        = new FGStandardAtmosphere(this);
  Models[eWinds]             = new FGWinds(this);
  Models[eSystems]           = new FGFCS(this);
  Models[eMassBalance]       = new FGMassBalance(this);
  Models[eAuxiliary]         = new FGAuxiliary(this);
  Models[ePropulsion]        = new FGPropulsion(this);
  Models[eAerodynamics]      = new FGAerodynamics (this);
  Models[eGroundReactions]   = new FGGroundReactions(this);
  Models[eExternalReactions] = new FGExternalReactions(this);
  Models[eBuoyantForces]     = new FGBuoyantForces(this);
  Models[eAircraft]          = new FGAircraft(this);
  Models[eAccelerations]     = new FGAccelerations(this);
  Models[eOutput]            = new FGOutput(this);

  // Assign the Model shortcuts for internal executive use only.
  Propagate = (FGPropagate*)Models[ePropagate];
  Inertial = (FGInertial*)Models[eInertial];
  Atmosphere = (FGAtmosphere*)Models[eAtmosphere];
  Winds = (FGWinds*)Models[eWinds];
  FCS = (FGFCS*)Models[eSystems];
  MassBalance = (FGMassBalance*)Models[eMassBalance];
  Auxiliary = (FGAuxiliary*)Models[eAuxiliary];
  Propulsion = (FGPropulsion*)Models[ePropulsion];
  Aerodynamics = (FGAerodynamics*)Models[eAerodynamics];
  GroundReactions = (FGGroundReactions*)Models[eGroundReactions];
  ExternalReactions = (FGExternalReactions*)Models[eExternalReactions];
  BuoyantForces = (FGBuoyantForces*)Models[eBuoyantForces];
  Aircraft = (FGAircraft*)Models[eAircraft];
  Accelerations = (FGAccelerations*)Models[eAccelerations];
  Output = (FGOutput*)Models[eOutput];

  // Initialize planet (environment) constants
  LoadPlanetConstants();

  // Initialize models
  for (unsigned int i = 0; i < Models.size(); i++) {
    // The Input/Output models must not be initialized prior to IC loading
    if (i == eInput || i == eOutput) continue;

    LoadInputs(i);
    Models[i]->InitModel();
  }

  IC = new FGInitialCondition(this);
  IC->bind(instance);

  modelLoaded = false;

  return result;
}