1 /*******************************************************************************
3 Header: FGInitialCondition.h
7 ------------- Copyright (C) 1999 Anthony K. Peden (apeden@earthlink.net) -------------
9 This program is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free Software
11 Foundation; either version 2 of the License, or (at your option) any later
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19 You should have received a copy of the GNU General Public License along with
20 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21 Place - Suite 330, Boston, MA 02111-1307, USA.
23 Further information about the GNU General Public License can also be found on
24 the world wide web at http://www.gnu.org.
28 --------------------------------------------------------------------------------
32 FUNCTIONAL DESCRIPTION
33 --------------------------------------------------------------------------------
35 The purpose of this class is to take a set of initial conditions and provide
36 a kinematically consistent set of body axis velocity components, euler
37 angles, and altitude. This class does not attempt to trim the model i.e.
38 the sim will most likely start in a very dynamic state (unless, of course,
39 you have chosen your IC's wisely) even after setting it up with this class.
41 ********************************************************************************
43 *******************************************************************************/
45 #ifndef FGINITIALCONDITION_H
46 #define FGINITIALCONDITION_H
48 /*******************************************************************************
50 *******************************************************************************/
52 #include "FGFDMExec.h"
53 #include "FGAtmosphere.h"
56 #define ID_INITIALCONDITION "$Header"
58 /*******************************************************************************
60 *******************************************************************************/
62 typedef enum { setvt, setvc, setve, setmach, setuvw, setned } speedset;
64 #define jsbFPSTOKTS 0.5924838
65 #define jsbKTSTOFPS 1.6878099
69 With a valid object of FGFDMExec and an aircraft model loaded
70 FGInitialCondition fgic=new FGInitialCondition(FDMExec);
71 fgic->SetVcalibratedKtsIC()
72 fgic->SetAltitudeFtIC();
76 //to directly into Run
77 FDMExec->GetState()->Initialize(fgic)
81 //or to loop the sim w/o integrating
87 Since vc, ve, vt, and mach all represent speed, the remaining
88 three are recalculated each time one of them is set (using the
89 current altitude). The most recent speed set is remembered so
90 that if and when altitude is reset, the last set speed is used
91 to recalculate the remaining three. Setting any of the body
92 components forces a recalculation of vt and vt then becomes the
93 most recent speed set.
95 Alpha,Gamma, and Theta:
96 This class assumes that it will be used to set up the sim for a
97 steady, zero pitch rate condition. Since any two of those angles
98 specifies the third gamma (flight path angle) is favored when setting
99 alpha and theta and alpha is favored when setting gamma. i.e.
100 set alpha : recalculate theta using gamma as currently set
101 set theta : recalculate alpha using gamma as currently set
102 set gamma : recalculate theta using alpha as currently set
104 The idea being that gamma is most interesting to pilots (since it
105 is indicative of climb rate).
107 Setting climb rate is, for the purpose of this discussion,
108 considered equivalent to setting gamma.
111 class FGInitialCondition {
114 FGInitialCondition(FGFDMExec *fdmex);
115 ~FGInitialCondition(void);
117 inline speedset GetSpeedSet(void) { return lastSpeedSet; }
119 void SetVcalibratedKtsIC(float tt);
120 void SetVequivalentKtsIC(float tt);
121 inline void SetVtrueKtsIC(float tt) { SetVtrueFpsIC(tt*jsbKTSTOFPS); }
122 void SetVtrueFpsIC(float tt);
123 void SetMachIC(float tt);
125 void SetUBodyFpsIC(float tt);
126 void SetVBodyFpsIC(float tt);
127 void SetWBodyFpsIC(float tt);
129 void SetVnorthFpsIC(float tt);
130 void SetVeastFpsIC(float tt);
131 void SetVdownFpsIC(float tt);
133 void SetAltitudeFtIC(float tt);
134 void SetAltitudeAGLFtIC(float tt);
136 void SetSeaLevelRadiusFtIC(double tt);
137 void SetTerrainAltitudeFtIC(double tt);
139 //"vertical" flight path, recalculate theta
140 inline void SetFlightPathAngleDegIC(float tt) { SetFlightPathAngleRadIC(tt*DEGTORAD); }
141 void SetFlightPathAngleRadIC(float tt);
143 void SetClimbRateFpmIC(float tt);
144 void SetClimbRateFpsIC(float tt);
145 //use currently stored gamma, recalcualte theta
146 inline void SetAlphaDegIC(float tt) { alpha=tt*DEGTORAD; getTheta(); }
147 inline void SetAlphaRadIC(float tt) { alpha=tt; getTheta(); }
148 //use currently stored gamma, recalcualte alpha
149 inline void SetPitchAngleDegIC(float tt) { theta=tt*DEGTORAD; getAlpha(); }
150 inline void SetPitchAngleRadIC(float tt) { theta=tt; getAlpha(); }
152 inline void SetBetaDegIC(float tt) { beta=tt*DEGTORAD; getTheta();}
153 inline void SetBetaRadIC(float tt) { beta=tt; getTheta(); }
155 inline void SetRollAngleDegIC(float tt) { phi=tt*DEGTORAD; getTheta(); }
156 inline void SetRollAngleRadIC(float tt) { phi=tt; getTheta(); }
158 inline void SetTrueHeadingDegIC(float tt) { psi=tt*DEGTORAD; }
159 inline void SetTrueHeadingRadIC(float tt) { psi=tt; }
161 inline void SetLatitudeDegIC(float tt) { latitude=tt*DEGTORAD; }
162 inline void SetLatitudeRadIC(float tt) { latitude=tt; }
164 inline void SetLongitudeDegIC(float tt) { longitude=tt*DEGTORAD; }
165 inline void SetLongitudeRadIC(float tt) { longitude=tt; }
167 inline float GetVcalibratedKtsIC(void) { return vc*jsbFPSTOKTS; }
168 inline float GetVequivalentKtsIC(void) { return ve*jsbFPSTOKTS; }
169 inline float GetVtrueKtsIC(void) { return vt*jsbFPSTOKTS; }
170 inline float GetVtrueFpsIC(void) { return vt; }
171 inline float GetMachIC(void) { return mach; }
173 inline float GetAltitudeFtIC(void) { return altitude; }
174 inline float GetAltitudeAGLFtIC(void) { return altitude - terrain_altitude; }
176 inline float GetFlightPathAngleDegIC(void) { return gamma*RADTODEG; }
177 inline float GetFlightPathAngleRadIC(void) { return gamma; }
179 inline float GetClimbRateFpmIC(void) { return hdot*60; }
180 inline float GetClimbRateFpsIC(void) { return hdot; }
182 inline float GetAlphaDegIC(void) { return alpha*RADTODEG; }
183 inline float GetAlphaRadIC(void) { return alpha; }
185 inline float GetPitchAngleDegIC(void) { return theta*RADTODEG; }
186 inline float GetPitchAngleRadIC(void) { return theta; }
189 inline float GetBetaDegIC(void) { return beta*RADTODEG; }
190 inline float GetBetaRadIC(void) { return beta*RADTODEG; }
192 inline float GetRollAngleDegIC(void) { return phi*RADTODEG; }
193 inline float GetRollAngleRadIC(void) { return phi; }
195 inline float GetHeadingDegIC(void) { return psi*RADTODEG; }
196 inline float GetHeadingRadIC(void) { return psi; }
198 inline float GetLatitudeDegIC(void) { return latitude*RADTODEG; }
199 inline float GetLatitudeRadIC(void) { return latitude; }
201 inline float GetLongitudeDegIC(void) { return longitude*RADTODEG; }
202 inline float GetLongitudeRadIC(void) { return longitude; }
204 inline float GetUBodyFpsIC(void) { return vt*cos(alpha)*cos(beta); }
205 inline float GetVBodyFpsIC(void) { return vt*sin(beta); }
206 inline float GetWBodyFpsIC(void) { return vt*sin(alpha)*cos(beta); }
208 inline float GetThetaRadIC(void) { return theta; }
209 inline float GetPhiRadIC(void) { return phi; }
210 inline float GetPsiRadIC(void) { return psi; }
212 inline float GetSeaLevelRadiusFtIC(void) { return sea_level_radius; }
213 inline float GetTerrainAltitudeFtIC(void) { return terrain_altitude; }
219 float alpha,beta,gamma,theta,phi,psi;
222 float latitude,longitude;
224 float vnorth,veast,vdown;
225 double sea_level_radius;
226 double terrain_altitude;
227 double radius_to_vehicle;
229 float xlo, xhi,xmin,xmax;
231 typedef float (FGInitialCondition::*fp)(float x);
234 speedset lastSpeedSet;
241 bool getMachFromVcas(float *Mach,float vcas);
243 float GammaEqOfTheta(float Theta);
244 float GammaEqOfAlpha(float Alpha);
245 float calcVcas(float Mach);
246 void calcUVWfromNED(void);
248 bool findInterval(float x,float guess);
249 bool solve(float *y, float x);