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