1
0
Fork 0

Sync. w. JSBSim CVS

This commit is contained in:
ehofman 2006-02-02 09:35:25 +00:00
parent 9968dfd814
commit 6849328fea
9 changed files with 506 additions and 218 deletions

View file

@ -724,8 +724,6 @@ void FGFDMExec::DoTrim(int mode)
{ {
double saved_time; double saved_time;
cout << "DoTrim called" << endl;
if (Constructing) return; if (Constructing) return;
if (mode < 0 || mode > JSBSim::tNone) { if (mode < 0 || mode > JSBSim::tNone) {

View file

@ -158,10 +158,11 @@ CLASS DOCUMENTATION
a message is printed out when they go out of bounds a message is printed out when they go out of bounds
<h3>Properties</h3> <h3>Properties</h3>
@property simulator/do_trim Can be set to the integer equivalent to one of @property simulator/do_trim (write only) Can be set to the integer equivalent to one of
tLongitudinal (0), tFull (1), tGround (2), tPullup (3), tLongitudinal (0), tFull (1), tGround (2), tPullup (3),
tCustom (4), tTurn (5). Setting this to a legal value tCustom (4), tTurn (5). Setting this to a legal value
(such as by a script) causes a trim to be performed. (such as by a script) causes a trim to be performed. This
property actually maps toa function call of DoTrim().
@author Jon S. Berndt @author Jon S. Berndt
@version $Revision$ @version $Revision$

View file

@ -272,8 +272,7 @@ void FGState::ReportState(void)
void FGState::bind(void) void FGState::bind(void)
{ {
PropertyManager->Tie("sim-time-sec",this, PropertyManager->Tie("sim-time-sec", this, &FGState::Getsim_time);
&FGState::Getsim_time);
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View file

@ -90,8 +90,10 @@ CLASS DOCUMENTATION
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
/** Encapsulates the calculation of aircraft state. /** Encapsulates the calculation of aircraft state.
<h3>Properties</h3>
@property sim-time-sec (read only) cumulative simulation in seconds.
@author Jon S. Berndt @author Jon S. Berndt
@version $Id$ @version $Revision$
*/ */
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -109,43 +111,39 @@ public:
/** Initializes the simulation state based on parameters from an Initial Conditions object. /** Initializes the simulation state based on parameters from an Initial Conditions object.
@param FGIC pointer to an initial conditions object. @param FGIC pointer to an initial conditions object.
@see FGInitialConditions. @see FGInitialConditions. */
*/
void Initialize(FGInitialCondition *FGIC); void Initialize(FGInitialCondition *FGIC);
/// Returns the simulation time in seconds. /// Returns the cumulative simulation time in seconds.
inline double Getsim_time(void) const { return sim_time; } inline double Getsim_time(void) const { return sim_time; }
/// Returns the simulation delta T. /// Returns the simulation delta T.
inline double Getdt(void) { inline double Getdt(void) {return dt;}
return dt;
}
/// Suspends the simulation and sets the delta T to zero. /// Suspends the simulation and sets the delta T to zero.
inline void SuspendIntegration(void) {saved_dt = dt; dt = 0.0;} inline void SuspendIntegration(void) {saved_dt = dt; dt = 0.0;}
/// Resumes the simulation by resetting delta T to the correct value. /// Resumes the simulation by resetting delta T to the correct value.
inline void ResumeIntegration(void) {dt = saved_dt;} inline void ResumeIntegration(void) {dt = saved_dt;}
/** Returns the simulation suspension state.
@return true if suspended, false if executing */
bool IntegrationSuspended(void) {return dt == 0.0;} bool IntegrationSuspended(void) {return dt == 0.0;}
/** Sets the current sim time. /** Sets the current sim time.
@param cur_time the current time @param cur_time the current time
@return the current time. @return the current simulation time. */
*/
inline double Setsim_time(double cur_time) { inline double Setsim_time(double cur_time) {
sim_time = cur_time; sim_time = cur_time;
return sim_time; return sim_time;
} }
/** Sets the integration time step for the simulation executive. /** Sets the integration time step for the simulation executive.
@param delta_t the time step in seconds. @param delta_t the time step in seconds. */
*/ inline void Setdt(double delta_t) { dt = delta_t; }
inline void Setdt(double delta_t) {
dt = delta_t;
}
/** Increments the simulation time. /** Increments the simulation time.
@return the new simulation time. @return the new simulation time. */
*/
inline double IncrTime(void) { inline double IncrTime(void) {
sim_time+=dt; sim_time+=dt;
return sim_time; return sim_time;
@ -162,13 +160,9 @@ public:
FGMatrix33& GetTb2s(void); FGMatrix33& GetTb2s(void);
/** Prints a summary of simulator state (speed, altitude, /** Prints a summary of simulator state (speed, altitude,
configuration, etc.) configuration, etc.) */
*/
void ReportState(void); void ReportState(void);
void bind();
void unbind();
private: private:
double sim_time, dt; double sim_time, dt;
double saved_dt; double saved_dt;
@ -187,6 +181,9 @@ private:
FGAuxiliary* Auxiliary; FGAuxiliary* Auxiliary;
FGPropertyManager* PropertyManager; FGPropertyManager* PropertyManager;
void bind();
void unbind();
void Debug(int from); void Debug(int from);
}; };
} }

View file

@ -850,7 +850,7 @@ bool FGJSBsim::copy_from_JSBsim()
spoilers_pos_pct->setDoubleValue( FCS->GetDspPos(ofNorm) ); spoilers_pos_pct->setDoubleValue( FCS->GetDspPos(ofNorm) );
// force a sim reset if crashed (altitude AGL < 0) // force a sim reset if crashed (altitude AGL < 0)
if (get_Altitude_AGL() < 0.0) { if (get_Altitude_AGL() < -100.0) {
fgSetBool("/sim/crashed", true); fgSetBool("/sim/crashed", true);
SGPropertyNode* node = fgGetNode("/sim/presets", true); SGPropertyNode* node = fgGetNode("/sim/presets", true);
globals->get_commands()->execute("old-reinit-dialog", node); globals->get_commands()->execute("old-reinit-dialog", node);
@ -1009,9 +1009,9 @@ void FGJSBsim::set_Euler_Angles( double phi, double theta, double psi )
FGInterface::set_Euler_Angles(phi, theta, psi); FGInterface::set_Euler_Angles(phi, theta, psi);
update_ic(); update_ic();
fgic->SetPitchAngleRadIC(theta); fgic->SetThetaRadIC(theta);
fgic->SetRollAngleRadIC(phi); fgic->SetPhiRadIC(phi);
fgic->SetTrueHeadingRadIC(psi); fgic->SetPsiRadIC(psi);
needTrim=true; needTrim=true;
} }
@ -1126,9 +1126,9 @@ void FGJSBsim::update_ic(void)
fgic->SetLongitudeRadIC( get_Longitude() ); fgic->SetLongitudeRadIC( get_Longitude() );
fgic->SetAltitudeFtIC( get_Altitude() ); fgic->SetAltitudeFtIC( get_Altitude() );
fgic->SetVcalibratedKtsIC( get_V_calibrated_kts() ); fgic->SetVcalibratedKtsIC( get_V_calibrated_kts() );
fgic->SetPitchAngleRadIC( get_Theta() ); fgic->SetThetaRadIC( get_Theta() );
fgic->SetRollAngleRadIC( get_Phi() ); fgic->SetPhiRadIC( get_Phi() );
fgic->SetTrueHeadingRadIC( get_Psi() ); fgic->SetPsiRadIC( get_Psi() );
fgic->SetClimbRateFpsIC( get_Climb_Rate() ); fgic->SetClimbRateFpsIC( get_Climb_Rate() );
} }
} }

View file

@ -225,7 +225,7 @@ void FGInitialCondition::SetAlphaRadIC(double tt) {
//****************************************************************************** //******************************************************************************
void FGInitialCondition::SetPitchAngleRadIC(double tt) { void FGInitialCondition::SetThetaRadIC(double tt) {
theta=tt; theta=tt;
stheta=sin(theta); ctheta=cos(theta); stheta=sin(theta); ctheta=cos(theta);
getAlpha(); getAlpha();
@ -242,7 +242,7 @@ void FGInitialCondition::SetBetaRadIC(double tt) {
//****************************************************************************** //******************************************************************************
void FGInitialCondition::SetRollAngleRadIC(double tt) { void FGInitialCondition::SetPhiRadIC(double tt) {
phi=tt; phi=tt;
sphi=sin(phi); cphi=cos(phi); sphi=sin(phi); cphi=cos(phi);
getTheta(); getTheta();
@ -250,7 +250,7 @@ void FGInitialCondition::SetRollAngleRadIC(double tt) {
//****************************************************************************** //******************************************************************************
void FGInitialCondition::SetTrueHeadingRadIC(double tt) { void FGInitialCondition::SetPsiRadIC(double tt) {
psi=tt; psi=tt;
spsi=sin(psi); cpsi=cos(psi); spsi=sin(psi); cpsi=cos(psi);
calcWindUVW(); calcWindUVW();
@ -718,7 +718,7 @@ bool FGInitialCondition::solve(double *y,double x)
//****************************************************************************** //******************************************************************************
double FGInitialCondition::GetWindDirDegIC(void) { double FGInitialCondition::GetWindDirDegIC(void) const {
if(weast != 0.0) if(weast != 0.0)
return atan2(weast,wnorth)*radtodeg; return atan2(weast,wnorth)*radtodeg;
else if(wnorth > 0) else if(wnorth > 0)
@ -774,11 +774,11 @@ bool FGInitialCondition::Load(string rstfile, bool useStoredPath)
if (document->FindElement("longitude")) if (document->FindElement("longitude"))
SetLongitudeDegIC(document->FindElementValueAsNumberConvertTo("longitude", "DEG")); SetLongitudeDegIC(document->FindElementValueAsNumberConvertTo("longitude", "DEG"));
if (document->FindElement("phi")) if (document->FindElement("phi"))
SetRollAngleDegIC(document->FindElementValueAsNumberConvertTo("phi", "DEG")); SetPhiDegIC(document->FindElementValueAsNumberConvertTo("phi", "DEG"));
if (document->FindElement("theta")) if (document->FindElement("theta"))
SetPitchAngleDegIC(document->FindElementValueAsNumberConvertTo("theta", "DEG")); SetThetaDegIC(document->FindElementValueAsNumberConvertTo("theta", "DEG"));
if (document->FindElement("psi")) if (document->FindElement("psi"))
SetTrueHeadingDegIC(document->FindElementValueAsNumberConvertTo("psi", "DEG")); SetPsiDegIC(document->FindElementValueAsNumberConvertTo("psi", "DEG"));
if (document->FindElement("alpha")) if (document->FindElement("alpha"))
SetAlphaDegIC(document->FindElementValueAsNumberConvertTo("alpha", "DEG")); SetAlphaDegIC(document->FindElementValueAsNumberConvertTo("alpha", "DEG"));
if (document->FindElement("beta")) if (document->FindElement("beta"))
@ -837,7 +837,7 @@ void FGInitialCondition::bind(void){
&FGInitialCondition::GetVtrueKtsIC, &FGInitialCondition::GetVtrueKtsIC,
&FGInitialCondition::SetVtrueKtsIC, &FGInitialCondition::SetVtrueKtsIC,
true); true);
PropertyManager->Tie("ic/mach-norm", this, PropertyManager->Tie("ic/mach", this,
&FGInitialCondition::GetMachIC, &FGInitialCondition::GetMachIC,
&FGInitialCondition::SetMachIC, &FGInitialCondition::SetMachIC,
true); true);
@ -858,15 +858,15 @@ void FGInitialCondition::bind(void){
&FGInitialCondition::SetBetaDegIC, &FGInitialCondition::SetBetaDegIC,
true); true);
PropertyManager->Tie("ic/theta-deg", this, PropertyManager->Tie("ic/theta-deg", this,
&FGInitialCondition::GetPitchAngleDegIC, &FGInitialCondition::GetThetaDegIC,
&FGInitialCondition::SetPitchAngleDegIC, &FGInitialCondition::SetThetaDegIC,
true); true);
PropertyManager->Tie("ic/phi-deg", this, PropertyManager->Tie("ic/phi-deg", this,
&FGInitialCondition::GetRollAngleDegIC, &FGInitialCondition::GetPhiDegIC,
&FGInitialCondition::SetRollAngleDegIC, &FGInitialCondition::SetPhiDegIC,
true); true);
PropertyManager->Tie("ic/psi-true-deg", this, PropertyManager->Tie("ic/psi-true-deg", this,
&FGInitialCondition::GetHeadingDegIC ); &FGInitialCondition::GetPsiDegIC );
PropertyManager->Tie("ic/lat-gc-deg", this, PropertyManager->Tie("ic/lat-gc-deg", this,
&FGInitialCondition::GetLatitudeDegIC, &FGInitialCondition::GetLatitudeDegIC,
&FGInitialCondition::SetLatitudeDegIC, &FGInitialCondition::SetLatitudeDegIC,
@ -913,16 +913,16 @@ void FGInitialCondition::bind(void){
&FGInitialCondition::GetWindDFpsIC); &FGInitialCondition::GetWindDFpsIC);
PropertyManager->Tie("ic/vw-mag-fps", this, PropertyManager->Tie("ic/vw-mag-fps", this,
&FGInitialCondition::GetWindFpsIC); &FGInitialCondition::GetWindFpsIC);
/* PropertyManager->Tie("ic/vw-dir-deg", this, PropertyManager->Tie("ic/vw-dir-deg", this,
&FGInitialCondition::GetWindDirDegIC, &FGInitialCondition::GetWindDirDegIC,
&FGInitialCondition::SetWindDirDegIC, &FGInitialCondition::SetWindDirDegIC,
true); */ true);
PropertyManager->Tie("ic/roc-fps", this, PropertyManager->Tie("ic/roc-fps", this,
&FGInitialCondition::GetClimbRateFpsIC, &FGInitialCondition::GetClimbRateFpsIC,
&FGInitialCondition::SetClimbRateFpsIC, &FGInitialCondition::SetClimbRateFpsIC,
true); true);
/* PropertyManager->Tie("ic/u-fps", this, PropertyManager->Tie("ic/u-fps", this,
&FGInitialCondition::GetUBodyFpsIC, &FGInitialCondition::GetUBodyFpsIC,
&FGInitialCondition::SetUBodyFpsIC, &FGInitialCondition::SetUBodyFpsIC,
true); true);
@ -933,7 +933,7 @@ void FGInitialCondition::bind(void){
PropertyManager->Tie("ic/w-fps", this, PropertyManager->Tie("ic/w-fps", this,
&FGInitialCondition::GetWBodyFpsIC, &FGInitialCondition::GetWBodyFpsIC,
&FGInitialCondition::SetWBodyFpsIC, &FGInitialCondition::SetWBodyFpsIC,
true); */ true);
PropertyManager->Tie("ic/gamma-rad", this, PropertyManager->Tie("ic/gamma-rad", this,
&FGInitialCondition::GetFlightPathAngleRadIC, &FGInitialCondition::GetFlightPathAngleRadIC,
@ -944,19 +944,19 @@ void FGInitialCondition::bind(void){
&FGInitialCondition::SetAlphaRadIC, &FGInitialCondition::SetAlphaRadIC,
true); true);
PropertyManager->Tie("ic/theta-rad", this, PropertyManager->Tie("ic/theta-rad", this,
&FGInitialCondition::GetPitchAngleRadIC, &FGInitialCondition::GetThetaRadIC,
&FGInitialCondition::SetPitchAngleRadIC, &FGInitialCondition::SetThetaRadIC,
true); true);
PropertyManager->Tie("ic/beta-rad", this, PropertyManager->Tie("ic/beta-rad", this,
&FGInitialCondition::GetBetaRadIC, &FGInitialCondition::GetBetaRadIC,
&FGInitialCondition::SetBetaRadIC, &FGInitialCondition::SetBetaRadIC,
true); true);
PropertyManager->Tie("ic/phi-rad", this, PropertyManager->Tie("ic/phi-rad", this,
&FGInitialCondition::GetRollAngleRadIC, &FGInitialCondition::GetPhiRadIC,
&FGInitialCondition::SetRollAngleRadIC, &FGInitialCondition::SetPhiRadIC,
true); true);
PropertyManager->Tie("ic/psi-true-rad", this, PropertyManager->Tie("ic/psi-true-rad", this,
&FGInitialCondition::GetHeadingRadIC); &FGInitialCondition::GetPsiRadIC);
PropertyManager->Tie("ic/lat-gc-rad", this, PropertyManager->Tie("ic/lat-gc-rad", this,
&FGInitialCondition::GetLatitudeRadIC, &FGInitialCondition::GetLatitudeRadIC,
&FGInitialCondition::SetLatitudeRadIC, &FGInitialCondition::SetLatitudeRadIC,

View file

@ -73,25 +73,28 @@ CLASS DOCUMENTATION
/** Takes a set of initial conditions and provide a kinematically consistent set /** Takes a set of initial conditions and provide a kinematically consistent set
of body axis velocity components, euler angles, and altitude. This class 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 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) very dynamic state (unless, of course, you have chosen your IC's wisely, or
even after setting it up with this class. started on the ground) even after setting it up with this class.
USAGE NOTES <h2>Usage Notes</h2>
With a valid object of FGFDMExec and an aircraft model loaded With a valid object of FGFDMExec and an aircraft model loaded:
@code
FGInitialCondition fgic=new FGInitialCondition(FDMExec); FGInitialCondition fgic=new FGInitialCondition(FDMExec);
fgic->SetVcalibratedKtsIC() fgic->SetVcalibratedKtsIC()
fgic->SetAltitudeFtIC(); fgic->SetAltitudeFtIC();
//to directly into Run // directly into Run
FDMExec->GetState()->Initialize(fgic) FDMExec->GetState()->Initialize(fgic)
delete fgic; delete fgic;
FDMExec->Run() FDMExec->Run()
//or to loop the sim w/o integrating //or to loop the sim w/o integrating
FDMExec->RunIC(fgic) FDMExec->RunIC(fgic)
@endcode
Speed: <h2>Speed</h2>
Since vc, ve, vt, and mach all represent speed, the remaining Since vc, ve, vt, and mach all represent speed, the remaining
three are recalculated each time one of them is set (using the three are recalculated each time one of them is set (using the
@ -101,7 +104,7 @@ CLASS DOCUMENTATION
components forces a recalculation of vt and vt then becomes the components forces a recalculation of vt and vt then becomes the
most recent speed set. most recent speed set.
Alpha,Gamma, and Theta: <h2>Alpha,Gamma, and Theta</h2>
This class assumes that it will be used to set up the sim for a 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 steady, zero pitch rate condition. Since any two of those angles
@ -120,28 +123,72 @@ CLASS DOCUMENTATION
These are the items that can be set in an initialization file: These are the items that can be set in an initialization file:
UBODY <velocity, ft/sec> - ubody (velocity, ft/sec)
VBODY <velocity, ft/sec> - vbody (velocity, ft/sec)
WBODY <velocity, ft/sec> - wbody (velocity, ft/sec)
LATITUDE <position, degrees> - latitude (position, degrees)
LONGITUDE <position, degrees> - longitude (position, degrees)
PHI <orientation, degrees> - phi (orientation, degrees)
THETA <orientation, degrees> - theta (orientation, degrees)
PSI <orientation, degrees> - psi (orientation, degrees)
ALPHA <angle, degrees> - alpha (angle, degrees)
BETA <angle, degrees> - beta (angle, degrees)
GAMMA <angle, degrees> - gamma (angle, degrees)
ROC <vertical velocity, ft/sec> - roc (vertical velocity, ft/sec)
ALTITUDE <altitude, ft> - altitude (altitude, ft)
WINDDIR <wind from-angle, degrees> - winddir (wind from-angle, degrees)
VWIND <magnitude wind speed, ft/sec> - vwind (magnitude wind speed, ft/sec)
HWIND <headwind speed, knots> - hwind (headwind speed, knots)
XWIND <crosswind speed, knots> - xwind (crosswind speed, knots)
VC <calibrated airspeed, ft/sec> - vc (calibrated airspeed, ft/sec)
MACH <mach> - mach (mach)
VGROUND <ground speed, ft/sec> - vground (ground speed, ft/sec)
RUNNING <0 or 1> - running (0 or 1)
<h2>Properties</h2>
@property ic/vc-kts (read/write) Calibrated airspeed initial condition in knots
@property ic/ve-kts (read/write) Knots equivalent airspeed initial condition
@property ic/vg-kts (read/write) Ground speed initial condition in knots
@property ic/vt-kts (read/write) True airspeed initial condition in knots
@property ic/mach (read/write) Mach initial condition
@property ic/roc-fpm (read/write) Rate of climb initial condition in feet/minute
@property ic/gamma-deg (read/write) Flightpath angle initial condition in degrees
@property ic/alpha-deg (read/write) Angle of attack initial condition in degrees
@property ic/beta-deg (read/write) Angle of sideslip initial condition in degrees
@property ic/theta-deg (read/write) Pitch angle initial condition in degrees
@property ic/phi-deg (read/write) Roll angle initial condition in degrees
@property ic/psi-true-deg (read/write) Heading angle initial condition in degrees
@property ic/lat-gc-deg (read/write) Latitude initial condition in degrees
@property ic/long-gc-deg (read/write) Longitude initial condition in degrees
@property ic/h-sl-ft (read/write) Height above sea level initial condition in feet
@property ic/h-agl-ft (read/write) Height above ground level initial condition in feet
@property ic/sea-level-radius-ft (read/write) Radius of planet at sea level in feet
@property ic/terrain-altitude-ft (read/write) Terrain elevation above sea level in feet
@property ic/vg-fps (read/write) Ground speed initial condition in feet/second
@property ic/vt-fps (read/write) True airspeed initial condition in feet/second
@property ic/vw-bx-fps (read/write) Wind velocity initial condition in Body X frame in feet/second
@property ic/vw-by-fps (read/write) Wind velocity initial condition in Body Y frame in feet/second
@property ic/vw-bz-fps (read/write) Wind velocity initial condition in Body Z frame in feet/second
@property ic/vw-north-fps (read/write) Wind northward velocity initial condition in feet/second
@property ic/vw-east-fps (read/write) Wind eastward velocity initial condition in feet/second
@property ic/vw-down-fps (read/write) Wind downward velocity initial condition in feet/second
@property ic/vw-mag-fps (read/write) Wind velocity magnitude initial condition in feet/sec.
@property ic/vw-dir-deg (read/write) Wind direction initial condition, in degrees from north
@property ic/roc-fps (read/write) Rate of climb initial condition, in feet/second
@property ic/u-fps (read/write) Body frame x-axis velocity initial condition in feet/second
@property ic/v-fps (read/write) Body frame y-axis velocity initial condition in feet/second
@property ic/w-fps (read/write) Body frame z-axis velocity initial condition in feet/second
@property ic/gamma-rad (read/write) Flight path angle initial condition in radians
@property ic/alpha-rad (read/write) Angle of attack initial condition in radians
@property ic/theta-rad (read/write) Pitch angle initial condition in radians
@property ic/beta-rad (read/write) Angle of sideslip initial condition in radians
@property ic/phi-rad (read/write) Roll angle initial condition in radians
@property ic/psi-true-rad (read/write) Heading angle initial condition in radians
@property ic/lat-gc-rad (read/write) Geocentric latitude initial condition in radians
@property ic/long-gc-rad (read/write) Longitude initial condition in radians
@property ic/p-rad_sec (read/write) Roll rate initial condition in radians/second
@property ic/q-rad_sec (read/write) Pitch rate initial condition in radians/second
@property ic/r-rad_sec (read/write) Yaw rate initial condition in radians/second
@author Tony Peden @author Tony Peden
@version "$Id$" @version "$Id$"
@ -159,126 +206,370 @@ public:
/// Destructor /// Destructor
~FGInitialCondition(); ~FGInitialCondition();
void SetVcalibratedKtsIC(double tt); /** Set calibrated airspeed initial condition in knots.
void SetVequivalentKtsIC(double tt); @param vc Calibrated airspeed in knots */
inline void SetVtrueKtsIC(double tt) { SetVtrueFpsIC(tt*ktstofps); } void SetVcalibratedKtsIC(double vc);
inline void SetVgroundKtsIC(double tt) { SetVgroundFpsIC(tt*ktstofps); }
void SetMachIC(double tt);
inline void SetAlphaDegIC(double tt) { SetAlphaRadIC(tt*degtorad); } /** Set equivalent airspeed initial condition in knots.
inline void SetBetaDegIC(double tt) { SetBetaRadIC(tt*degtorad);} @param ve Equivalent airspeed in knots */
void SetVequivalentKtsIC(double ve);
inline void SetPitchAngleDegIC(double tt) { SetPitchAngleRadIC(tt*degtorad); } /** Set true airspeed initial condition in knots.
inline void SetRollAngleDegIC(double tt) { SetRollAngleRadIC(tt*degtorad);} @param vt True airspeed in knots */
inline void SetTrueHeadingDegIC(double tt){ SetTrueHeadingRadIC(tt*degtorad); } inline void SetVtrueKtsIC(double vt) { SetVtrueFpsIC(vt*ktstofps); }
void SetClimbRateFpmIC(double tt); /** Set ground speed initial condition in knots.
inline void SetFlightPathAngleDegIC(double tt) { SetFlightPathAngleRadIC(tt*degtorad); } @param vg Ground speed in knots */
inline void SetVgroundKtsIC(double vg) { SetVgroundFpsIC(vg*ktstofps); }
void SetAltitudeFtIC(double tt); /** Set mach initial condition.
void SetAltitudeAGLFtIC(double tt); @param mach Mach number */
void SetMachIC(double mach);
void SetSeaLevelRadiusFtIC(double tt); /** Sets angle of attack initial condition in degrees.
void SetTerrainAltitudeFtIC(double tt); @param a Alpha in degrees */
inline void SetAlphaDegIC(double a) { SetAlphaRadIC(a*degtorad); }
inline void SetLatitudeDegIC(double tt) { latitude=tt*degtorad; } /** Sets angle of sideslip initial condition in degrees.
inline void SetLongitudeDegIC(double tt) { longitude=tt*degtorad; } @param B Beta in degrees */
inline void SetBetaDegIC(double B) { SetBetaRadIC(B*degtorad);}
/** Sets pitch angle initial condition in degrees.
@param theta Theta (pitch) angle in degrees */
inline void SetThetaDegIC(double theta) { SetThetaRadIC(theta*degtorad); }
/** Sets the roll angle initial condition in degrees.
@param phi roll angle in degrees */
inline void SetPhiDegIC(double phi) { SetPhiRadIC(phi*degtorad);}
/** Sets the heading angle initial condition in degrees.
@param psi Heading angle in degrees */
inline void SetPsiDegIC(double psi){ SetPsiRadIC(psi*degtorad); }
/** Sets the climb rate initial condition in feet/minute.
@param roc Rate of Climb in feet/minute */
void SetClimbRateFpmIC(double roc);
/** Sets the flight path angle initial condition in degrees.
@param gamma Flight path angle in degrees */
inline void SetFlightPathAngleDegIC(double gamma) { SetFlightPathAngleRadIC(gamma*degtorad); }
/** Sets the altitude initial condition in feet.
@param alt Altitude in feet */
void SetAltitudeFtIC(double alt);
/** Sets the initial Altitude above ground level.
@param agl Altitude above ground level in feet */
void SetAltitudeAGLFtIC(double agl);
/** Sets the initial sea level radius from planet center
@param sl_rad sea level radius in feet */
void SetSeaLevelRadiusFtIC(double sl_rad);
/** Sets the initial terrain elevation.
@param elev Initial terrain elevation in feet */
void SetTerrainAltitudeFtIC(double elev);
/** Sets the initial latitude.
@param lat Initial latitude in degrees */
inline void SetLatitudeDegIC(double lat) { latitude=lat*degtorad; }
/** Sets the initial longitude.
@param lon Initial longitude in degrees */
inline void SetLongitudeDegIC(double lon) { longitude=lon*degtorad; }
/** Gets the initial calibrated airspeed.
@return Initial calibrated airspeed in knots */
inline double GetVcalibratedKtsIC(void) const { return vc*fpstokts; } inline double GetVcalibratedKtsIC(void) const { return vc*fpstokts; }
/** Gets the initial equivalent airspeed.
@return Initial equivalent airspeed in knots */
inline double GetVequivalentKtsIC(void) const { return ve*fpstokts; } inline double GetVequivalentKtsIC(void) const { return ve*fpstokts; }
/** Gets the initial ground speed.
@return Initial ground speed in knots */
inline double GetVgroundKtsIC(void) const { return vg*fpstokts; } inline double GetVgroundKtsIC(void) const { return vg*fpstokts; }
/** Gets the initial true velocity.
@return Initial true airspeed in knots. */
inline double GetVtrueKtsIC(void) const { return vt*fpstokts; } inline double GetVtrueKtsIC(void) const { return vt*fpstokts; }
/** Gets the initial mach.
@return Initial mach number */
inline double GetMachIC(void) const { return mach; } inline double GetMachIC(void) const { return mach; }
/** Gets the initial climb rate.
@return Initial climb rate in feet/minute */
inline double GetClimbRateFpmIC(void) const { return hdot*60; } inline double GetClimbRateFpmIC(void) const { return hdot*60; }
/** Gets the initial flight path angle.
@return Initial flight path angle in degrees */
inline double GetFlightPathAngleDegIC(void)const { return gamma*radtodeg; } inline double GetFlightPathAngleDegIC(void)const { return gamma*radtodeg; }
/** Gets the initial angle of attack.
@return Initial alpha in degrees */
inline double GetAlphaDegIC(void) const { return alpha*radtodeg; } inline double GetAlphaDegIC(void) const { return alpha*radtodeg; }
/** Gets the initial sideslip angle.
@return Initial beta in degrees */
inline double GetBetaDegIC(void) const { return beta*radtodeg; } inline double GetBetaDegIC(void) const { return beta*radtodeg; }
inline double GetPitchAngleDegIC(void) const { return theta*radtodeg; } /** Gets the initial pitch angle.
inline double GetRollAngleDegIC(void) const { return phi*radtodeg; } @return Initial pitch angle in degrees */
inline double GetHeadingDegIC(void) const { return psi*radtodeg; } inline double GetThetaDegIC(void) const { return theta*radtodeg; }
/** Gets the initial roll angle.
@return Initial phi in degrees */
inline double GetPhiDegIC(void) const { return phi*radtodeg; }
/** Gets the initial heading angle.
@return Initial psi in degrees */
inline double GetPsiDegIC(void) const { return psi*radtodeg; }
/** Gets the initial latitude.
@return Initial geocentric latitude in degrees */
inline double GetLatitudeDegIC(void) const { return latitude*radtodeg; } inline double GetLatitudeDegIC(void) const { return latitude*radtodeg; }
/** Gets the initial longitude.
@return Initial longitude in degrees */
inline double GetLongitudeDegIC(void) const { return longitude*radtodeg; } inline double GetLongitudeDegIC(void) const { return longitude*radtodeg; }
/** Gets the initial altitude.
@return Initial altitude in feet. */
inline double GetAltitudeFtIC(void) const { return altitude; } inline double GetAltitudeFtIC(void) const { return altitude; }
/** Gets the initial altitude above ground level.
@return Initial altitude AGL in feet */
inline double GetAltitudeAGLFtIC(void) const { return altitude - terrain_altitude; } inline double GetAltitudeAGLFtIC(void) const { return altitude - terrain_altitude; }
/** Gets the initial sea level radius.
@return Initial sea level radius */
inline double GetSeaLevelRadiusFtIC(void) const { return sea_level_radius; } inline double GetSeaLevelRadiusFtIC(void) const { return sea_level_radius; }
/** Gets the initial terrain elevation.
@return Initial terrain elevation in feet */
inline double GetTerrainAltitudeFtIC(void) const { return terrain_altitude; } inline double GetTerrainAltitudeFtIC(void) const { return terrain_altitude; }
void SetVgroundFpsIC(double tt); /** Sets the initial ground speed.
void SetVtrueFpsIC(double tt); @param vg Initial ground speed in feet/second */
void SetUBodyFpsIC(double tt); void SetVgroundFpsIC(double vg);
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; }
/** Sets the initial true airspeed.
@param vt Initial true airspeed in feet/second */
void SetVtrueFpsIC(double vt);
/** Sets the initial body axis X velocity.
@param ubody Initial X velocity in feet/second */
void SetUBodyFpsIC(double ubody);
/** Sets the initial body axis Y velocity.
@param vbody Initial Y velocity in feet/second */
void SetVBodyFpsIC(double vbody);
/** Sets the initial body axis Z velocity.
@param wbody Initial Z velocity in feet/second */
void SetWBodyFpsIC(double wbody);
/** Sets the initial local axis north velocity.
@param vn Initial north velocity in feet/second */
void SetVnorthFpsIC(double vn);
/** Sets the initial local axis east velocity.
@param ve Initial east velocity in feet/second */
void SetVeastFpsIC(double ve);
/** Sets the initial local axis down velocity.
@param vd Initial down velocity in feet/second */
void SetVdownFpsIC(double vd);
/** Sets the initial roll rate.
@param P Initial roll rate in radians/second */
void SetPRadpsIC(double P) { p = P; }
/** Sets the initial pitch rate.
@param Q Initial pitch rate in radians/second */
void SetQRadpsIC(double Q) { q = Q; }
/** Sets the initial yaw rate.
@param R initial yaw rate in radians/second */
void SetRRadpsIC(double R) { r = R; }
/** Sets the initial wind velocity.
@param wN Initial wind velocity in local north direction, feet/second
@param wE Initial wind velocity in local east direction, feet/second
@param wD Initial wind velocity in local down direction, feet/second */
void SetWindNEDFpsIC(double wN, double wE, double wD); void SetWindNEDFpsIC(double wN, double wE, double wD);
/** Sets the initial total wind speed.
@param mag Initial wind velocity magnitude in knots */
void SetWindMagKtsIC(double mag); void SetWindMagKtsIC(double mag);
/** Sets the initial wind direction.
@param dir Initial direction wind is coming from in degrees */
void SetWindDirDegIC(double dir); void SetWindDirDegIC(double dir);
/** Sets the initial headwind velocity.
@param head Initial headwind speed in knots */
void SetHeadWindKtsIC(double head); void SetHeadWindKtsIC(double head);
void SetCrossWindKtsIC(double cross);// positive from left
/** Sets the initial crosswind speed.
@param cross Initial crosswind speed, positive from left to right */
void SetCrossWindKtsIC(double cross);
/** Sets the initial wind downward speed.
@param wD Initial downward wind speed in knots*/
void SetWindDownKtsIC(double wD); void SetWindDownKtsIC(double wD);
void SetClimbRateFpsIC(double tt); /** Sets the initial climb rate.
@param roc Initial Rate of climb in feet/second */
void SetClimbRateFpsIC(double roc);
/** Gets the initial ground velocity.
@return Initial ground velocity in feet/second */
inline double GetVgroundFpsIC(void) const { return vg; } inline double GetVgroundFpsIC(void) const { return vg; }
/** Gets the initial true velocity.
@return Initial true velocity in feet/second */
inline double GetVtrueFpsIC(void) const { return vt; } inline double GetVtrueFpsIC(void) const { return vt; }
/** Gets the initial body axis X wind velocity.
@return Initial body axis X wind velocity in feet/second */
inline double GetWindUFpsIC(void) const { return uw; } inline double GetWindUFpsIC(void) const { return uw; }
/** Gets the initial body axis Y wind velocity.
@return Initial body axis Y wind velocity in feet/second */
inline double GetWindVFpsIC(void) const { return vw; } inline double GetWindVFpsIC(void) const { return vw; }
/** Gets the initial body axis Z wind velocity.
@return Initial body axis Z wind velocity in feet/second */
inline double GetWindWFpsIC(void) const { return ww; } inline double GetWindWFpsIC(void) const { return ww; }
/** Gets the initial wind velocity in local frame.
@return Initial wind velocity toward north in feet/second */
inline double GetWindNFpsIC(void) const { return wnorth; } inline double GetWindNFpsIC(void) const { return wnorth; }
/** Gets the initial wind velocity in local frame.
@return Initial wind velocity toward north in feet/second */
inline double GetWindEFpsIC(void) const { return weast; } inline double GetWindEFpsIC(void) const { return weast; }
/** Gets the initial wind velocity in local frame.
@return Initial wind velocity toward north in feet/second */
inline double GetWindDFpsIC(void) const { return wdown; } inline double GetWindDFpsIC(void) const { return wdown; }
/** Gets the initial total wind velocity in feet/sec.
@return Initial wind velocity in feet/second */
inline double GetWindFpsIC(void) const { return sqrt(wnorth*wnorth + weast*weast); } inline double GetWindFpsIC(void) const { return sqrt(wnorth*wnorth + weast*weast); }
double GetWindDirDegIC(void);
/** Gets the initial wind direction.
@return Initial wind direction in feet/second */
double GetWindDirDegIC(void) const;
/** Gets the initial climb rate.
@return Initial rate of climb in feet/second */
inline double GetClimbRateFpsIC(void) const { return hdot; } inline double GetClimbRateFpsIC(void) const { return hdot; }
/** Gets the initial body axis X velocity.
@return Initial body axis X velocity in feet/second. */
double GetUBodyFpsIC(void) const; double GetUBodyFpsIC(void) const;
/** Gets the initial body axis Y velocity.
@return Initial body axis Y velocity in feet/second. */
double GetVBodyFpsIC(void) const; double GetVBodyFpsIC(void) const;
/** Gets the initial body axis Z velocity.
@return Initial body axis Z velocity in feet/second. */
double GetWBodyFpsIC(void) const; double GetWBodyFpsIC(void) const;
/** Gets the initial body axis roll rate.
@return Initial body axis roll rate in radians/second */
double GetPRadpsIC() const { return p; } double GetPRadpsIC() const { return p; }
/** Gets the initial body axis pitch rate.
@return Initial body axis pitch rate in radians/second */
double GetQRadpsIC() const { return q; } double GetQRadpsIC() const { return q; }
/** Gets the initial body axis yaw rate.
@return Initial body axis yaw rate in radians/second */
double GetRRadpsIC() const { return r; } double GetRRadpsIC() const { return r; }
void SetFlightPathAngleRadIC(double tt);
void SetAlphaRadIC(double tt); /** Sets the initial flight path angle.
void SetPitchAngleRadIC(double tt); @param gamma Initial flight path angle in radians */
void SetBetaRadIC(double tt); void SetFlightPathAngleRadIC(double gamma);
void SetRollAngleRadIC(double tt);
void SetTrueHeadingRadIC(double tt); /** Sets the initial angle of attack.
inline void SetLatitudeRadIC(double tt) { latitude=tt; } @param alpha Initial angle of attack in radians */
inline void SetLongitudeRadIC(double tt) { longitude=tt; } void SetAlphaRadIC(double alpha);
/** Sets the initial pitch angle.
@param theta Initial pitch angle in radians */
void SetThetaRadIC(double theta);
/** Sets the initial sideslip angle.
@param beta Initial angle of sideslip in radians. */
void SetBetaRadIC(double beta);
/** Sets the initial roll angle.
@param phi Initial roll angle in radians */
void SetPhiRadIC(double phi);
/** Sets the initial heading angle.
@param psi Initial heading angle in radians */
void SetPsiRadIC(double psi);
/** Sets the initial latitude.
@param lat Initial latitude in radians */
inline void SetLatitudeRadIC(double lat) { latitude=lat; }
/** Sets the initial longitude.
@param lon Initial longitude in radians */
inline void SetLongitudeRadIC(double lon) { longitude=lon; }
/** Gets the initial flight path angle.
@return Initial flight path angle in radians */
inline double GetFlightPathAngleRadIC(void) const { return gamma; } inline double GetFlightPathAngleRadIC(void) const { return gamma; }
/** Gets the initial angle of attack.
@return Initial alpha in radians */
inline double GetAlphaRadIC(void) const { return alpha; } inline double GetAlphaRadIC(void) const { return alpha; }
inline double GetPitchAngleRadIC(void) const { return theta; }
/** Gets the initial angle of sideslip.
@return Initial sideslip angle in radians */
inline double GetBetaRadIC(void) const { return beta; } inline double GetBetaRadIC(void) const { return beta; }
inline double GetRollAngleRadIC(void) const { return phi; }
inline double GetHeadingRadIC(void) const { return psi; } /** Gets the initial roll angle.
@return Initial roll angle in radians */
inline double GetPhiRadIC(void) const { return phi; }
/** Gets the initial latitude.
@return Initial latitude in radians */
inline double GetLatitudeRadIC(void) const { return latitude; } inline double GetLatitudeRadIC(void) const { return latitude; }
/** Gets the initial longitude.
@return Initial longitude in radians */
inline double GetLongitudeRadIC(void) const { return longitude; } inline double GetLongitudeRadIC(void) const { return longitude; }
/** Gets the initial pitch angle.
@return Initial pitch angle in radians */
inline double GetThetaRadIC(void) const { return theta; } inline double GetThetaRadIC(void) const { return theta; }
inline double GetPhiRadIC(void) const { return phi; }
/** Gets the initial heading angle.
@return Initial heading angle in radians */
inline double GetPsiRadIC(void) const { return psi; } inline double GetPsiRadIC(void) const { return psi; }
/** Gets the initial speedset.
@return Initial speedset */
inline speedset GetSpeedSet(void) { return lastSpeedSet; } inline speedset GetSpeedSet(void) { return lastSpeedSet; }
/** Gets the initial windset.
@return Initial windset */
inline windset GetWindSet(void) { return lastWindSet; } inline windset GetWindSet(void) { return lastWindSet; }
/** Loads the initial conditions.
@param rstname The name of an initial conditions file
@param useStoredPath true if the stored path to the IC file should be used
@return true if successful */
bool Load(string rstname, bool useStoredPath = true ); bool Load(string rstname, bool useStoredPath = true );
void bind(void);
void unbind(void);
private: private:
double vt,vc,ve,vg; double vt,vc,ve,vg;
double mach; double mach;
@ -321,6 +612,8 @@ private:
bool findInterval(double x,double guess); bool findInterval(double x,double guess);
bool solve(double *y, double x); bool solve(double *y, double x);
void bind(void);
void unbind(void);
void Debug(int from); void Debug(int from);
}; };
} }

View file

@ -1,37 +1,37 @@
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Header: FGTrim.cpp Header: FGTrim.cpp
Author: Tony Peden Author: Tony Peden
Date started: 9/8/99 Date started: 9/8/99
--------- Copyright (C) 1999 Anthony K. Peden (apeden@earthlink.net) --------- --------- Copyright (C) 1999 Anthony K. Peden (apeden@earthlink.net) ---------
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later Foundation; either version 2 of the License, or (at your option) any later
version. version.
This program is distributed in the hope that it will be useful, but WITHOUT This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details. details.
You should have received a copy of the GNU General Public License along with You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA. Place - Suite 330, Boston, MA 02111-1307, USA.
Further information about the GNU General Public License can also be found on Further information about the GNU General Public License can also be found on
the world wide web at http://www.gnu.org. the world wide web at http://www.gnu.org.
HISTORY HISTORY
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
9/8/99 TP Created 9/8/99 TP Created
FUNCTIONAL DESCRIPTION FUNCTIONAL DESCRIPTION
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
This class takes the given set of IC's and finds the angle of attack, elevator, This class takes the given set of IC's and finds the angle of attack, elevator,
and throttle setting required to fly steady level. This is currently for in-air and throttle setting required to fly steady level. This is currently for in-air
conditions only. It is implemented using an iterative, one-axis-at-a-time conditions only. It is implemented using an iterative, one-axis-at-a-time
@ -74,7 +74,7 @@ FGTrim::FGTrim(FGFDMExec *FDMExec,TrimMode tt) {
max_sub_iterations=100; max_sub_iterations=100;
Tolerance=1E-3; Tolerance=1E-3;
A_Tolerance = Tolerance / 10; A_Tolerance = Tolerance / 10;
Debug=0;DebugLevel=0; Debug=0;DebugLevel=0;
fdmex=FDMExec; fdmex=FDMExec;
fgic=fdmex->GetIC(); fgic=fdmex->GetIC();
@ -138,7 +138,7 @@ void FGTrim::Report(void) {
void FGTrim::ClearStates(void) { void FGTrim::ClearStates(void) {
FGTrimAxis* ta; FGTrimAxis* ta;
mode=tCustom; mode=tCustom;
vector<FGTrimAxis*>::iterator iAxes; vector<FGTrimAxis*>::iterator iAxes;
iAxes = TrimAxes.begin(); iAxes = TrimAxes.begin();
@ -150,13 +150,13 @@ void FGTrim::ClearStates(void) {
TrimAxes.clear(); TrimAxes.clear();
//cout << "TrimAxes.size(): " << TrimAxes.size() << endl; //cout << "TrimAxes.size(): " << TrimAxes.size() << endl;
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGTrim::AddState( State state, Control control ) { bool FGTrim::AddState( State state, Control control ) {
FGTrimAxis* ta; FGTrimAxis* ta;
bool result=true; bool result=true;
mode = tCustom; mode = tCustom;
vector <FGTrimAxis*>::iterator iAxes = TrimAxes.begin(); vector <FGTrimAxis*>::iterator iAxes = TrimAxes.begin();
while (iAxes != TrimAxes.end()) { while (iAxes != TrimAxes.end()) {
@ -175,14 +175,14 @@ bool FGTrim::AddState( State state, Control control ) {
solution=new bool[TrimAxes.size()]; solution=new bool[TrimAxes.size()];
} }
return result; return result;
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGTrim::RemoveState( State state ) { bool FGTrim::RemoveState( State state ) {
FGTrimAxis* ta; FGTrimAxis* ta;
bool result=false; bool result=false;
mode = tCustom; mode = tCustom;
vector <FGTrimAxis*>::iterator iAxes = TrimAxes.begin(); vector <FGTrimAxis*>::iterator iAxes = TrimAxes.begin();
while (iAxes != TrimAxes.end()) { while (iAxes != TrimAxes.end()) {
@ -202,16 +202,16 @@ bool FGTrim::RemoveState( State state ) {
sub_iterations=new double[TrimAxes.size()]; sub_iterations=new double[TrimAxes.size()];
successful=new double[TrimAxes.size()]; successful=new double[TrimAxes.size()];
solution=new bool[TrimAxes.size()]; solution=new bool[TrimAxes.size()];
} }
return result; return result;
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGTrim::EditState( State state, Control new_control ){ bool FGTrim::EditState( State state, Control new_control ){
FGTrimAxis* ta; FGTrimAxis* ta;
bool result=false; bool result=false;
mode = tCustom; mode = tCustom;
vector <FGTrimAxis*>::iterator iAxes = TrimAxes.begin(); vector <FGTrimAxis*>::iterator iAxes = TrimAxes.begin();
while (iAxes != TrimAxes.end()) { while (iAxes != TrimAxes.end()) {
@ -226,13 +226,13 @@ bool FGTrim::EditState( State state, Control new_control ){
iAxes++; iAxes++;
} }
return result; return result;
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bool FGTrim::DoTrim(void) { bool FGTrim::DoTrim(void) {
trim_failed=false; trim_failed=false;
int i; int i;
@ -241,7 +241,7 @@ bool FGTrim::DoTrim(void) {
} }
fdmex->DisableOutput(); fdmex->DisableOutput();
fgic->SetPRadpsIC(0.0); fgic->SetPRadpsIC(0.0);
fgic->SetQRadpsIC(0.0); fgic->SetQRadpsIC(0.0);
fgic->SetRRadpsIC(0.0); fgic->SetRRadpsIC(0.0);
@ -253,8 +253,8 @@ bool FGTrim::DoTrim(void) {
if(TrimAxes[current_axis]->GetStateType() == tQdot) { if(TrimAxes[current_axis]->GetStateType() == tQdot) {
if(mode == tGround) { if(mode == tGround) {
TrimAxes[current_axis]->initTheta(); TrimAxes[current_axis]->initTheta();
} }
} }
xlo=TrimAxes[current_axis]->GetControlMin(); xlo=TrimAxes[current_axis]->GetControlMin();
xhi=TrimAxes[current_axis]->GetControlMax(); xhi=TrimAxes[current_axis]->GetControlMax();
TrimAxes[current_axis]->SetControl((xlo+xhi)/2); TrimAxes[current_axis]->SetControl((xlo+xhi)/2);
@ -264,8 +264,8 @@ bool FGTrim::DoTrim(void) {
successful[current_axis]=0; successful[current_axis]=0;
solution[current_axis]=false; solution[current_axis]=false;
} }
if(mode == tPullup ) { if(mode == tPullup ) {
cout << "Setting pitch rate and nlf... " << endl; cout << "Setting pitch rate and nlf... " << endl;
setupPullup(); setupPullup();
@ -275,8 +275,8 @@ bool FGTrim::DoTrim(void) {
} else if (mode == tTurn) { } else if (mode == tTurn) {
setupTurn(); setupTurn();
//TrimAxes[0]->SetStateTarget(targetNlf); //TrimAxes[0]->SetStateTarget(targetNlf);
} }
do { do {
axis_count=0; axis_count=0;
for(current_axis=0;current_axis<TrimAxes.size();current_axis++) { for(current_axis=0;current_axis<TrimAxes.size();current_axis++) {
@ -284,26 +284,26 @@ bool FGTrim::DoTrim(void) {
updateRates(); updateRates();
Nsub=0; Nsub=0;
if(!solution[current_axis]) { if(!solution[current_axis]) {
if(checkLimits()) { if(checkLimits()) {
solution[current_axis]=true; solution[current_axis]=true;
solve(); solve();
} }
} else if(findInterval()) { } else if(findInterval()) {
solve(); solve();
} else { } else {
solution[current_axis]=false; solution[current_axis]=false;
} }
sub_iterations[current_axis]+=Nsub; sub_iterations[current_axis]+=Nsub;
} }
for(current_axis=0;current_axis<TrimAxes.size();current_axis++) { for(current_axis=0;current_axis<TrimAxes.size();current_axis++) {
//these checks need to be done after all the axes have run //these checks need to be done after all the axes have run
if(Debug > 0) TrimAxes[current_axis]->AxisReport(); if(Debug > 0) TrimAxes[current_axis]->AxisReport();
if(TrimAxes[current_axis]->InTolerance()) { if(TrimAxes[current_axis]->InTolerance()) {
axis_count++; axis_count++;
successful[current_axis]++; successful[current_axis]++;
} }
} }
if((axis_count == TrimAxes.size()-1) && (TrimAxes.size() > 1)) { if((axis_count == TrimAxes.size()-1) && (TrimAxes.size() > 1)) {
//cout << TrimAxes.size()-1 << " out of " << TrimAxes.size() << "!" << endl; //cout << TrimAxes.size()-1 << " out of " << TrimAxes.size() << "!" << endl;
@ -412,19 +412,19 @@ bool FGTrim::solve(void) {
} }
//cout << i << endl; //cout << i << endl;
}//end while }//end while
if(Nsub < max_sub_iterations) success=true; if(Nsub < max_sub_iterations) success=true;
} }
return success; return success;
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/* /*
produces an interval (xlo..xhi) on one side or the other of the current produces an interval (xlo..xhi) on one side or the other of the current
control value in which a solution exists. This domain is, hopefully, control value in which a solution exists. This domain is, hopefully,
smaller than xmin..0 or 0..xmax and the solver will require fewer iterations smaller than xmin..0 or 0..xmax and the solver will require fewer iterations
to find the solution. This is, hopefully, more efficient than having the to find the solution. This is, hopefully, more efficient than having the
solver start from scratch every time. Maybe it isn't though... solver start from scratch every time. Maybe it isn't though...
This tries to take advantage of the idea that the changes from iteration to This tries to take advantage of the idea that the changes from iteration to
iteration will be small after the first one or two top-level iterations. iteration will be small after the first one or two top-level iterations.
@ -432,16 +432,16 @@ bool FGTrim::solve(void) {
assumes that changing the control will a produce significant change in the assumes that changing the control will a produce significant change in the
accel i.e. checkLimits() has already been called. accel i.e. checkLimits() has already been called.
if a solution is found above the current control, the function returns true if a solution is found above the current control, the function returns true
and xlo is set to the current control, xhi to the interval max it found, and and xlo is set to the current control, xhi to the interval max it found, and
solutionDomain is set to 1. solutionDomain is set to 1.
if the solution lies below the current control, then the function returns if the solution lies below the current control, then the function returns
true and xlo is set to the interval min it found and xmax to the current true and xlo is set to the interval min it found and xmax to the current
control. if no solution is found, then the function returns false. control. if no solution is found, then the function returns false.
in all cases, alo=accel(xlo) and ahi=accel(xhi) after the function exits. in all cases, alo=accel(xlo) and ahi=accel(xhi) after the function exits.
no assumptions about the state of the sim after this function has run no assumptions about the state of the sim after this function has run
can be made. can be made.
*/ */
bool FGTrim::findInterval(void) { bool FGTrim::findInterval(void) {
@ -452,14 +452,14 @@ bool FGTrim::findInterval(void) {
double xmin=TrimAxes[current_axis]->GetControlMin(); double xmin=TrimAxes[current_axis]->GetControlMin();
double xmax=TrimAxes[current_axis]->GetControlMax(); double xmax=TrimAxes[current_axis]->GetControlMax();
double lastxlo,lastxhi,lastalo,lastahi; double lastxlo,lastxhi,lastalo,lastahi;
step=0.025*fabs(xmax); step=0.025*fabs(xmax);
xlo=xhi=current_control; xlo=xhi=current_control;
alo=ahi=current_accel; alo=ahi=current_accel;
lastxlo=xlo;lastxhi=xhi; lastxlo=xlo;lastxhi=xhi;
lastalo=alo;lastahi=ahi; lastalo=alo;lastahi=ahi;
do { do {
Nsub++; Nsub++;
step*=2; step*=2;
xlo-=step; xlo-=step;
@ -487,7 +487,7 @@ bool FGTrim::findInterval(void) {
alo=lastahi; alo=lastahi;
//xlo=current_control; //xlo=current_control;
//alo=current_accel; //alo=current_accel;
} }
} }
lastxlo=xlo;lastxhi=xhi; lastxlo=xlo;lastxhi=xhi;
lastalo=alo;lastahi=ahi; lastalo=alo;lastahi=ahi;
@ -505,13 +505,13 @@ bool FGTrim::findInterval(void) {
// 1 if solution is between the current and max // 1 if solution is between the current and max
// -1 if solution is between the min and current // -1 if solution is between the min and current
// 0 if there is no solution // 0 if there is no solution
// //
//if changing the control produces no significant change in the accel then //if changing the control produces no significant change in the accel then
//solutionDomain is set to zero and the function returns false //solutionDomain is set to zero and the function returns false
//if a solution is found, then xlo and xhi are set so that they bracket //if a solution is found, then xlo and xhi are set so that they bracket
//the solution, alo is set to accel(xlo), and ahi is set to accel(xhi) //the solution, alo is set to accel(xlo), and ahi is set to accel(xhi)
//if there is no change or no solution then xlo=xmin, alo=accel(xmin) and //if there is no change or no solution then xlo=xmin, alo=accel(xmin) and
//xhi=xmax and ahi=accel(xmax) //xhi=xmax and ahi=accel(xmax)
//in all cases the sim is left such that the control=xmax and accel=ahi //in all cases the sim is left such that the control=xmax and accel=ahi
bool FGTrim::checkLimits(void) { bool FGTrim::checkLimits(void) {
@ -542,9 +542,9 @@ bool FGTrim::checkLimits(void) {
solutionExists=true; solutionExists=true;
solutionDomain=1; solutionDomain=1;
xlo=current_control; xlo=current_control;
alo=current_accel; alo=current_accel;
} }
} }
TrimAxes[current_axis]->SetControl(current_control); TrimAxes[current_axis]->SetControl(current_control);
TrimAxes[current_axis]->Run(); TrimAxes[current_axis]->Run();
return solutionExists; return solutionExists;
@ -562,40 +562,40 @@ void FGTrim::setupPullup() {
cout << targetNlf << ", " << q << endl; cout << targetNlf << ", " << q << endl;
fgic->SetQRadpsIC(q); fgic->SetQRadpsIC(q);
cout << "setPitchRateInPullup() complete" << endl; cout << "setPitchRateInPullup() complete" << endl;
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGTrim::setupTurn(void){ void FGTrim::setupTurn(void){
double g,phi; double g,phi;
phi = fgic->GetRollAngleRadIC(); phi = fgic->GetPhiRadIC();
if( fabs(phi) > 0.001 && fabs(phi) < 1.56 ) { if( fabs(phi) > 0.001 && fabs(phi) < 1.56 ) {
targetNlf = 1 / cos(phi); targetNlf = 1 / cos(phi);
g = fdmex->GetInertial()->gravity(); g = fdmex->GetInertial()->gravity();
psidot = g*tan(phi) / fgic->GetUBodyFpsIC(); psidot = g*tan(phi) / fgic->GetUBodyFpsIC();
cout << targetNlf << ", " << psidot << endl; cout << targetNlf << ", " << psidot << endl;
} }
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGTrim::updateRates(void){ void FGTrim::updateRates(void){
if( mode == tTurn ) { if( mode == tTurn ) {
double phi = fgic->GetRollAngleRadIC(); double phi = fgic->GetPhiRadIC();
double g = fdmex->GetInertial()->gravity(); double g = fdmex->GetInertial()->gravity();
double p,q,r,theta; double p,q,r,theta;
if(fabs(phi) > 0.001 && fabs(phi) < 1.56 ) { if(fabs(phi) > 0.001 && fabs(phi) < 1.56 ) {
theta=fgic->GetPitchAngleRadIC(); theta=fgic->GetThetaRadIC();
phi=fgic->GetRollAngleRadIC(); phi=fgic->GetPhiRadIC();
psidot = g*tan(phi) / fgic->GetUBodyFpsIC(); psidot = g*tan(phi) / fgic->GetUBodyFpsIC();
p=-psidot*sin(theta); p=-psidot*sin(theta);
q=psidot*cos(theta)*sin(phi); q=psidot*cos(theta)*sin(phi);
r=psidot*cos(theta)*cos(phi); r=psidot*cos(theta)*cos(phi);
} else { } else {
p=q=r=0; p=q=r=0;
} }
fgic->SetPRadpsIC(p); fgic->SetPRadpsIC(p);
fgic->SetQRadpsIC(q); fgic->SetQRadpsIC(q);
fgic->SetRRadpsIC(r); fgic->SetRRadpsIC(r);
@ -605,21 +605,21 @@ void FGTrim::updateRates(void){
cgamma=cos(fgic->GetFlightPathAngleRadIC()); cgamma=cos(fgic->GetFlightPathAngleRadIC());
q=g*(targetNlf-cgamma)/fgic->GetVtrueFpsIC(); q=g*(targetNlf-cgamma)/fgic->GetVtrueFpsIC();
fgic->SetQRadpsIC(q); fgic->SetQRadpsIC(q);
} }
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGTrim::setDebug(void) { void FGTrim::setDebug(void) {
if(debug_axis == tAll || if(debug_axis == tAll ||
TrimAxes[current_axis]->GetStateType() == debug_axis ) { TrimAxes[current_axis]->GetStateType() == debug_axis ) {
Debug=DebugLevel; Debug=DebugLevel;
return; return;
} else { } else {
Debug=0; Debug=0;
return; return;
} }
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -628,7 +628,7 @@ void FGTrim::SetMode(TrimMode tt) {
mode=tt; mode=tt;
switch(tt) { switch(tt) {
case tFull: case tFull:
if (debug_lvl > 0) if (debug_lvl > 0)
cout << " Full Trim" << endl; cout << " Full Trim" << endl;
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAlpha )); TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAlpha ));
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle )); TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle ));
@ -639,14 +639,14 @@ void FGTrim::SetMode(TrimMode tt) {
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tRdot,tRudder )); TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tRdot,tRudder ));
break; break;
case tLongitudinal: case tLongitudinal:
if (debug_lvl > 0) if (debug_lvl > 0)
cout << " Longitudinal Trim" << endl; cout << " Longitudinal Trim" << endl;
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAlpha )); TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAlpha ));
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle )); TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tUdot,tThrottle ));
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim )); TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tPitchTrim ));
break; break;
case tGround: case tGround:
if (debug_lvl > 0) if (debug_lvl > 0)
cout << " Ground Trim" << endl; cout << " Ground Trim" << endl;
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAltAGL )); TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAltAGL ));
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tTheta )); TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tTheta ));
@ -678,6 +678,6 @@ void FGTrim::SetMode(TrimMode tt) {
successful=new double[TrimAxes.size()]; successful=new double[TrimAxes.size()];
solution=new bool[TrimAxes.size()]; solution=new bool[TrimAxes.size()];
current_axis=0; current_axis=0;
} }
//YOU WERE WARNED, BUT YOU DID IT ANYWAY. //YOU WERE WARNED, BUT YOU DID IT ANYWAY.
} }

View file

@ -230,10 +230,10 @@ void FGTrimAxis::setControl(void) {
case tYawTrim: case tYawTrim:
case tRudder: fdmex->GetFCS()->SetDrCmd(control_value); break; case tRudder: fdmex->GetFCS()->SetDrCmd(control_value); break;
case tAltAGL: fgic->SetAltitudeAGLFtIC(control_value); break; case tAltAGL: fgic->SetAltitudeAGLFtIC(control_value); break;
case tTheta: fgic->SetPitchAngleRadIC(control_value); break; case tTheta: fgic->SetThetaRadIC(control_value); break;
case tPhi: fgic->SetRollAngleRadIC(control_value); break; case tPhi: fgic->SetPhiRadIC(control_value); break;
case tGamma: fgic->SetFlightPathAngleRadIC(control_value); break; case tGamma: fgic->SetFlightPathAngleRadIC(control_value); break;
case tHeading: fgic->SetTrueHeadingRadIC(control_value); break; case tHeading: fgic->SetPsiRadIC(control_value); break;
} }
} }
@ -282,7 +282,7 @@ void FGTrimAxis::SetThetaOnGround(double ff) {
fgic->SetAltitudeAGLFtIC(hagl); fgic->SetAltitudeAGLFtIC(hagl);
cout << "SetThetaOnGround new alt: " << hagl << endl; cout << "SetThetaOnGround new alt: " << hagl << endl;
} }
fgic->SetPitchAngleRadIC(ff); fgic->SetThetaRadIC(ff);
cout << "SetThetaOnGround new theta: " << ff << endl; cout << "SetThetaOnGround new theta: " << ff << endl;
} }
@ -327,10 +327,10 @@ bool FGTrimAxis::initTheta(void) {
zForward=fdmex->GetGroundReactions()->GetGearUnit(iForward)->GetLocalGear(3); zForward=fdmex->GetGroundReactions()->GetGearUnit(iForward)->GetLocalGear(3);
zDiff = zForward - zAft; zDiff = zForward - zAft;
level=false; level=false;
theta=fgic->GetPitchAngleDegIC(); theta=fgic->GetThetaDegIC();
while(!level && (i < 100)) { while(!level && (i < 100)) {
theta+=radtodeg*atan(zDiff/xDiff); theta+=radtodeg*atan(zDiff/xDiff);
fgic->SetPitchAngleDegIC(theta); fgic->SetThetaDegIC(theta);
fdmex->RunIC(); fdmex->RunIC();
zAft=fdmex->GetGroundReactions()->GetGearUnit(iAft)->GetLocalGear(3); zAft=fdmex->GetGroundReactions()->GetGearUnit(iAft)->GetLocalGear(3);
zForward=fdmex->GetGroundReactions()->GetGearUnit(iForward)->GetLocalGear(3); zForward=fdmex->GetGroundReactions()->GetGearUnit(iForward)->GetLocalGear(3);
@ -381,7 +381,7 @@ void FGTrimAxis::SetPhiOnGround(double ff) {
fgic->SetAltitudeAGLFtIC(hagl); fgic->SetAltitudeAGLFtIC(hagl);
} }
fgic->SetRollAngleRadIC(ff); fgic->SetPhiRadIC(ff);
} }