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 CAVEAT: This class makes use of alpha=theta-gamma. This means that setting
42 any of the three with this class is only valid for steady state
43 (all accels zero) and zero pitch rate. One example where this
44 would produce invalid results is setting up for a trim in a pull-up
45 or pushover (both have nonzero pitch rate). Maybe someday...
47 ********************************************************************************
49 *******************************************************************************/
51 #ifndef FGINITIALCONDITION_H
52 #define FGINITIALCONDITION_H
54 /*******************************************************************************
56 *******************************************************************************/
58 #include "FGFDMExec.h"
59 #include "FGAtmosphere.h"
62 /*******************************************************************************
64 *******************************************************************************/
66 typedef enum { setvt, setvc, setve, setmach } speedset;
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. This entails the assumption
98 that alpha=theta-gamma. Since any two of those angles specifies
99 the third (again, for zero pitch rate) gamma (flight path angle)
100 is favored when setting alpha and theta and alpha is favored when
102 set alpha : recalculate theta using gamma as currently set
103 set theta : recalculate alpha using gamma as currently set
104 set gamma : recalculate theta using alpha as currently set
106 The idea being that gamma is most interesting to pilots (since it
107 is indicative of climb rate).
109 Setting climb rate is, for the purpose of this discussion,
110 considered equivalent to setting gamma.
113 class FGInitialCondition {
116 FGInitialCondition(FGFDMExec *fdmex);
117 ~FGInitialCondition(void);
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 SetAltitudeFtIC(float tt);
130 //"vertical" flight path, recalculate theta
131 inline void SetFlightPathAngleDegIC(float tt) { gamma=tt*DEGTORAD; theta=alpha+gamma; }
132 inline void SetFlightPathAngleRadIC(float tt) { gamma=tt; theta=alpha+gamma; }
134 void SetClimbRateFpmIC(float tt);
135 //use currently stored gamma, recalcualte theta
136 inline void SetAlphaDegIC(float tt) { alpha=tt*DEGTORAD; theta=alpha+gamma; }
137 inline void SetAlphaRadIC(float tt) { alpha=tt; theta=alpha+gamma; }
138 //use currently stored gamma, recalcualte alpha
139 inline void SetPitchAngleDegIC(float tt) { theta=tt*DEGTORAD; alpha=theta-gamma; }
140 inline void SetPitchAngleRadIC(float tt) { theta=tt; alpha=theta-gamma; }
142 inline void SetBetaDegIC(float tt) { beta=tt*DEGTORAD; }
143 inline void SetBetaRadIC(float tt) { beta=tt; }
145 inline void SetRollAngleDegIC(float tt) { phi=tt*DEGTORAD; }
146 inline void SetRollAngleRadIC(float tt) { phi=tt; }
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 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;
210 speedset lastSpeedSet;
214 float calcVcas(float Mach);
215 bool findMachInterval(float *mlo, float *mhi,float vcas);
216 bool getMachFromVcas(float *Mach,float vcas);