]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/FGState.cpp
Updated JSBsim code.
[flightgear.git] / src / FDM / JSBSim / FGState.cpp
1 /*******************************************************************************
2                                                                        
3  Module:       FGState.cpp
4  Author:       Jon Berndt
5  Date started: 11/17/98
6  Called by:    FGFDMExec and accessed by all models.
7
8  ------------- Copyright (C) 1999  Jon S. Berndt (jsb@hal-pc.org) -------------
9
10  This program is free software; you can redistribute it and/or modify it under
11  the terms of the GNU General Public License as published by the Free Software
12  Foundation; either version 2 of the License, or (at your option) any later
13  version.
14
15  This program is distributed in the hope that it will be useful, but WITHOUT
16  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
18  details.
19
20  You should have received a copy of the GNU General Public License along with
21  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22  Place - Suite 330, Boston, MA  02111-1307, USA.
23
24  Further information about the GNU General Public License can also be found on
25  the world wide web at http://www.gnu.org.
26
27 FUNCTIONAL DESCRIPTION
28 --------------------------------------------------------------------------------
29 See header file.
30
31 HISTORY
32 --------------------------------------------------------------------------------
33 11/17/98   JSB   Created
34
35 ********************************************************************************
36 INCLUDES
37 *******************************************************************************/
38
39 #ifdef FGFS
40 #  include <simgear/compiler.h>
41 #  ifdef FG_HAVE_STD_INCLUDES
42 #    include <cmath>
43 #  else
44 #    include <math.h>
45 #  endif
46 #else
47 #  include <cmath>
48 #endif
49
50 #include "FGState.h"
51 #include "FGFDMExec.h"
52 #include "FGAtmosphere.h"
53 #include "FGFCS.h"
54 #include "FGAircraft.h"
55 #include "FGTranslation.h"
56 #include "FGRotation.h"
57 #include "FGPosition.h"
58 #include "FGAuxiliary.h"
59 #include "FGOutput.h"
60
61 /*******************************************************************************
62 ************************************ CODE **************************************
63 *******************************************************************************/
64
65
66 FGState::FGState(FGFDMExec* fdex) : mTb2l(3,3),
67                                     mTl2b(3,3),
68                                     mTs2b(3,3),
69                                     vQtrn(4)
70 {
71   FDMExec = fdex;
72
73   Vt = 0.0;
74   latitude = longitude = 0.0;
75   adot = bdot = 0.0;
76   h = 0.0;
77   a = 1000.0;
78   qbar = 0.0;
79   sim_time = 0.0;
80   dt = 1.0/120.0;
81
82   coeffdef["FG_QBAR"]          = 1           ;
83   coeffdef["FG_WINGAREA"]      = 2           ;
84   coeffdef["FG_WINGSPAN"]      = 4           ;
85   coeffdef["FG_CBAR"]          = 8           ;
86   coeffdef["FG_ALPHA"]         = 16          ;
87   coeffdef["FG_ALPHADOT"]      = 32          ;
88   coeffdef["FG_BETA"]          = 64          ;
89   coeffdef["FG_BETADOT"]       = 128         ;
90   coeffdef["FG_PITCHRATE"]     = 256         ;
91   coeffdef["FG_ROLLRATE"]      = 512         ;
92   coeffdef["FG_YAWRATE"]       = 1024        ;
93   coeffdef["FG_MACH"]          = 2048        ;
94   coeffdef["FG_ALTITUDE"]      = 4096        ;
95   coeffdef["FG_BI2VEL"]        = 8192        ;
96   coeffdef["FG_CI2VEL"]        = 16384       ;
97   coeffdef["FG_ELEVATOR_POS"]  = 32768L      ;
98   coeffdef["FG_AILERON_POS"]   = 65536L      ;
99   coeffdef["FG_RUDDER_POS"]    = 131072L     ;
100   coeffdef["FG_SPDBRAKE_POS"]  = 262144L     ;
101   coeffdef["FG_SPOILERS_POS"]  = 524288L     ;
102   coeffdef["FG_FLAPS_POS"]     = 1048576L    ;
103   coeffdef["FG_ELEVATOR_CMD"]  = 2097152L    ;
104   coeffdef["FG_AILERON_CMD"]   = 4194304L    ;
105   coeffdef["FG_RUDDER_CMD"]    = 8388608L    ;
106   coeffdef["FG_SPDBRAKE_CMD"]  = 16777216L   ;
107   coeffdef["FG_SPOILERS_CMD"]  = 33554432L   ;
108   coeffdef["FG_FLAPS_CMD"]     = 67108864L   ;
109   coeffdef["FG_SPARE3"]        = 134217728L  ;
110   coeffdef["FG_SPARE4"]        = 268435456L  ;
111   coeffdef["FG_SPARE5"]        = 536870912L  ;
112   coeffdef["FG_SPARE6"]        = 1073741824L ;
113 }
114
115 /******************************************************************************/
116
117 FGState::~FGState(void)
118 {
119 }
120
121 //***************************************************************************
122 //
123 // Reset: Assume all angles READ FROM FILE IN DEGREES !!
124 //
125
126 bool FGState::Reset(string path, string acname, string fname)
127 {
128   string resetDef;
129   float U, V, W;
130   float phi, tht, psi;
131
132   resetDef = path + "/" + acname + "/" + fname;
133
134   ifstream resetfile(resetDef.c_str());
135
136   if (resetfile) {
137     resetfile >> U;
138     resetfile >> V;
139     resetfile >> W;
140     resetfile >> latitude;
141     resetfile >> longitude;
142     resetfile >> phi;
143     resetfile >> tht;
144     resetfile >> psi;
145     resetfile >> h;
146     resetfile.close();
147
148     Initialize(U, V, W, phi*DEGTORAD, tht*DEGTORAD, psi*DEGTORAD,
149                latitude*DEGTORAD, longitude*DEGTORAD, h);
150
151     return true;
152   } else {
153     cerr << "Unable to load reset file " << fname << endl;
154     return false;
155   }
156 }
157
158 //***************************************************************************
159 //
160 // Initialize: Assume all angles GIVEN IN RADIANS !!
161 //
162
163 void FGState::Initialize(float U, float V, float W,
164                          float phi, float tht, float psi,
165                          float Latitude, float Longitude, float H)
166 {
167   FGColumnVector vUVW(3);
168   FGColumnVector vEuler(3);
169   float alpha, beta, gamma;
170
171   latitude = Latitude;
172   longitude = Longitude;
173   h = H;
174   FDMExec->GetAtmosphere()->Run();
175
176   gamma = 0.0;
177   if (W != 0.0)
178     alpha = U*U > 0.0 ? atan2(W, U) : 0.0;
179   else
180     alpha = 0.0;
181   if (V != 0.0)
182     beta = U*U+W*W > 0.0 ? atan2(V, (fabs(U)/U)*sqrt(U*U + W*W)) : 0.0;
183   else
184     beta = 0.0;
185
186   vUVW << U << V << W;
187   FDMExec->GetTranslation()->SetUVW(vUVW);
188   vEuler << phi << tht << psi;
189   FDMExec->GetRotation()->SetEuler(vEuler);
190   FDMExec->GetTranslation()->SetABG(alpha, beta, gamma);
191
192   Vt = sqrt(U*U + V*V + W*W);
193   qbar = 0.5*(U*U + V*V + W*W)*FDMExec->GetAtmosphere()->GetDensity();
194
195   InitMatrices(phi, tht, psi);
196 }
197
198 /******************************************************************************/
199
200 void FGState::Initialize(FGInitialCondition *FGIC)
201 {
202
203   float tht,psi,phi;
204   float U,V,W;
205
206   latitude = FGIC->GetLatitudeRadIC();
207   longitude = FGIC->GetLongitudeRadIC();
208   h = FGIC->GetAltitudeFtIC();
209   U = FGIC->GetUBodyFpsIC();
210   V = FGIC->GetVBodyFpsIC();
211   W = FGIC->GetWBodyFpsIC();
212   tht = FGIC->GetThetaRadIC();
213   phi = FGIC->GetPhiRadIC();
214   psi = FGIC->GetPsiRadIC();
215
216   Initialize(U, V, W, phi, tht, psi, latitude, longitude, h);
217 }
218
219 /******************************************************************************/
220
221 bool FGState::StoreData(string fname)
222 {
223   ofstream datafile(fname.c_str());
224
225   if (datafile) {
226     datafile << (FDMExec->GetTranslation()->GetUVW())(1);
227     datafile << (FDMExec->GetTranslation()->GetUVW())(2);
228     datafile << (FDMExec->GetTranslation()->GetUVW())(3);
229     datafile << latitude;
230     datafile << longitude;
231     datafile << (FDMExec->GetRotation()->GetEuler())(1);
232     datafile << (FDMExec->GetRotation()->GetEuler())(2);
233     datafile << (FDMExec->GetRotation()->GetEuler())(3);
234     datafile << h;
235     datafile.close();
236     return true;
237   } else {
238     cerr << "Could not open dump file " << fname << endl;
239     return false;
240   }
241 }
242
243 /******************************************************************************/
244
245 float FGState::GetParameter(string val_string)
246 {
247   return GetParameter(coeffdef[val_string]);
248 }
249
250 /******************************************************************************/
251
252 int FGState::GetParameterIndex(string val_string)
253 {
254   return coeffdef[val_string];
255 }
256
257 /******************************************************************************/
258 //
259 // NEED WORK BELOW TO ADD NEW PARAMETERS !!!
260 //
261 float FGState::GetParameter(int val_idx)
262 {
263   switch(val_idx) {
264   case FG_QBAR:
265     return Getqbar();
266   case FG_WINGAREA:
267     return FDMExec->GetAircraft()->GetWingArea();
268   case FG_WINGSPAN:
269     return FDMExec->GetAircraft()->GetWingSpan();
270   case FG_CBAR:
271     return FDMExec->GetAircraft()->Getcbar();
272   case FG_ALPHA:
273     return FDMExec->GetTranslation()->Getalpha();
274   case FG_ALPHADOT:
275     return Getadot();
276   case FG_BETA:
277     return FDMExec->GetTranslation()->Getbeta();
278   case FG_BETADOT:
279     return Getbdot();
280   case FG_PITCHRATE:
281     return (FDMExec->GetRotation()->GetPQR())(2);
282   case FG_ROLLRATE:
283     return (FDMExec->GetRotation()->GetPQR())(1);
284   case FG_YAWRATE:
285     return (FDMExec->GetRotation()->GetPQR())(3);
286   case FG_ELEVATOR_POS:
287     return FDMExec->GetFCS()->GetDePos();
288   case FG_AILERON_POS:
289     return FDMExec->GetFCS()->GetDaPos();
290   case FG_RUDDER_POS:
291     return FDMExec->GetFCS()->GetDrPos();
292   case FG_SPDBRAKE_POS:
293     return FDMExec->GetFCS()->GetDsbPos();
294   case FG_SPOILERS_POS:
295     return FDMExec->GetFCS()->GetDspPos();
296   case FG_FLAPS_POS:
297     return FDMExec->GetFCS()->GetDfPos();
298   case FG_ELEVATOR_CMD:
299     return FDMExec->GetFCS()->GetDeCmd();
300   case FG_AILERON_CMD:
301     return FDMExec->GetFCS()->GetDaCmd();
302   case FG_RUDDER_CMD:
303     return FDMExec->GetFCS()->GetDrCmd();
304   case FG_SPDBRAKE_CMD:
305     return FDMExec->GetFCS()->GetDsbCmd();
306   case FG_SPOILERS_CMD:
307     return FDMExec->GetFCS()->GetDspCmd();
308   case FG_FLAPS_CMD:
309     return FDMExec->GetFCS()->GetDfCmd();
310   case FG_MACH:
311     return GetMach();
312   case FG_ALTITUDE:
313     return Geth();
314   case FG_BI2VEL:
315     return FDMExec->GetAircraft()->GetWingSpan()/(2.0 * GetVt());
316   case FG_CI2VEL:
317     return FDMExec->GetAircraft()->Getcbar()/(2.0 * GetVt());
318   }
319   return 0;
320 }
321
322 /******************************************************************************/
323
324 void FGState::SetParameter(int val_idx, float val)
325 {
326   switch(val_idx) {
327   case FG_ELEVATOR_POS:
328     FDMExec->GetFCS()->SetDePos(val);
329     break;
330   case FG_AILERON_POS:
331     FDMExec->GetFCS()->SetDaPos(val);
332     break;
333   case FG_RUDDER_POS:
334     FDMExec->GetFCS()->SetDrPos(val);
335     break;
336   case FG_SPDBRAKE_POS:
337     FDMExec->GetFCS()->SetDrPos(val);
338     break;
339   case FG_SPOILERS_POS:
340     FDMExec->GetFCS()->SetDrPos(val);
341     break;
342   case FG_FLAPS_POS:
343     FDMExec->GetFCS()->SetDrPos(val);
344     break;
345   }
346 }
347
348 /******************************************************************************/
349
350 void FGState::InitMatrices(float phi, float tht, float psi)
351 {
352   float thtd2, psid2, phid2;
353   float Sthtd2, Spsid2, Sphid2;
354   float Cthtd2, Cpsid2, Cphid2;
355   float Cphid2Cthtd2;
356   float Cphid2Sthtd2;
357   float Sphid2Sthtd2;
358   float Sphid2Cthtd2;
359
360   thtd2 = tht/2.0;
361   psid2 = psi/2.0;
362   phid2 = phi/2.0;
363
364   Sthtd2 = sin(thtd2);
365   Spsid2 = sin(psid2);
366   Sphid2 = sin(phid2);
367
368   Cthtd2 = cos(thtd2);
369   Cpsid2 = cos(psid2);
370   Cphid2 = cos(phid2);
371
372   Cphid2Cthtd2 = Cphid2*Cthtd2;
373   Cphid2Sthtd2 = Cphid2*Sthtd2;
374   Sphid2Sthtd2 = Sphid2*Sthtd2;
375   Sphid2Cthtd2 = Sphid2*Cthtd2;
376
377   vQtrn(1) = Cphid2Cthtd2*Cpsid2 + Sphid2Sthtd2*Spsid2;
378   vQtrn(2) = Sphid2Cthtd2*Cpsid2 - Cphid2Sthtd2*Spsid2;
379   vQtrn(3) = Cphid2Sthtd2*Cpsid2 + Sphid2Cthtd2*Spsid2;
380   vQtrn(4) = Cphid2Cthtd2*Spsid2 - Sphid2Sthtd2*Cpsid2;
381
382   CalcMatrices();
383 }
384
385 /******************************************************************************/
386
387 void FGState::CalcMatrices(void)
388 {
389   float Q0Q0, Q1Q1, Q2Q2, Q3Q3;
390   float Q0Q1, Q0Q2, Q0Q3, Q1Q2;
391   float Q1Q3, Q2Q3;
392
393   Q0Q0 = vQtrn(1)*vQtrn(1);
394   Q1Q1 = vQtrn(2)*vQtrn(2);
395   Q2Q2 = vQtrn(3)*vQtrn(3);
396   Q3Q3 = vQtrn(4)*vQtrn(4);
397   Q0Q1 = vQtrn(1)*vQtrn(2);
398   Q0Q2 = vQtrn(1)*vQtrn(3);
399   Q0Q3 = vQtrn(1)*vQtrn(4);
400   Q1Q2 = vQtrn(2)*vQtrn(3);
401   Q1Q3 = vQtrn(2)*vQtrn(4);
402   Q2Q3 = vQtrn(3)*vQtrn(4);
403
404   mTb2l(1,1) = Q0Q0 + Q1Q1 - Q2Q2 - Q3Q3;
405   mTb2l(1,2) = 2*(Q1Q2 + Q0Q3);
406   mTb2l(1,3) = 2*(Q1Q3 - Q0Q2);
407   mTb2l(2,1) = 2*(Q1Q2 - Q0Q3);
408   mTb2l(2,2) = Q0Q0 - Q1Q1 + Q2Q2 - Q3Q3;
409   mTb2l(2,3) = 2*(Q2Q3 + Q0Q1);
410   mTb2l(3,1) = 2*(Q1Q3 + Q0Q2);
411   mTb2l(3,2) = 2*(Q2Q3 - Q0Q1);
412   mTb2l(3,3) = Q0Q0 - Q1Q1 - Q2Q2 + Q3Q3;
413
414   mTl2b = mTb2l;
415   mTl2b.T();
416 }
417
418 /******************************************************************************/
419
420 void FGState::IntegrateQuat(FGColumnVector vPQR, int rate)
421 {
422   static FGColumnVector vlastQdot(4);
423   static FGColumnVector vQdot(4);
424
425   vQdot(1) = -0.5*(vQtrn(2)*vPQR(eP) + vQtrn(3)*vPQR(eQ) + vQtrn(4)*vPQR(eR));
426   vQdot(2) =  0.5*(vQtrn(1)*vPQR(eP) + vQtrn(3)*vPQR(eR) - vQtrn(4)*vPQR(eQ));
427   vQdot(3) =  0.5*(vQtrn(1)*vPQR(eQ) + vQtrn(4)*vPQR(eP) - vQtrn(2)*vPQR(eR));
428   vQdot(4) =  0.5*(vQtrn(1)*vPQR(eR) + vQtrn(2)*vPQR(eQ) - vQtrn(3)*vPQR(eP));
429
430   vQtrn += 0.5*dt*rate*(vlastQdot + vQdot);
431
432   vQtrn.Normalize();
433
434   vlastQdot = vQdot;
435 }
436
437 /******************************************************************************/
438
439 FGColumnVector FGState::CalcEuler(void)
440 {
441   static FGColumnVector vEuler(3);
442
443   if (mTb2l(3,3) == 0)    vEuler(ePhi) = 0.0;
444   else                    vEuler(ePhi) = atan2(mTb2l(2,3), mTb2l(3,3));
445
446   vEuler(eTht) = asin(-mTb2l(1,3));
447
448   if (mTb2l(1,1) == 0.0)  vEuler(ePsi) = 0.0;
449   else                    vEuler(ePsi) = atan2(mTb2l(1,2), mTb2l(1,1));
450
451   if (vEuler(ePsi) < 0.0) vEuler(ePsi) += 2*M_PI;
452
453   return vEuler;
454 }
455
456 /******************************************************************************/
457
458 FGMatrix FGState::GetTs2b(float alpha, float beta)
459 {
460   float ca, cb, sa, sb;
461
462   ca = cos(alpha);
463   sa = sin(alpha);
464   cb = cos(beta);
465   sb = sin(beta);
466
467   mTs2b(1,1) = -ca*cb;
468   mTs2b(1,2) = -ca*sb;
469   mTs2b(1,3) = sa;
470   mTs2b(2,1) = sb;
471   mTs2b(2,2) = cb;
472   mTs2b(2,3) = 0.0;
473   mTs2b(3,1) = -sa*cb;
474   mTs2b(3,2) = -sa*sb;
475   mTs2b(3,3) = -ca;
476
477   return mTs2b;
478 }
479
480 /******************************************************************************/
481