]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/FGAircraft.cpp
Sync with latest JSBSim.
[flightgear.git] / src / FDM / JSBSim / FGAircraft.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2  
3  Module:       FGAircraft.cpp
4  Author:       Jon S. Berndt
5  Date started: 12/12/98                                   
6  Purpose:      Encapsulates an aircraft
7  Called by:    FGFDMExec
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 Models the aircraft reactions and forces. This class is instantiated by the
31 FGFDMExec class and scheduled as an FDM entry. 
32  
33 HISTORY
34 --------------------------------------------------------------------------------
35 12/12/98   JSB   Created
36 04/03/99   JSB   Changed Aero() method to correct body axis force calculation
37                  from wind vector. Fix provided by Tony Peden.
38 05/03/99   JSB   Changed (for the better?) the way configurations are read in.
39 9/17/99     TP   Combined force and moment functions. Added aero reference 
40                  point to config file. Added calculations for moments due to 
41                  difference in cg and aero reference point
42  
43 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
44 COMMENTS, REFERENCES,  and NOTES
45 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
46  
47 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
48 INCLUDES
49 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
50
51 #include <sys/stat.h>
52 #include <sys/types.h>
53
54 #ifdef FGFS
55 #  ifndef __BORLANDC__
56 #    include <simgear/compiler.h>
57 #  endif
58 #  ifdef SG_HAVE_STD_INCLUDES
59 #    include <cmath>
60 #  else
61 #    include <math.h>
62 #  endif
63 #else
64 #  if defined (sgi) && !defined(__GNUC__)
65 #    include <math.h>
66 #  else
67 #    include <cmath>
68 #  endif
69 #endif
70
71 #include "FGAircraft.h"
72 #include "FGMassBalance.h"
73 #include "FGInertial.h"
74 #include "FGGroundReactions.h"
75 #include "FGAerodynamics.h"
76 #include "FGTranslation.h"
77 #include "FGRotation.h"
78 #include "FGAtmosphere.h"
79 #include "FGState.h"
80 #include "FGFDMExec.h"
81 #include "FGFCS.h"
82 #include "FGPosition.h"
83 #include "FGAuxiliary.h"
84 #include "FGOutput.h"
85
86 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
87 DEFINITIONS
88 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
89
90 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
91 GLOBAL DATA
92 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
93
94 static const char *IdSrc = "$Id$";
95 static const char *IdHdr = ID_AIRCRAFT;
96
97 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
98 CLASS IMPLEMENTATION
99 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
100
101 FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex),
102     vMoments(3),
103     vForces(3),
104     vXYZrp(3),
105     vXYZep(3),
106     vDXYZcg(3),
107     vBodyAccel(3),
108     vNcg(3),
109     vNwcg(3)
110 {
111   Name = "FGAircraft";
112   alphaclmin = alphaclmax = 0;
113   HTailArea = VTailArea = HTailArm = VTailArm = 0.0;
114   lbarh = lbarv = vbarh = vbarv = 0.0;
115   WingIncidence=0;
116   impending_stall = 0;
117
118   if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
119 }
120
121
122 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
123
124
125 FGAircraft::~FGAircraft()
126 {
127   if (debug_lvl & 2) cout << "Destroyed:    FGAircraft" << endl;
128 }
129
130 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
131
132 bool FGAircraft::Load(FGConfigFile* AC_cfg)
133 {
134   string token;
135
136   if (!ReadPrologue(AC_cfg)) return false;
137
138   while ((AC_cfg->GetNextConfigLine() != string("EOF")) &&
139          (token = AC_cfg->GetValue()) != string("/FDM_CONFIG")) {
140     if (token == "METRICS") {
141       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Metrics" << fgdef << endl;
142       if (!ReadMetrics(AC_cfg)) return false;
143     } else if (token == "AERODYNAMICS") {
144       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Aerodynamics" << fgdef << endl;
145       if (!ReadAerodynamics(AC_cfg)) return false;
146     } else if (token == "UNDERCARRIAGE") {
147       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Landing Gear" << fgdef << endl;
148       if (!ReadUndercarriage(AC_cfg)) return false;
149     } else if (token == "PROPULSION") {
150       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Propulsion" << fgdef << endl;
151       if (!ReadPropulsion(AC_cfg)) return false;
152     } else if (token == "FLIGHT_CONTROL") {
153       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Flight Control" << fgdef << endl;
154       if (!ReadFlightControls(AC_cfg)) return false;
155     } else if (token == "OUTPUT") {
156       if (debug_lvl > 0) cout << fgcyan << "\n  Reading Output directives" << fgdef << endl;
157       if (!ReadOutput(AC_cfg)) return false;
158     }
159   }
160   
161   return true;
162 }
163
164 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
165
166 bool FGAircraft::Run(void)
167 {
168   if (!FGModel::Run()) {                 // if false then execute this Run()
169     vForces.InitMatrix();
170     vForces += Aerodynamics->GetForces();
171     vForces += Inertial->GetForces();
172     vForces += Propulsion->GetForces();
173     vForces += GroundReactions->GetForces();
174
175     vMoments.InitMatrix();
176     vMoments += Aerodynamics->GetMoments();
177     vMoments += Propulsion->GetMoments();
178     vMoments += GroundReactions->GetMoments();
179     
180     vBodyAccel = vForces/MassBalance->GetMass();
181     
182     vNcg = vBodyAccel/Inertial->gravity();
183
184     vNwcg = State->GetTb2s() * vNcg;
185     vNwcg(3) = -1*vNwcg(3) + 1;
186     
187     if (alphaclmax != 0) {
188       if (Translation->Getalpha() > 0.85*alphaclmax) {
189         impending_stall = 10*(Translation->Getalpha()/alphaclmax - 0.85);
190       } else {
191         impending_stall = 0;
192       }
193     }      
194     
195     return false;
196   } else {                               // skip Run() execution this time
197     return true;
198   }
199 }
200
201 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
202
203 float FGAircraft::GetNlf(void)
204 {
205   return vNwcg(3);
206 }
207
208 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
209
210 bool FGAircraft::ReadPrologue(FGConfigFile* AC_cfg)
211 {
212   string token = AC_cfg->GetValue();
213   string scratch;
214   AircraftName = AC_cfg->GetValue("NAME");
215   if (debug_lvl > 0) cout << underon << "Reading Aircraft Configuration File"
216             << underoff << ": " << highint << AircraftName << normint << endl;
217   scratch = AC_cfg->GetValue("VERSION").c_str();
218
219   CFGVersion = AC_cfg->GetValue("VERSION");
220
221   if (debug_lvl > 0)
222     cout << "                            Version: " << highint << CFGVersion
223                                                              << normint << endl;
224   if (CFGVersion != needed_cfg_version) {
225     cerr << endl << fgred << "YOU HAVE AN INCOMPATIBLE CFG FILE FOR THIS AIRCRAFT."
226             " RESULTS WILL BE UNPREDICTABLE !!" << endl;
227     cerr << "Current version needed is: " << needed_cfg_version << endl;
228     cerr << "         You have version: " << CFGVersion << endl << fgdef << endl;
229     return false;
230   }
231   return true;
232 }
233
234 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
235
236 bool FGAircraft::ReadMetrics(FGConfigFile* AC_cfg)
237 {
238   string token = "";
239   string parameter;
240   double EW, bixx, biyy, bizz, bixz, biyz;
241   FGColumnVector3 vbaseXYZcg(3);
242
243   AC_cfg->GetNextConfigLine();
244
245   while ((token = AC_cfg->GetValue()) != string("/METRICS")) {
246     *AC_cfg >> parameter;
247     if (parameter == "AC_WINGAREA") {
248       *AC_cfg >> WingArea;
249       if (debug_lvl > 0) cout << "    WingArea: " << WingArea  << endl;
250     } else if (parameter == "AC_WINGSPAN") {
251       *AC_cfg >> WingSpan;
252       if (debug_lvl > 0) cout << "    WingSpan: " << WingSpan  << endl;
253     } else if (parameter == "AC_WINGINCIDENCE") {
254       *AC_cfg >> WingIncidence;
255       if (debug_lvl > 0) cout << "    Chord: " << cbar << endl;
256     } else if (parameter == "AC_CHORD") {
257       *AC_cfg >> cbar;
258       if (debug_lvl > 0) cout << "    Chord: " << cbar << endl;
259     } else if (parameter == "AC_HTAILAREA") {
260       *AC_cfg >> HTailArea;
261       if (debug_lvl > 0) cout << "    H. Tail Area: " << HTailArea << endl;
262     } else if (parameter == "AC_HTAILARM") {
263       *AC_cfg >> HTailArm;
264       if (debug_lvl > 0) cout << "    H. Tail Arm: " << HTailArm << endl;
265     } else if (parameter == "AC_VTAILAREA") {
266       *AC_cfg >> VTailArea;
267       if (debug_lvl > 0) cout << "    V. Tail Area: " << VTailArea << endl;
268     } else if (parameter == "AC_VTAILARM") {
269       *AC_cfg >> VTailArm;
270       if (debug_lvl > 0) cout << "    V. Tail Arm: " << VTailArm << endl;
271     } else if (parameter == "AC_IXX") {
272       *AC_cfg >> bixx;
273       if (debug_lvl > 0) cout << "    baseIxx: " << bixx << endl;
274       MassBalance->SetBaseIxx(bixx);
275     } else if (parameter == "AC_IYY") {
276       *AC_cfg >> biyy;
277       if (debug_lvl > 0) cout << "    baseIyy: " << biyy << endl;
278       MassBalance->SetBaseIyy(biyy);
279     } else if (parameter == "AC_IZZ") {
280       *AC_cfg >> bizz;
281       if (debug_lvl > 0) cout << "    baseIzz: " << bizz << endl;
282       MassBalance->SetBaseIzz(bizz);
283     } else if (parameter == "AC_IXZ") {
284       *AC_cfg >> bixz;
285       if (debug_lvl > 0) cout << "    baseIxz: " << bixz  << endl;
286       MassBalance->SetBaseIxz(bixz);
287     } else if (parameter == "AC_IYZ") {
288       *AC_cfg >> biyz;
289       if (debug_lvl > 0) cout << "    baseIyz: " << biyz  << endl;
290       MassBalance->SetBaseIyz(biyz);
291     } else if (parameter == "AC_EMPTYWT") {
292       *AC_cfg >> EW;
293       MassBalance->SetEmptyWeight(EW);
294       if (debug_lvl > 0) cout << "    EmptyWeight: " << EW  << endl;
295     } else if (parameter == "AC_CGLOC") {
296       *AC_cfg >> vbaseXYZcg(eX) >> vbaseXYZcg(eY) >> vbaseXYZcg(eZ);
297       MassBalance->SetBaseCG(vbaseXYZcg);
298       if (debug_lvl > 0) cout << "    CG (x, y, z): " << vbaseXYZcg << endl;
299     } else if (parameter == "AC_EYEPTLOC") {
300       *AC_cfg >> vXYZep(eX) >> vXYZep(eY) >> vXYZep(eZ);
301       if (debug_lvl > 0) cout << "    Eyepoint (x, y, z): " << vXYZep << endl;
302     } else if (parameter == "AC_AERORP") {
303       *AC_cfg >> vXYZrp(eX) >> vXYZrp(eY) >> vXYZrp(eZ);
304       if (debug_lvl > 0) cout << "    Ref Pt (x, y, z): " << vXYZrp << endl;
305     } else if (parameter == "AC_ALPHALIMITS") {
306       *AC_cfg >> alphaclmin >> alphaclmax;
307       if (debug_lvl > 0) cout << "    Maximum Alpha: " << alphaclmax
308              << "    Minimum Alpha: " << alphaclmin
309              << endl;
310     }
311   }
312   
313   // calculate some derived parameters
314   if (cbar != 0.0) {
315     lbarh = HTailArm/cbar;
316     lbarv = VTailArm/cbar;
317     if (WingArea != 0.0) {
318       vbarh = HTailArm*HTailArea / (cbar*WingArea);
319       vbarv = VTailArm*VTailArea / (cbar*WingArea);
320     }
321   }     
322   return true;
323 }
324
325 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
326
327 bool FGAircraft::ReadPropulsion(FGConfigFile* AC_cfg)
328 {
329   if (!Propulsion->Load(AC_cfg)) {
330     cerr << "  Propulsion not successfully loaded" << endl;
331     return false;
332   }
333   return true;
334 }
335
336 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
337
338 bool FGAircraft::ReadFlightControls(FGConfigFile* AC_cfg)
339 {
340   if (!FCS->Load(AC_cfg)) {
341     cerr << "  Flight Controls not successfully loaded" << endl;
342     return false;
343   }
344   return true;
345 }
346
347 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
348
349 bool FGAircraft::ReadAerodynamics(FGConfigFile* AC_cfg)
350 {
351   if (!Aerodynamics->Load(AC_cfg)) {
352     cerr << "  Aerodynamics not successfully loaded" << endl;
353     return false;
354   }
355   return true;
356 }
357
358 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
359
360 bool FGAircraft::ReadUndercarriage(FGConfigFile* AC_cfg)
361 {
362   if (!GroundReactions->Load(AC_cfg)) {
363     cerr << "  Ground Reactions not successfully loaded" << endl;
364     return false;
365   }
366   return true;
367 }
368
369 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
370
371 bool FGAircraft::ReadOutput(FGConfigFile* AC_cfg)
372 {
373   if (!Output->Load(AC_cfg)) {
374     cerr << "  Output not successfully loaded" << endl;
375     return false;
376   }
377   return true;
378 }
379
380 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
381
382 void FGAircraft::Debug(void)
383 {
384     //TODO: Add your source code here
385 }
386