]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/FGFDMExec.h
9ab3e33b2410fda50bd7483b8ca34612c2bfda72
[flightgear.git] / src / FDM / JSBSim / FGFDMExec.h
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2  Header:       FGFDMExec.h
3  Author:       Jon Berndt
4  Date started: 11/17/98
5  file The header file for the JSBSim executive.
6
7  ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
8
9  This program is free software; you can redistribute it and/or modify it under
10  the terms of the GNU Lesser General Public License as published by the Free Software
11  Foundation; either version 2 of the License, or (at your option) any later
12  version.
13
14  This program is distributed in the hope that it will be useful, but WITHOUT
15  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
17  details.
18
19  You should have received a copy of the GNU Lesser General Public License along with
20  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21  Place - Suite 330, Boston, MA  02111-1307, USA.
22
23  Further information about the GNU Lesser General Public License can also be found on
24  the world wide web at http://www.gnu.org.
25
26 HISTORY
27 --------------------------------------------------------------------------------
28 11/17/98   JSB   Created
29 7/31/99     TP   Added RunIC function that runs the sim so that every frame
30                  begins with the IC values from the given FGInitialCondition
31                  object and dt=0.
32
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 SENTRY
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
36
37 #ifndef FGFDMEXEC_HEADER_H
38 #define FGFDMEXEC_HEADER_H
39
40 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41 INCLUDES
42 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
43
44 #include <models/FGModel.h>
45 #include <models/FGOutput.h>
46 #include <models/FGInput.h>
47 #include <initialization/FGTrim.h>
48 #include <initialization/FGInitialCondition.h>
49 #include <FGJSBBase.h>
50 #include <input_output/FGPropertyManager.h>
51 #include <input_output/FGGroundCallback.h>
52 #include <input_output/FGXMLFileRead.h>
53 #include <models/FGPropagate.h>
54
55 #include <vector>
56 #include <string>
57
58 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59 DEFINITIONS
60 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
61
62 #define ID_FDMEXEC "$Id$"
63
64 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
65 FORWARD DECLARATIONS
66 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
67
68 namespace JSBSim {
69
70 class FGScript;
71 class FGTrim;
72
73 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
74 CLASS DOCUMENTATION
75 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
76
77 /** Encapsulates the JSBSim simulation executive.
78     This class is the executive class through which all other simulation classes
79     are instantiated, initialized, and run. When integrated with FlightGear (or
80     other flight simulator) this class is typically instantiated by an interface
81     class on the simulator side.
82
83     At the time of simulation initialization, the interface
84     class creates an instance of this executive class. The
85     executive is subsequently directed to load the chosen aircraft specification
86     file:
87
88     @code
89     fdmex = new FGFDMExec( \85 );
90     result = fdmex->LoadModel( \85 );
91     @endcode
92
93     When an aircraft model is loaded, the config file is parsed and for each of the
94     sections of the config file (propulsion, flight control, etc.) the
95     corresponding Load() method is called (e.g. FGFCS::Load()).
96
97     Subsequent to the creation of the executive and loading of the model,
98     initialization is performed. Initialization involves copying control inputs
99     into the appropriate JSBSim data storage locations, configuring it for the set
100     of user supplied initial conditions, and then copying state variables from
101     JSBSim. The state variables are used to drive the instrument displays and to
102     place the vehicle model in world space for visual rendering:
103
104     @code
105     copy_to_JSBsim(); // copy control inputs to JSBSim
106     fdmex->RunIC(); // loop JSBSim once w/o integrating
107     copy_from_JSBsim(); // update the bus
108     @endcode
109
110     Once initialization is complete, cyclic execution proceeds:
111
112     @code
113     copy_to_JSBsim(); // copy control inputs to JSBSim
114     fdmex->Run(); // execute JSBSim
115     copy_from_JSBsim(); // update the bus
116     @endcode
117
118     JSBSim can be used in a standalone mode by creating a compact stub program
119     that effectively performs the same progression of steps as outlined above for
120     the integrated version, but with two exceptions. First, the copy_to_JSBSim()
121     and copy_from_JSBSim() functions are not used because the control inputs are
122     handled directly by the scripting facilities and outputs are handled by the
123     output (data logging) class. Second, the name of a script file can be supplied
124     to the stub program. Scripting (see FGScript) provides a way to supply command
125     inputs to the simulation:
126
127     @code
128     FDMExec = new JSBSim::FGFDMExec();
129     FDMExec->LoadScript( ScriptName ); // the script loads the aircraft and ICs
130     result = FDMExec->Run();
131     while (result) { // cyclic execution
132       result = FDMExec->Run(); // execute JSBSim
133     }
134     @endcode
135
136     The standalone mode has been useful for verifying changes before committing
137     updates to the source code repository. It is also useful for running sets of
138     tests that reveal some aspects of simulated aircraft performance, such as
139     range, time-to-climb, takeoff distance, etc.
140
141     <h3>JSBSim Debugging Directives</h3>
142
143     This describes to any interested entity the debug level
144     requested by setting the JSBSIM_DEBUG environment variable.
145     The bitmasked value choices are as follows:
146     - <b>unset</b>: In this case (the default) JSBSim would only print
147        out the normally expected messages, essentially echoing
148        the config files as they are read. If the environment
149        variable is not set, debug_lvl is set to 1 internally
150     - <b>0</b>: This requests JSBSim not to output any messages
151        whatsoever
152     - <b>1</b>: This value explicity requests the normal JSBSim
153        startup messages
154     - <b>2</b>: This value asks for a message to be printed out when
155        a class is instantiated
156     - <b>4</b>: When this value is set, a message is displayed when a
157        FGModel object executes its Run() method
158     - <b>8</b>: When this value is set, various runtime state variables
159        are printed out periodically
160     - <b>16</b>: When set various parameters are sanity checked and
161        a message is printed out when they go out of bounds
162
163     <h3>Properties</h3>
164     @property simulator/do_trim (write only) Can be set to the integer equivalent to one of
165                                 tLongitudinal (0), tFull (1), tGround (2), tPullup (3),
166                                 tCustom (4), tTurn (5). Setting this to a legal value
167                                 (such as by a script) causes a trim to be performed. This
168                                 property actually maps toa function call of DoTrim().
169
170     @author Jon S. Berndt
171     @version $Revision$
172 */
173
174 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
175 CLASS DECLARATION
176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
177
178 class FGFDMExec : public FGJSBBase, public FGXMLFileRead
179 {
180 public:
181
182   /// Default constructor
183   FGFDMExec(FGPropertyManager* root = 0);
184
185   /// Default destructor
186   ~FGFDMExec();
187
188   /** This routine places a model into the runlist at the specified rate. The
189       "rate" is not really a clock rate. It represents how many calls to the
190       FGFDMExec::Run() method must be made before the model is executed. A
191       value of 1 means that the model will be executed for each call to the
192       exec's Run() method. A value of 5 means that the model will only be
193       executed every 5th call to the exec's Run() method. Use of a rate other than
194       one is at this time not recommended.
195       @param model A pointer to the model being scheduled.
196       @param rate The rate at which to execute the model as described above.
197       @return Currently returns 0 always. */
198   int  Schedule(FGModel* model, int rate);
199
200   /** This function executes each scheduled model in succession.
201       @return true if successful, false if sim should be ended  */
202   bool Run(void);
203
204   /** Initializes the sim from the initial condition object and executes
205       each scheduled model without integrating i.e. dt=0.
206       @return true if successful */
207   bool RunIC(void);
208
209   /** Sets the ground callback pointer.
210       @param gc A pointer to a ground callback object.  */
211   void SetGroundCallback(FGGroundCallback* gc);
212
213   /** Loads an aircraft model.
214       @param AircraftPath path to the aircraft/ directory. For instance:
215       "aircraft". Under aircraft, then, would be directories for various
216       modeled aircraft such as C172/, x15/, etc.
217       @param EnginePath path to the directory under which engine config
218       files are kept, for instance "engine"
219       @param SystemsPath path to the directory under which systems config
220       files are kept, for instance "systems"
221       @param model the name of the aircraft model itself. This file will
222       be looked for in the directory specified in the AircraftPath variable,
223       and in turn under the directory with the same name as the model. For
224       instance: "aircraft/x15/x15.xml"
225       @param addModelToPath set to true to add the model name to the
226       AircraftPath, defaults to true
227       @return true if successful */
228   bool LoadModel(string AircraftPath, string EnginePath, string SystemsPath,
229                  string model, bool addModelToPath = true);
230
231   /** Loads an aircraft model.  The paths to the aircraft and engine
232       config file directories must be set prior to calling this.  See
233       below.
234       @param model the name of the aircraft model itself. This file will
235       be looked for in the directory specified in the AircraftPath variable,
236       and in turn under the directory with the same name as the model. For
237       instance: "aircraft/x15/x15.xml"
238       @param addModelToPath set to true to add the model name to the
239       AircraftPath, defaults to true
240       @return true if successful*/
241   bool LoadModel(string model, bool addModelToPath = true);
242
243   /** Loads a script
244       @param Script the full path name and file name for the script to be loaded.
245       @return true if successfully loadsd; false otherwise. */
246   bool LoadScript(string Script);
247
248   /** Sets the path to the engine config file directories.
249       @param path path to the directory under which engine config
250       files are kept, for instance "engine"  */
251   bool SetEnginePath(string path)   { EnginePath = path; return true; }
252
253   /** Sets the path to the aircraft config file directories.
254       @param path path to the aircraft directory. For instance:
255       "aircraft". Under aircraft, then, would be directories for various
256       modeled aircraft such as C172/, x15/, etc.  */
257   bool SetAircraftPath(string path) { AircraftPath = path; return true; }
258   
259   /** Sets the path to the systems config file directories.
260       @param path path to the directory under which systems config
261       files are kept, for instance "systems"  */
262   bool SetSystemsPath(string path)   { SystemsPath = path; return true; }
263   
264   /// @name Top-level executive State and Model retrieval mechanism
265   //@{
266   /// Returns the FGAtmosphere pointer.
267   inline FGAtmosphere* GetAtmosphere(void)    {return Atmosphere;}
268   /// Returns the FGFCS pointer.
269   inline FGFCS* GetFCS(void)                  {return FCS;}
270   /// Returns the FGPropulsion pointer.
271   inline FGPropulsion* GetPropulsion(void)    {return Propulsion;}
272   /// Returns the FGAircraft pointer.
273   inline FGMassBalance* GetMassBalance(void)  {return MassBalance;}
274   /// Returns the FGAerodynamics pointer
275   inline FGAerodynamics* GetAerodynamics(void){return Aerodynamics;}
276   /// Returns the FGInertial pointer.
277   inline FGInertial* GetInertial(void)        {return Inertial;}
278   /// Returns the FGGroundReactions pointer.
279   inline FGGroundReactions* GetGroundReactions(void) {return GroundReactions;}
280   /// Returns the FGExternalReactions pointer.
281   inline FGExternalReactions* GetExternalReactions(void) {return ExternalReactions;}
282   /// Returns the FGBuoyantForces pointer.
283   inline FGBuoyantForces* GetBuoyantForces(void) {return BuoyantForces;}
284   /// Returns the FGAircraft pointer.
285   inline FGAircraft* GetAircraft(void)        {return Aircraft;}
286   /// Returns the FGPropagate pointer.
287   inline FGPropagate* GetPropagate(void)      {return Propagate;}
288   /// Returns the FGAuxiliary pointer.
289   inline FGAuxiliary* GetAuxiliary(void)      {return Auxiliary;}
290   /// Returns the FGInput pointer.
291   inline FGInput* GetInput(void)              {return Input;}
292   /// Returns the FGGroundCallback pointer.
293   inline FGGroundCallback* GetGroundCallback(void) {return GroundCallback;}
294   /// Returns the FGState pointer.
295   inline FGState* GetState(void)              {return State;}
296   /// Retrieves the script object
297   inline FGScript* GetScript(void) {return Script;}
298   // Returns a pointer to the FGInitialCondition object
299   inline FGInitialCondition* GetIC(void)      {return IC;}
300   // Returns a pointer to the FGTrim object
301   FGTrim* GetTrim(void);
302   //@}
303
304   /// Retrieves the engine path.
305   inline string GetEnginePath(void)          {return EnginePath;}
306   /// Retrieves the aircraft path.
307   inline string GetAircraftPath(void)        {return AircraftPath;}
308   /// Retrieves the systems path.
309   inline string GetSystemsPath(void)         {return SystemsPath;}
310   /// Retrieves the full aircraft path name.
311   inline string GetFullAircraftPath(void)    {return FullAircraftPath;}
312
313   /** Retrieves the value of a property.
314       @param property the name of the property
315       @result the value of the specified property */
316   inline double GetPropertyValue(string property) {return instance->GetDouble(property);}
317
318   /** Sets a property value.
319       @param property the property to be set
320       @param value the value to set the property to */
321   inline void SetPropertyValue(string property, double value) {
322     instance->SetDouble(property, value);
323   }
324
325   /// Returns the model name.
326   string GetModelName(void) { return modelName; }
327
328   /// Returns the current time.
329   double GetSimTime(void);
330
331   /// Returns the current frame time (delta T).
332   double GetDeltaT(void);
333   
334   /// Returns a pointer to the property manager object.
335   FGPropertyManager* GetPropertyManager(void);
336   /// Returns a vector of strings representing the names of all loaded models (future)
337   vector <string> EnumerateFDMs(void);
338   /// Marks this instance of the Exec object as a "slave" object.
339   void SetSlave(bool s) {IsSlave = s;}
340
341   /** Sets the output (logging) mechanism for this run.
342       Calling this function passes the name of an output directives file to
343       the FGOutput object associated with this run. The call to this function
344       should be made prior to loading an aircraft model. This call results in an
345       FGOutput object being built as the first Output object in the FDMExec-managed
346       list of Output objects that may be created for an aircraft model. If this call
347       is made after an aircraft model is loaded, there is no effect. Any Output
348       objects added by the aircraft model itself (in an &lt;output> element) will be
349       added after this one. Care should be taken not to refer to the same file
350       name.
351       An output directives file contains an &lt;output> &lt;/output> element, within
352       which should be specified the parameters or parameter groups that should
353       be logged.
354       @param fname the filename of an output directives file.
355     */
356   bool SetOutputDirectives(string fname);
357
358   /** Sets (or overrides) the output filename
359       @param fname the name of the file to output data to
360       @return true if successful, false if there is no output specified for the flight model */
361   bool SetOutputFileName(string fname) {
362     if (Outputs.size() > 0) Outputs[0]->SetOutputFileName(fname);
363     else return false;
364     return true;
365   }
366
367   /** Retrieves the current output filename.
368       @return the name of the output file for the first output specified by the flight model.
369               If none is specified, the empty string is returned. */
370   string GetOutputFileName(void) {
371     if (Outputs.size() > 0) return Outputs[0]->GetOutputFileName();
372     else return string("");
373   }
374
375   /** Executes trimming in the selected mode.
376   *   @param mode Specifies how to trim:
377   * - tLongitudinal=0
378   * - tFull
379   * - tGround
380   * - tPullup
381   * - tCustom
382   * - tTurn
383   * - tNone  */
384   void DoTrim(int mode);
385 //  void DoTrimAnalysis(int mode);
386
387   /// Disables data logging to all outputs.
388   void DisableOutput(void);
389   /// Enables data logging to all outputs.
390   void EnableOutput(void);
391   /// Pauses execution by preventing time from incrementing.
392   void Hold(void) {holding = true;}
393   /// Resumes execution from a "Hold".
394   void Resume(void) {holding = false;}
395   /// Returns true if the simulation is Holding (i.e. simulation time is not moving).
396   bool Holding(void) {return holding;}
397   /// Resets the initial conditions object and prepares the simulation to run again.
398   void ResetToInitialConditions(void);
399   /// Sets the debug level.
400   void SetDebugLevel(int level) {debug_lvl = level;}
401
402   struct PropertyCatalogStructure {
403     /// Name of the property.
404     string base_string;
405     /// The node for the property.
406     FGPropertyManager *node;
407   };
408
409   /** Builds a catalog of properties.
410   *   This function descends the property tree and creates a list (an STL vector)
411   *   containing the name and node for all properties.
412   *   @param pcs The "root" property catalog structure pointer.  */
413   void BuildPropertyCatalog(struct PropertyCatalogStructure* pcs);
414
415   /** Retrieves property or properties matching the supplied string.
416   *   A string is returned that contains a carriage return delimited list of all
417   *   strings in the property catalog that matches the supplied check string.
418   *   @param check The string to search for in the property catalog.
419   *   @return the carriage-return-delimited string containing all matching strings
420   *               in the catalog.  */
421   string QueryPropertyCatalog(string check);
422
423   // Print the contents of the property catalog for the loaded aircraft.
424   void PrintPropertyCatalog(void);
425
426   /// Use the MSIS atmosphere model.
427   void UseAtmosphereMSIS(void);
428
429   /// Use the Mars atmosphere model. (Not operative yet.)
430   void UseAtmosphereMars(void);
431
432   void SetTrimStatus(bool status){ trim_status = status; }
433   bool GetTrimStatus(void) const { return trim_status; }
434   void SetTrimMode(int mode){ ta_mode = mode; }
435   int GetTrimMode(void) const { return ta_mode; }
436
437 private:
438   static unsigned int FDMctr;
439   int Error;
440   unsigned int Frame;
441   unsigned int IdFDM;
442   unsigned short Terminate;
443   bool holding;
444   bool Constructing;
445   bool modelLoaded;
446   bool IsSlave;
447   string modelName;
448   string AircraftPath;
449   string FullAircraftPath;
450   string EnginePath;
451   string SystemsPath;
452   string CFGVersion;
453   string Release;
454
455   bool trim_status;
456   int ta_mode;
457
458
459   struct slaveData {
460     FGFDMExec* exec;
461     string info;
462     double x, y, z;
463     double roll, pitch, yaw;
464     bool mated;
465
466     slaveData(void) {
467       info = "";
468       x = y = z = 0.0;
469       roll = pitch = yaw = 0.0;
470       mated = true;
471     }
472
473     ~slaveData(void) {
474       delete exec;
475     }
476   };
477
478   static FGPropertyManager *master;
479
480   FGModel*            FirstModel;
481   FGGroundCallback*   GroundCallback;
482   FGState*            State;
483   FGAtmosphere*       Atmosphere;
484   FGFCS*              FCS;
485   FGPropulsion*       Propulsion;
486   FGMassBalance*      MassBalance;
487   FGAerodynamics*     Aerodynamics;
488   FGInertial*         Inertial;
489   FGGroundReactions*  GroundReactions;
490   FGExternalReactions* ExternalReactions;
491   FGBuoyantForces*    BuoyantForces;
492   FGAircraft*         Aircraft;
493   FGPropagate*        Propagate;
494   FGAuxiliary*        Auxiliary;
495   FGInput*            Input;
496   FGScript*           Script;
497   FGInitialCondition* IC;
498   FGTrim*             Trim;
499
500   FGPropertyManager* Root;
501   FGPropertyManager* instance;
502
503   vector <string> PropertyCatalog;
504   vector <FGOutput*> Outputs;
505   vector <slaveData*> SlaveFDMList;
506
507   bool ReadFileHeader(Element*);
508   bool ReadSlave(Element*);
509   bool ReadPrologue(Element*);
510   void ResetToInitialConditions(int mode);
511   bool Allocate(void);
512   bool DeAllocate(void);
513
514   void Debug(int from);
515 };
516 }
517 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
518 #endif