1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5 file The header file for the JSBSim executive.
7 ------------- Copyright (C) 1999 Jon S. Berndt (jon@jsbsim.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: FGFDMExec.h,v 1.52 2010/07/04 13:50:21 jberndt Exp $"
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
172 @version $Revision: 1.52 $
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 void 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, double deltaT);
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 = RootDir + 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 = RootDir + 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 = RootDir + 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 /// Retrieves the script object
322 inline FGScript* GetScript(void) {return Script;}
323 // Returns a pointer to the FGInitialCondition object
324 inline FGInitialCondition* GetIC(void) {return IC;}
325 // Returns a pointer to the FGTrim object
326 FGTrim* GetTrim(void);
329 /// Retrieves the engine path.
330 inline string GetEnginePath(void) {return EnginePath;}
331 /// Retrieves the aircraft path.
332 inline string GetAircraftPath(void) {return AircraftPath;}
333 /// Retrieves the systems path.
334 inline string GetSystemsPath(void) {return SystemsPath;}
335 /// Retrieves the full aircraft path name.
336 inline string GetFullAircraftPath(void) {return FullAircraftPath;}
338 /** Retrieves the value of a property.
339 @param property the name of the property
340 @result the value of the specified property */
341 inline double GetPropertyValue(string property) {return instance->GetDouble(property);}
343 /** Sets a property value.
344 @param property the property to be set
345 @param value the value to set the property to */
346 inline void SetPropertyValue(string property, double value) {
347 instance->SetDouble(property, value);
350 /// Returns the model name.
351 string GetModelName(void) { return modelName; }
353 /// Returns the current time.
354 double GetSimTime(void);
356 /// Returns the current frame time (delta T).
357 double GetDeltaT(void);
359 /// Returns a pointer to the property manager object.
360 FGPropertyManager* GetPropertyManager(void);
361 /// Returns a vector of strings representing the names of all loaded models (future)
362 vector <string> EnumerateFDMs(void);
363 /// Gets the number of child FDMs.
364 int GetFDMCount(void) {return (int)ChildFDMList.size();}
365 /// Gets a particular child FDM.
366 childData* GetChildFDM(int i) {return ChildFDMList[i];}
367 /// Marks this instance of the Exec object as a "child" object.
368 void SetChild(bool ch) {IsChild = ch;}
370 /** Sets the output (logging) mechanism for this run.
371 Calling this function passes the name of an output directives file to
372 the FGOutput object associated with this run. The call to this function
373 should be made prior to loading an aircraft model. This call results in an
374 FGOutput object being built as the first Output object in the FDMExec-managed
375 list of Output objects that may be created for an aircraft model. If this call
376 is made after an aircraft model is loaded, there is no effect. Any Output
377 objects added by the aircraft model itself (in an <output> element) will be
378 added after this one. Care should be taken not to refer to the same file
380 An output directives file contains an <output> </output> element, within
381 which should be specified the parameters or parameter groups that should
383 @param fname the filename of an output directives file.
385 bool SetOutputDirectives(string fname);
387 /** Sets (or overrides) the output filename
388 @param fname the name of the file to output data to
389 @return true if successful, false if there is no output specified for the flight model */
390 bool SetOutputFileName(string fname) {
391 if (Outputs.size() > 0) Outputs[0]->SetOutputFileName(fname);
396 /** Retrieves the current output filename.
397 @return the name of the output file for the first output specified by the flight model.
398 If none is specified, the empty string is returned. */
399 string GetOutputFileName(void) {
400 if (Outputs.size() > 0) return Outputs[0]->GetOutputFileName();
401 else return string("");
404 /** Executes trimming in the selected mode.
405 * @param mode Specifies how to trim:
413 void DoTrim(int mode);
414 // void DoTrimAnalysis(int mode);
416 /// Disables data logging to all outputs.
417 void DisableOutput(void);
418 /// Enables data logging to all outputs.
419 void EnableOutput(void);
420 /// Pauses execution by preventing time from incrementing.
421 void Hold(void) {holding = true;}
422 /// Resumes execution from a "Hold".
423 void Resume(void) {holding = false;}
424 /// Returns true if the simulation is Holding (i.e. simulation time is not moving).
425 bool Holding(void) {return holding;}
426 /// Resets the initial conditions object and prepares the simulation to run again.
427 void ResetToInitialConditions(void);
428 /// Sets the debug level.
429 void SetDebugLevel(int level) {debug_lvl = level;}
431 struct PropertyCatalogStructure {
432 /// Name of the property.
434 /// The node for the property.
435 FGPropertyManager *node;
438 /** Builds a catalog of properties.
439 * This function descends the property tree and creates a list (an STL vector)
440 * containing the name and node for all properties.
441 * @param pcs The "root" property catalog structure pointer. */
442 void BuildPropertyCatalog(struct PropertyCatalogStructure* pcs);
444 /** Retrieves property or properties matching the supplied string.
445 * A string is returned that contains a carriage return delimited list of all
446 * strings in the property catalog that matches the supplied check string.
447 * @param check The string to search for in the property catalog.
448 * @return the carriage-return-delimited string containing all matching strings
450 string QueryPropertyCatalog(string check);
452 // Print the contents of the property catalog for the loaded aircraft.
453 void PrintPropertyCatalog(void);
455 vector<string>& GetPropertyCatalog(void) {return PropertyCatalog;}
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; }
468 /// Returns the cumulative simulation time in seconds.
469 double GetSimTime(void) const { return sim_time; }
471 /// Returns the simulation delta T.
472 double GetDeltaT(void) {return dT;}
474 /// Suspends the simulation and sets the delta T to zero.
475 void SuspendIntegration(void) {saved_dT = dT; dT = 0.0;}
477 /// Resumes the simulation by resetting delta T to the correct value.
478 void ResumeIntegration(void) {dT = saved_dT;}
480 /** Returns the simulation suspension state.
481 @return true if suspended, false if executing */
482 bool IntegrationSuspended(void) {return dT == 0.0;}
484 /** Sets the current sim time.
485 @param cur_time the current time
486 @return the current simulation time. */
487 double Setsim_time(double cur_time) {
492 /** Sets the integration time step for the simulation executive.
493 @param delta_t the time step in seconds. */
494 void Setdt(double delta_t) { dT = delta_t; }
496 /** Sets the root directory where JSBSim starts looking for its system directories.
497 @param rootDir the string containing the root directory. */
498 void SetRootDir(string rootDir) {RootDir = rootDir;}
500 /** Retrieves teh Root Directory.
501 @return the string representing the root (base) JSBSim directory. */
502 string GetRootDir(void) const {return RootDir;}
504 /** Increments the simulation time.
505 @return the new simulation time. */
506 double IncrTime(void) {
511 /** Retrieves the current debug level setting. */
512 int GetDebugLevel(void) const {return debug_lvl;};
515 static unsigned int FDMctr;
519 unsigned short Terminate;
529 string FullAircraftPath;
539 static FGPropertyManager *master;
541 FGGroundCallback* GroundCallback;
542 FGAtmosphere* Atmosphere;
544 FGPropulsion* Propulsion;
545 FGMassBalance* MassBalance;
546 FGAerodynamics* Aerodynamics;
547 FGInertial* Inertial;
548 FGGroundReactions* GroundReactions;
549 FGExternalReactions* ExternalReactions;
550 FGBuoyantForces* BuoyantForces;
551 FGAircraft* Aircraft;
552 FGPropagate* Propagate;
553 FGAuxiliary* Auxiliary;
556 FGInitialCondition* IC;
559 FGPropertyManager* Root;
560 FGPropertyManager* instance;
562 vector <string> PropertyCatalog;
563 vector <FGOutput*> Outputs;
564 vector <childData*> ChildFDMList;
565 vector <FGModel*> Models;
567 bool ReadFileHeader(Element*);
568 bool ReadChild(Element*);
569 bool ReadPrologue(Element*);
570 void ResetToInitialConditions(int mode);
572 bool DeAllocate(void);
573 void Initialize(FGInitialCondition *FGIC);
575 void Debug(int from);
578 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%