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 /*******************************************************************************
58 *******************************************************************************/
60 typedef enum { setvt, setvc, setve, setmach } speedset;
64 With a valid object of FGFDMExec and an aircraft model loaded
65 FGInitialCondition fgic=new FGInitialCondition(FDMExec);
66 fgic->SetVcalibratedKtsIC()
67 fgic->SetAltitudeFtIC();
71 //to directly into Run
72 FDMExec->GetState()->Initialize(fgic)
76 //or to loop the sim w/o integrating
82 Since vc, ve, vt, and mach all represent speed, the remaining
83 three are recalculated each time one of them is set (using the
84 current altitude). The most recent speed set is remembered so
85 that if and when altitude is reset, the last set speed is used
86 to recalculate the remaining three. Setting any of the body
87 components forces a recalculation of vt and vt then becomes the
88 most recent speed set.
90 Alpha,Gamma, and Theta:
91 This class assumes that it will be used to set up the sim for a
92 steady, zero pitch rate condition. Since any two of those angles
93 specifies the third gamma (flight path angle) is favored when setting
94 alpha and theta and alpha is favored when setting gamma. i.e.
95 set alpha : recalculate theta using gamma as currently set
96 set theta : recalculate alpha using gamma as currently set
97 set gamma : recalculate theta using alpha as currently set
99 The idea being that gamma is most interesting to pilots (since it
100 is indicative of climb rate).
102 Setting climb rate is, for the purpose of this discussion,
103 considered equivalent to setting gamma.
107 class FGInitialCondition {
110 FGInitialCondition(FGFDMExec *fdmex);
111 ~FGInitialCondition(void);
113 void SetVcalibratedKtsIC(float tt);
114 void SetVequivalentKtsIC(float tt);
115 void SetVtrueKtsIC(float tt);
116 void SetMachIC(float tt);
118 void SetUBodyFpsIC(float tt);
119 void SetVBodyFpsIC(float tt);
120 void SetWBodyFpsIC(float tt);
122 void SetVnorthFpsIC(float tt);
123 void SetVeastFpsIC(float tt);
124 void SetVdownFpsIC(float tt);
126 void SetAltitudeFtIC(float tt);
127 void SetAltitudeAGLFtIC(float tt);
129 //"vertical" flight path, recalculate theta
130 inline void SetFlightPathAngleDegIC(float tt) { SetFlightPathAngleRadIC(tt*DEGTORAD); }
131 void SetFlightPathAngleRadIC(float tt);
133 void SetClimbRateFpmIC(float tt);
134 void SetClimbRateFpsIC(float tt);
135 //use currently stored gamma, recalcualte theta
136 inline void SetAlphaDegIC(float tt) { alpha=tt*DEGTORAD; getTheta(); }
137 inline void SetAlphaRadIC(float tt) { alpha=tt; getTheta(); }
138 //use currently stored gamma, recalcualte alpha
139 inline void SetPitchAngleDegIC(float tt) { theta=tt*DEGTORAD; getAlpha(); }
140 inline void SetPitchAngleRadIC(float tt) { theta=tt; getAlpha(); }
142 inline void SetBetaDegIC(float tt) { beta=tt*DEGTORAD; getTheta();}
143 inline void SetBetaRadIC(float tt) { beta=tt; getTheta(); }
145 inline void SetRollAngleDegIC(float tt) { phi=tt*DEGTORAD; getTheta(); }
146 inline void SetRollAngleRadIC(float tt) { phi=tt; getTheta(); }
148 inline void SetHeadingDegIC(float tt) { psi=tt*DEGTORAD; }
149 inline void SetHeadingRadIC(float tt) { psi=tt; }
151 inline void SetLatitudeDegIC(float tt) { latitude=tt*DEGTORAD; }
152 inline void SetLatitudeRadIC(float tt) { latitude=tt; }
154 inline void SetLongitudeDegIC(float tt) { longitude=tt*DEGTORAD; }
155 inline void SetLongitudeRadIC(float tt) { longitude=tt; }
157 inline float GetVcalibratedKtsIC(void) { return vc*FPSTOKTS; }
158 inline float GetVequivalentKtsIC(void) { return ve*FPSTOKTS; }
159 inline float GetVtrueKtsIC(void) { return vt*FPSTOKTS; }
160 inline float GetVtrueFpsIC(void) { return vt; }
161 inline float GetMachIC(void) { return mach; }
163 inline float GetAltitudeFtIC(void) { return altitude; }
165 inline float GetFlightPathAngleDegIC(void) { return gamma*RADTODEG; }
166 inline float GetFlightPathAngleRadIC(void) { return gamma; }
168 inline float GetClimbRateFpmIC(void) { return hdot*60; }
169 inline float GetClimbRateFpsIC(void) { return hdot; }
171 inline float GetAlphaDegIC(void) { return alpha*RADTODEG; }
172 inline float GetAlphaRadIC(void) { return alpha; }
174 inline float GetPitchAngleDegIC(void) { return theta*RADTODEG; }
175 inline float GetPitchAngleRadIC(void) { return theta; }
178 inline float GetBetaDegIC(void) { return beta*RADTODEG; }
179 inline float GetBetaRadIC(void) { return beta*RADTODEG; }
181 inline float GetRollAngleDegIC(void) { return phi*RADTODEG; }
182 inline float GetRollAngleRadIC(void) { return phi; }
184 inline float GetHeadingDegIC(void) { return psi*RADTODEG; }
185 inline float GetHeadingRadIC(void) { return psi; }
187 inline float GetLatitudeDegIC(void) { return latitude*RADTODEG; }
188 inline float GetLatitudeRadIC(void) { return latitude; }
190 inline float GetLongitudeDegIC(void) { return longitude*RADTODEG; }
191 inline float GetLongitudeRadIC(void) { return longitude; }
193 inline float GetUBodyFpsIC(void) { return vt*cos(alpha)*cos(beta); }
194 inline float GetVBodyFpsIC(void) { return vt*sin(beta); }
195 inline float GetWBodyFpsIC(void) { return vt*sin(alpha)*cos(beta); }
197 inline float GetThetaRadIC(void) { return theta; }
198 inline float GetPhiRadIC(void) { return phi; }
199 inline float GetPsiRadIC(void) { return psi; }
205 float alpha,beta,gamma,theta,phi,psi;
208 float latitude,longitude;
210 float vnorth,veast,vdown;
212 float xlo, xhi,xmin,xmax;
214 typedef float (FGInitialCondition::*fp)(float x);
217 speedset lastSpeedSet;
224 bool getMachFromVcas(float *Mach,float vcas);
226 float GammaEqOfTheta(float Theta);
227 float GammaEqOfAlpha(float Alpha);
228 float calcVcas(float Mach);
229 void calcUVWfromNED(void);
231 bool findInterval(float x,float guess);
232 bool solve(float *y, float x);