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 void SetVtrueKtsIC(float tt);
122 void SetMachIC(float tt);
124 void SetUBodyFpsIC(float tt);
125 void SetVBodyFpsIC(float tt);
126 void SetWBodyFpsIC(float tt);
128 void SetVnorthFpsIC(float tt);
129 void SetVeastFpsIC(float tt);
130 void SetVdownFpsIC(float tt);
132 void SetAltitudeFtIC(float tt);
133 void SetAltitudeAGLFtIC(float tt);
135 void SetSeaLevelRadiusFtIC(double tt);
136 void SetTerrainAltitudeFtIC(double tt);
138 //"vertical" flight path, recalculate theta
139 inline void SetFlightPathAngleDegIC(float tt) { SetFlightPathAngleRadIC(tt*DEGTORAD); }
140 void SetFlightPathAngleRadIC(float tt);
142 void SetClimbRateFpmIC(float tt);
143 void SetClimbRateFpsIC(float tt);
144 //use currently stored gamma, recalcualte theta
145 inline void SetAlphaDegIC(float tt) { alpha=tt*DEGTORAD; getTheta(); }
146 inline void SetAlphaRadIC(float tt) { alpha=tt; getTheta(); }
147 //use currently stored gamma, recalcualte alpha
148 inline void SetPitchAngleDegIC(float tt) { theta=tt*DEGTORAD; getAlpha(); }
149 inline void SetPitchAngleRadIC(float tt) { theta=tt; getAlpha(); }
151 inline void SetBetaDegIC(float tt) { beta=tt*DEGTORAD; getTheta();}
152 inline void SetBetaRadIC(float tt) { beta=tt; getTheta(); }
154 inline void SetRollAngleDegIC(float tt) { phi=tt*DEGTORAD; getTheta(); }
155 inline void SetRollAngleRadIC(float tt) { phi=tt; getTheta(); }
157 inline void SetTrueHeadingDegIC(float tt) { psi=tt*DEGTORAD; }
158 inline void SetTrueHeadingRadIC(float tt) { psi=tt; }
160 inline void SetLatitudeDegIC(float tt) { latitude=tt*DEGTORAD; }
161 inline void SetLatitudeRadIC(float tt) { latitude=tt; }
163 inline void SetLongitudeDegIC(float tt) { longitude=tt*DEGTORAD; }
164 inline void SetLongitudeRadIC(float tt) { longitude=tt; }
166 inline float GetVcalibratedKtsIC(void) { return vc*jsbFPSTOKTS; }
167 inline float GetVequivalentKtsIC(void) { return ve*jsbFPSTOKTS; }
168 inline float GetVtrueKtsIC(void) { return vt*jsbFPSTOKTS; }
169 inline float GetVtrueFpsIC(void) { return vt; }
170 inline float GetMachIC(void) { return mach; }
172 inline float GetAltitudeFtIC(void) { return altitude; }
174 inline float GetFlightPathAngleDegIC(void) { return gamma*RADTODEG; }
175 inline float GetFlightPathAngleRadIC(void) { return gamma; }
177 inline float GetClimbRateFpmIC(void) { return hdot*60; }
178 inline float GetClimbRateFpsIC(void) { return hdot; }
180 inline float GetAlphaDegIC(void) { return alpha*RADTODEG; }
181 inline float GetAlphaRadIC(void) { return alpha; }
183 inline float GetPitchAngleDegIC(void) { return theta*RADTODEG; }
184 inline float GetPitchAngleRadIC(void) { return theta; }
187 inline float GetBetaDegIC(void) { return beta*RADTODEG; }
188 inline float GetBetaRadIC(void) { return beta*RADTODEG; }
190 inline float GetRollAngleDegIC(void) { return phi*RADTODEG; }
191 inline float GetRollAngleRadIC(void) { return phi; }
193 inline float GetHeadingDegIC(void) { return psi*RADTODEG; }
194 inline float GetHeadingRadIC(void) { return psi; }
196 inline float GetLatitudeDegIC(void) { return latitude*RADTODEG; }
197 inline float GetLatitudeRadIC(void) { return latitude; }
199 inline float GetLongitudeDegIC(void) { return longitude*RADTODEG; }
200 inline float GetLongitudeRadIC(void) { return longitude; }
202 inline float GetUBodyFpsIC(void) { return vt*cos(alpha)*cos(beta); }
203 inline float GetVBodyFpsIC(void) { return vt*sin(beta); }
204 inline float GetWBodyFpsIC(void) { return vt*sin(alpha)*cos(beta); }
206 inline float GetThetaRadIC(void) { return theta; }
207 inline float GetPhiRadIC(void) { return phi; }
208 inline float GetPsiRadIC(void) { return psi; }
214 float alpha,beta,gamma,theta,phi,psi;
217 float latitude,longitude;
219 float vnorth,veast,vdown;
220 double sea_level_radius;
221 double terrain_altitude;
222 double radius_to_vehicle;
224 float xlo, xhi,xmin,xmax;
226 typedef float (FGInitialCondition::*fp)(float x);
229 speedset lastSpeedSet;
236 bool getMachFromVcas(float *Mach,float vcas);
238 float GammaEqOfTheta(float Theta);
239 float GammaEqOfAlpha(float Alpha);
240 float calcVcas(float Mach);
241 void calcUVWfromNED(void);
243 bool findInterval(float x,float guess);
244 bool solve(float *y, float x);