]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/JSBSim.cpp
Latest JSBSim changes, including a kludge from Tony to keep the
[flightgear.git] / src / FDM / JSBSim / 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 (jsb@hal-pc.org) -------------
10
11  This program is free software; you can redistribute it and/or modify it under
12  the terms of the GNU 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 General Public License for more
19  details.
20
21  You should have received a copy of the GNU 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 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 Handles calling JSBSim standalone. It is set up for compilation under
32 Borland C+Builder or other compiler.
33
34 HISTORY
35 --------------------------------------------------------------------------------
36 08/17/99   JSB   Created
37
38 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39 INCLUDES
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
41
42 #include "FGFDMExec.h"
43 #include "FGRotation.h"
44 #include "FGAtmosphere.h"
45 #include "FGState.h"
46 #include "FGFCS.h"
47 #include "FGAircraft.h"
48 #include "FGTranslation.h"
49 #include "FGPosition.h"
50 #include "FGAuxiliary.h"
51 #include "FGOutput.h"
52 #include "FGConfigFile.h"
53 #include "FGScript.h"
54 #include "FGJSBBase.h"
55
56 #ifdef FGFS
57 #include <simgear/compiler.h>
58 #include STL_IOSTREAM
59 #else
60 #  if defined(sgi) && !defined(__GNUC__)
61 #    include <iostream.h>
62 #  else
63 #    include <iostream>
64 #  endif
65 #endif
66
67 #if __BCPLUSPLUS__ == 0x540
68 #pragma hdrstop
69 #include <condefs.h>
70 //---------------------------------------------------------------------------
71 USERES("JSBSim.res");
72 USEUNIT("FGUtility.cpp");
73 USEUNIT("FGAircraft.cpp");
74 USEUNIT("FGAtmosphere.cpp");
75 USEUNIT("FGAuxiliary.cpp");
76 USEUNIT("FGCoefficient.cpp");
77 USEUNIT("FGColumnVector3.cpp");
78 USEUNIT("FGColumnVector4.cpp");
79 USEUNIT("FGConfigFile.cpp");
80 USEUNIT("FGEngine.cpp");
81 USEUNIT("FGFactorGroup.cpp");
82 USEUNIT("FGFCS.cpp");
83 USEUNIT("FGFDMExec.cpp");
84 USEUNIT("FGfdmSocket.cpp");
85 USEUNIT("FGForce.cpp");
86 USEUNIT("FGGroundReactions.cpp");
87 USEUNIT("FGInertial.cpp");
88 USEUNIT("FGInitialCondition.cpp");
89 USEUNIT("FGJSBBase.cpp");
90 USEUNIT("FGLGear.cpp");
91 USEUNIT("FGMassBalance.cpp");
92 USEUNIT("FGMatrix33.cpp");
93 USEUNIT("FGModel.cpp");
94 USEUNIT("FGNozzle.cpp");
95 USEUNIT("FGOutput.cpp");
96 USEUNIT("FGPiston.cpp");
97 USEUNIT("FGPosition.cpp");
98 USEUNIT("FGPropeller.cpp");
99 USEUNIT("FGPropulsion.cpp");
100 USEUNIT("FGRocket.cpp");
101 USEUNIT("FGRotation.cpp");
102 USEUNIT("FGRotor.cpp");
103 USEUNIT("FGScript.cpp");
104 USEUNIT("FGState.cpp");
105 USEUNIT("FGTable.cpp");
106 USEUNIT("FGTank.cpp");
107 USEUNIT("FGThruster.cpp");
108 USEUNIT("FGTranslation.cpp");
109 USEUNIT("FGTrim.cpp");
110 USEUNIT("FGTrimAxis.cpp");
111 USEUNIT("FGTurboJet.cpp");
112 USEUNIT("FGTurboProp.cpp");
113 USEUNIT("FGTurboShaft.cpp");
114 USEUNIT("FGAerodynamics.cpp");
115 USEUNIT("filtersjb\FGSwitch.cpp");
116 USEUNIT("filtersjb\FGFCSComponent.cpp");
117 USEUNIT("filtersjb\FGFilter.cpp");
118 USEUNIT("filtersjb\FGGain.cpp");
119 USEUNIT("filtersjb\FGGradient.cpp");
120 USEUNIT("filtersjb\FGKinemat.cpp");
121 USEUNIT("filtersjb\FGSummer.cpp");
122 USEUNIT("filtersjb\FGDeadBand.cpp");
123 //---------------------------------------------------------------------------
124 #pragma argsused
125 #endif
126
127 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
128 DEFINITIONS
129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
130
131 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
132 GLOBAL DATA
133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
134
135 static const char *IdSrc = "$Id$";
136
137 string ScriptName;
138 string AircraftName;
139 string ResetName;
140 string LogOutputName;
141 string LogDirectiveName;
142 FGFDMExec* FDMExec;
143
144 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
145 COMMENTS, REFERENCES, and NOTES [use "class documentation" below for API docs]
146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
147
148 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
149 FORWARD DECLARATIONS
150 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
151
152 void options(int, char**);
153
154 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
155 DOCUMENTATION
156 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
157
158 /** Standalone JSBSim main program
159     This is the wrapper program used to instantiate the JSBSim system and control
160     it. Use this program to build a version of JSBSim that can be run from the
161     command line. To get any use out of this, you will have to create a script
162     to run a test case and specify what kind of output you would like.
163     @author Jon S. Berndt
164     @version $Id$
165     @see -
166 */
167
168 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
169 IMPLEMENTATION
170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
171
172 int main(int argc, char* argv[])
173 {
174   ScriptName = "";
175   AircraftName = "";
176   ResetName = "";
177   LogOutputName = "";
178   LogDirectiveName = "";
179   bool result = false;
180   bool Scripted = false;
181   FGScript* Script;
182
183   options(argc, argv);
184
185   FDMExec = new FGFDMExec();
186
187   if (!ScriptName.empty()) { // SCRIPTED CASE
188
189     Script = new FGScript(FDMExec);
190     result = Script->LoadScript(ScriptName);
191
192     if (!result) {
193       cerr << "Script file " << ScriptName << " was not successfully loaded" << endl;
194       exit(-1);
195     }
196
197     Scripted = true;
198
199   } else if (!AircraftName.empty() || !ResetName.empty()) {        // form jsbsim <acname> <resetfile>
200
201     if ( ! FDMExec->LoadModel("aircraft", "engine", AircraftName)) {
202         cerr << "  JSBSim could not be started" << endl << endl;
203       exit(-1);
204     }
205
206     FGInitialCondition IC(FDMExec);
207     if ( ! IC.Load("aircraft",AircraftName,ResetName)) {
208         cerr << "Initialization unsuccessful" << endl;
209       exit(-1);
210     }
211   } else {
212     cout << "  No Aircraft, Script, or Reset information given" << endl << endl;
213     exit(-1);
214   }
215
216 //
217 // RUN loop. MESSAGES are read inside the Run() loop and output as necessary.
218 //
219
220   FGJSBBase::Message* msg;
221   result = FDMExec->Run();
222   while (result) {
223     while (FDMExec->ReadMessage()) {
224       msg = FDMExec->ProcessMessage();
225       switch (msg->type) {
226       case FGJSBBase::Message::eText:
227         cout << msg->messageId << ": " << msg->text << endl;
228         break;
229       case FGJSBBase::Message::eBool:
230         cout << msg->messageId << ": " << msg->text << " " << msg->bVal << endl;
231         break;
232       case FGJSBBase::Message::eInteger:
233         cout << msg->messageId << ": " << msg->text << " " << msg->iVal << endl;
234         break;
235       case FGJSBBase::Message::eDouble:
236         cout << msg->messageId << ": " << msg->text << " " << msg->dVal << endl;
237         break;
238       default:
239         cerr << "Unrecognized message type." << endl;
240               break;
241       }
242     }
243
244     if (Scripted) {
245       if (!Script->RunScript()) break;
246     }
247
248     result = FDMExec->Run();
249   }
250
251   delete FDMExec;
252
253   return 0;
254 }
255
256 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
257
258 void options(int count, char **arg)
259 {
260   int i;
261
262   if (count == 1) {
263     cout << endl << "  JSBSim version " << FDMExec->GetVersion() << endl << endl;
264     cout << "  Usage: jsbsim <options>" << endl << endl;
265     cout << "  options:" << endl;
266       cout << "    --help  returns this message" << endl;
267       cout << "    --version  returns the version number" << endl;
268       cout << "    --outputlogfile=<filename>  sets the name of the data output file" << endl;
269       cout << "    --logdirectivefile=<filename>  specifies the name of the data logging directives file" << endl;
270       cout << "    --aircraft=<filename>  specifies the name of the aircraft to be modeled" << endl;
271       cout << "    --script=<filename>  specifies a script to run" << endl;
272       cout << "    --initfile=<filename>  specifies an initilization file" << endl << endl;
273     cout << "  NOTE: There can be no spaces around the = sign when" << endl;
274     cout << "        an option is followed by a filename" << endl << endl;
275   }
276
277   for (i=1; i<count; i++) {
278     string argument = string(arg[i]);
279     int n=0;
280     if (argument.find("--help") != string::npos) {
281       cout << endl << "  JSBSim version " << FDMExec->GetVersion() << endl << endl;
282       cout << "  Usage: jsbsim <options>" << endl << endl;
283       cout << "  options:" << endl;
284       cout << "    --help  returns this message" << endl;
285       cout << "    --version  returns the version number" << endl;
286       cout << "    --outputlogfile=<filename>  sets the name of the data output file" << endl;
287       cout << "    --logdirectivefile=<filename>  specifies the name of the data logging directives file" << endl;
288       cout << "    --aircraft=<filename>  specifies the name of the aircraft to be modeled" << endl;
289       cout << "    --script=<filename>  specifies a script to run" << endl;
290       cout << "    --initfile=<filename>  specifies an initilization file" << endl << endl;
291       cout << "  NOTE: There can be no spaces around the = sign when" << endl;
292       cout << "        an option is followed by a filename" << endl << endl;
293       exit(0);
294     } else if (argument.find("--version") != string::npos) {
295       cout << endl << "  JSBSim Version: " << FDMExec->GetVersion() << endl << endl;
296       exit (0);
297     } else if (argument.find("--outputlogfile") != string::npos) {
298       n = argument.find("=")+1;
299       if (n > 0) {
300         LogOutputName = argument.substr(argument.find("=")+1);
301       } else {
302         LogOutputName = "JSBout.csv";
303         cerr << "  Output log file name not valid or not understood. Using JSBout.csv as default";
304       }
305     } else if (argument.find("--logdirectivefile") != string::npos) {
306       n = argument.find("=")+1;
307       if (n > 0) {
308         LogDirectiveName = argument.substr(argument.find("=")+1);
309       } else {
310         cerr << "  Log directives file not valid or not understood." << endl << endl;
311         exit(1);
312       }
313     } else if (argument.find("--aircraft") != string::npos) {
314       n = argument.find("=")+1;
315       if (n > 0) {
316         AircraftName = argument.substr(argument.find("=")+1);
317       } else {
318         cerr << "  Aircraft name not valid or not understood." << endl << endl;
319         exit(1);
320       }
321     } else if (argument.find("--script") != string::npos) {
322       n = argument.find("=")+1;
323       if (n > 0) {
324         ScriptName = argument.substr(argument.find("=")+1);
325       } else {
326         cerr << "  Script name not valid or not understood." << endl << endl;
327         exit(1);
328       }
329     } else if (argument.find("--initfile") != string::npos) {
330       n = argument.find("=")+1;
331       if (n > 0) {
332         ResetName = argument.substr(argument.find("=")+1);
333       } else {
334         cerr << "  Reset name not valid or not understood." << endl << endl;
335         exit(1);
336       }
337     } else {
338       cerr << endl << "  Parameter: " << argument << " not understood" << endl;
339     }
340   }
341
342 }
343