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 } speedset;
66 With a valid object of FGFDMExec and an aircraft model loaded
67 FGInitialCondition fgic=new FGInitialCondition(FDMExec);
68 fgic->SetVcalibratedKtsIC()
69 fgic->SetAltitudeFtIC();
73 //to directly into Run
74 FDMExec->GetState()->Initialize(fgic)
78 //or to loop the sim w/o integrating
84 Since vc, ve, vt, and mach all represent speed, the remaining
85 three are recalculated each time one of them is set (using the
86 current altitude). The most recent speed set is remembered so
87 that if and when altitude is reset, the last set speed is used
88 to recalculate the remaining three. Setting any of the body
89 components forces a recalculation of vt and vt then becomes the
90 most recent speed set.
92 Alpha,Gamma, and Theta:
93 This class assumes that it will be used to set up the sim for a
94 steady, zero pitch rate condition. Since any two of those angles
95 specifies the third gamma (flight path angle) is favored when setting
96 alpha and theta and alpha is favored when setting gamma. i.e.
97 set alpha : recalculate theta using gamma as currently set
98 set theta : recalculate alpha using gamma as currently set
99 set gamma : recalculate theta using alpha as currently set
101 The idea being that gamma is most interesting to pilots (since it
102 is indicative of climb rate).
104 Setting climb rate is, for the purpose of this discussion,
105 considered equivalent to setting gamma.
109 class FGInitialCondition {
112 FGInitialCondition(FGFDMExec *fdmex);
113 ~FGInitialCondition(void);
115 void SetVcalibratedKtsIC(float tt);
116 void SetVequivalentKtsIC(float tt);
117 void SetVtrueKtsIC(float tt);
118 void SetMachIC(float tt);
120 void SetUBodyFpsIC(float tt);
121 void SetVBodyFpsIC(float tt);
122 void SetWBodyFpsIC(float tt);
124 void SetVnorthFpsIC(float tt);
125 void SetVeastFpsIC(float tt);
126 void SetVdownFpsIC(float tt);
128 void SetAltitudeFtIC(float tt);
129 void SetAltitudeAGLFtIC(float tt);
131 //"vertical" flight path, recalculate theta
132 inline void SetFlightPathAngleDegIC(float tt) { SetFlightPathAngleRadIC(tt*DEGTORAD); }
133 void SetFlightPathAngleRadIC(float tt);
135 void SetClimbRateFpmIC(float tt);
136 void SetClimbRateFpsIC(float tt);
137 //use currently stored gamma, recalcualte theta
138 inline void SetAlphaDegIC(float tt) { alpha=tt*DEGTORAD; getTheta(); }
139 inline void SetAlphaRadIC(float tt) { alpha=tt; getTheta(); }
140 //use currently stored gamma, recalcualte alpha
141 inline void SetPitchAngleDegIC(float tt) { theta=tt*DEGTORAD; getAlpha(); }
142 inline void SetPitchAngleRadIC(float tt) { theta=tt; getAlpha(); }
144 inline void SetBetaDegIC(float tt) { beta=tt*DEGTORAD; getTheta();}
145 inline void SetBetaRadIC(float tt) { beta=tt; getTheta(); }
147 inline void SetRollAngleDegIC(float tt) { phi=tt*DEGTORAD; getTheta(); }
148 inline void SetRollAngleRadIC(float tt) { phi=tt; getTheta(); }
150 inline void SetHeadingDegIC(float tt) { psi=tt*DEGTORAD; }
151 inline void SetHeadingRadIC(float tt) { psi=tt; }
153 inline void SetLatitudeDegIC(float tt) { latitude=tt*DEGTORAD; }
154 inline void SetLatitudeRadIC(float tt) { latitude=tt; }
156 inline void SetLongitudeDegIC(float tt) { longitude=tt*DEGTORAD; }
157 inline void SetLongitudeRadIC(float tt) { longitude=tt; }
159 inline float GetVcalibratedKtsIC(void) { return vc*FPSTOKTS; }
160 inline float GetVequivalentKtsIC(void) { return ve*FPSTOKTS; }
161 inline float GetVtrueKtsIC(void) { return vt*FPSTOKTS; }
162 inline float GetVtrueFpsIC(void) { return vt; }
163 inline float GetMachIC(void) { return mach; }
165 inline float GetAltitudeFtIC(void) { return altitude; }
167 inline float GetFlightPathAngleDegIC(void) { return gamma*RADTODEG; }
168 inline float GetFlightPathAngleRadIC(void) { return gamma; }
170 inline float GetClimbRateFpmIC(void) { return hdot*60; }
171 inline float GetClimbRateFpsIC(void) { return hdot; }
173 inline float GetAlphaDegIC(void) { return alpha*RADTODEG; }
174 inline float GetAlphaRadIC(void) { return alpha; }
176 inline float GetPitchAngleDegIC(void) { return theta*RADTODEG; }
177 inline float GetPitchAngleRadIC(void) { return theta; }
180 inline float GetBetaDegIC(void) { return beta*RADTODEG; }
181 inline float GetBetaRadIC(void) { return beta*RADTODEG; }
183 inline float GetRollAngleDegIC(void) { return phi*RADTODEG; }
184 inline float GetRollAngleRadIC(void) { return phi; }
186 inline float GetHeadingDegIC(void) { return psi*RADTODEG; }
187 inline float GetHeadingRadIC(void) { return psi; }
189 inline float GetLatitudeDegIC(void) { return latitude*RADTODEG; }
190 inline float GetLatitudeRadIC(void) { return latitude; }
192 inline float GetLongitudeDegIC(void) { return longitude*RADTODEG; }
193 inline float GetLongitudeRadIC(void) { return longitude; }
195 inline float GetUBodyFpsIC(void) { return vt*cos(alpha)*cos(beta); }
196 inline float GetVBodyFpsIC(void) { return vt*sin(beta); }
197 inline float GetWBodyFpsIC(void) { return vt*sin(alpha)*cos(beta); }
199 inline float GetThetaRadIC(void) { return theta; }
200 inline float GetPhiRadIC(void) { return phi; }
201 inline float GetPsiRadIC(void) { return psi; }
207 float alpha,beta,gamma,theta,phi,psi;
210 float latitude,longitude;
212 float vnorth,veast,vdown;
214 float xlo, xhi,xmin,xmax;
216 typedef float (FGInitialCondition::*fp)(float x);
219 speedset lastSpeedSet;
226 bool getMachFromVcas(float *Mach,float vcas);
228 float GammaEqOfTheta(float Theta);
229 float GammaEqOfAlpha(float Alpha);
230 float calcVcas(float Mach);
231 void calcUVWfromNED(void);
233 bool findInterval(float x,float guess);
234 bool solve(float *y, float x);