JSBSim Flight Dynamics Model  1.0 (02 March 2017)
An Open Source Flight Dynamics and Control Software Library in C++
JSBSim.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 
3  Module: JSBSim.cpp
4  Author: Jon S. Berndt
5  Date started: 08/17/99
6  Purpose: Standalone version of JSBSim.
7  Called by: The USER.
8 
9  ------------- Copyright (C) 1999 Jon S. Berndt (jon@jsbsim.org) -------------
10 
11  This program is free software; you can redistribute it and/or modify it under
12  the terms of the GNU Lesser General Public License as published by the Free Software
13  Foundation; either version 2 of the License, or (at your option) any later
14  version.
15 
16  This program is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18  FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
19  details.
20 
21  You should have received a copy of the GNU Lesser General Public License along with
22  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
23  Place - Suite 330, Boston, MA 02111-1307, USA.
24 
25  Further information about the GNU Lesser General Public License can also be found on
26  the world wide web at http://www.gnu.org.
27 
28 FUNCTIONAL DESCRIPTION
29 --------------------------------------------------------------------------------
30 
31 This class implements the JSBSim standalone application. It is set up for compilation
32 under gnu C++, MSVC++, or other compiler.
33 
34 HISTORY
35 --------------------------------------------------------------------------------
36 08/17/99 JSB Created
37 
38 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39 INCLUDES
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
41 
42 #include "initialization/FGTrim.h"
43 #include "FGFDMExec.h"
44 #include "input_output/FGXMLFileRead.h"
45 
46 #if !defined(__GNUC__) && !defined(sgi) && !defined(_MSC_VER)
47 # include <time>
48 #else
49 # include <time.h>
50 #endif
51 
52 #if defined(_MSC_VER)
53 # include <float.h>
54 #elif defined(__GNUC__) && !defined(sgi)
55 # include <fenv.h>
56 #endif
57 
58 #if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
59 # define WIN32_LEAN_AND_MEAN
60 # include <windows.h>
61 # include <mmsystem.h>
62 # include <regstr.h>
63 # include <sys/types.h>
64 # include <sys/timeb.h>
65 #else
66 # include <sys/time.h>
67 #endif
68 
69 #include <iostream>
70 #include <cstdlib>
71 
72 using namespace std;
74 using JSBSim::Element;
75 
76 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
77 DEFINITIONS
78 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
79 
80 IDENT(IdSrc,"$Id: JSBSim.cpp,v 1.91 2017/02/25 15:50:02 bcoconni Exp $");
81 
82 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83 GLOBAL DATA
84 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
85 
86 SGPath RootDir;
87 SGPath ScriptName;
88 string AircraftName;
89 SGPath ResetName;
90 vector <string> LogOutputName;
91 vector <SGPath> LogDirectiveName;
92 vector <string> CommandLineProperties;
93 vector <double> CommandLinePropertyValues;
94 JSBSim::FGFDMExec* FDMExec;
95 JSBSim::FGTrim* trimmer;
96 
97 bool realtime;
98 bool play_nice;
99 bool suspend;
100 bool catalog;
101 bool nohighlight;
102 
103 double end_time = 1e99;
104 double simulation_rate = 1./120.;
105 bool override_sim_rate = false;
106 double sleep_period=0.01;
107 
108 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
109 FORWARD DECLARATIONS
110 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
111 
112 bool options(int, char**);
113 int real_main(int argc, char* argv[]);
114 void PrintHelp(void);
115 
116 #if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
117  double getcurrentseconds(void)
118  {
119  struct timeb tm_ptr;
120  ftime(&tm_ptr);
121  return tm_ptr.time + tm_ptr.millitm*0.001;
122  }
123 #else
124  double getcurrentseconds(void)
125  {
126  struct timeval tval;
127  struct timezone tz;
128 
129  gettimeofday(&tval, &tz);
130  return (tval.tv_sec + tval.tv_usec*1e-6);
131  }
132 #endif
133 
134 #if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__)
135  void sim_nsleep(long nanosec)
136  {
137  Sleep((DWORD)(nanosec*1e-6)); // convert nanoseconds (passed in) to milliseconds for Win32.
138  }
139 #else
140  void sim_nsleep(long nanosec)
141  {
142  struct timespec ts, ts1;
143 
144  ts.tv_sec = 0;
145  ts.tv_nsec = nanosec;
146  nanosleep(&ts, &ts1);
147  }
148 #endif
149 
152 class XMLFile : public FGXMLFileRead {
153 public:
154  bool IsScriptFile(const SGPath& filename) {
155  bool result=false;
156  Element *document = LoadXMLDocument(filename, false);
157  if (document && document->GetName() == "runscript") result = true;
158  ResetParser();
159  return result;
160  }
161  bool IsLogDirectiveFile(const SGPath& filename) {
162  bool result=false;
163  Element *document = LoadXMLDocument(filename, false);
164  if (document && document->GetName() == "output") result = true;
165  ResetParser();
166  return result;
167  }
168  bool IsAircraftFile(const SGPath& filename) {
169  bool result=false;
170  Element* document = LoadXMLDocument(filename, false);
171  if (document && document->GetName() == "fdm_config") result = true;
172  ResetParser();
173  return result;
174  }
175  bool IsInitFile(const SGPath& filename) {
176  bool result=false;
177  Element *document = LoadXMLDocument(filename, false);
178  if (document && document->GetName() == "initialize") result = true;
179  ResetParser();
180  return result;
181  }
182 };
183 
184 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
185 CLASS DOCUMENTATION
186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
187 
280 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
281 IMPLEMENTATION
282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
283 
284 int main(int argc, char* argv[])
285 {
286 #if defined(_MSC_VER)
287  _clearfp();
288  _controlfp(_controlfp(0, 0) & ~(_EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW),
289  _MCW_EM);
290 #elif defined(__GNUC__) && !defined(sgi) && !defined(__APPLE__)
291  feenableexcept(FE_DIVBYZERO | FE_INVALID);
292 #endif
293 
294  try {
295  real_main(argc, argv);
296  } catch (string& msg) {
297  std::cerr << "FATAL ERROR: JSBSim terminated with an exception."
298  << std::endl << "The message was: " << msg << std::endl;
299  return 1;
300  } catch (...) {
301  std::cerr << "FATAL ERROR: JSBSim terminated with an unknown exception."
302  << std::endl;
303  return 1;
304  }
305  return 0;
306 }
307 
308 int real_main(int argc, char* argv[])
309 {
310  // *** INITIALIZATIONS *** //
311 
312  ScriptName = "";
313  AircraftName = "";
314  ResetName = "";
315  LogOutputName.clear();
316  LogDirectiveName.clear();
317  bool result = false, success;
318  bool was_paused = false;
319 
320  double frame_duration;
321 
322  double new_five_second_value = 0.0;
323  double actual_elapsed_time = 0;
324  double initial_seconds = 0;
325  double current_seconds = 0.0;
326  double paused_seconds = 0.0;
327  double sim_lag_time = 0;
328  double cycle_duration = 0.0;
329  double override_sim_rate_value = 0.0;
330  long sleep_nseconds = 0;
331 
332  realtime = false;
333  play_nice = false;
334  suspend = false;
335  catalog = false;
336  nohighlight = false;
337 
338  // *** PARSE OPTIONS PASSED INTO THIS SPECIFIC APPLICATION: JSBSim *** //
339  success = options(argc, argv);
340  if (!success) {
341  PrintHelp();
342  exit(-1);
343  }
344 
345  // *** SET UP JSBSIM *** //
346  FDMExec = new JSBSim::FGFDMExec();
347  FDMExec->SetRootDir(RootDir);
348  FDMExec->SetAircraftPath(SGPath("aircraft"));
349  FDMExec->SetEnginePath(SGPath("engine"));
350  FDMExec->SetSystemsPath(SGPath("systems"));
351  FDMExec->GetPropertyManager()->Tie("simulation/frame_start_time", &actual_elapsed_time);
352  FDMExec->GetPropertyManager()->Tie("simulation/cycle_duration", &cycle_duration);
353 
354  if (nohighlight) FDMExec->disableHighLighting();
355 
356  if (simulation_rate < 1.0 )
357  FDMExec->Setdt(simulation_rate);
358  else
359  FDMExec->Setdt(1.0/simulation_rate);
360 
361  if (override_sim_rate) override_sim_rate_value = FDMExec->GetDeltaT();
362 
363  // SET PROPERTY VALUES THAT ARE GIVEN ON THE COMMAND LINE and which are for the simulation only.
364 
365  for (unsigned int i=0; i<CommandLineProperties.size(); i++) {
366 
367  if (CommandLineProperties[i].find("simulation") != std::string::npos) {
368  if (FDMExec->GetPropertyManager()->GetNode(CommandLineProperties[i])) {
369  FDMExec->SetPropertyValue(CommandLineProperties[i], CommandLinePropertyValues[i]);
370  }
371  }
372  }
373 
374  // *** OPTION A: LOAD A SCRIPT, WHICH LOADS EVERYTHING ELSE *** //
375  if (!ScriptName.isNull()) {
376 
377  result = FDMExec->LoadScript(ScriptName, override_sim_rate_value, ResetName);
378 
379  if (!result) {
380  cerr << "Script file " << ScriptName << " was not successfully loaded" << endl;
381  delete FDMExec;
382  exit(-1);
383  }
384 
385  // *** OPTION B: LOAD AN AIRCRAFT AND A SET OF INITIAL CONDITIONS *** //
386  } else if (!AircraftName.empty() || !ResetName.isNull()) {
387 
388  if (catalog) FDMExec->SetDebugLevel(0);
389 
390  if ( ! FDMExec->LoadModel(SGPath("aircraft"),
391  SGPath("engine"),
392  SGPath("systems"),
393  AircraftName)) {
394  cerr << " JSBSim could not be started" << endl << endl;
395  delete FDMExec;
396  exit(-1);
397  }
398 
399  if (catalog) {
400  FDMExec->PrintPropertyCatalog();
401  delete FDMExec;
402  return 0;
403  }
404 
405  JSBSim::FGInitialCondition *IC = FDMExec->GetIC();
406  if ( ! IC->Load(ResetName)) {
407  delete FDMExec;
408  cerr << "Initialization unsuccessful" << endl;
409  exit(-1);
410  }
411 
412  } else {
413  cout << " No Aircraft, Script, or Reset information given" << endl << endl;
414  delete FDMExec;
415  exit(-1);
416  }
417 
418  // Load output directives file[s], if given
419  for (unsigned int i=0; i<LogDirectiveName.size(); i++) {
420  if (!LogDirectiveName[i].isNull()) {
421  if (!FDMExec->SetOutputDirectives(LogDirectiveName[i])) {
422  cout << "Output directives not properly set in file " << LogDirectiveName[i] << endl;
423  delete FDMExec;
424  exit(-1);
425  }
426  }
427  }
428 
429  // OVERRIDE OUTPUT FILE NAME. THIS IS USEFUL FOR CASES WHERE MULTIPLE
430  // RUNS ARE BEING MADE (SUCH AS IN A MONTE CARLO STUDY) AND THE OUTPUT FILE
431  // NAME MUST BE SET EACH TIME TO AVOID THE PREVIOUS RUN DATA FROM BEING OVER-
432  // WRITTEN.
433  for (unsigned int i=0; i<LogOutputName.size(); i++) {
434  string old_filename = FDMExec->GetOutputFileName(i);
435  if (!FDMExec->SetOutputFileName(i, LogOutputName[i])) {
436  cout << "Output filename could not be set" << endl;
437  } else {
438  cout << "Output filename change from " << old_filename << " from aircraft"
439  " configuration file to " << LogOutputName[i] << " specified on"
440  " command line" << endl;
441  }
442  }
443 
444  // SET PROPERTY VALUES THAT ARE GIVEN ON THE COMMAND LINE
445 
446  for (unsigned int i=0; i<CommandLineProperties.size(); i++) {
447 
448  if (!FDMExec->GetPropertyManager()->GetNode(CommandLineProperties[i])) {
449  cerr << endl << " No property by the name " << CommandLineProperties[i] << endl;
450  goto quit;
451  } else {
452  FDMExec->SetPropertyValue(CommandLineProperties[i], CommandLinePropertyValues[i]);
453  }
454  }
455 
456  FDMExec->RunIC();
457 
458  // PRINT SIMULATION CONFIGURATION
459  FDMExec->PrintSimulationConfiguration();
460 
461  // Dump the simulation state (position, orientation, etc.)
462  FDMExec->GetPropagate()->DumpState();
463 
464  if (FDMExec->GetIC()->NeedTrim()) {
465  trimmer = new JSBSim::FGTrim( FDMExec );
466  try {
467  trimmer->DoTrim();
468  delete trimmer;
469  } catch (string& msg) {
470  cerr << endl << msg << endl << endl;
471  exit(1);
472  }
473  }
474 
476  << "---- JSBSim Execution beginning ... --------------------------------------------"
477  << JSBSim::FGFDMExec::reset << endl << endl;
478 
479  result = FDMExec->Run(); // MAKE AN INITIAL RUN
480 
481  if (suspend) FDMExec->Hold();
482 
483  // Print actual time at start
484  char s[100];
485  time_t tod;
486  time(&tod);
487  strftime(s, 99, "%A %B %d %Y %X", localtime(&tod));
488  cout << "Start: " << s << " (HH:MM:SS)" << endl;
489 
490  frame_duration = FDMExec->GetDeltaT();
491  if (realtime) sleep_nseconds = (long)(frame_duration*1e9);
492  else sleep_nseconds = (sleep_period )*1e9; // 0.01 seconds
493 
494  tzset();
495  current_seconds = initial_seconds = getcurrentseconds();
496 
497  // *** CYCLIC EXECUTION LOOP, AND MESSAGE READING *** //
498  while (result && FDMExec->GetSimTime() <= end_time) {
499 
500  FDMExec->ProcessMessage(); // Process messages, if any.
501 
502  // Check if increment then hold is on and take appropriate actions if it is
503  // Iterate is not supported in realtime - only in batch and playnice modes
504  FDMExec->CheckIncrementalHold();
505 
506  // if running realtime, throttle the execution, else just run flat-out fast
507  // unless "playing nice", in which case sleep for a while (0.01 seconds) each frame.
508  // If suspended, then don't increment cumulative realtime "stopwatch".
509 
510  if ( ! FDMExec->Holding()) {
511  if ( ! realtime ) { // ------------ RUNNING IN BATCH MODE
512 
513  result = FDMExec->Run();
514 
515  if (play_nice) sim_nsleep(sleep_nseconds);
516 
517  } else { // ------------ RUNNING IN REALTIME MODE
518 
519  // "was_paused" will be true if entering this "run" loop from a paused state.
520  if (was_paused) {
521  initial_seconds += paused_seconds;
522  was_paused = false;
523  }
524  current_seconds = getcurrentseconds(); // Seconds since 1 Jan 1970
525  actual_elapsed_time = current_seconds - initial_seconds; // Real world elapsed seconds since start
526  sim_lag_time = actual_elapsed_time - FDMExec->GetSimTime(); // How far behind sim-time is from actual
527  // elapsed time.
528  for (int i=0; i<(int)(sim_lag_time/frame_duration); i++) { // catch up sim time to actual elapsed time.
529  result = FDMExec->Run();
530  cycle_duration = getcurrentseconds() - current_seconds; // Calculate cycle duration
531  current_seconds = getcurrentseconds(); // Get new current_seconds
532  if (FDMExec->Holding()) break;
533  }
534 
535  if (play_nice) sim_nsleep(sleep_nseconds);
536 
537  if (FDMExec->GetSimTime() >= new_five_second_value) { // Print out elapsed time every five seconds.
538  cout << "Simulation elapsed time: " << FDMExec->GetSimTime() << endl;
539  new_five_second_value += 5.0;
540  }
541  }
542  } else { // Suspended
543  was_paused = true;
544  paused_seconds = getcurrentseconds() - current_seconds;
545  sim_nsleep(sleep_nseconds);
546  result = FDMExec->Run();
547  }
548 
549  }
550 
551 
552 quit:
553 
554  // PRINT ENDING CLOCK TIME
555  time(&tod);
556  strftime(s, 99, "%A %B %d %Y %X", localtime(&tod));
557  cout << "End: " << s << " (HH:MM:SS)" << endl;
558 
559  // CLEAN UP
560  delete FDMExec;
561 
562  return 0;
563 }
564 
565 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
566 
567 #define gripe cerr << "Option '" << keyword \
568  << "' requires a value, as in '" \
569  << keyword << "=something'" << endl << endl;
570 
571 bool options(int count, char **arg)
572 {
573  int i;
574  bool result = true;
575 
576  if (count == 1) {
577  PrintHelp();
578  exit(0);
579  }
580 
581  cout.setf(ios_base::fixed);
582 
583  for (i=1; i<count; i++) {
584  string argument = string(arg[i]);
585  string keyword(argument);
586  string value("");
587  string::size_type n=argument.find("=");
588 
589  if (n != string::npos && n > 0) {
590  keyword = argument.substr(0, n);
591  value = argument.substr(n+1);
592  }
593 
594  if (keyword == "--help") {
595  PrintHelp();
596  exit(0);
597  } else if (keyword == "--version") {
598  cout << endl << " JSBSim Version: " << FDMExec->GetVersion() << endl << endl;
599  exit (0);
600  } else if (keyword == "--realtime") {
601  realtime = true;
602  } else if (keyword == "--nice") {
603  play_nice = true;
604  if (n != string::npos) {
605  try {
606  sleep_period = atof( value.c_str() );
607  } catch (...) {
608  cerr << endl << " Invalid sleep period given!" << endl << endl;
609  result = false;
610  }
611  } else {
612  sleep_period = 0.01;
613  }
614  } else if (keyword == "--suspend") {
615  suspend = true;
616  } else if (keyword == "--nohighlight") {
617  nohighlight = true;
618  } else if (keyword == "--outputlogfile") {
619  if (n != string::npos) {
620  LogOutputName.push_back(value);
621  }
622  } else if (keyword == "--logdirectivefile") {
623  if (n != string::npos) {
624  LogDirectiveName.push_back(SGPath::fromLocal8Bit(value.c_str()));
625  } else {
626  gripe;
627  exit(1);
628  }
629  } else if (keyword == "--root") {
630  if (n != string::npos) {
631  RootDir = SGPath::fromLocal8Bit(value.c_str());
632  } else {
633  gripe;
634  exit(1);
635  }
636  } else if (keyword == "--aircraft") {
637  if (n != string::npos) {
638  AircraftName = value;
639  } else {
640  gripe;
641  exit(1);
642  }
643  } else if (keyword == "--script") {
644  if (n != string::npos) {
645  ScriptName = SGPath::fromLocal8Bit(value.c_str());
646  } else {
647  gripe;
648  exit(1);
649  }
650  } else if (keyword == "--initfile") {
651  if (n != string::npos) {
652  ResetName = SGPath::fromLocal8Bit(value.c_str());
653  } else {
654  gripe;
655  exit(1);
656  }
657 
658  } else if (keyword == "--property") {
659  if (n != string::npos) {
660  string propName = value.substr(0,value.find("="));
661  string propValueString = value.substr(value.find("=")+1);
662  double propValue = atof(propValueString.c_str());
663  CommandLineProperties.push_back(propName);
664  CommandLinePropertyValues.push_back(propValue);
665  } else {
666  gripe;
667  exit(1);
668  }
669 
670  } else if (keyword.substr(0,5) == "--end") {
671  if (n != string::npos) {
672  try {
673  end_time = atof( value.c_str() );
674  } catch (...) {
675  cerr << endl << " Invalid end time given!" << endl << endl;
676  result = false;
677  }
678  } else {
679  gripe;
680  exit(1);
681  }
682 
683  } else if (keyword == "--simulation-rate") {
684  if (n != string::npos) {
685  try {
686  simulation_rate = atof( value.c_str() );
687  override_sim_rate = true;
688  } catch (...) {
689  cerr << endl << " Invalid simulation rate given!" << endl << endl;
690  result = false;
691  }
692  } else {
693  gripe;
694  exit(1);
695  }
696 
697  } else if (keyword == "--catalog") {
698  catalog = true;
699  if (value.size() > 0) AircraftName=value;
700  } else if (keyword.substr(0,2) != "--" && value.empty() ) {
701  // See what kind of files we are specifying on the command line
702 
703  XMLFile xmlFile;
704  SGPath path = SGPath::fromLocal8Bit(keyword.c_str());
705 
706  if (xmlFile.IsScriptFile(path)) ScriptName = path;
707  else if (xmlFile.IsLogDirectiveFile(path)) LogDirectiveName.push_back(path);
708  else if (xmlFile.IsAircraftFile(SGPath("aircraft")/keyword/keyword)) AircraftName = keyword;
709  else if (xmlFile.IsInitFile(path)) ResetName = path;
710  else if (xmlFile.IsInitFile(SGPath("aircraft")/AircraftName/keyword)) ResetName = SGPath("aircraft")/AircraftName/keyword;
711  else {
712  cerr << "The argument \"" << keyword << "\" cannot be interpreted as a file name or option." << endl;
713  exit(1);
714  }
715 
716  }
717  else //Unknown keyword so print the help file, the bad keyword and abort
718  {
719  PrintHelp();
720  cerr << "The argument \"" << keyword << "\" cannot be interpreted as a file name or option." << endl;
721  exit(1);
722  }
723 
724  }
725 
726  // Post-processing for script options. check for incompatible options.
727 
728  if (catalog && !ScriptName.isNull()) {
729  cerr << "Cannot specify catalog with script option" << endl << endl;
730  result = false;
731  }
732  if (!AircraftName.empty() && ResetName.isNull() && !catalog) {
733  cerr << "You must specify an initialization file with the aircraft name." << endl << endl;
734  result = false;
735  }
736  if (!ScriptName.isNull() && !AircraftName.empty()) {
737  cerr << "You cannot specify an aircraft file with a script." << endl;
738  result = false;
739  }
740 
741  return result;
742 
743 }
744 
745 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
746 
747 void PrintHelp(void)
748 {
749  cout << endl << " JSBSim version " << FDMExec->GetVersion() << endl << endl;
750  cout << " Usage: jsbsim [script file name] [output file names] <options>" << endl << endl;
751  cout << " options:" << endl;
752  cout << " --help returns this message" << endl;
753  cout << " --version returns the version number" << endl;
754  cout << " --outputlogfile=<filename> sets (overrides) the name of a data output file" << endl;
755  cout << " --logdirectivefile=<filename> specifies the name of a data logging directives file" << endl;
756  cout << " (can appear multiple times)" << endl;
757  cout << " --root=<path> specifies the JSBSim root directory (where aircraft/, engine/, etc. reside)" << endl;
758  cout << " --aircraft=<filename> specifies the name of the aircraft to be modeled" << endl;
759  cout << " --script=<filename> specifies a script to run" << endl;
760  cout << " --realtime specifies to run in actual real world time" << endl;
761  cout << " --nice specifies to run at lower CPU usage" << endl;
762  cout << " --nohighlight specifies that console output should be pure text only (no color)" << endl;
763  cout << " --suspend specifies to suspend the simulation after initialization" << endl;
764  cout << " --initfile=<filename> specifies an initilization file" << endl;
765  cout << " --catalog specifies that all properties for this aircraft model should be printed" << endl;
766  cout << " (catalog=aircraftname is an optional format)" << endl;
767  cout << " --property=<name=value> e.g. --property=simulation/integrator/rate/rotational=1" << endl;
768  cout << " --simulation-rate=<rate (double)> specifies the sim dT time or frequency" << endl;
769  cout << " If rate specified is less than 1, it is interpreted as" << endl;
770  cout << " a time step size, otherwise it is assumed to be a rate in Hertz." << endl;
771  cout << " --end=<time (double)> specifies the sim end time" << endl << endl;
772 
773  cout << " NOTE: There can be no spaces around the = sign when" << endl;
774  cout << " an option is followed by a filename" << endl << endl;
775 }
776 
FGInitialCondition * GetIC(void)
Returns a pointer to the FGInitialCondition object.
Definition: FGFDMExec.h:385
bool LoadScript(const SGPath &Script, double deltaT=0.0, const SGPath &initfile=SGPath())
Loads a script.
Definition: FGFDMExec.cpp:653
bool RunIC(void)
Initializes the sim from the initial condition object and executes each scheduled model without integ...
Definition: FGFDMExec.cpp:552
static char reset[5]
resets text properties
Definition: FGJSBBase.h:131
void SetPropertyValue(const std::string &property, double value)
Sets a property value.
Definition: FGFDMExec.h:408
STL namespace.
std::string GetVersion(void)
Returns the version number of JSBSim.
Definition: FGJSBBase.h:187
void disableHighLighting(void)
Disables highlighting in the console output.
Definition: FGJSBBase.cpp:224
bool SetOutputFileName(const int n, const std::string &fname)
Sets (or overrides) the output filename.
Definition: FGFDMExec.h:454
FGPropertyManager * GetPropertyManager(void)
Returns a pointer to the property manager object.
Definition: FGFDMExec.cpp:1099
void SetRootDir(const SGPath &rootDir)
Sets the root directory where JSBSim starts looking for its system directories.
Definition: FGFDMExec.h:563
void SetDebugLevel(int level)
Sets the debug level.
Definition: FGFDMExec.h:494
void Setdt(double delta_t)
Sets the integration time step for the simulation executive.
Definition: FGFDMExec.h:559
void Tie(const std::string &name, bool *pointer, bool useDefault=true)
Tie a property to an external bool variable.
bool NeedTrim(void) const
Does initialization file call for trim ?
void ProcessMessage(void)
Reads the message on the queue and removes it from the queue.
Definition: FGJSBBase.cpp:181
void Hold(void)
Pauses execution by preventing time from incrementing.
Definition: FGFDMExec.h:478
const std::string & GetName(void) const
Retrieves the element name.
Definition: FGXMLElement.h:186
static char fggreen[6]
green text
Definition: FGJSBBase.h:143
std::string GetOutputFileName(int n) const
Retrieves the current output filename.
Definition: FGFDMExec.h:460
bool Load(const SGPath &rstname, bool useStoredPath=true)
Loads the initial conditions.
bool SetOutputDirectives(const SGPath &fname)
Sets the output (logging) mechanism for this run.
Definition: FGFDMExec.h:441
The trimming routine for JSBSim.
Definition: FGTrim.h:130
This class is solely for the purpose of determining what type of file is given on the command line...
Definition: JSBSim.cpp:152
bool Holding(void)
Returns true if the simulation is Holding (i.e. simulation time is not moving).
Definition: FGFDMExec.h:486
Initializes the simulation run.
bool SetSystemsPath(const SGPath &path)
Sets the path to the systems config file directories.
Definition: FGFDMExec.h:337
bool SetEnginePath(const SGPath &path)
Sets the path to the engine config file directories.
Definition: FGFDMExec.h:320
double GetSimTime(void) const
Returns the cumulative simulation time in seconds.
Definition: FGFDMExec.h:533
static char highint[5]
highlights text
Definition: FGJSBBase.h:125
double GetDeltaT(void) const
Returns the simulation delta T.
Definition: FGFDMExec.h:536
void CheckIncrementalHold(void)
Checks if required to hold afer increment.
Definition: FGFDMExec.cpp:1115
bool Run(void)
This function executes each scheduled model in succession.
Definition: FGFDMExec.cpp:310
Encapsulates the JSBSim simulation executive.
Definition: FGFDMExec.h:189
bool LoadModel(const SGPath &AircraftPath, const SGPath &EnginePath, const SGPath &SystemsPath, const std::string &model, bool addModelToPath=true)
Loads an aircraft model.
Definition: FGFDMExec.cpp:666
bool SetAircraftPath(const SGPath &path)
Sets the path to the aircraft config file directories.
Definition: FGFDMExec.h:329
bool DoTrim(void)
Execute the trim.
Definition: FGTrim.cpp:190
FGPropagate * GetPropagate(void)
Returns the FGPropagate pointer.
Definition: FGFDMExec.h:369