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.
106 class FGInitialCondition {
109 FGInitialCondition(FGFDMExec *fdmex);
110 ~FGInitialCondition(void);
112 void SetVcalibratedKtsIC(float tt);
113 void SetVequivalentKtsIC(float tt);
114 void SetVtrueKtsIC(float tt);
115 void SetMachIC(float tt);
117 void SetUBodyFpsIC(float tt);
118 void SetVBodyFpsIC(float tt);
119 void SetWBodyFpsIC(float tt);
121 void SetVnorthFpsIC(float tt);
122 void SetVeastFpsIC(float tt);
123 void SetVdownFpsIC(float tt);
125 void SetAltitudeFtIC(float tt);
126 void SetAltitudeAGLFtIC(float tt);
128 //"vertical" flight path, recalculate theta
129 inline void SetFlightPathAngleDegIC(float tt) { SetFlightPathAngleRadIC(gamma=tt*DEGTORAD); }
130 void SetFlightPathAngleRadIC(float tt);
132 void SetClimbRateFpmIC(float tt);
133 void SetClimbRateFpsIC(float tt);
134 //use currently stored gamma, recalcualte theta
135 inline void SetAlphaDegIC(float tt) { alpha=tt*DEGTORAD; getTheta(); }
136 inline void SetAlphaRadIC(float tt) { alpha=tt; getTheta(); }
137 //use currently stored gamma, recalcualte alpha
138 inline void SetPitchAngleDegIC(float tt) { theta=tt*DEGTORAD; getAlpha(); }
139 inline void SetPitchAngleRadIC(float tt) { theta=tt; getAlpha(); }
141 inline void SetBetaDegIC(float tt) { beta=tt*DEGTORAD; getTheta();}
142 inline void SetBetaRadIC(float tt) { beta=tt; getTheta(); }
144 inline void SetRollAngleDegIC(float tt) { phi=tt*DEGTORAD; getTheta(); }
145 inline void SetRollAngleRadIC(float tt) { phi=tt; getTheta(); }
147 inline void SetHeadingDegIC(float tt) { psi=tt*DEGTORAD; }
148 inline void SetHeadingRadIC(float tt) { psi=tt; }
150 inline void SetLatitudeDegIC(float tt) { latitude=tt*DEGTORAD; }
151 inline void SetLatitudeRadIC(float tt) { latitude=tt; }
153 inline void SetLongitudeDegIC(float tt) { longitude=tt*DEGTORAD; }
154 inline void SetLongitudeRadIC(float tt) { longitude=tt; }
156 inline float GetVcalibratedKtsIC(void) { return vc*FPSTOKTS; }
157 inline float GetVequivalentKtsIC(void) { return ve*FPSTOKTS; }
158 inline float GetVtrueKtsIC(void) { return vt*FPSTOKTS; }
159 inline float GetVtrueFpsIC(void) { return vt; }
160 inline float GetMachIC(void) { return mach; }
162 inline float GetAltitudeFtIC(void) { return altitude; }
164 inline float GetFlightPathAngleDegIC(void) { return gamma*RADTODEG; }
165 inline float GetFlightPathAngleRadIC(void) { return gamma; }
167 inline float GetClimbRateFpmIC(void) { return hdot*60; }
168 inline float GetClimbRateFpsIC(void) { return hdot; }
170 inline float GetAlphaDegIC(void) { return alpha*RADTODEG; }
171 inline float GetAlphaRadIC(void) { return alpha; }
173 inline float GetPitchAngleDegIC(void) { return theta*RADTODEG; }
174 inline float GetPitchAngleRadIC(void) { return theta; }
177 inline float GetBetaDegIC(void) { return beta*RADTODEG; }
178 inline float GetBetaRadIC(void) { return beta*RADTODEG; }
180 inline float GetRollAngleDegIC(void) { return phi*RADTODEG; }
181 inline float GetRollAngleRadIC(void) { return phi; }
183 inline float GetHeadingDegIC(void) { return psi*RADTODEG; }
184 inline float GetHeadingRadIC(void) { return psi; }
186 inline float GetLatitudeDegIC(void) { return latitude*RADTODEG; }
187 inline float GetLatitudeRadIC(void) { return latitude; }
189 inline float GetLongitudeDegIC(void) { return longitude*RADTODEG; }
190 inline float GetLongitudeRadIC(void) { return longitude; }
192 inline float GetUBodyFpsIC(void) { return vt*cos(alpha)*cos(beta); }
193 inline float GetVBodyFpsIC(void) { return vt*sin(beta); }
194 inline float GetWBodyFpsIC(void) { return vt*sin(alpha)*cos(beta); }
196 inline float GetThetaRadIC(void) { return theta; }
197 inline float GetPhiRadIC(void) { return phi; }
198 inline float GetPsiRadIC(void) { return psi; }
204 float alpha,beta,gamma,theta,phi,psi;
207 float latitude,longitude;
209 float vnorth,veast,vdown;
211 float xlo, xhi,xmin,xmax;
213 typedef float (FGInitialCondition::*fp)(float x);
216 speedset lastSpeedSet;
223 bool getMachFromVcas(float *Mach,float vcas);
225 float GammaEqOfTheta(float Theta);
226 float GammaEqOfAlpha(float Alpha);
227 float calcVcas(float Mach);
228 void calcUVWfromNED(void);
230 bool findInterval(float x,float guess);
231 bool solve(float *y, float x);