-/*******************************************************************************
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGInitialCondition.h
Author: Tony Peden
Further information about the GNU General Public License can also be found on
the world wide web at http://www.gnu.org.
-
HISTORY
--------------------------------------------------------------------------------
7/1/99 TP Created
-
FUNCTIONAL DESCRIPTION
--------------------------------------------------------------------------------
the sim will most likely start in a very dynamic state (unless, of course,
you have chosen your IC's wisely) even after setting it up with this class.
-********************************************************************************
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
SENTRY
-*******************************************************************************/
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifndef FGINITIALCONDITION_H
#define FGINITIALCONDITION_H
-/*******************************************************************************
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
INCLUDES
-*******************************************************************************/
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#include "FGFDMExec.h"
-#include "FGAtmosphere.h"
-#include "FGMatrix.h"
+#include "FGJSBBase.h"
+#include "FGColumnVector3.h"
-/*******************************************************************************
-CLASS DECLARATION
-*******************************************************************************/
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+DEFINITIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+#define ID_INITIALCONDITION "$Id$"
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+FORWARD DECLARATIONS
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+namespace JSBSim {
+
+typedef enum { setvt, setvc, setve, setmach, setuvw, setned, setvg } speedset;
+typedef enum { setwned, setwmd, setwhc } windset;
+
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DOCUMENTATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
-typedef enum { setvt, setvc, setve, setmach } speedset;
+/** Takes a set of initial conditions and provide a kinematically consistent set
+ of body axis velocity components, euler angles, and altitude. This class
+ does not attempt to trim the model i.e. the sim will most likely start in a
+ very dynamic state (unless, of course, you have chosen your IC's wisely)
+ even after setting it up with this class.
+ USAGE NOTES
-/* USAGE NOTES
With a valid object of FGFDMExec and an aircraft model loaded
FGInitialCondition fgic=new FGInitialCondition(FDMExec);
fgic->SetVcalibratedKtsIC()
fgic->SetAltitudeFtIC();
- .
- .
- .
+
//to directly into Run
FDMExec->GetState()->Initialize(fgic)
delete fgic;
//or to loop the sim w/o integrating
FDMExec->RunIC(fgic)
-
-
Speed:
- Since vc, ve, vt, and mach all represent speed, the remaining
- three are recalculated each time one of them is set (using the
- current altitude). The most recent speed set is remembered so
- that if and when altitude is reset, the last set speed is used
- to recalculate the remaining three. Setting any of the body
- components forces a recalculation of vt and vt then becomes the
- most recent speed set.
+
+ Since vc, ve, vt, and mach all represent speed, the remaining
+ three are recalculated each time one of them is set (using the
+ current altitude). The most recent speed set is remembered so
+ that if and when altitude is reset, the last set speed is used
+ to recalculate the remaining three. Setting any of the body
+ components forces a recalculation of vt and vt then becomes the
+ most recent speed set.
Alpha,Gamma, and Theta:
- This class assumes that it will be used to set up the sim for a
- steady, zero pitch rate condition. This entails the assumption
- that alpha=theta-gamma. Since any two of those angles specifies
- the third (again, for zero pitch rate) gamma (flight path angle)
- is favored when setting alpha and theta and alpha is favored when
- setting gamma. i.e.
- set alpha : recalculate theta using gamma as currently set
- set theta : recalculate alpha using gamma as currently set
- set gamma : recalculate theta using alpha as currently set
-
- The idea being that gamma is most interesting to pilots (since it
- is indicative of climb rate).
-
- Setting climb rate is, for the purpose of this discussion,
- considered equivalent to setting gamma.
+
+ This class assumes that it will be used to set up the sim for a
+ steady, zero pitch rate condition. Since any two of those angles
+ specifies the third gamma (flight path angle) is favored when setting
+ alpha and theta and alpha is favored when setting gamma. i.e.
+
+ - set alpha : recalculate theta using gamma as currently set
+ - set theta : recalculate alpha using gamma as currently set
+ - set gamma : recalculate theta using alpha as currently set
+ The idea being that gamma is most interesting to pilots (since it
+ is indicative of climb rate).
+
+ Setting climb rate is, for the purpose of this discussion,
+ considered equivalent to setting gamma.
+ @author Tony Peden
+ @version "$Id$"
*/
-class FGInitialCondition {
-public:
+/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+CLASS DECLARATION
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
+
+class FGInitialCondition : public FGJSBBase
+{
+public:
+ /// Constructor
FGInitialCondition(FGFDMExec *fdmex);
- ~FGInitialCondition(void);
-
- void SetVcalibratedKtsIC(float tt);
- void SetVequivalentKtsIC(float tt);
- void SetVtrueKtsIC(float tt);
- void SetMachIC(float tt);
-
- void SetUBodyFpsIC(float tt);
- void SetVBodyFpsIC(float tt);
- void SetWBodyFpsIC(float tt);
-
- void SetAltitudeFtIC(float tt);
- void SetAltitudeAGLFtIC(float tt);
-
- //"vertical" flight path, recalculate theta
- inline void SetFlightPathAngleDegIC(float tt) { SetFlightPathAngleRadIC(gamma=tt*DEGTORAD); }
- void SetFlightPathAngleRadIC(float tt);
- //set speed first
- void SetClimbRateFpmIC(float tt);
- //use currently stored gamma, recalcualte theta
- inline void SetAlphaDegIC(float tt) { alpha=tt*DEGTORAD; getTheta(); }
- inline void SetAlphaRadIC(float tt) { alpha=tt; getTheta(); }
- //use currently stored gamma, recalcualte alpha
- inline void SetPitchAngleDegIC(float tt) { theta=tt*DEGTORAD; getAlpha(); }
- inline void SetPitchAngleRadIC(float tt) { theta=tt; getAlpha(); }
-
- inline void SetBetaDegIC(float tt) { beta=tt*DEGTORAD; getTheta();}
- inline void SetBetaRadIC(float tt) { beta=tt; getTheta(); }
+ /// Destructor
+ ~FGInitialCondition();
+
+ void SetVcalibratedKtsIC(double tt);
+ void SetVequivalentKtsIC(double tt);
+ inline void SetVtrueKtsIC(double tt) { SetVtrueFpsIC(tt*ktstofps); }
+ inline void SetVgroundKtsIC(double tt) { SetVgroundFpsIC(tt*ktstofps); }
+ void SetMachIC(double tt);
- inline void SetRollAngleDegIC(float tt) { phi=tt*DEGTORAD; getTheta(); }
- inline void SetRollAngleRadIC(float tt) { phi=tt; getTheta(); }
-
- inline void SetHeadingDegIC(float tt) { psi=tt*DEGTORAD; }
- inline void SetHeadingRadIC(float tt) { psi=tt; }
-
- inline void SetLatitudeDegIC(float tt) { latitude=tt*DEGTORAD; }
- inline void SetLatitudeRadIC(float tt) { latitude=tt; }
-
- inline void SetLongitudeDegIC(float tt) { longitude=tt*DEGTORAD; }
- inline void SetLongitudeRadIC(float tt) { longitude=tt; }
-
- inline float GetVcalibratedKtsIC(void) { return vc*FPSTOKTS; }
- inline float GetVequivalentKtsIC(void) { return ve*FPSTOKTS; }
- inline float GetVtrueKtsIC(void) { return vt*FPSTOKTS; }
- inline float GetVtrueFpsIC(void) { return vt; }
- inline float GetMachIC(void) { return mach; }
-
- inline float GetAltitudeFtIC(void) { return altitude; }
-
- inline float GetFlightPathAngleDegIC(void) { return gamma*RADTODEG; }
- inline float GetFlightPathAngleRadIC(void) { return gamma; }
-
- inline float GetClimbRateFpmIC(void) { return hdot*60; }
- inline float GetClimbRateFpsIC(void) { return hdot; }
-
- inline float GetAlphaDegIC(void) { return alpha*RADTODEG; }
- inline float GetAlphaRadIC(void) { return alpha; }
-
- inline float GetPitchAngleDegIC(void) { return theta*RADTODEG; }
- inline float GetPitchAngleRadIC(void) { return theta; }
-
-
- inline float GetBetaDegIC(void) { return beta*RADTODEG; }
- inline float GetBetaRadIC(void) { return beta*RADTODEG; }
-
- inline float GetRollAngleDegIC(void) { return phi*RADTODEG; }
- inline float GetRollAngleRadIC(void) { return phi; }
-
- inline float GetHeadingDegIC(void) { return psi*RADTODEG; }
- inline float GetHeadingRadIC(void) { return psi; }
-
- inline float GetLatitudeDegIC(void) { return latitude*RADTODEG; }
- inline float GetLatitudeRadIC(void) { return latitude; }
-
- inline float GetLongitudeDegIC(void) { return longitude*RADTODEG; }
- inline float GetLongitudeRadIC(void) { return longitude; }
-
- inline float GetUBodyFpsIC(void) { return vt*cos(alpha)*cos(beta); }
- inline float GetVBodyFpsIC(void) { return vt*sin(beta); }
- inline float GetWBodyFpsIC(void) { return vt*sin(alpha)*cos(beta); }
+ inline void SetAlphaDegIC(double tt) { SetAlphaRadIC(tt*degtorad); }
+ inline void SetBetaDegIC(double tt) { SetBetaRadIC(tt*degtorad);}
+
+ inline void SetPitchAngleDegIC(double tt) { SetPitchAngleRadIC(tt*degtorad); }
+ inline void SetRollAngleDegIC(double tt) { SetRollAngleRadIC(tt*degtorad);}
+ inline void SetTrueHeadingDegIC(double tt){ SetTrueHeadingRadIC(tt*degtorad); }
+
+ void SetClimbRateFpmIC(double tt);
+ inline void SetFlightPathAngleDegIC(double tt) { SetFlightPathAngleRadIC(tt*degtorad); }
- inline float GetThetaRadIC(void) { return theta; }
- inline float GetPhiRadIC(void) { return phi; }
- inline float GetPsiRadIC(void) { return psi; }
+ void SetAltitudeFtIC(double tt);
+ void SetAltitudeAGLFtIC(double tt);
+
+ void SetSeaLevelRadiusFtIC(double tt);
+ void SetTerrainAltitudeFtIC(double tt);
+ inline void SetLatitudeDegIC(double tt) { latitude=tt*degtorad; }
+ inline void SetLongitudeDegIC(double tt) { longitude=tt*degtorad; }
+
+ inline double GetVcalibratedKtsIC(void) const { return vc*fpstokts; }
+ inline double GetVequivalentKtsIC(void) const { return ve*fpstokts; }
+ inline double GetVgroundKtsIC(void) const { return vg*fpstokts; }
+ inline double GetVtrueKtsIC(void) const { return vt*fpstokts; }
+ inline double GetMachIC(void) const { return mach; }
+
+ inline double GetClimbRateFpmIC(void) const { return hdot*60; }
+ inline double GetFlightPathAngleDegIC(void)const { return gamma*radtodeg; }
+
+ inline double GetAlphaDegIC(void) const { return alpha*radtodeg; }
+ inline double GetBetaDegIC(void) const { return beta*radtodeg; }
+
+ inline double GetPitchAngleDegIC(void) const { return theta*radtodeg; }
+ inline double GetRollAngleDegIC(void) const { return phi*radtodeg; }
+ inline double GetHeadingDegIC(void) const { return psi*radtodeg; }
-private:
- float vt,vc,ve;
- float alpha,beta,gamma,theta,phi,psi;
- float mach;
- float altitude,hdot;
- float latitude,longitude;
- float u,v,w;
+ inline double GetLatitudeDegIC(void) const { return latitude*radtodeg; }
+ inline double GetLongitudeDegIC(void) const { return longitude*radtodeg; }
- float xlo, xhi,xmin,xmax;
+ inline double GetAltitudeFtIC(void) const { return altitude; }
+ inline double GetAltitudeAGLFtIC(void) const { return altitude - terrain_altitude; }
- typedef float (FGInitialCondition::*fp)(float x);
+ inline double GetSeaLevelRadiusFtIC(void) const { return sea_level_radius; }
+ inline double GetTerrainAltitudeFtIC(void) const { return terrain_altitude; }
+
+ void SetVgroundFpsIC(double tt);
+ void SetVtrueFpsIC(double tt);
+ void SetUBodyFpsIC(double tt);
+ void SetVBodyFpsIC(double tt);
+ void SetWBodyFpsIC(double tt);
+ void SetVnorthFpsIC(double tt);
+ void SetVeastFpsIC(double tt);
+ void SetVdownFpsIC(double tt);
+ void SetPRadpsIC(double tt) { p = tt; }
+ void SetQRadpsIC(double tt) { q = tt; }
+ void SetRRadpsIC(double tt) { r = tt; }
+
+ void SetWindNEDFpsIC(double wN, double wE, double wD);
+
+ void SetWindMagKtsIC(double mag);
+ void SetWindDirDegIC(double dir);
+
+ void SetHeadWindKtsIC(double head);
+ void SetCrossWindKtsIC(double cross);// positive from left
+
+ void SetWindDownKtsIC(double wD);
+
+ void SetClimbRateFpsIC(double tt);
+ inline double GetVgroundFpsIC(void) const { return vg; }
+ inline double GetVtrueFpsIC(void) const { return vt; }
+ inline double GetWindUFpsIC(void) const { return uw; }
+ inline double GetWindVFpsIC(void) const { return vw; }
+ inline double GetWindWFpsIC(void) const { return ww; }
+ inline double GetWindNFpsIC(void) const { return wnorth; }
+ inline double GetWindEFpsIC(void) const { return weast; }
+ inline double GetWindDFpsIC(void) const { return wdown; }
+ inline double GetWindFpsIC(void) const { return sqrt(wnorth*wnorth + weast*weast); }
+ double GetWindDirDegIC(void);
+ inline double GetClimbRateFpsIC(void) const { return hdot; }
+ double GetUBodyFpsIC(void) const;
+ double GetVBodyFpsIC(void) const;
+ double GetWBodyFpsIC(void) const;
+ double GetPRadpsIC() const { return p; }
+ double GetQRadpsIC() const { return q; }
+ double GetRRadpsIC() const { return r; }
+ void SetFlightPathAngleRadIC(double tt);
+ void SetAlphaRadIC(double tt);
+ void SetPitchAngleRadIC(double tt);
+ void SetBetaRadIC(double tt);
+ void SetRollAngleRadIC(double tt);
+ void SetTrueHeadingRadIC(double tt);
+ inline void SetLatitudeRadIC(double tt) { latitude=tt; }
+ inline void SetLongitudeRadIC(double tt) { longitude=tt; }
+ inline double GetFlightPathAngleRadIC(void) const { return gamma; }
+ inline double GetAlphaRadIC(void) const { return alpha; }
+ inline double GetPitchAngleRadIC(void) const { return theta; }
+ inline double GetBetaRadIC(void) const { return beta; }
+ inline double GetRollAngleRadIC(void) const { return phi; }
+ inline double GetHeadingRadIC(void) const { return psi; }
+ inline double GetLatitudeRadIC(void) const { return latitude; }
+ inline double GetLongitudeRadIC(void) const { return longitude; }
+ inline double GetThetaRadIC(void) const { return theta; }
+ inline double GetPhiRadIC(void) const { return phi; }
+ inline double GetPsiRadIC(void) const { return psi; }
+
+ inline speedset GetSpeedSet(void) { return lastSpeedSet; }
+ inline windset GetWindSet(void) { return lastWindSet; }
+
+ bool Load(string rstname, bool useStoredPath = true );
+
+ void bind(void);
+ void unbind(void);
+
+
+private:
+ double vt,vc,ve,vg;
+ double mach;
+ double altitude,hdot;
+ double latitude,longitude;
+ double u,v,w;
+ double p,q,r;
+ double uw,vw,ww;
+ double vnorth,veast,vdown;
+ double wnorth,weast,wdown;
+ double whead, wcross, wdir, wmag;
+ double sea_level_radius;
+ double terrain_altitude;
+ double radius_to_vehicle;
+
+ double alpha, beta, theta, phi, psi, gamma;
+ double salpha,sbeta,stheta,sphi,spsi,sgamma;
+ double calpha,cbeta,ctheta,cphi,cpsi,cgamma;
+
+ double xlo, xhi,xmin,xmax;
+
+ typedef double (FGInitialCondition::*fp)(double x);
fp sfunc;
speedset lastSpeedSet;
+ windset lastWindSet;
FGFDMExec *fdmex;
-
-
+ FGPropertyManager *PropertyManager;
+
bool getAlpha(void);
bool getTheta(void);
- bool getMachFromVcas(float *Mach,float vcas);
-
- float GammaEqOfTheta(float Theta);
- float GammaEqOfAlpha(float Alpha);
- float calcVcas(float Mach);
-
- bool findInterval(float x,float guess);
- bool solve(float *y, float x);
-};
+ bool getMachFromVcas(double *Mach,double vcas);
+ double GammaEqOfTheta(double Theta);
+ double GammaEqOfAlpha(double Alpha);
+ double calcVcas(double Mach);
+ void calcUVWfromNED(void);
+ void calcWindUVW(void);
+
+ bool findInterval(double x,double guess);
+ bool solve(double *y, double x);
+ void Debug(int from);
+};
+}
#endif
+