]> git.mxchange.org Git - flightgear.git/blobdiff - src/FDM/JSBSim/FGFDMExec.h
Merge branch 'next' of http://git.gitorious.org/fg/flightgear into next
[flightgear.git] / src / FDM / JSBSim / FGFDMExec.h
index 046b2403f0a367697c787e6b56bed3598145f1f9..b982654e7aa613158ec47548c21fbb0b5ac18d76 100644 (file)
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
- Header:       FGFDMExec.h\r
- Author:       Jon Berndt\r
- Date started: 11/17/98\r
-\r
- ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------\r
-\r
- This program is free software; you can redistribute it and/or modify it under\r
- the terms of the GNU General Public License as published by the Free Software\r
- Foundation; either version 2 of the License, or (at your option) any later\r
- version.\r
-\r
- This program is distributed in the hope that it will be useful, but WITHOUT\r
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
- FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more\r
- details.\r
-\r
- You should have received a copy of the GNU General Public License along with\r
- this program; if not, write to the Free Software Foundation, Inc., 59 Temple\r
- Place - Suite 330, Boston, MA  02111-1307, USA.\r
-\r
- Further information about the GNU General Public License can also be found on\r
- the world wide web at http://www.gnu.org.\r
-\r
-HISTORY\r
---------------------------------------------------------------------------------\r
-11/17/98   JSB   Created\r
-7/31/99     TP   Added RunIC function that runs the sim so that every frame\r
-                 begins with the IC values from the given FGInitialCondition\r
-                                  object and dt=0.\r
-\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-SENTRY\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
-\r
-#ifndef FGFDMEXEC_HEADER_H\r
-#define FGFDMEXEC_HEADER_H\r
-\r
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-INCLUDES\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
-\r
-#ifdef FGFS\r
-#  include <simgear/compiler.h>\r
-#  ifdef FG_HAVE_STD_INCLUDES\r
-#    include <vector>\r
-#  else\r
-#    include <vector.h>\r
-#  endif\r
-#else\r
-#  include <vector>\r
-#endif\r
-\r
-#include "FGModel.h"\r
-#include "FGInitialCondition.h"\r
-\r
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-DEFINITIONS\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
-\r
-#define ID_FDMEXEC "$Id$"\r
-\r
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-FORWARD DECLARATIONS\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
-\r
-class FGState;\r
-class FGAtmosphere;\r
-class FGFCS;\r
-class FGPropulsion;\r
-class FGAircraft;\r
-class FGTranslation;\r
-class FGRotation;\r
-class FGPosition;\r
-class FGAuxiliary;\r
-class FGOutput;\r
-class FGInitialCondition;\r
-\r
-struct condition {\r
-  vector <eParam>  TestParam;\r
-  vector <eParam>  SetParam;\r
-  vector <float>   TestValue;\r
-  vector <float>   SetValue;\r
-  vector <string>  Comparison;\r
-  vector <float>   TC;\r
-  vector <bool>    Persistent;\r
-  vector <eAction> Action;\r
-  vector <eType>   Type;\r
-  vector <bool>    Triggered;\r
-  vector <float>   newValue;\r
-  vector <float>   OriginalValue;\r
-  vector <float>   StartTime;\r
-  vector <float>   EndTime;\r
-\r
-  condition() {\r
-  }\r
-};\r
-\r
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
-\r
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-CLASS DOCUMENTATION\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
-\r
-/** Encapsulates the JSBSim simulation executive.\r
-    @author Jon S. Berndt\r
-    @version $Id$\r
-\r
-    @doc This class is the interface class through which all other simulation classes\r
-    are instantiated, initialized, and run. When integrated with FlightGear (or\r
-    other flight simulator) this class is typically instantiated by an interface\r
-    class on the simulator side.\r
-\r
-    <h4>Scripting support provided in the Executive</h4>\r
-\r
-    <p>There is simple scripting support provided in the FGFDMExec\r
-    class. Commands are specified using the <u>Simple Scripting\r
-    Directives for JSBSim</u> (SSDJ). The script file is in XML\r
-    format. A test condition (or conditions) can be set up in the\r
-    script and when the condition evaluates to true, the specified\r
-    action[s] is/are taken. A test condition can be <em>persistent</em>,\r
-    meaning that if a test condition evaluates to true, then passes\r
-    and evaluates to false, the condition is reset and may again be\r
-    triggered. When the set of tests evaluates to true for a given\r
-    condition, an item may be set to another value. This value might\r
-    be a boolean, a value, or a delta value, and the change from the\r
-    current value to the new value can be either via a step function,\r
-    a ramp, or an exponential approach. The speed of a ramp or\r
-    approach is specified via the time constant. Here is the format\r
-    of the script file:</p>\r
-\r
-    <pre><strong>&lt;?xml version=&quot;1.0&quot;?&gt;\r
-    &lt;runscript name=&quot;C172-01A&quot;&gt;\r
-\r
-    &lt;!--\r
-    This run is for testing C172 runs\r
-    --&gt;\r
-\r
-    &lt;use aircraft=&quot;c172&quot;&gt;\r
-    &lt;use initialize=&quot;reset00&quot;&gt;\r
-\r
-    &lt;run start=&quot;0.0&quot; end=&quot;4.5&quot; dt=&quot;0.05&quot;&gt;\r
-      &lt;when&gt;\r
-        &lt;parameter name=&quot;FG_TIME&quot; comparison=&quot;ge&quot; value=&quot;0.25&quot;&gt;\r
-        &lt;parameter name=&quot;FG_TIME&quot; comparison=&quot;le&quot; value=&quot;0.50&quot;&gt;\r
-        &lt;set name=&quot;FG_AILERON_CMD&quot; type=&quot;FG_VALUE&quot; value=&quot;0.25&quot;\r
-        action=&quot;FG_STEP&quot; persistent=&quot;false&quot; tc =&quot;0.25&quot;&gt;\r
-      &lt;/when&gt;\r
-      &lt;when&gt;\r
-        &lt;parameter name=&quot;FG_TIME&quot; comparison=&quot;ge&quot; value=&quot;0.5&quot;&gt;\r
-        &lt;parameter name=&quot;FG_TIME&quot; comparison=&quot;le&quot; value=&quot;1.5&quot;&gt;\r
-        &lt;set name=&quot;FG_AILERON_CMD&quot; type=&quot;FG_DELTA&quot; value=&quot;0.5&quot;\r
-        action=&quot;FG_EXP&quot; persistent=&quot;false&quot; tc =&quot;0.5&quot;&gt;\r
-      &lt;/when&gt;\r
-      &lt;when&gt;\r
-        &lt;parameter name=&quot;FG_TIME&quot; comparison=&quot;ge&quot; value=&quot;1.5&quot;&gt;\r
-        &lt;parameter name=&quot;FG_TIME&quot; comparison=&quot;le&quot; value=&quot;2.5&quot;&gt;\r
-        &lt;set name=&quot;FG_RUDDER_CMD&quot; type=&quot;FG_DELTA&quot; value=&quot;0.5&quot;\r
-        action=&quot;FG_RAMP&quot; persistent=&quot;false&quot; tc =&quot;0.5&quot;&gt;\r
-      &lt;/when&gt;\r
-    &lt;/run&gt;\r
-\r
-    &lt;/runscript&gt;</strong></pre>\r
-\r
-    <p>The first line must always be present. The second line\r
-    identifies this file as a script file, and gives a descriptive\r
-    name to the script file. Comments are next, delineated by the\r
-    &lt;!-- and --&gt; symbols. The aircraft and initialization files\r
-    to be used are specified in the &quot;use&quot; lines. Next,\r
-    comes the &quot;run&quot; section, where the conditions are\r
-    described in &quot;when&quot; clauses.</p>\r
-\r
-    <h4>JSBSim Debugging Directives</h4>\r
-\r
-    This describes to any interested entity the debug level\r
-    requested by setting the JSBSIM_DEBUG environment variable.\r
-    The bitmasked value choices are as follows:<ol>\r
-    <li><b>unset</b>: In this case (the default) JSBSim would only print\r
-       out the normally expected messages, essentially echoing\r
-       the config files as they are read. If the environment\r
-       variable is not set, debug_lvl is set to 1 internally</li>\r
-    <li><b>0</b>: This requests JSBSim not to output any messages\r
-       whatsoever.</li>\r
-    <li><b>1</b>: This value explicity requests the normal JSBSim\r
-       startup messages</li>\r
-    <li><b>2</b>: This value asks for a message to be printed out when\r
-       a class is instantiated</li>\r
-    <li><b>4</b>: When this value is set, a message is displayed when a\r
-       FGModel object executes its Run() method</li>\r
-    <li><b>8</b>: When this value is set, various runtime state variables\r
-       are printed out periodically</li>\r
-    </ol>\r
-\r
-*/\r
-\r
-/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-CLASS DECLARATION\r
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/\r
-\r
-class FGFDMExec\r
-{\r
-public:\r
-  /// Default constructor\r
-  FGFDMExec(void);\r
-\r
-  /// Default destructor\r
-  ~FGFDMExec();\r
-\r
-  /** This routine places a model into the runlist at the specified rate. The\r
-      "rate" is not really a clock rate. It represents how many calls to the\r
-      FGFDMExec::Run() method must be made before the model is executed. A\r
-      value of 1 means that the model will be executed for each call to the\r
-      exec's Run() method. A value of 5 means that the model will only be\r
-      executed every 5th call to the exec's Run() method.\r
-      @param model A pointer to the model being scheduled.\r
-      @param rate The rate at which to execute the model as described above.\r
-      @return Currently returns 0 always. */\r
-  int  Schedule(FGModel* model, int rate);\r
-\r
-  /** This executes each scheduled model in succession, as well as running any\r
-      scripts which are loaded.\r
-      @return true if successful, false if sim should be ended  */\r
-  bool Run(void);\r
-\r
-  /** Initializes the sim with a set of initial conditions.\r
-      @param fgic A pointer to a filled out initial conditions class which\r
-      describes the desired initial conditions.\r
-      @return true if successful\r
-       */\r
-  bool RunIC(FGInitialCondition *fgic);\r
-\r
-  /// Freezes the sim\r
-  void Freeze(void) {frozen = true;}\r
-\r
-  /// Resumes the sim\r
-  void Resume(void) {frozen = false;}\r
-\r
-  /** Loads an aircraft model.\r
-      @param AircraftPath path to the aircraft directory. For instance:\r
-      "aircraft". Under aircraft, then, would be directories for various\r
-      modeled aircraft such as C172/, x15/, etc.\r
-      @param EnginePath path to the directory under which engine config\r
-      files are kept, for instance "engine"\r
-      @param model the name of the aircraft model itself. This file will\r
-      be looked for in the directory specified in the AircraftPath variable,\r
-      and in turn under the directory with the same name as the model. For\r
-      instance: "aircraft/x15/x15.xml"\r
-      @return true if successful*/\r
-  bool LoadModel(string AircraftPath, string EnginePath, string model);\r
-\r
-  /** Loads a script to drive JSBSim (usually in standalone mode).\r
-      The language is the Simple Script Directives for JSBSim (SSDJ).\r
-      @param script the filename (including path name, if any) for the script.\r
-      @return true if successful */\r
-  bool LoadScript(string script);\r
-\r
-  /** This function is called each pass through the executive Run() method IF\r
-      scripting is enabled. */\r
-  void RunScript(void);\r
-\r
-  bool SetEnginePath(string path)   {EnginePath = path; return true;}\r
-  bool SetAircraftPath(string path) {AircraftPath = path; return true;}\r
-  bool SetScriptPath(string path)   {ScriptPath = path; return true;}\r
-\r
-  /// @name Top-level executive State and Model retrieval mechanism\r
-  //@{\r
-  /// Returns the FGState pointer.\r
-  inline FGState* GetState(void)              {return State;}\r
-  /// Returns the FGAtmosphere pointer.\r
-  inline FGAtmosphere* GetAtmosphere(void)    {return Atmosphere;}\r
-  /// Returns the FGFCS pointer.\r
-  inline FGFCS* GetFCS(void)                  {return FCS;}\r
-  /// Returns the FGPropulsion pointer.\r
-  inline FGPropulsion* GetPropulsion(void)    {return Propulsion;}\r
-  /// Returns the FGAircraft pointer.\r
-  inline FGAircraft* GetAircraft(void)        {return Aircraft;}\r
-  /// Returns the FGTranslation pointer.\r
-  inline FGTranslation* GetTranslation(void)  {return Translation;}\r
-  /// Returns the FGRotation pointer.\r
-  inline FGRotation* GetRotation(void)        {return Rotation;}\r
-  /// Returns the FGPosition pointer.\r
-  inline FGPosition* GetPosition(void)        {return Position;}\r
-  /// Returns the FGAuxiliary pointer.\r
-  inline FGAuxiliary* GetAuxiliary(void)      {return Auxiliary;}\r
-  /// Returns the FGOutput pointer.\r
-  inline FGOutput* GetOutput(void)            {return Output;}\r
-  //@}\r
-\r
-  /// Retrieves the engine path.\r
-  inline string GetEnginePath(void)          {return EnginePath;}\r
-  /// Retrieves the aircraft path.\r
-  inline string GetAircraftPath(void)        {return AircraftPath;}\r
-\r
-private:\r
-  FGModel* FirstModel;\r
-\r
-  bool frozen;\r
-  bool terminate;\r
-  int  Error;\r
-  bool modelLoaded;\r
-  bool Scripted;\r
-\r
-  string AircraftPath;\r
-  string EnginePath;\r
-  string ScriptPath;\r
-  string ScriptName;\r
-  float  StartTime;\r
-  float  EndTime;\r
-  vector <struct condition> Conditions;\r
-\r
-  FGState*       State;\r
-  FGAtmosphere*  Atmosphere;\r
-  FGFCS*         FCS;\r
-  FGPropulsion*  Propulsion;\r
-  FGAircraft*    Aircraft;\r
-  FGTranslation* Translation;\r
-  FGRotation*    Rotation;\r
-  FGPosition*    Position;\r
-  FGAuxiliary*   Auxiliary;\r
-  FGOutput*      Output;\r
-\r
-  bool Allocate(void);\r
-  bool DeAllocate(void);\r
-  void Debug(void);\r
-};\r
-\r
-//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\r
-#endif\r
-\r
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ Header:       FGFDMExec.h
+ Author:       Jon Berndt
+ Date started: 11/17/98
+ file The header file for the JSBSim executive.
+
+ ------------- Copyright (C) 1999  Jon S. Berndt (jon@jsbsim.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.
+
+HISTORY
+--------------------------------------------------------------------------------
+11/17/98   JSB   Created
+7/31/99     TP   Added RunIC function that runs the sim so that every frame
+                 begins with the IC values from the given FGInitialCondition
+                 object and dt=0.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+SENTRY
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#ifndef FGFDMEXEC_HEADER_H
+#define FGFDMEXEC_HEADER_H
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+INCLUDES
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#include <vector>
+#include <string>
+
+//#include "models/FGModel.h"
+#include "models/FGOutput.h"
+#include "models/FGInput.h"
+#include "initialization/FGTrim.h"
+#include "initialization/FGInitialCondition.h"
+#include "FGJSBBase.h"
+#include "input_output/FGPropertyManager.h"
+#include "input_output/FGGroundCallback.h"
+#include "input_output/FGXMLFileRead.h"
+#include "models/FGPropagate.h"
+#include "math/FGColumnVector3.h"
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+DEFINITIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#define ID_FDMEXEC "$Id: FGFDMExec.h,v 1.56 2010/11/18 20:37:10 jberndt Exp $"
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+FORWARD DECLARATIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+namespace JSBSim {
+
+class FGScript;
+class FGTrim;
+class FGAerodynamics;
+class FGAircraft;
+class FGAtmosphere;
+class FGAuxiliary;
+class FGBuoyantForces;
+class FGExternalReactions;
+class FGGroundReactions;
+class FGFCS;
+class FGInertial;
+class FGInput;
+class FGOutput;
+class FGPropagate;
+class FGPropulsion;
+class FGMassBalance;
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DOCUMENTATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+/** Encapsulates the JSBSim simulation executive.
+    This class is the executive class through which all other simulation classes
+    are instantiated, initialized, and run. When integrated with FlightGear (or
+    other flight simulator) this class is typically instantiated by an interface
+    class on the simulator side.
+
+    At the time of simulation initialization, the interface
+    class creates an instance of this executive class. The
+    executive is subsequently directed to load the chosen aircraft specification
+    file:
+
+    @code
+    fdmex = new FGFDMExec( ... );
+    result = fdmex->LoadModel( ... );
+    @endcode
+
+    When an aircraft model is loaded, the config file is parsed and for each of the
+    sections of the config file (propulsion, flight control, etc.) the
+    corresponding Load() method is called (e.g. FGFCS::Load()).
+
+    Subsequent to the creation of the executive and loading of the model,
+    initialization is performed. Initialization involves copying control inputs
+    into the appropriate JSBSim data storage locations, configuring it for the set
+    of user supplied initial conditions, and then copying state variables from
+    JSBSim. The state variables are used to drive the instrument displays and to
+    place the vehicle model in world space for visual rendering:
+
+    @code
+    copy_to_JSBsim(); // copy control inputs to JSBSim
+    fdmex->RunIC(); // loop JSBSim once w/o integrating
+    copy_from_JSBsim(); // update the bus
+    @endcode
+
+    Once initialization is complete, cyclic execution proceeds:
+
+    @code
+    copy_to_JSBsim(); // copy control inputs to JSBSim
+    fdmex->Run(); // execute JSBSim
+    copy_from_JSBsim(); // update the bus
+    @endcode
+
+    JSBSim can be used in a standalone mode by creating a compact stub program
+    that effectively performs the same progression of steps as outlined above for
+    the integrated version, but with two exceptions. First, the copy_to_JSBSim()
+    and copy_from_JSBSim() functions are not used because the control inputs are
+    handled directly by the scripting facilities and outputs are handled by the
+    output (data logging) class. Second, the name of a script file can be supplied
+    to the stub program. Scripting (see FGScript) provides a way to supply command
+    inputs to the simulation:
+
+    @code
+    FDMExec = new JSBSim::FGFDMExec();
+    FDMExec->LoadScript( ScriptName ); // the script loads the aircraft and ICs
+    result = FDMExec->Run();
+    while (result) { // cyclic execution
+      result = FDMExec->Run(); // execute JSBSim
+    }
+    @endcode
+
+    The standalone mode has been useful for verifying changes before committing
+    updates to the source code repository. It is also useful for running sets of
+    tests that reveal some aspects of simulated aircraft performance, such as
+    range, time-to-climb, takeoff distance, etc.
+
+    <h3>JSBSim Debugging Directives</h3>
+
+    This describes to any interested entity the debug level
+    requested by setting the JSBSIM_DEBUG environment variable.
+    The bitmasked value choices are as follows:
+    - <b>unset</b>: 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
+    - <b>0</b>: This requests JSBSim not to output any messages
+       whatsoever
+    - <b>1</b>: This value explicity requests the normal JSBSim
+       startup messages
+    - <b>2</b>: This value asks for a message to be printed out when
+       a class is instantiated
+    - <b>4</b>: When this value is set, a message is displayed when a
+       FGModel object executes its Run() method
+    - <b>8</b>: When this value is set, various runtime state variables
+       are printed out periodically
+    - <b>16</b>: When set various parameters are sanity checked and
+       a message is printed out when they go out of bounds
+
+    <h3>Properties</h3>
+    @property simulator/do_trim (write only) Can be set to the integer equivalent to one of
+                                tLongitudinal (0), tFull (1), tGround (2), tPullup (3),
+                                tCustom (4), tTurn (5). Setting this to a legal value
+                                (such as by a script) causes a trim to be performed. This
+                                property actually maps toa function call of DoTrim().
+
+    @author Jon S. Berndt
+    @version $Revision: 1.56 $
+*/
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DECLARATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+class FGFDMExec : public FGJSBBase, public FGXMLFileRead
+{
+  struct childData {
+    FGFDMExec* exec;
+    string info;
+    FGColumnVector3 Loc;
+    FGColumnVector3 Orient;
+    bool mated;
+    bool internal;
+
+    childData(void) {
+      info = "";
+      Loc = FGColumnVector3(0,0,0);
+      Orient = FGColumnVector3(0,0,0);
+      mated = true;
+      internal = false;
+    }
+    
+    void Run(void) {exec->Run();}
+    void AssignState(FGPropagate* source_prop) {
+      exec->GetPropagate()->SetVState(source_prop->GetVState());
+    }
+
+    ~childData(void) {
+      delete exec;
+    }
+  };
+
+public:
+
+  /// Default constructor
+  FGFDMExec(FGPropertyManager* root = 0, unsigned int* fdmctr = 0);
+
+  /// Default destructor
+  ~FGFDMExec();
+
+  /** Unbind all tied JSBSim properties. */
+  void Unbind(void) {instance->Unbind();}
+
+  /** This routine places a model into the runlist at the specified rate. The
+      "rate" is not really a clock rate. It represents how many calls to the
+      FGFDMExec::Run() method must be made before the model is executed. A
+      value of 1 means that the model will be executed for each call to the
+      exec's Run() method. A value of 5 means that the model will only be
+      executed every 5th call to the exec's Run() method. Use of a rate other than
+      one is at this time not recommended.
+      @param model A pointer to the model being scheduled.
+      @param rate The rate at which to execute the model as described above.
+      @return Currently returns 0 always. */
+  void Schedule(FGModel* model, int rate);
+
+  /** This function executes each scheduled model in succession.
+      @return true if successful, false if sim should be ended  */
+  bool Run(void);
+
+  /** Initializes the sim from the initial condition object and executes
+      each scheduled model without integrating i.e. dt=0.
+      @return true if successful */
+  bool RunIC(void);
+
+  /** Sets the ground callback pointer.
+      @param gc A pointer to a ground callback object.  */
+  void SetGroundCallback(FGGroundCallback* gc);
+
+  /** Loads an aircraft model.
+      @param AircraftPath path to the aircraft/ directory. For instance:
+      "aircraft". Under aircraft, then, would be directories for various
+      modeled aircraft such as C172/, x15/, etc.
+      @param EnginePath path to the directory under which engine config
+      files are kept, for instance "engine"
+      @param SystemsPath path to the directory under which systems config
+      files are kept, for instance "systems"
+      @param model the name of the aircraft model itself. This file will
+      be looked for in the directory specified in the AircraftPath variable,
+      and in turn under the directory with the same name as the model. For
+      instance: "aircraft/x15/x15.xml"
+      @param addModelToPath set to true to add the model name to the
+      AircraftPath, defaults to true
+      @return true if successful */
+  bool LoadModel(const string& AircraftPath, const string& EnginePath, const string& SystemsPath,
+                 const string& model, bool addModelToPath = true);
+
+  /** Loads an aircraft model.  The paths to the aircraft and engine
+      config file directories must be set prior to calling this.  See
+      below.
+      @param model the name of the aircraft model itself. This file will
+      be looked for in the directory specified in the AircraftPath variable,
+      and in turn under the directory with the same name as the model. For
+      instance: "aircraft/x15/x15.xml"
+      @param addModelToPath set to true to add the model name to the
+      AircraftPath, defaults to true
+      @return true if successful*/
+  bool LoadModel(const string& model, bool addModelToPath = true);
+
+  /** Loads a script
+      @param Script the full path name and file name for the script to be loaded.
+      @return true if successfully loadsd; false otherwise. */
+  bool LoadScript(const string& Script, double deltaT);
+
+  /** Sets the path to the engine config file directories.
+      @param path path to the directory under which engine config
+      files are kept, for instance "engine"  */
+  bool SetEnginePath(const string& path)   { EnginePath = RootDir + path; return true; }
+
+  /** Sets the path to the aircraft config file directories.
+      @param path path to the aircraft directory. For instance:
+      "aircraft". Under aircraft, then, would be directories for various
+      modeled aircraft such as C172/, x15/, etc.  */
+  bool SetAircraftPath(const string& path) { AircraftPath = RootDir + path; return true; }
+  
+  /** Sets the path to the systems config file directories.
+      @param path path to the directory under which systems config
+      files are kept, for instance "systems"  */
+  bool SetSystemsPath(const string& path)   { SystemsPath = RootDir + path; return true; }
+  
+  /// @name Top-level executive State and Model retrieval mechanism
+  //@{
+  /// Returns the FGAtmosphere pointer.
+  FGAtmosphere* GetAtmosphere(void)    {return Atmosphere;}
+  /// Returns the FGFCS pointer.
+  FGFCS* GetFCS(void)                  {return FCS;}
+  /// Returns the FGPropulsion pointer.
+  FGPropulsion* GetPropulsion(void)    {return Propulsion;}
+  /// Returns the FGAircraft pointer.
+  FGMassBalance* GetMassBalance(void)  {return MassBalance;}
+  /// Returns the FGAerodynamics pointer
+  FGAerodynamics* GetAerodynamics(void){return Aerodynamics;}
+  /// Returns the FGInertial pointer.
+  FGInertial* GetInertial(void)        {return Inertial;}
+  /// Returns the FGGroundReactions pointer.
+  FGGroundReactions* GetGroundReactions(void) {return GroundReactions;}
+  /// Returns the FGExternalReactions pointer.
+  FGExternalReactions* GetExternalReactions(void) {return ExternalReactions;}
+  /// Returns the FGBuoyantForces pointer.
+  FGBuoyantForces* GetBuoyantForces(void) {return BuoyantForces;}
+  /// Returns the FGAircraft pointer.
+  FGAircraft* GetAircraft(void)        {return Aircraft;}
+  /// Returns the FGPropagate pointer.
+  FGPropagate* GetPropagate(void)      {return Propagate;}
+  /// Returns the FGAuxiliary pointer.
+  FGAuxiliary* GetAuxiliary(void)      {return Auxiliary;}
+  /// Returns the FGInput pointer.
+  FGInput* GetInput(void)              {return Input;}
+  /// Returns the FGGroundCallback pointer.
+  FGGroundCallback* GetGroundCallback(void) {return GroundCallback;}
+  /// Retrieves the script object
+  FGScript* GetScript(void) {return Script;}
+  // Returns a pointer to the FGInitialCondition object
+  FGInitialCondition* GetIC(void)      {return IC;}
+  // Returns a pointer to the FGTrim object
+  FGTrim* GetTrim(void);
+  //@}
+
+  /// Retrieves the engine path.
+  const string& GetEnginePath(void)    {return EnginePath;}
+  /// Retrieves the aircraft path.
+  const string& GetAircraftPath(void)  {return AircraftPath;}
+  /// Retrieves the systems path.
+  const string& GetSystemsPath(void)   {return SystemsPath;}
+  /// Retrieves the full aircraft path name.
+  const string& GetFullAircraftPath(void) {return FullAircraftPath;}
+
+  /** Retrieves the value of a property.
+      @param property the name of the property
+      @result the value of the specified property */
+  inline double GetPropertyValue(const string& property) {return instance->GetDouble(property);}
+
+  /** Sets a property value.
+      @param property the property to be set
+      @param value the value to set the property to */
+  inline void SetPropertyValue(const string& property, double value) {
+    instance->SetDouble(property, value);
+  }
+
+  /// Returns the model name.
+  const string& GetModelName(void) { return modelName; }
+/*
+  /// Returns the current time.
+  double GetSimTime(void);
+
+  /// Returns the current frame time (delta T).
+  double GetDeltaT(void);
+*/  
+  /// Returns a pointer to the property manager object.
+  FGPropertyManager* GetPropertyManager(void);
+  /// Returns a vector of strings representing the names of all loaded models (future)
+  vector <string> EnumerateFDMs(void);
+  /// Gets the number of child FDMs.
+  int GetFDMCount(void) {return (int)ChildFDMList.size();}
+  /// Gets a particular child FDM.
+  childData* GetChildFDM(int i) {return ChildFDMList[i];}
+  /// Marks this instance of the Exec object as a "child" object.
+  void SetChild(bool ch) {IsChild = ch;}
+
+  /** Sets the output (logging) mechanism for this run.
+      Calling this function passes the name of an output directives file to
+      the FGOutput object associated with this run. The call to this function
+      should be made prior to loading an aircraft model. This call results in an
+      FGOutput object being built as the first Output object in the FDMExec-managed
+      list of Output objects that may be created for an aircraft model. If this call
+      is made after an aircraft model is loaded, there is no effect. Any Output
+      objects added by the aircraft model itself (in an &lt;output> element) will be
+      added after this one. Care should be taken not to refer to the same file
+      name.
+      An output directives file contains an &lt;output> &lt;/output> element, within
+      which should be specified the parameters or parameter groups that should
+      be logged.
+      @param fname the filename of an output directives file.
+    */
+  bool SetOutputDirectives(const string& fname);
+
+  /** Sets (or overrides) the output filename
+      @param fname the name of the file to output data to
+      @return true if successful, false if there is no output specified for the flight model */
+  bool SetOutputFileName(const string& fname) {
+    if (Outputs.size() > 0) Outputs[0]->SetOutputFileName(fname);
+    else return false;
+    return true;
+  }
+
+  /** Retrieves the current output filename.
+      @return the name of the output file for the first output specified by the flight model.
+              If none is specified, the empty string is returned. */
+  string GetOutputFileName(void) {
+    if (Outputs.size() > 0) return Outputs[0]->GetOutputFileName();
+    else return string("");
+  }
+
+  /** Executes trimming in the selected mode.
+  *   @param mode Specifies how to trim:
+  * - tLongitudinal=0
+  * - tFull
+  * - tGround
+  * - tPullup
+  * - tCustom
+  * - tTurn
+  * - tNone  */
+  void DoTrim(int mode);
+//  void DoTrimAnalysis(int mode);
+
+  /// Disables data logging to all outputs.
+  void DisableOutput(void);
+  /// Enables data logging to all outputs.
+  void EnableOutput(void);
+  /// Pauses execution by preventing time from incrementing.
+  void Hold(void) {holding = true;}
+  /// Resumes execution from a "Hold".
+  void Resume(void) {holding = false;}
+  /// Returns true if the simulation is Holding (i.e. simulation time is not moving).
+  bool Holding(void) {return holding;}
+  /// Resets the initial conditions object and prepares the simulation to run again.
+  void ResetToInitialConditions(void);
+  /// Sets the debug level.
+  void SetDebugLevel(int level) {debug_lvl = level;}
+
+  struct PropertyCatalogStructure {
+    /// Name of the property.
+    string base_string;
+    /// The node for the property.
+    FGPropertyManager *node;
+  };
+
+  /** Builds a catalog of properties.
+  *   This function descends the property tree and creates a list (an STL vector)
+  *   containing the name and node for all properties.
+  *   @param pcs The "root" property catalog structure pointer.  */
+  void BuildPropertyCatalog(struct PropertyCatalogStructure* pcs);
+
+  /** Retrieves property or properties matching the supplied string.
+  *   A string is returned that contains a carriage return delimited list of all
+  *   strings in the property catalog that matches the supplied check string.
+  *   @param check The string to search for in the property catalog.
+  *   @return the carriage-return-delimited string containing all matching strings
+  *               in the catalog.  */
+  string QueryPropertyCatalog(const string& check);
+
+  // Print the contents of the property catalog for the loaded aircraft.
+  void PrintPropertyCatalog(void);
+
+  vector<string>& GetPropertyCatalog(void) {return PropertyCatalog;}
+
+  /// Use the MSIS atmosphere model.
+  void UseAtmosphereMSIS(void);
+
+  /// Use the Mars atmosphere model. (Not operative yet.)
+  void UseAtmosphereMars(void);
+
+  void SetTrimStatus(bool status){ trim_status = status; }
+  bool GetTrimStatus(void) const { return trim_status; }
+  void SetTrimMode(int mode){ ta_mode = mode; }
+  int GetTrimMode(void) const { return ta_mode; }
+
+  /// Returns the cumulative simulation time in seconds.
+  double GetSimTime(void) const { return sim_time; }
+
+  /// Returns the simulation delta T.
+  double GetDeltaT(void) {return dT;}
+
+  /// Suspends the simulation and sets the delta T to zero.
+  void SuspendIntegration(void) {saved_dT = dT; dT = 0.0;}
+
+  /// Resumes the simulation by resetting delta T to the correct value.
+  void ResumeIntegration(void)  {dT = saved_dT;}
+
+  /** Returns the simulation suspension state.
+      @return true if suspended, false if executing  */
+  bool IntegrationSuspended(void) {return dT == 0.0;}
+
+  /** Sets the current sim time.
+      @param cur_time the current time
+      @return the current simulation time.      */
+  double Setsim_time(double cur_time) {
+    sim_time = cur_time;
+    return sim_time;
+  }
+
+  /** Sets the integration time step for the simulation executive.
+      @param delta_t the time step in seconds.     */
+  void Setdt(double delta_t) { dT = delta_t; }
+
+  /** Sets the root directory where JSBSim starts looking for its system directories.
+      @param rootDir the string containing the root directory. */
+  void SetRootDir(const string& rootDir) {RootDir = rootDir;}
+
+  /** Retrieves teh Root Directory.
+      @return the string representing the root (base) JSBSim directory. */
+  const string& GetRootDir(void) const {return RootDir;}
+
+  /** Increments the simulation time.
+      @return the new simulation time.     */
+  double IncrTime(void) {
+    sim_time += dT;
+    return sim_time;
+  }
+
+  /** Retrieves the current debug level setting. */
+  int GetDebugLevel(void) const {return debug_lvl;};
+
+private:
+  int Error;
+  unsigned int Frame;
+  unsigned int IdFDM;
+  unsigned short Terminate;
+  double dT;
+  double saved_dT;
+  double sim_time;
+  bool holding;
+  bool Constructing;
+  bool modelLoaded;
+  bool IsChild;
+  string modelName;
+  string AircraftPath;
+  string FullAircraftPath;
+  string EnginePath;
+  string SystemsPath;
+  string CFGVersion;
+  string Release;
+  string RootDir;
+
+  bool trim_status;
+  int ta_mode;
+
+  FGGroundCallback*   GroundCallback;
+  FGAtmosphere*       Atmosphere;
+  FGFCS*              FCS;
+  FGPropulsion*       Propulsion;
+  FGMassBalance*      MassBalance;
+  FGAerodynamics*     Aerodynamics;
+  FGInertial*         Inertial;
+  FGGroundReactions*  GroundReactions;
+  FGExternalReactions* ExternalReactions;
+  FGBuoyantForces*    BuoyantForces;
+  FGAircraft*         Aircraft;
+  FGPropagate*        Propagate;
+  FGAuxiliary*        Auxiliary;
+  FGInput*            Input;
+  FGScript*           Script;
+  FGInitialCondition* IC;
+  FGTrim*             Trim;
+
+  FGPropertyManager* Root;
+  bool StandAlone;
+  FGPropertyManager* instance;
+  
+  // The FDM counter is used to give each child FDM an unique ID. The root FDM has the ID 0
+  unsigned int*      FDMctr;
+
+  vector <string> PropertyCatalog;
+  vector <FGOutput*> Outputs;
+  vector <childData*> ChildFDMList;
+  vector <FGModel*> Models;
+
+  bool ReadFileHeader(Element*);
+  bool ReadChild(Element*);
+  bool ReadPrologue(Element*);
+  void ResetToInitialConditions(int mode);
+  bool Allocate(void);
+  bool DeAllocate(void);
+  void Initialize(FGInitialCondition *FGIC);
+
+  void Debug(int from);
+};
+}
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+#endif