Sync. w. JSBSim CVS
This commit is contained in:
parent
9968dfd814
commit
6849328fea
9 changed files with 506 additions and 218 deletions
|
@ -724,8 +724,6 @@ void FGFDMExec::DoTrim(int mode)
|
|||
{
|
||||
double saved_time;
|
||||
|
||||
cout << "DoTrim called" << endl;
|
||||
|
||||
if (Constructing) return;
|
||||
|
||||
if (mode < 0 || mode > JSBSim::tNone) {
|
||||
|
|
|
@ -158,10 +158,11 @@ CLASS DOCUMENTATION
|
|||
a message is printed out when they go out of bounds
|
||||
|
||||
<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),
|
||||
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
|
||||
@version $Revision$
|
||||
|
|
|
@ -272,8 +272,7 @@ void FGState::ReportState(void)
|
|||
|
||||
void FGState::bind(void)
|
||||
{
|
||||
PropertyManager->Tie("sim-time-sec",this,
|
||||
&FGState::Getsim_time);
|
||||
PropertyManager->Tie("sim-time-sec", this, &FGState::Getsim_time);
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
|
|
@ -90,8 +90,10 @@ CLASS DOCUMENTATION
|
|||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
|
||||
|
||||
/** Encapsulates the calculation of aircraft state.
|
||||
<h3>Properties</h3>
|
||||
@property sim-time-sec (read only) cumulative simulation in seconds.
|
||||
@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.
|
||||
@param FGIC pointer to an initial conditions object.
|
||||
@see FGInitialConditions.
|
||||
*/
|
||||
@see FGInitialConditions. */
|
||||
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; }
|
||||
|
||||
/// Returns the simulation delta T.
|
||||
inline double Getdt(void) {
|
||||
return dt;
|
||||
}
|
||||
inline double Getdt(void) {return dt;}
|
||||
|
||||
/// Suspends the simulation and sets the delta T to zero.
|
||||
inline void SuspendIntegration(void) {saved_dt = dt; dt = 0.0;}
|
||||
|
||||
/// Resumes the simulation by resetting delta T to the correct value.
|
||||
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;}
|
||||
|
||||
/** Sets the current sim time.
|
||||
@param cur_time the current time
|
||||
@return the current time.
|
||||
*/
|
||||
@return the current simulation time. */
|
||||
inline double Setsim_time(double cur_time) {
|
||||
sim_time = cur_time;
|
||||
return sim_time;
|
||||
}
|
||||
|
||||
/** Sets the integration time step for the simulation executive.
|
||||
@param delta_t the time step in seconds.
|
||||
*/
|
||||
inline void Setdt(double delta_t) {
|
||||
dt = delta_t;
|
||||
}
|
||||
@param delta_t the time step in seconds. */
|
||||
inline void Setdt(double delta_t) { dt = delta_t; }
|
||||
|
||||
/** Increments the simulation time.
|
||||
@return the new simulation time.
|
||||
*/
|
||||
@return the new simulation time. */
|
||||
inline double IncrTime(void) {
|
||||
sim_time+=dt;
|
||||
return sim_time;
|
||||
|
@ -162,13 +160,9 @@ public:
|
|||
FGMatrix33& GetTb2s(void);
|
||||
|
||||
/** Prints a summary of simulator state (speed, altitude,
|
||||
configuration, etc.)
|
||||
*/
|
||||
configuration, etc.) */
|
||||
void ReportState(void);
|
||||
|
||||
void bind();
|
||||
void unbind();
|
||||
|
||||
private:
|
||||
double sim_time, dt;
|
||||
double saved_dt;
|
||||
|
@ -187,6 +181,9 @@ private:
|
|||
FGAuxiliary* Auxiliary;
|
||||
FGPropertyManager* PropertyManager;
|
||||
|
||||
void bind();
|
||||
void unbind();
|
||||
|
||||
void Debug(int from);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -850,7 +850,7 @@ bool FGJSBsim::copy_from_JSBsim()
|
|||
spoilers_pos_pct->setDoubleValue( FCS->GetDspPos(ofNorm) );
|
||||
|
||||
// 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);
|
||||
SGPropertyNode* node = fgGetNode("/sim/presets", true);
|
||||
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);
|
||||
|
||||
update_ic();
|
||||
fgic->SetPitchAngleRadIC(theta);
|
||||
fgic->SetRollAngleRadIC(phi);
|
||||
fgic->SetTrueHeadingRadIC(psi);
|
||||
fgic->SetThetaRadIC(theta);
|
||||
fgic->SetPhiRadIC(phi);
|
||||
fgic->SetPsiRadIC(psi);
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
|
@ -1126,9 +1126,9 @@ void FGJSBsim::update_ic(void)
|
|||
fgic->SetLongitudeRadIC( get_Longitude() );
|
||||
fgic->SetAltitudeFtIC( get_Altitude() );
|
||||
fgic->SetVcalibratedKtsIC( get_V_calibrated_kts() );
|
||||
fgic->SetPitchAngleRadIC( get_Theta() );
|
||||
fgic->SetRollAngleRadIC( get_Phi() );
|
||||
fgic->SetTrueHeadingRadIC( get_Psi() );
|
||||
fgic->SetThetaRadIC( get_Theta() );
|
||||
fgic->SetPhiRadIC( get_Phi() );
|
||||
fgic->SetPsiRadIC( get_Psi() );
|
||||
fgic->SetClimbRateFpsIC( get_Climb_Rate() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -225,7 +225,7 @@ void FGInitialCondition::SetAlphaRadIC(double tt) {
|
|||
|
||||
//******************************************************************************
|
||||
|
||||
void FGInitialCondition::SetPitchAngleRadIC(double tt) {
|
||||
void FGInitialCondition::SetThetaRadIC(double tt) {
|
||||
theta=tt;
|
||||
stheta=sin(theta); ctheta=cos(theta);
|
||||
getAlpha();
|
||||
|
@ -242,7 +242,7 @@ void FGInitialCondition::SetBetaRadIC(double tt) {
|
|||
|
||||
//******************************************************************************
|
||||
|
||||
void FGInitialCondition::SetRollAngleRadIC(double tt) {
|
||||
void FGInitialCondition::SetPhiRadIC(double tt) {
|
||||
phi=tt;
|
||||
sphi=sin(phi); cphi=cos(phi);
|
||||
getTheta();
|
||||
|
@ -250,7 +250,7 @@ void FGInitialCondition::SetRollAngleRadIC(double tt) {
|
|||
|
||||
//******************************************************************************
|
||||
|
||||
void FGInitialCondition::SetTrueHeadingRadIC(double tt) {
|
||||
void FGInitialCondition::SetPsiRadIC(double tt) {
|
||||
psi=tt;
|
||||
spsi=sin(psi); cpsi=cos(psi);
|
||||
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)
|
||||
return atan2(weast,wnorth)*radtodeg;
|
||||
else if(wnorth > 0)
|
||||
|
@ -774,11 +774,11 @@ bool FGInitialCondition::Load(string rstfile, bool useStoredPath)
|
|||
if (document->FindElement("longitude"))
|
||||
SetLongitudeDegIC(document->FindElementValueAsNumberConvertTo("longitude", "DEG"));
|
||||
if (document->FindElement("phi"))
|
||||
SetRollAngleDegIC(document->FindElementValueAsNumberConvertTo("phi", "DEG"));
|
||||
SetPhiDegIC(document->FindElementValueAsNumberConvertTo("phi", "DEG"));
|
||||
if (document->FindElement("theta"))
|
||||
SetPitchAngleDegIC(document->FindElementValueAsNumberConvertTo("theta", "DEG"));
|
||||
SetThetaDegIC(document->FindElementValueAsNumberConvertTo("theta", "DEG"));
|
||||
if (document->FindElement("psi"))
|
||||
SetTrueHeadingDegIC(document->FindElementValueAsNumberConvertTo("psi", "DEG"));
|
||||
SetPsiDegIC(document->FindElementValueAsNumberConvertTo("psi", "DEG"));
|
||||
if (document->FindElement("alpha"))
|
||||
SetAlphaDegIC(document->FindElementValueAsNumberConvertTo("alpha", "DEG"));
|
||||
if (document->FindElement("beta"))
|
||||
|
@ -837,7 +837,7 @@ void FGInitialCondition::bind(void){
|
|||
&FGInitialCondition::GetVtrueKtsIC,
|
||||
&FGInitialCondition::SetVtrueKtsIC,
|
||||
true);
|
||||
PropertyManager->Tie("ic/mach-norm", this,
|
||||
PropertyManager->Tie("ic/mach", this,
|
||||
&FGInitialCondition::GetMachIC,
|
||||
&FGInitialCondition::SetMachIC,
|
||||
true);
|
||||
|
@ -858,15 +858,15 @@ void FGInitialCondition::bind(void){
|
|||
&FGInitialCondition::SetBetaDegIC,
|
||||
true);
|
||||
PropertyManager->Tie("ic/theta-deg", this,
|
||||
&FGInitialCondition::GetPitchAngleDegIC,
|
||||
&FGInitialCondition::SetPitchAngleDegIC,
|
||||
&FGInitialCondition::GetThetaDegIC,
|
||||
&FGInitialCondition::SetThetaDegIC,
|
||||
true);
|
||||
PropertyManager->Tie("ic/phi-deg", this,
|
||||
&FGInitialCondition::GetRollAngleDegIC,
|
||||
&FGInitialCondition::SetRollAngleDegIC,
|
||||
&FGInitialCondition::GetPhiDegIC,
|
||||
&FGInitialCondition::SetPhiDegIC,
|
||||
true);
|
||||
PropertyManager->Tie("ic/psi-true-deg", this,
|
||||
&FGInitialCondition::GetHeadingDegIC );
|
||||
&FGInitialCondition::GetPsiDegIC );
|
||||
PropertyManager->Tie("ic/lat-gc-deg", this,
|
||||
&FGInitialCondition::GetLatitudeDegIC,
|
||||
&FGInitialCondition::SetLatitudeDegIC,
|
||||
|
@ -913,16 +913,16 @@ void FGInitialCondition::bind(void){
|
|||
&FGInitialCondition::GetWindDFpsIC);
|
||||
PropertyManager->Tie("ic/vw-mag-fps", this,
|
||||
&FGInitialCondition::GetWindFpsIC);
|
||||
/* PropertyManager->Tie("ic/vw-dir-deg", this,
|
||||
PropertyManager->Tie("ic/vw-dir-deg", this,
|
||||
&FGInitialCondition::GetWindDirDegIC,
|
||||
&FGInitialCondition::SetWindDirDegIC,
|
||||
true); */
|
||||
true);
|
||||
|
||||
PropertyManager->Tie("ic/roc-fps", this,
|
||||
&FGInitialCondition::GetClimbRateFpsIC,
|
||||
&FGInitialCondition::SetClimbRateFpsIC,
|
||||
true);
|
||||
/* PropertyManager->Tie("ic/u-fps", this,
|
||||
PropertyManager->Tie("ic/u-fps", this,
|
||||
&FGInitialCondition::GetUBodyFpsIC,
|
||||
&FGInitialCondition::SetUBodyFpsIC,
|
||||
true);
|
||||
|
@ -933,7 +933,7 @@ void FGInitialCondition::bind(void){
|
|||
PropertyManager->Tie("ic/w-fps", this,
|
||||
&FGInitialCondition::GetWBodyFpsIC,
|
||||
&FGInitialCondition::SetWBodyFpsIC,
|
||||
true); */
|
||||
true);
|
||||
|
||||
PropertyManager->Tie("ic/gamma-rad", this,
|
||||
&FGInitialCondition::GetFlightPathAngleRadIC,
|
||||
|
@ -944,19 +944,19 @@ void FGInitialCondition::bind(void){
|
|||
&FGInitialCondition::SetAlphaRadIC,
|
||||
true);
|
||||
PropertyManager->Tie("ic/theta-rad", this,
|
||||
&FGInitialCondition::GetPitchAngleRadIC,
|
||||
&FGInitialCondition::SetPitchAngleRadIC,
|
||||
&FGInitialCondition::GetThetaRadIC,
|
||||
&FGInitialCondition::SetThetaRadIC,
|
||||
true);
|
||||
PropertyManager->Tie("ic/beta-rad", this,
|
||||
&FGInitialCondition::GetBetaRadIC,
|
||||
&FGInitialCondition::SetBetaRadIC,
|
||||
true);
|
||||
PropertyManager->Tie("ic/phi-rad", this,
|
||||
&FGInitialCondition::GetRollAngleRadIC,
|
||||
&FGInitialCondition::SetRollAngleRadIC,
|
||||
&FGInitialCondition::GetPhiRadIC,
|
||||
&FGInitialCondition::SetPhiRadIC,
|
||||
true);
|
||||
PropertyManager->Tie("ic/psi-true-rad", this,
|
||||
&FGInitialCondition::GetHeadingRadIC);
|
||||
&FGInitialCondition::GetPsiRadIC);
|
||||
PropertyManager->Tie("ic/lat-gc-rad", this,
|
||||
&FGInitialCondition::GetLatitudeRadIC,
|
||||
&FGInitialCondition::SetLatitudeRadIC,
|
||||
|
|
|
@ -73,25 +73,28 @@ CLASS DOCUMENTATION
|
|||
/** 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.
|
||||
very dynamic state (unless, of course, you have chosen your IC's wisely, or
|
||||
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);
|
||||
fgic->SetVcalibratedKtsIC()
|
||||
fgic->SetAltitudeFtIC();
|
||||
|
||||
//to directly into Run
|
||||
// directly into Run
|
||||
FDMExec->GetState()->Initialize(fgic)
|
||||
delete fgic;
|
||||
FDMExec->Run()
|
||||
|
||||
//or to loop the sim w/o integrating
|
||||
FDMExec->RunIC(fgic)
|
||||
@endcode
|
||||
|
||||
Speed:
|
||||
<h2>Speed</h2>
|
||||
|
||||
Since vc, ve, vt, and mach all represent speed, the remaining
|
||||
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
|
||||
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
|
||||
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:
|
||||
|
||||
UBODY <velocity, ft/sec>
|
||||
VBODY <velocity, ft/sec>
|
||||
WBODY <velocity, ft/sec>
|
||||
LATITUDE <position, degrees>
|
||||
LONGITUDE <position, degrees>
|
||||
PHI <orientation, degrees>
|
||||
THETA <orientation, degrees>
|
||||
PSI <orientation, degrees>
|
||||
ALPHA <angle, degrees>
|
||||
BETA <angle, degrees>
|
||||
GAMMA <angle, degrees>
|
||||
ROC <vertical velocity, ft/sec>
|
||||
ALTITUDE <altitude, ft>
|
||||
WINDDIR <wind from-angle, degrees>
|
||||
VWIND <magnitude wind speed, ft/sec>
|
||||
HWIND <headwind speed, knots>
|
||||
XWIND <crosswind speed, knots>
|
||||
VC <calibrated airspeed, ft/sec>
|
||||
MACH <mach>
|
||||
VGROUND <ground speed, ft/sec>
|
||||
RUNNING <0 or 1>
|
||||
- ubody (velocity, ft/sec)
|
||||
- vbody (velocity, ft/sec)
|
||||
- wbody (velocity, ft/sec)
|
||||
- latitude (position, degrees)
|
||||
- longitude (position, degrees)
|
||||
- phi (orientation, degrees)
|
||||
- theta (orientation, degrees)
|
||||
- psi (orientation, degrees)
|
||||
- alpha (angle, degrees)
|
||||
- beta (angle, degrees)
|
||||
- gamma (angle, degrees)
|
||||
- roc (vertical velocity, ft/sec)
|
||||
- altitude (altitude, ft)
|
||||
- winddir (wind from-angle, degrees)
|
||||
- vwind (magnitude wind speed, ft/sec)
|
||||
- hwind (headwind speed, knots)
|
||||
- xwind (crosswind speed, knots)
|
||||
- vc (calibrated airspeed, ft/sec)
|
||||
- mach (mach)
|
||||
- vground (ground speed, ft/sec)
|
||||
- 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
|
||||
@version "$Id$"
|
||||
|
@ -159,126 +206,370 @@ public:
|
|||
/// 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);
|
||||
/** Set calibrated airspeed initial condition in knots.
|
||||
@param vc Calibrated airspeed in knots */
|
||||
void SetVcalibratedKtsIC(double vc);
|
||||
|
||||
inline void SetAlphaDegIC(double tt) { SetAlphaRadIC(tt*degtorad); }
|
||||
inline void SetBetaDegIC(double tt) { SetBetaRadIC(tt*degtorad);}
|
||||
/** Set equivalent airspeed initial condition in knots.
|
||||
@param ve Equivalent airspeed in knots */
|
||||
void SetVequivalentKtsIC(double ve);
|
||||
|
||||
inline void SetPitchAngleDegIC(double tt) { SetPitchAngleRadIC(tt*degtorad); }
|
||||
inline void SetRollAngleDegIC(double tt) { SetRollAngleRadIC(tt*degtorad);}
|
||||
inline void SetTrueHeadingDegIC(double tt){ SetTrueHeadingRadIC(tt*degtorad); }
|
||||
/** Set true airspeed initial condition in knots.
|
||||
@param vt True airspeed in knots */
|
||||
inline void SetVtrueKtsIC(double vt) { SetVtrueFpsIC(vt*ktstofps); }
|
||||
|
||||
void SetClimbRateFpmIC(double tt);
|
||||
inline void SetFlightPathAngleDegIC(double tt) { SetFlightPathAngleRadIC(tt*degtorad); }
|
||||
/** Set ground speed initial condition in knots.
|
||||
@param vg Ground speed in knots */
|
||||
inline void SetVgroundKtsIC(double vg) { SetVgroundFpsIC(vg*ktstofps); }
|
||||
|
||||
void SetAltitudeFtIC(double tt);
|
||||
void SetAltitudeAGLFtIC(double tt);
|
||||
/** Set mach initial condition.
|
||||
@param mach Mach number */
|
||||
void SetMachIC(double mach);
|
||||
|
||||
void SetSeaLevelRadiusFtIC(double tt);
|
||||
void SetTerrainAltitudeFtIC(double tt);
|
||||
/** Sets angle of attack initial condition in degrees.
|
||||
@param a Alpha in degrees */
|
||||
inline void SetAlphaDegIC(double a) { SetAlphaRadIC(a*degtorad); }
|
||||
|
||||
inline void SetLatitudeDegIC(double tt) { latitude=tt*degtorad; }
|
||||
inline void SetLongitudeDegIC(double tt) { longitude=tt*degtorad; }
|
||||
/** Sets angle of sideslip initial condition in degrees.
|
||||
@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; }
|
||||
|
||||
/** Gets the initial equivalent airspeed.
|
||||
@return Initial equivalent airspeed in knots */
|
||||
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; }
|
||||
|
||||
/** Gets the initial true velocity.
|
||||
@return Initial true airspeed in knots. */
|
||||
inline double GetVtrueKtsIC(void) const { return vt*fpstokts; }
|
||||
|
||||
/** Gets the initial mach.
|
||||
@return Initial mach number */
|
||||
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; }
|
||||
|
||||
/** Gets the initial flight path angle.
|
||||
@return Initial flight path angle in degrees */
|
||||
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; }
|
||||
|
||||
/** Gets the initial sideslip angle.
|
||||
@return Initial beta in degrees */
|
||||
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; }
|
||||
/** Gets the initial pitch angle.
|
||||
@return Initial pitch angle in degrees */
|
||||
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; }
|
||||
|
||||
/** Gets the initial longitude.
|
||||
@return Initial longitude in degrees */
|
||||
inline double GetLongitudeDegIC(void) const { return longitude*radtodeg; }
|
||||
|
||||
/** Gets the initial altitude.
|
||||
@return Initial altitude in feet. */
|
||||
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; }
|
||||
|
||||
/** Gets the initial sea level radius.
|
||||
@return Initial 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; }
|
||||
|
||||
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; }
|
||||
/** Sets the initial ground speed.
|
||||
@param vg Initial ground speed in feet/second */
|
||||
void SetVgroundFpsIC(double vg);
|
||||
|
||||
/** 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);
|
||||
|
||||
/** Sets the initial total wind speed.
|
||||
@param mag Initial wind velocity magnitude in knots */
|
||||
void SetWindMagKtsIC(double mag);
|
||||
|
||||
/** Sets the initial wind direction.
|
||||
@param dir Initial direction wind is coming from in degrees */
|
||||
void SetWindDirDegIC(double dir);
|
||||
|
||||
/** Sets the initial headwind velocity.
|
||||
@param head Initial headwind speed in knots */
|
||||
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 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; }
|
||||
|
||||
/** Gets the initial true velocity.
|
||||
@return Initial true velocity in feet/second */
|
||||
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; }
|
||||
|
||||
/** 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; }
|
||||
|
||||
/** 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; }
|
||||
|
||||
/** Gets the initial wind velocity in local frame.
|
||||
@return Initial wind velocity toward north in feet/second */
|
||||
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; }
|
||||
|
||||
/** Gets the initial wind velocity in local frame.
|
||||
@return Initial wind velocity toward north in feet/second */
|
||||
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); }
|
||||
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; }
|
||||
|
||||
/** Gets the initial body axis X velocity.
|
||||
@return Initial body axis X velocity in feet/second. */
|
||||
double GetUBodyFpsIC(void) const;
|
||||
|
||||
/** Gets the initial body axis Y velocity.
|
||||
@return Initial body axis Y velocity in feet/second. */
|
||||
double GetVBodyFpsIC(void) const;
|
||||
|
||||
/** Gets the initial body axis Z velocity.
|
||||
@return Initial body axis Z velocity in feet/second. */
|
||||
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; }
|
||||
|
||||
/** Gets the initial body axis pitch rate.
|
||||
@return Initial body axis pitch rate in radians/second */
|
||||
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; }
|
||||
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; }
|
||||
|
||||
/** Sets the initial flight path angle.
|
||||
@param gamma Initial flight path angle in radians */
|
||||
void SetFlightPathAngleRadIC(double gamma);
|
||||
|
||||
/** Sets the initial angle of attack.
|
||||
@param alpha Initial angle of attack in radians */
|
||||
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; }
|
||||
|
||||
/** Gets the initial angle of attack.
|
||||
@return Initial alpha in radians */
|
||||
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 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; }
|
||||
|
||||
/** Gets the initial longitude.
|
||||
@return Initial longitude in radians */
|
||||
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 GetPhiRadIC(void) const { return phi; }
|
||||
|
||||
/** Gets the initial heading angle.
|
||||
@return Initial heading angle in radians */
|
||||
inline double GetPsiRadIC(void) const { return psi; }
|
||||
|
||||
/** Gets the initial speedset.
|
||||
@return Initial speedset */
|
||||
inline speedset GetSpeedSet(void) { return lastSpeedSet; }
|
||||
|
||||
/** Gets the initial windset.
|
||||
@return Initial windset */
|
||||
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 );
|
||||
|
||||
void bind(void);
|
||||
void unbind(void);
|
||||
|
||||
|
||||
private:
|
||||
double vt,vc,ve,vg;
|
||||
double mach;
|
||||
|
@ -321,6 +612,8 @@ private:
|
|||
|
||||
bool findInterval(double x,double guess);
|
||||
bool solve(double *y, double x);
|
||||
void bind(void);
|
||||
void unbind(void);
|
||||
void Debug(int from);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
/*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
|
||||
Header: FGTrim.cpp
|
||||
Author: Tony Peden
|
||||
Date started: 9/8/99
|
||||
|
||||
|
||||
--------- Copyright (C) 1999 Anthony K. Peden (apeden@earthlink.net) ---------
|
||||
|
||||
|
||||
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
|
||||
Foundation; either version 2 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
|
||||
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
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
|
||||
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
|
||||
Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
|
||||
Further information about the GNU General Public License can also be found on
|
||||
the world wide web at http://www.gnu.org.
|
||||
|
||||
|
||||
|
||||
|
||||
HISTORY
|
||||
--------------------------------------------------------------------------------
|
||||
9/8/99 TP Created
|
||||
|
||||
|
||||
|
||||
|
||||
FUNCTIONAL DESCRIPTION
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
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
|
||||
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;
|
||||
Tolerance=1E-3;
|
||||
A_Tolerance = Tolerance / 10;
|
||||
|
||||
|
||||
Debug=0;DebugLevel=0;
|
||||
fdmex=FDMExec;
|
||||
fgic=fdmex->GetIC();
|
||||
|
@ -138,7 +138,7 @@ void FGTrim::Report(void) {
|
|||
|
||||
void FGTrim::ClearStates(void) {
|
||||
FGTrimAxis* ta;
|
||||
|
||||
|
||||
mode=tCustom;
|
||||
vector<FGTrimAxis*>::iterator iAxes;
|
||||
iAxes = TrimAxes.begin();
|
||||
|
@ -150,13 +150,13 @@ void FGTrim::ClearStates(void) {
|
|||
TrimAxes.clear();
|
||||
//cout << "TrimAxes.size(): " << TrimAxes.size() << endl;
|
||||
}
|
||||
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
bool FGTrim::AddState( State state, Control control ) {
|
||||
FGTrimAxis* ta;
|
||||
bool result=true;
|
||||
|
||||
|
||||
mode = tCustom;
|
||||
vector <FGTrimAxis*>::iterator iAxes = TrimAxes.begin();
|
||||
while (iAxes != TrimAxes.end()) {
|
||||
|
@ -175,14 +175,14 @@ bool FGTrim::AddState( State state, Control control ) {
|
|||
solution=new bool[TrimAxes.size()];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
bool FGTrim::RemoveState( State state ) {
|
||||
FGTrimAxis* ta;
|
||||
bool result=false;
|
||||
|
||||
|
||||
mode = tCustom;
|
||||
vector <FGTrimAxis*>::iterator iAxes = TrimAxes.begin();
|
||||
while (iAxes != TrimAxes.end()) {
|
||||
|
@ -202,16 +202,16 @@ bool FGTrim::RemoveState( State state ) {
|
|||
sub_iterations=new double[TrimAxes.size()];
|
||||
successful=new double[TrimAxes.size()];
|
||||
solution=new bool[TrimAxes.size()];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
bool FGTrim::EditState( State state, Control new_control ){
|
||||
bool FGTrim::EditState( State state, Control new_control ){
|
||||
FGTrimAxis* ta;
|
||||
bool result=false;
|
||||
|
||||
|
||||
mode = tCustom;
|
||||
vector <FGTrimAxis*>::iterator iAxes = TrimAxes.begin();
|
||||
while (iAxes != TrimAxes.end()) {
|
||||
|
@ -226,13 +226,13 @@ bool FGTrim::EditState( State state, Control new_control ){
|
|||
iAxes++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
bool FGTrim::DoTrim(void) {
|
||||
|
||||
|
||||
trim_failed=false;
|
||||
int i;
|
||||
|
||||
|
@ -241,7 +241,7 @@ bool FGTrim::DoTrim(void) {
|
|||
}
|
||||
|
||||
fdmex->DisableOutput();
|
||||
|
||||
|
||||
fgic->SetPRadpsIC(0.0);
|
||||
fgic->SetQRadpsIC(0.0);
|
||||
fgic->SetRRadpsIC(0.0);
|
||||
|
@ -253,8 +253,8 @@ bool FGTrim::DoTrim(void) {
|
|||
if(TrimAxes[current_axis]->GetStateType() == tQdot) {
|
||||
if(mode == tGround) {
|
||||
TrimAxes[current_axis]->initTheta();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
xlo=TrimAxes[current_axis]->GetControlMin();
|
||||
xhi=TrimAxes[current_axis]->GetControlMax();
|
||||
TrimAxes[current_axis]->SetControl((xlo+xhi)/2);
|
||||
|
@ -264,8 +264,8 @@ bool FGTrim::DoTrim(void) {
|
|||
successful[current_axis]=0;
|
||||
solution[current_axis]=false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if(mode == tPullup ) {
|
||||
cout << "Setting pitch rate and nlf... " << endl;
|
||||
setupPullup();
|
||||
|
@ -275,8 +275,8 @@ bool FGTrim::DoTrim(void) {
|
|||
} else if (mode == tTurn) {
|
||||
setupTurn();
|
||||
//TrimAxes[0]->SetStateTarget(targetNlf);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
do {
|
||||
axis_count=0;
|
||||
for(current_axis=0;current_axis<TrimAxes.size();current_axis++) {
|
||||
|
@ -284,26 +284,26 @@ bool FGTrim::DoTrim(void) {
|
|||
updateRates();
|
||||
Nsub=0;
|
||||
if(!solution[current_axis]) {
|
||||
if(checkLimits()) {
|
||||
if(checkLimits()) {
|
||||
solution[current_axis]=true;
|
||||
solve();
|
||||
}
|
||||
}
|
||||
} else if(findInterval()) {
|
||||
solve();
|
||||
} else {
|
||||
solution[current_axis]=false;
|
||||
}
|
||||
}
|
||||
sub_iterations[current_axis]+=Nsub;
|
||||
}
|
||||
}
|
||||
for(current_axis=0;current_axis<TrimAxes.size();current_axis++) {
|
||||
//these checks need to be done after all the axes have run
|
||||
if(Debug > 0) TrimAxes[current_axis]->AxisReport();
|
||||
if(TrimAxes[current_axis]->InTolerance()) {
|
||||
axis_count++;
|
||||
successful[current_axis]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if((axis_count == TrimAxes.size()-1) && (TrimAxes.size() > 1)) {
|
||||
//cout << TrimAxes.size()-1 << " out of " << TrimAxes.size() << "!" << endl;
|
||||
|
@ -412,19 +412,19 @@ bool FGTrim::solve(void) {
|
|||
}
|
||||
//cout << i << endl;
|
||||
|
||||
|
||||
|
||||
}//end while
|
||||
if(Nsub < max_sub_iterations) success=true;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
/*
|
||||
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,
|
||||
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
|
||||
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,
|
||||
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
|
||||
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
|
||||
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
|
||||
accel i.e. checkLimits() has already been called.
|
||||
|
||||
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
|
||||
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
|
||||
solutionDomain is set to 1.
|
||||
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
|
||||
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
|
||||
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.
|
||||
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.
|
||||
*/
|
||||
bool FGTrim::findInterval(void) {
|
||||
|
@ -452,14 +452,14 @@ bool FGTrim::findInterval(void) {
|
|||
double xmin=TrimAxes[current_axis]->GetControlMin();
|
||||
double xmax=TrimAxes[current_axis]->GetControlMax();
|
||||
double lastxlo,lastxhi,lastalo,lastahi;
|
||||
|
||||
|
||||
step=0.025*fabs(xmax);
|
||||
xlo=xhi=current_control;
|
||||
alo=ahi=current_accel;
|
||||
lastxlo=xlo;lastxhi=xhi;
|
||||
lastalo=alo;lastahi=ahi;
|
||||
do {
|
||||
|
||||
|
||||
Nsub++;
|
||||
step*=2;
|
||||
xlo-=step;
|
||||
|
@ -487,7 +487,7 @@ bool FGTrim::findInterval(void) {
|
|||
alo=lastahi;
|
||||
//xlo=current_control;
|
||||
//alo=current_accel;
|
||||
}
|
||||
}
|
||||
}
|
||||
lastxlo=xlo;lastxhi=xhi;
|
||||
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 min and current
|
||||
// 0 if there is no solution
|
||||
//
|
||||
//
|
||||
//if changing the control produces no significant change in the accel then
|
||||
//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
|
||||
//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
|
||||
//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
|
||||
|
||||
bool FGTrim::checkLimits(void) {
|
||||
|
@ -542,9 +542,9 @@ bool FGTrim::checkLimits(void) {
|
|||
solutionExists=true;
|
||||
solutionDomain=1;
|
||||
xlo=current_control;
|
||||
alo=current_accel;
|
||||
alo=current_accel;
|
||||
}
|
||||
}
|
||||
}
|
||||
TrimAxes[current_axis]->SetControl(current_control);
|
||||
TrimAxes[current_axis]->Run();
|
||||
return solutionExists;
|
||||
|
@ -562,40 +562,40 @@ void FGTrim::setupPullup() {
|
|||
cout << targetNlf << ", " << q << endl;
|
||||
fgic->SetQRadpsIC(q);
|
||||
cout << "setPitchRateInPullup() complete" << endl;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGTrim::setupTurn(void){
|
||||
double g,phi;
|
||||
phi = fgic->GetRollAngleRadIC();
|
||||
phi = fgic->GetPhiRadIC();
|
||||
if( fabs(phi) > 0.001 && fabs(phi) < 1.56 ) {
|
||||
targetNlf = 1 / cos(phi);
|
||||
g = fdmex->GetInertial()->gravity();
|
||||
g = fdmex->GetInertial()->gravity();
|
||||
psidot = g*tan(phi) / fgic->GetUBodyFpsIC();
|
||||
cout << targetNlf << ", " << psidot << endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGTrim::updateRates(void){
|
||||
if( mode == tTurn ) {
|
||||
double phi = fgic->GetRollAngleRadIC();
|
||||
double g = fdmex->GetInertial()->gravity();
|
||||
double phi = fgic->GetPhiRadIC();
|
||||
double g = fdmex->GetInertial()->gravity();
|
||||
double p,q,r,theta;
|
||||
if(fabs(phi) > 0.001 && fabs(phi) < 1.56 ) {
|
||||
theta=fgic->GetPitchAngleRadIC();
|
||||
phi=fgic->GetRollAngleRadIC();
|
||||
theta=fgic->GetThetaRadIC();
|
||||
phi=fgic->GetPhiRadIC();
|
||||
psidot = g*tan(phi) / fgic->GetUBodyFpsIC();
|
||||
p=-psidot*sin(theta);
|
||||
q=psidot*cos(theta)*sin(phi);
|
||||
r=psidot*cos(theta)*cos(phi);
|
||||
} else {
|
||||
p=q=r=0;
|
||||
}
|
||||
}
|
||||
fgic->SetPRadpsIC(p);
|
||||
fgic->SetQRadpsIC(q);
|
||||
fgic->SetRRadpsIC(r);
|
||||
|
@ -605,21 +605,21 @@ void FGTrim::updateRates(void){
|
|||
cgamma=cos(fgic->GetFlightPathAngleRadIC());
|
||||
q=g*(targetNlf-cgamma)/fgic->GetVtrueFpsIC();
|
||||
fgic->SetQRadpsIC(q);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
void FGTrim::setDebug(void) {
|
||||
if(debug_axis == tAll ||
|
||||
TrimAxes[current_axis]->GetStateType() == debug_axis ) {
|
||||
Debug=DebugLevel;
|
||||
Debug=DebugLevel;
|
||||
return;
|
||||
} else {
|
||||
Debug=0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
|
@ -628,7 +628,7 @@ void FGTrim::SetMode(TrimMode tt) {
|
|||
mode=tt;
|
||||
switch(tt) {
|
||||
case tFull:
|
||||
if (debug_lvl > 0)
|
||||
if (debug_lvl > 0)
|
||||
cout << " Full Trim" << endl;
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAlpha ));
|
||||
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 ));
|
||||
break;
|
||||
case tLongitudinal:
|
||||
if (debug_lvl > 0)
|
||||
if (debug_lvl > 0)
|
||||
cout << " Longitudinal Trim" << endl;
|
||||
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,tQdot,tPitchTrim ));
|
||||
break;
|
||||
case tGround:
|
||||
if (debug_lvl > 0)
|
||||
if (debug_lvl > 0)
|
||||
cout << " Ground Trim" << endl;
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tWdot,tAltAGL ));
|
||||
TrimAxes.push_back(new FGTrimAxis(fdmex,fgic,tQdot,tTheta ));
|
||||
|
@ -678,6 +678,6 @@ void FGTrim::SetMode(TrimMode tt) {
|
|||
successful=new double[TrimAxes.size()];
|
||||
solution=new bool[TrimAxes.size()];
|
||||
current_axis=0;
|
||||
}
|
||||
}
|
||||
//YOU WERE WARNED, BUT YOU DID IT ANYWAY.
|
||||
}
|
||||
|
|
|
@ -230,10 +230,10 @@ void FGTrimAxis::setControl(void) {
|
|||
case tYawTrim:
|
||||
case tRudder: fdmex->GetFCS()->SetDrCmd(control_value); break;
|
||||
case tAltAGL: fgic->SetAltitudeAGLFtIC(control_value); break;
|
||||
case tTheta: fgic->SetPitchAngleRadIC(control_value); break;
|
||||
case tPhi: fgic->SetRollAngleRadIC(control_value); break;
|
||||
case tTheta: fgic->SetThetaRadIC(control_value); break;
|
||||
case tPhi: fgic->SetPhiRadIC(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);
|
||||
cout << "SetThetaOnGround new alt: " << hagl << endl;
|
||||
}
|
||||
fgic->SetPitchAngleRadIC(ff);
|
||||
fgic->SetThetaRadIC(ff);
|
||||
cout << "SetThetaOnGround new theta: " << ff << endl;
|
||||
}
|
||||
|
||||
|
@ -327,10 +327,10 @@ bool FGTrimAxis::initTheta(void) {
|
|||
zForward=fdmex->GetGroundReactions()->GetGearUnit(iForward)->GetLocalGear(3);
|
||||
zDiff = zForward - zAft;
|
||||
level=false;
|
||||
theta=fgic->GetPitchAngleDegIC();
|
||||
theta=fgic->GetThetaDegIC();
|
||||
while(!level && (i < 100)) {
|
||||
theta+=radtodeg*atan(zDiff/xDiff);
|
||||
fgic->SetPitchAngleDegIC(theta);
|
||||
fgic->SetThetaDegIC(theta);
|
||||
fdmex->RunIC();
|
||||
zAft=fdmex->GetGroundReactions()->GetGearUnit(iAft)->GetLocalGear(3);
|
||||
zForward=fdmex->GetGroundReactions()->GetGearUnit(iForward)->GetLocalGear(3);
|
||||
|
@ -381,7 +381,7 @@ void FGTrimAxis::SetPhiOnGround(double ff) {
|
|||
|
||||
fgic->SetAltitudeAGLFtIC(hagl);
|
||||
}
|
||||
fgic->SetRollAngleRadIC(ff);
|
||||
fgic->SetPhiRadIC(ff);
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue