1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5 file The header file for the JSBSim executive.
7 ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
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
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
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.
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.
27 --------------------------------------------------------------------------------
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
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
37 #ifndef FGFDMEXEC_HEADER_H
38 #define FGFDMEXEC_HEADER_H
40 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
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 #include <math/FGColumnVector3.h>
59 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
61 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
63 #define ID_FDMEXEC "$Id$"
65 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
67 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
74 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
78 /** Encapsulates the JSBSim simulation executive.
79 This class is the executive class through which all other simulation classes
80 are instantiated, initialized, and run. When integrated with FlightGear (or
81 other flight simulator) this class is typically instantiated by an interface
82 class on the simulator side.
84 At the time of simulation initialization, the interface
85 class creates an instance of this executive class. The
86 executive is subsequently directed to load the chosen aircraft specification
90 fdmex = new FGFDMExec(
\85 );
91 result = fdmex->LoadModel(
\85 );
94 When an aircraft model is loaded, the config file is parsed and for each of the
95 sections of the config file (propulsion, flight control, etc.) the
96 corresponding Load() method is called (e.g. FGFCS::Load()).
98 Subsequent to the creation of the executive and loading of the model,
99 initialization is performed. Initialization involves copying control inputs
100 into the appropriate JSBSim data storage locations, configuring it for the set
101 of user supplied initial conditions, and then copying state variables from
102 JSBSim. The state variables are used to drive the instrument displays and to
103 place the vehicle model in world space for visual rendering:
106 copy_to_JSBsim(); // copy control inputs to JSBSim
107 fdmex->RunIC(); // loop JSBSim once w/o integrating
108 copy_from_JSBsim(); // update the bus
111 Once initialization is complete, cyclic execution proceeds:
114 copy_to_JSBsim(); // copy control inputs to JSBSim
115 fdmex->Run(); // execute JSBSim
116 copy_from_JSBsim(); // update the bus
119 JSBSim can be used in a standalone mode by creating a compact stub program
120 that effectively performs the same progression of steps as outlined above for
121 the integrated version, but with two exceptions. First, the copy_to_JSBSim()
122 and copy_from_JSBSim() functions are not used because the control inputs are
123 handled directly by the scripting facilities and outputs are handled by the
124 output (data logging) class. Second, the name of a script file can be supplied
125 to the stub program. Scripting (see FGScript) provides a way to supply command
126 inputs to the simulation:
129 FDMExec = new JSBSim::FGFDMExec();
130 FDMExec->LoadScript( ScriptName ); // the script loads the aircraft and ICs
131 result = FDMExec->Run();
132 while (result) { // cyclic execution
133 result = FDMExec->Run(); // execute JSBSim
137 The standalone mode has been useful for verifying changes before committing
138 updates to the source code repository. It is also useful for running sets of
139 tests that reveal some aspects of simulated aircraft performance, such as
140 range, time-to-climb, takeoff distance, etc.
142 <h3>JSBSim Debugging Directives</h3>
144 This describes to any interested entity the debug level
145 requested by setting the JSBSIM_DEBUG environment variable.
146 The bitmasked value choices are as follows:
147 - <b>unset</b>: In this case (the default) JSBSim would only print
148 out the normally expected messages, essentially echoing
149 the config files as they are read. If the environment
150 variable is not set, debug_lvl is set to 1 internally
151 - <b>0</b>: This requests JSBSim not to output any messages
153 - <b>1</b>: This value explicity requests the normal JSBSim
155 - <b>2</b>: This value asks for a message to be printed out when
156 a class is instantiated
157 - <b>4</b>: When this value is set, a message is displayed when a
158 FGModel object executes its Run() method
159 - <b>8</b>: When this value is set, various runtime state variables
160 are printed out periodically
161 - <b>16</b>: When set various parameters are sanity checked and
162 a message is printed out when they go out of bounds
165 @property simulator/do_trim (write only) Can be set to the integer equivalent to one of
166 tLongitudinal (0), tFull (1), tGround (2), tPullup (3),
167 tCustom (4), tTurn (5). Setting this to a legal value
168 (such as by a script) causes a trim to be performed. This
169 property actually maps toa function call of DoTrim().
171 @author Jon S. Berndt
175 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
179 class FGFDMExec : public FGJSBBase, public FGXMLFileRead
185 FGColumnVector3 Orient;
191 Loc = FGColumnVector3(0,0,0);
192 Orient = FGColumnVector3(0,0,0);
197 void Run(void) {exec->Run();}
198 void AssignState(FGPropagate* source_prop) {
199 exec->GetPropagate()->SetVState(source_prop->GetVState());
209 /// Default constructor
210 FGFDMExec(FGPropertyManager* root = 0);
212 /// Default destructor
215 /** This routine places a model into the runlist at the specified rate. The
216 "rate" is not really a clock rate. It represents how many calls to the
217 FGFDMExec::Run() method must be made before the model is executed. A
218 value of 1 means that the model will be executed for each call to the
219 exec's Run() method. A value of 5 means that the model will only be
220 executed every 5th call to the exec's Run() method. Use of a rate other than
221 one is at this time not recommended.
222 @param model A pointer to the model being scheduled.
223 @param rate The rate at which to execute the model as described above.
224 @return Currently returns 0 always. */
225 int Schedule(FGModel* model, int rate);
227 /** This function executes each scheduled model in succession.
228 @return true if successful, false if sim should be ended */
231 /** Initializes the sim from the initial condition object and executes
232 each scheduled model without integrating i.e. dt=0.
233 @return true if successful */
236 /** Sets the ground callback pointer.
237 @param gc A pointer to a ground callback object. */
238 void SetGroundCallback(FGGroundCallback* gc);
240 /** Loads an aircraft model.
241 @param AircraftPath path to the aircraft/ directory. For instance:
242 "aircraft". Under aircraft, then, would be directories for various
243 modeled aircraft such as C172/, x15/, etc.
244 @param EnginePath path to the directory under which engine config
245 files are kept, for instance "engine"
246 @param SystemsPath path to the directory under which systems config
247 files are kept, for instance "systems"
248 @param model the name of the aircraft model itself. This file will
249 be looked for in the directory specified in the AircraftPath variable,
250 and in turn under the directory with the same name as the model. For
251 instance: "aircraft/x15/x15.xml"
252 @param addModelToPath set to true to add the model name to the
253 AircraftPath, defaults to true
254 @return true if successful */
255 bool LoadModel(string AircraftPath, string EnginePath, string SystemsPath,
256 string model, bool addModelToPath = true);
258 /** Loads an aircraft model. The paths to the aircraft and engine
259 config file directories must be set prior to calling this. See
261 @param model the name of the aircraft model itself. This file will
262 be looked for in the directory specified in the AircraftPath variable,
263 and in turn under the directory with the same name as the model. For
264 instance: "aircraft/x15/x15.xml"
265 @param addModelToPath set to true to add the model name to the
266 AircraftPath, defaults to true
267 @return true if successful*/
268 bool LoadModel(string model, bool addModelToPath = true);
271 @param Script the full path name and file name for the script to be loaded.
272 @return true if successfully loadsd; false otherwise. */
273 bool LoadScript(string Script);
275 /** Sets the path to the engine config file directories.
276 @param path path to the directory under which engine config
277 files are kept, for instance "engine" */
278 bool SetEnginePath(string path) { EnginePath = path; return true; }
280 /** Sets the path to the aircraft config file directories.
281 @param path path to the aircraft directory. For instance:
282 "aircraft". Under aircraft, then, would be directories for various
283 modeled aircraft such as C172/, x15/, etc. */
284 bool SetAircraftPath(string path) { AircraftPath = path; return true; }
286 /** Sets the path to the systems config file directories.
287 @param path path to the directory under which systems config
288 files are kept, for instance "systems" */
289 bool SetSystemsPath(string path) { SystemsPath = path; return true; }
291 /// @name Top-level executive State and Model retrieval mechanism
293 /// Returns the FGAtmosphere pointer.
294 inline FGAtmosphere* GetAtmosphere(void) {return Atmosphere;}
295 /// Returns the FGFCS pointer.
296 inline FGFCS* GetFCS(void) {return FCS;}
297 /// Returns the FGPropulsion pointer.
298 inline FGPropulsion* GetPropulsion(void) {return Propulsion;}
299 /// Returns the FGAircraft pointer.
300 inline FGMassBalance* GetMassBalance(void) {return MassBalance;}
301 /// Returns the FGAerodynamics pointer
302 inline FGAerodynamics* GetAerodynamics(void){return Aerodynamics;}
303 /// Returns the FGInertial pointer.
304 inline FGInertial* GetInertial(void) {return Inertial;}
305 /// Returns the FGGroundReactions pointer.
306 inline FGGroundReactions* GetGroundReactions(void) {return GroundReactions;}
307 /// Returns the FGExternalReactions pointer.
308 inline FGExternalReactions* GetExternalReactions(void) {return ExternalReactions;}
309 /// Returns the FGBuoyantForces pointer.
310 inline FGBuoyantForces* GetBuoyantForces(void) {return BuoyantForces;}
311 /// Returns the FGAircraft pointer.
312 inline FGAircraft* GetAircraft(void) {return Aircraft;}
313 /// Returns the FGPropagate pointer.
314 inline FGPropagate* GetPropagate(void) {return Propagate;}
315 /// Returns the FGAuxiliary pointer.
316 inline FGAuxiliary* GetAuxiliary(void) {return Auxiliary;}
317 /// Returns the FGInput pointer.
318 inline FGInput* GetInput(void) {return Input;}
319 /// Returns the FGGroundCallback pointer.
320 inline FGGroundCallback* GetGroundCallback(void) {return GroundCallback;}
321 /// Returns the FGState pointer.
322 inline FGState* GetState(void) {return State;}
323 /// Retrieves the script object
324 inline FGScript* GetScript(void) {return Script;}
325 // Returns a pointer to the FGInitialCondition object
326 inline FGInitialCondition* GetIC(void) {return IC;}
327 // Returns a pointer to the FGTrim object
328 FGTrim* GetTrim(void);
331 /// Retrieves the engine path.
332 inline string GetEnginePath(void) {return EnginePath;}
333 /// Retrieves the aircraft path.
334 inline string GetAircraftPath(void) {return AircraftPath;}
335 /// Retrieves the systems path.
336 inline string GetSystemsPath(void) {return SystemsPath;}
337 /// Retrieves the full aircraft path name.
338 inline string GetFullAircraftPath(void) {return FullAircraftPath;}
340 /** Retrieves the value of a property.
341 @param property the name of the property
342 @result the value of the specified property */
343 inline double GetPropertyValue(string property) {return instance->GetDouble(property);}
345 /** Sets a property value.
346 @param property the property to be set
347 @param value the value to set the property to */
348 inline void SetPropertyValue(string property, double value) {
349 instance->SetDouble(property, value);
352 /// Returns the model name.
353 string GetModelName(void) { return modelName; }
355 /// Returns the current time.
356 double GetSimTime(void);
358 /// Returns the current frame time (delta T).
359 double GetDeltaT(void);
361 /// Returns a pointer to the property manager object.
362 FGPropertyManager* GetPropertyManager(void);
363 /// Returns a vector of strings representing the names of all loaded models (future)
364 vector <string> EnumerateFDMs(void);
365 /// Gets the number of child FDMs.
366 int GetFDMCount(void) {return ChildFDMList.size();}
367 /// Gets a particular child FDM.
368 childData* GetChildFDM(int i) {return ChildFDMList[i];}
369 /// Marks this instance of the Exec object as a "child" object.
370 void SetChild(bool ch) {IsChild = ch;}
372 /** Sets the output (logging) mechanism for this run.
373 Calling this function passes the name of an output directives file to
374 the FGOutput object associated with this run. The call to this function
375 should be made prior to loading an aircraft model. This call results in an
376 FGOutput object being built as the first Output object in the FDMExec-managed
377 list of Output objects that may be created for an aircraft model. If this call
378 is made after an aircraft model is loaded, there is no effect. Any Output
379 objects added by the aircraft model itself (in an <output> element) will be
380 added after this one. Care should be taken not to refer to the same file
382 An output directives file contains an <output> </output> element, within
383 which should be specified the parameters or parameter groups that should
385 @param fname the filename of an output directives file.
387 bool SetOutputDirectives(string fname);
389 /** Sets (or overrides) the output filename
390 @param fname the name of the file to output data to
391 @return true if successful, false if there is no output specified for the flight model */
392 bool SetOutputFileName(string fname) {
393 if (Outputs.size() > 0) Outputs[0]->SetOutputFileName(fname);
398 /** Retrieves the current output filename.
399 @return the name of the output file for the first output specified by the flight model.
400 If none is specified, the empty string is returned. */
401 string GetOutputFileName(void) {
402 if (Outputs.size() > 0) return Outputs[0]->GetOutputFileName();
403 else return string("");
406 /** Executes trimming in the selected mode.
407 * @param mode Specifies how to trim:
415 void DoTrim(int mode);
416 // void DoTrimAnalysis(int mode);
418 /// Disables data logging to all outputs.
419 void DisableOutput(void);
420 /// Enables data logging to all outputs.
421 void EnableOutput(void);
422 /// Pauses execution by preventing time from incrementing.
423 void Hold(void) {holding = true;}
424 /// Resumes execution from a "Hold".
425 void Resume(void) {holding = false;}
426 /// Returns true if the simulation is Holding (i.e. simulation time is not moving).
427 bool Holding(void) {return holding;}
428 /// Resets the initial conditions object and prepares the simulation to run again.
429 void ResetToInitialConditions(void);
430 /// Sets the debug level.
431 void SetDebugLevel(int level) {debug_lvl = level;}
433 struct PropertyCatalogStructure {
434 /// Name of the property.
436 /// The node for the property.
437 FGPropertyManager *node;
440 /** Builds a catalog of properties.
441 * This function descends the property tree and creates a list (an STL vector)
442 * containing the name and node for all properties.
443 * @param pcs The "root" property catalog structure pointer. */
444 void BuildPropertyCatalog(struct PropertyCatalogStructure* pcs);
446 /** Retrieves property or properties matching the supplied string.
447 * A string is returned that contains a carriage return delimited list of all
448 * strings in the property catalog that matches the supplied check string.
449 * @param check The string to search for in the property catalog.
450 * @return the carriage-return-delimited string containing all matching strings
452 string QueryPropertyCatalog(string check);
454 // Print the contents of the property catalog for the loaded aircraft.
455 void PrintPropertyCatalog(void);
457 /// Use the MSIS atmosphere model.
458 void UseAtmosphereMSIS(void);
460 /// Use the Mars atmosphere model. (Not operative yet.)
461 void UseAtmosphereMars(void);
463 void SetTrimStatus(bool status){ trim_status = status; }
464 bool GetTrimStatus(void) const { return trim_status; }
465 void SetTrimMode(int mode){ ta_mode = mode; }
466 int GetTrimMode(void) const { return ta_mode; }
469 static unsigned int FDMctr;
473 unsigned short Terminate;
480 string FullAircraftPath;
489 static FGPropertyManager *master;
492 FGGroundCallback* GroundCallback;
494 FGAtmosphere* Atmosphere;
496 FGPropulsion* Propulsion;
497 FGMassBalance* MassBalance;
498 FGAerodynamics* Aerodynamics;
499 FGInertial* Inertial;
500 FGGroundReactions* GroundReactions;
501 FGExternalReactions* ExternalReactions;
502 FGBuoyantForces* BuoyantForces;
503 FGAircraft* Aircraft;
504 FGPropagate* Propagate;
505 FGAuxiliary* Auxiliary;
508 FGInitialCondition* IC;
511 FGPropertyManager* Root;
512 FGPropertyManager* instance;
514 vector <string> PropertyCatalog;
515 vector <FGOutput*> Outputs;
516 vector <childData*> ChildFDMList;
518 bool ReadFileHeader(Element*);
519 bool ReadChild(Element*);
520 bool ReadPrologue(Element*);
521 void ResetToInitialConditions(int mode);
523 bool DeAllocate(void);
525 void Debug(int from);
528 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%