![]() |
JSBSim Flight Dynamics Model 1.0 (23 February 2013)
An Open Source Flight Dynamics and Control Software Library in C++
|
00001 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00002 00003 Module: JSBSim.cpp 00004 Author: Jon S. Berndt 00005 Date started: 08/17/99 00006 Purpose: Standalone version of JSBSim. 00007 Called by: The USER. 00008 00009 ------------- Copyright (C) 1999 Jon S. Berndt (jon@jsbsim.org) ------------- 00010 00011 This program is free software; you can redistribute it and/or modify it under 00012 the terms of the GNU Lesser General Public License as published by the Free Software 00013 Foundation; either version 2 of the License, or (at your option) any later 00014 version. 00015 00016 This program is distributed in the hope that it will be useful, but WITHOUT 00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00018 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00019 details. 00020 00021 You should have received a copy of the GNU Lesser General Public License along with 00022 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00023 Place - Suite 330, Boston, MA 02111-1307, USA. 00024 00025 Further information about the GNU Lesser General Public License can also be found on 00026 the world wide web at http://www.gnu.org. 00027 00028 FUNCTIONAL DESCRIPTION 00029 -------------------------------------------------------------------------------- 00030 00031 This class implements the JSBSim standalone application. It is set up for compilation 00032 under gnu C++, MSVC++, or other compiler. 00033 00034 HISTORY 00035 -------------------------------------------------------------------------------- 00036 08/17/99 JSB Created 00037 00038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00039 INCLUDES 00040 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ 00041 00042 #include "FGFDMExec.h" 00043 #include "input_output/FGXMLFileRead.h" 00044 00045 #if !defined(__GNUC__) && !defined(sgi) && !defined(_MSC_VER) 00046 # include <time> 00047 #else 00048 # include <time.h> 00049 #endif 00050 00051 #if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__) 00052 # define WIN32_LEAN_AND_MEAN 00053 # include <windows.h> 00054 # include <mmsystem.h> 00055 # include <regstr.h> 00056 # include <sys/types.h> 00057 # include <sys/timeb.h> 00058 #else 00059 # include <sys/time.h> 00060 #endif 00061 00062 #include <iostream> 00063 #include <cstdlib> 00064 00065 using namespace std; 00066 using JSBSim::FGXMLFileRead; 00067 00068 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00069 DEFINITIONS 00070 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ 00071 00072 static const char *IdSrc = "$Id: JSBSim.cpp,v 1.78 2012/09/18 12:42:29 jberndt Exp $"; 00073 00074 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00075 GLOBAL DATA 00076 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ 00077 00078 string RootDir = ""; 00079 string ScriptName; 00080 string AircraftName; 00081 string ResetName; 00082 string LogOutputName; 00083 vector <string> LogDirectiveName; 00084 vector <string> CommandLineProperties; 00085 vector <double> CommandLinePropertyValues; 00086 JSBSim::FGFDMExec* FDMExec; 00087 bool realtime; 00088 bool play_nice; 00089 bool suspend; 00090 bool catalog; 00091 bool nohighlight; 00092 00093 double end_time = 1e99; 00094 double simulation_rate = 1./120.; 00095 bool override_sim_rate = false; 00096 double sleep_period=0.01; 00097 00098 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00099 FORWARD DECLARATIONS 00100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ 00101 00102 bool options(int, char**); 00103 int real_main(int argc, char* argv[]); 00104 void PrintHelp(void); 00105 00106 #if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__) 00107 double getcurrentseconds(void) 00108 { 00109 struct timeb tm_ptr; 00110 ftime(&tm_ptr); 00111 return tm_ptr.time + tm_ptr.millitm*0.001; 00112 } 00113 #else 00114 double getcurrentseconds(void) 00115 { 00116 struct timeval tval; 00117 struct timezone tz; 00118 00119 gettimeofday(&tval, &tz); 00120 return (tval.tv_sec + tval.tv_usec*1e-6); 00121 } 00122 #endif 00123 00124 #if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__) 00125 void sim_nsleep(long nanosec) 00126 { 00127 Sleep((DWORD)(nanosec*1e-6)); // convert nanoseconds (passed in) to milliseconds for Win32. 00128 } 00129 #else 00130 void sim_nsleep(long nanosec) 00131 { 00132 struct timespec ts, ts1; 00133 00134 ts.tv_sec = 0; 00135 ts.tv_nsec = nanosec; 00136 nanosleep(&ts, &ts1); 00137 } 00138 #endif 00139 00142 class XMLFile : public FGXMLFileRead { 00143 public: 00144 bool IsScriptFile(std::string filename) { 00145 bool result=false; 00146 document = LoadXMLDocument(filename, false); 00147 if (document) if (document->GetName() == "runscript") result = true; 00148 ResetParser(); 00149 return result; 00150 } 00151 bool IsLogDirectiveFile(std::string filename) { 00152 bool result=false; 00153 document = LoadXMLDocument(filename, false); 00154 if (document) if (document->GetName() == "output") result = true; 00155 ResetParser(); 00156 return result; 00157 } 00158 bool IsAircraftFile(std::string filename) { 00159 bool result=false; 00160 document = LoadXMLDocument(filename, false); 00161 if (document) if (document->GetName() == "fdm_config") result = true; 00162 ResetParser(); 00163 return result; 00164 } 00165 bool IsInitFile(std::string filename) { 00166 bool result=false; 00167 document = LoadXMLDocument(filename, false); 00168 if (document) if (document->GetName() == "initialize") result = true; 00169 ResetParser(); 00170 return result; 00171 } 00172 }; 00173 00174 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00175 CLASS DOCUMENTATION 00176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ 00177 00270 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00271 IMPLEMENTATION 00272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ 00273 00274 int main(int argc, char* argv[]) 00275 { 00276 try { 00277 real_main(argc, argv); 00278 } catch (string msg) { 00279 std::cerr << "FATAL ERROR: JSBSim terminated with an exception." 00280 << std::endl << "The message was: " << msg << std::endl; 00281 } catch (...) { 00282 std::cerr << "FATAL ERROR: JSBSim terminated with an unknown exception." 00283 << std::endl; 00284 throw; 00285 } 00286 } 00287 00288 int real_main(int argc, char* argv[]) 00289 { 00290 // *** INITIALIZATIONS *** // 00291 00292 ScriptName = ""; 00293 AircraftName = ""; 00294 ResetName = ""; 00295 LogOutputName = ""; 00296 LogDirectiveName.clear(); 00297 bool result = false, success; 00298 bool was_paused = false; 00299 00300 double frame_duration; 00301 00302 double new_five_second_value = 0.0; 00303 double actual_elapsed_time = 0; 00304 double initial_seconds = 0; 00305 double current_seconds = 0.0; 00306 double paused_seconds = 0.0; 00307 double sim_lag_time = 0; 00308 double cycle_duration = 0.0; 00309 double override_sim_rate_value = 0.0; 00310 long sleep_nseconds = 0; 00311 00312 realtime = false; 00313 play_nice = false; 00314 suspend = false; 00315 catalog = false; 00316 nohighlight = false; 00317 00318 // *** PARSE OPTIONS PASSED INTO THIS SPECIFIC APPLICATION: JSBSim *** // 00319 success = options(argc, argv); 00320 if (!success) { 00321 PrintHelp(); 00322 exit(-1); 00323 } 00324 00325 // *** SET UP JSBSIM *** // 00326 FDMExec = new JSBSim::FGFDMExec(); 00327 FDMExec->SetRootDir(RootDir); 00328 FDMExec->SetAircraftPath("aircraft"); 00329 FDMExec->SetEnginePath("engine"); 00330 FDMExec->SetSystemsPath("systems"); 00331 FDMExec->GetPropertyManager()->Tie("simulation/frame_start_time", &actual_elapsed_time); 00332 FDMExec->GetPropertyManager()->Tie("simulation/cycle_duration", &cycle_duration); 00333 00334 if (nohighlight) FDMExec->disableHighLighting(); 00335 00336 if (simulation_rate < 1.0 ) 00337 FDMExec->Setdt(simulation_rate); 00338 else 00339 FDMExec->Setdt(1.0/simulation_rate); 00340 00341 if (override_sim_rate) override_sim_rate_value = FDMExec->GetDeltaT(); 00342 00343 // SET PROPERTY VALUES THAT ARE GIVEN ON THE COMMAND LINE and which are for the simulation only. 00344 00345 for (unsigned int i=0; i<CommandLineProperties.size(); i++) { 00346 00347 if (CommandLineProperties[i].find("simulation") != std::string::npos) { 00348 if (FDMExec->GetPropertyManager()->GetNode(CommandLineProperties[i])) { 00349 FDMExec->SetPropertyValue(CommandLineProperties[i], CommandLinePropertyValues[i]); 00350 } 00351 } 00352 } 00353 00354 // *** OPTION A: LOAD A SCRIPT, WHICH LOADS EVERYTHING ELSE *** // 00355 if (!ScriptName.empty()) { 00356 00357 result = FDMExec->LoadScript(ScriptName, override_sim_rate_value, ResetName); 00358 00359 if (!result) { 00360 cerr << "Script file " << ScriptName << " was not successfully loaded" << endl; 00361 delete FDMExec; 00362 exit(-1); 00363 } 00364 00365 // *** OPTION B: LOAD AN AIRCRAFT AND A SET OF INITIAL CONDITIONS *** // 00366 } else if (!AircraftName.empty() || !ResetName.empty()) { 00367 00368 if (catalog) FDMExec->SetDebugLevel(0); 00369 00370 if ( ! FDMExec->LoadModel( "aircraft", 00371 "engine", 00372 "systems", 00373 AircraftName)) { 00374 cerr << " JSBSim could not be started" << endl << endl; 00375 delete FDMExec; 00376 exit(-1); 00377 } 00378 00379 if (catalog) { 00380 FDMExec->PrintPropertyCatalog(); 00381 delete FDMExec; 00382 return 0; 00383 } 00384 00385 JSBSim::FGInitialCondition *IC = FDMExec->GetIC(); 00386 if ( ! IC->Load(ResetName)) { 00387 delete FDMExec; 00388 cerr << "Initialization unsuccessful" << endl; 00389 exit(-1); 00390 } 00391 00392 } else { 00393 cout << " No Aircraft, Script, or Reset information given" << endl << endl; 00394 delete FDMExec; 00395 exit(-1); 00396 } 00397 00398 // Load output directives file[s], if given 00399 for (unsigned int i=0; i<LogDirectiveName.size(); i++) { 00400 if (!LogDirectiveName[i].empty()) { 00401 if (!FDMExec->SetOutputDirectives(LogDirectiveName[i])) { 00402 cout << "Output directives not properly set in file " << LogDirectiveName[i] << endl; 00403 delete FDMExec; 00404 exit(-1); 00405 } 00406 } 00407 } 00408 00409 // OVERRIDE OUTPUT FILE NAME. THIS IS USEFUL FOR CASES WHERE MULTIPLE 00410 // RUNS ARE BEING MADE (SUCH AS IN A MONTE CARLO STUDY) AND THE OUTPUT FILE 00411 // NAME MUST BE SET EACH TIME TO AVOID THE PREVIOUS RUN DATA FROM BEING OVER- 00412 // WRITTEN. THIS OVERRIDES ONLY THE FILENAME FOR THE FIRST FILE. 00413 if (!LogOutputName.empty()) { 00414 string old_filename = FDMExec->GetOutputFileName(); 00415 if (!FDMExec->SetOutputFileName(LogOutputName)) { 00416 cout << "Output filename could not be set" << endl; 00417 } else { 00418 cout << "Output filename change from " << old_filename << " from aircraft" 00419 " configuration file to " << LogOutputName << " specified on" 00420 " command line" << endl; 00421 } 00422 } 00423 00424 // SET PROPERTY VALUES THAT ARE GIVEN ON THE COMMAND LINE 00425 00426 for (unsigned int i=0; i<CommandLineProperties.size(); i++) { 00427 00428 if (!FDMExec->GetPropertyManager()->GetNode(CommandLineProperties[i])) { 00429 cerr << endl << " No property by the name " << CommandLineProperties[i] << endl; 00430 goto quit; 00431 } else { 00432 FDMExec->SetPropertyValue(CommandLineProperties[i], CommandLinePropertyValues[i]); 00433 } 00434 } 00435 00436 FDMExec->RunIC(); 00437 FDMExec->GetPropagate()->DumpState(); 00438 00439 cout << endl << JSBSim::FGFDMExec::fggreen << JSBSim::FGFDMExec::highint 00440 << "---- JSBSim Execution beginning ... --------------------------------------------" 00441 << JSBSim::FGFDMExec::reset << endl << endl; 00442 00443 result = FDMExec->Run(); // MAKE AN INITIAL RUN 00444 00445 if (suspend) FDMExec->Hold(); 00446 00447 // Print actual time at start 00448 char s[100]; 00449 time_t tod; 00450 time(&tod); 00451 strftime(s, 99, "%A %B %d %Y %X", localtime(&tod)); 00452 cout << "Start: " << s << " (HH:MM:SS)" << endl; 00453 00454 frame_duration = FDMExec->GetDeltaT(); 00455 if (realtime) sleep_nseconds = (long)(frame_duration*1e9); 00456 else sleep_nseconds = (sleep_period )*1e9; // 0.01 seconds 00457 00458 tzset(); 00459 current_seconds = initial_seconds = getcurrentseconds(); 00460 00461 // *** CYCLIC EXECUTION LOOP, AND MESSAGE READING *** // 00462 while (result && FDMExec->GetSimTime() <= end_time) { 00463 00464 FDMExec->ProcessMessage(); // Process messages, if any. 00465 00466 // Check if increment then hold is on and take appropriate actions if it is 00467 // Iterate is not supported in realtime - only in batch and playnice modes 00468 FDMExec->CheckIncrementalHold(); 00469 00470 // if running realtime, throttle the execution, else just run flat-out fast 00471 // unless "playing nice", in which case sleep for a while (0.01 seconds) each frame. 00472 // If suspended, then don't increment cumulative realtime "stopwatch". 00473 00474 if ( ! FDMExec->Holding()) { 00475 if ( ! realtime ) { // ------------ RUNNING IN BATCH MODE 00476 00477 result = FDMExec->Run(); 00478 00479 if (play_nice) sim_nsleep(sleep_nseconds); 00480 00481 } else { // ------------ RUNNING IN REALTIME MODE 00482 00483 // "was_paused" will be true if entering this "run" loop from a paused state. 00484 if (was_paused) { 00485 initial_seconds += paused_seconds; 00486 was_paused = false; 00487 } 00488 current_seconds = getcurrentseconds(); // Seconds since 1 Jan 1970 00489 actual_elapsed_time = current_seconds - initial_seconds; // Real world elapsed seconds since start 00490 sim_lag_time = actual_elapsed_time - FDMExec->GetSimTime(); // How far behind sim-time is from actual 00491 // elapsed time. 00492 for (int i=0; i<(int)(sim_lag_time/frame_duration); i++) { // catch up sim time to actual elapsed time. 00493 result = FDMExec->Run(); 00494 cycle_duration = getcurrentseconds() - current_seconds; // Calculate cycle duration 00495 current_seconds = getcurrentseconds(); // Get new current_seconds 00496 if (FDMExec->Holding()) break; 00497 } 00498 00499 if (play_nice) sim_nsleep(sleep_nseconds); 00500 00501 if (FDMExec->GetSimTime() >= new_five_second_value) { // Print out elapsed time every five seconds. 00502 cout << "Simulation elapsed time: " << FDMExec->GetSimTime() << endl; 00503 new_five_second_value += 5.0; 00504 } 00505 } 00506 } else { // Suspended 00507 was_paused = true; 00508 paused_seconds = getcurrentseconds() - current_seconds; 00509 sim_nsleep(sleep_nseconds); 00510 result = FDMExec->Run(); 00511 } 00512 00513 } 00514 00515 quit: 00516 00517 // PRINT ENDING CLOCK TIME 00518 time(&tod); 00519 strftime(s, 99, "%A %B %d %Y %X", localtime(&tod)); 00520 cout << "End: " << s << " (HH:MM:SS)" << endl; 00521 00522 // CLEAN UP 00523 delete FDMExec; 00524 00525 return 0; 00526 } 00527 00528 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00529 00530 #define gripe cerr << "Option '" << keyword \ 00531 << "' requires a value, as in '" \ 00532 << keyword << "=something'" << endl << endl; 00533 00534 bool options(int count, char **arg) 00535 { 00536 int i; 00537 bool result = true; 00538 00539 if (count == 1) { 00540 PrintHelp(); 00541 exit(0); 00542 } 00543 00544 cout.setf(ios_base::fixed); 00545 00546 for (i=1; i<count; i++) { 00547 string argument = string(arg[i]); 00548 string keyword(argument); 00549 string value(""); 00550 string::size_type n=argument.find("="); 00551 00552 if (n != string::npos && n > 0) { 00553 keyword = argument.substr(0, n); 00554 value = argument.substr(n+1); 00555 } 00556 00557 if (keyword == "--help") { 00558 PrintHelp(); 00559 exit(0); 00560 } else if (keyword == "--version") { 00561 cout << endl << " JSBSim Version: " << FDMExec->GetVersion() << endl << endl; 00562 exit (0); 00563 } else if (keyword == "--realtime") { 00564 realtime = true; 00565 } else if (keyword == "--nice") { 00566 play_nice = true; 00567 if (n != string::npos) { 00568 try { 00569 sleep_period = atof( value.c_str() ); 00570 } catch (...) { 00571 cerr << endl << " Invalid sleep period given!" << endl << endl; 00572 result = false; 00573 } 00574 } else { 00575 sleep_period = 0.01; 00576 } 00577 } else if (keyword == "--suspend") { 00578 suspend = true; 00579 } else if (keyword == "--nohighlight") { 00580 nohighlight = true; 00581 } else if (keyword == "--outputlogfile") { 00582 if (n != string::npos) { 00583 LogOutputName = value; 00584 } else { 00585 LogOutputName = "JSBout.csv"; 00586 cerr << " Output log file name must be specified with an = sign. Using JSBout.csv as default"; 00587 } 00588 } else if (keyword == "--logdirectivefile") { 00589 if (n != string::npos) { 00590 LogDirectiveName.push_back(value); 00591 } else { 00592 gripe; 00593 exit(1); 00594 } 00595 } else if (keyword == "--root") { 00596 if (n != string::npos) { 00597 RootDir = value; 00598 if (RootDir[RootDir.length()-1] != '/') { 00599 RootDir += '/'; 00600 } 00601 } else { 00602 gripe; 00603 exit(1); 00604 } 00605 } else if (keyword == "--aircraft") { 00606 if (n != string::npos) { 00607 AircraftName = value; 00608 } else { 00609 gripe; 00610 exit(1); 00611 } 00612 } else if (keyword == "--script") { 00613 if (n != string::npos) { 00614 ScriptName = value; 00615 } else { 00616 gripe; 00617 exit(1); 00618 } 00619 } else if (keyword == "--initfile") { 00620 if (n != string::npos) { 00621 ResetName = value; 00622 } else { 00623 gripe; 00624 exit(1); 00625 } 00626 00627 } else if (keyword == "--property") { 00628 if (n != string::npos) { 00629 string propName = value.substr(0,value.find("=")); 00630 string propValueString = value.substr(value.find("=")+1); 00631 double propValue = atof(propValueString.c_str()); 00632 CommandLineProperties.push_back(propName); 00633 CommandLinePropertyValues.push_back(propValue); 00634 } else { 00635 gripe; 00636 exit(1); 00637 } 00638 00639 } else if (keyword == "--end-time") { 00640 if (n != string::npos) { 00641 try { 00642 end_time = atof( value.c_str() ); 00643 } catch (...) { 00644 cerr << endl << " Invalid end time given!" << endl << endl; 00645 result = false; 00646 } 00647 } else { 00648 gripe; 00649 exit(1); 00650 } 00651 00652 } else if (keyword == "--simulation-rate") { 00653 if (n != string::npos) { 00654 try { 00655 simulation_rate = atof( value.c_str() ); 00656 override_sim_rate = true; 00657 } catch (...) { 00658 cerr << endl << " Invalid simulation rate given!" << endl << endl; 00659 result = false; 00660 } 00661 } else { 00662 gripe; 00663 exit(1); 00664 } 00665 00666 } else if (keyword == "--catalog") { 00667 catalog = true; 00668 if (value.size() > 0) AircraftName=value; 00669 } else if (keyword.substr(0,2) != "--" && value.empty() ) { 00670 // See what kind of files we are specifying on the command line 00671 00672 XMLFile xmlFile; 00673 00674 if (xmlFile.IsScriptFile(keyword)) ScriptName = keyword; 00675 else if (xmlFile.IsLogDirectiveFile(keyword)) LogDirectiveName.push_back(keyword); 00676 else if (xmlFile.IsAircraftFile("aircraft/" + keyword + "/" + keyword)) AircraftName = keyword; 00677 else if (xmlFile.IsInitFile(keyword)) ResetName = keyword; 00678 else if (xmlFile.IsInitFile("aircraft/" + AircraftName + "/" + keyword)) ResetName = keyword; 00679 else { 00680 cerr << "The argument \"" << keyword << "\" cannot be interpreted as a file name or option." << endl; 00681 exit(1); 00682 } 00683 00684 } 00685 else //Unknown keyword so print the help file, the bad keyword and abort 00686 { 00687 PrintHelp(); 00688 cerr << "The argument \"" << keyword << "\" cannot be interpreted as a file name or option." << endl; 00689 exit(1); 00690 } 00691 00692 } 00693 00694 // Post-processing for script options. check for incompatible options. 00695 00696 if (catalog && !ScriptName.empty()) { 00697 cerr << "Cannot specify catalog with script option" << endl << endl; 00698 result = false; 00699 } 00700 if (AircraftName.size() > 0 && ResetName.size() == 0 && !catalog) { 00701 cerr << "You must specify an initialization file with the aircraft name." << endl << endl; 00702 result = false; 00703 } 00704 if (ScriptName.size() > 0 && AircraftName.size() > 0) { 00705 cerr << "You cannot specify an aircraft file with a script." << endl; 00706 result = false; 00707 } 00708 00709 return result; 00710 00711 } 00712 00713 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00714 00715 void PrintHelp(void) 00716 { 00717 cout << endl << " JSBSim version " << FDMExec->GetVersion() << endl << endl; 00718 cout << " Usage: jsbsim [script file name] [output file names] <options>" << endl << endl; 00719 cout << " options:" << endl; 00720 cout << " --help returns this message" << endl; 00721 cout << " --version returns the version number" << endl; 00722 cout << " --outputlogfile=<filename> sets (overrides) the name of the first data output file" << endl; 00723 cout << " --logdirectivefile=<filename> specifies the name of a data logging directives file" << endl; 00724 cout << " (can appear multiple times)" << endl; 00725 cout << " --root=<path> specifies the JSBSim root directory (where aircraft/, engine/, etc. reside)" << endl; 00726 cout << " --aircraft=<filename> specifies the name of the aircraft to be modeled" << endl; 00727 cout << " --script=<filename> specifies a script to run" << endl; 00728 cout << " --realtime specifies to run in actual real world time" << endl; 00729 cout << " --nice specifies to run at lower CPU usage" << endl; 00730 cout << " --nohighlight specifies that console output should be pure text only (no color)" << endl; 00731 cout << " --suspend specifies to suspend the simulation after initialization" << endl; 00732 cout << " --initfile=<filename> specifies an initilization file" << endl; 00733 cout << " --catalog specifies that all properties for this aircraft model should be printed" << endl; 00734 cout << " (catalog=aircraftname is an optional format)" << endl; 00735 cout << " --property=<name=value> e.g. --property=simulation/integrator/rate/rotational=1" << endl; 00736 cout << " --simulation-rate=<rate (double)> specifies the sim dT time or frequency" << endl; 00737 cout << " If rate specified is less than 1, it is interpreted as" << endl; 00738 cout << " a time step size, otherwise it is assumed to be a rate in Hertz." << endl; 00739 cout << " --end-time=<time (double)> specifies the sim end time" << endl << endl; 00740 00741 cout << " NOTE: There can be no spaces around the = sign when" << endl; 00742 cout << " an option is followed by a filename" << endl << endl; 00743 } 00744