36# pragma warning (disable : 4786)
44#include "models/FGAtmosphere.h"
45#include "FGInitialCondition.h"
46#include "FGTrimAxis.h"
47#include "models/FGPropulsion.h"
48#include "models/FGAerodynamics.h"
49#include "models/FGFCS.h"
50#include "models/propulsion/FGEngine.h"
51#include "models/FGAuxiliary.h"
52#include "models/FGGroundReactions.h"
53#include "models/FGPropagate.h"
54#include "models/FGAccelerations.h"
55#include "input_output/FGLog.h"
72 its_to_stable_value=0;
74 total_stability_iterations=0;
79 tolerance=DEFAULT_TOLERANCE;
81 case tUdot: tolerance = DEFAULT_TOLERANCE;
break;
82 case tVdot: tolerance = DEFAULT_TOLERANCE;
break;
83 case tWdot: tolerance = DEFAULT_TOLERANCE;
break;
84 case tQdot: tolerance = DEFAULT_TOLERANCE / 10;
break;
85 case tPdot: tolerance = DEFAULT_TOLERANCE / 10;
break;
86 case tRdot: tolerance = DEFAULT_TOLERANCE / 10;
break;
87 case tHmgt: tolerance = 0.01;
break;
88 case tNlf: state_target=1.0; tolerance = 1E-5;
break;
100 control_min=-30*degtorad;
101 control_max=30*degtorad;
102 control_convert=radtodeg;
107 if(control_max <= control_min) {
108 control_max=20*degtorad;
109 control_min=-5*degtorad;
111 control_value= (control_min+control_max)/2;
112 control_convert=radtodeg;
113 solver_eps=tolerance/100;
123 state_convert=radtodeg;
124 solver_eps=tolerance/100;
130 solver_eps=tolerance/100;
135 state_convert=radtodeg;
140 state_convert=radtodeg;
141 control_convert=radtodeg;
144 solver_eps=tolerance/100;
145 control_min=-80*degtorad;
146 control_max=80*degtorad;
147 control_convert=radtodeg;
152 state_convert=radtodeg;
169void FGTrimAxis::getState(
void) {
171 case tUdot: state_value=fdmex->
GetAccelerations()->GetUVWdot(1)-state_target;
break;
172 case tVdot: state_value=fdmex->
GetAccelerations()->GetUVWdot(2)-state_target;
break;
173 case tWdot: state_value=fdmex->
GetAccelerations()->GetUVWdot(3)-state_target;
break;
174 case tQdot: state_value=fdmex->
GetAccelerations()->GetPQRdot(2)-state_target;
break;
175 case tPdot: state_value=fdmex->
GetAccelerations()->GetPQRdot(1)-state_target;
break;
176 case tRdot: state_value=fdmex->
GetAccelerations()->GetPQRdot(3)-state_target;
break;
177 case tHmgt: state_value=computeHmgt()-state_target;
break;
178 case tNlf: state_value=fdmex->
GetAuxiliary()->GetNlf()-state_target;
break;
187void FGTrimAxis::getControl(
void) {
189 case tThrottle: control_value=fdmex->
GetFCS()->GetThrottleCmd(0);
break;
190 case tBeta: control_value=fdmex->
GetAuxiliary()->Getbeta();
break;
191 case tAlpha: control_value=fdmex->
GetAuxiliary()->Getalpha();
break;
192 case tPitchTrim: control_value=fdmex->
GetFCS() -> GetPitchTrimCmd();
break;
193 case tElevator: control_value=fdmex->
GetFCS() -> GetDeCmd();
break;
195 case tAileron: control_value=fdmex->
GetFCS() -> GetDaCmd();
break;
197 case tRudder: control_value=fdmex->
GetFCS() -> GetDrCmd();
break;
198 case tAltAGL: control_value=fdmex->
GetPropagate()->GetDistanceAGL();
break;
199 case tTheta: control_value=fdmex->
GetPropagate()->GetEuler(eTht);
break;
200 case tPhi: control_value=fdmex->
GetPropagate()->GetEuler(ePhi);
break;
201 case tGamma: control_value=fdmex->
GetAuxiliary()->GetGamma();
break;
202 case tHeading: control_value=fdmex->
GetPropagate()->GetEuler(ePsi);
break;
208double FGTrimAxis::computeHmgt(
void) {
215 return (diff + 2*M_PI);
216 }
else if( diff > M_PI ) {
217 return (diff - 2*M_PI);
227void FGTrimAxis::setControl(
void) {
229 case tThrottle: setThrottlesPct();
break;
232 case tPitchTrim: fdmex->
GetFCS()->SetPitchTrimCmd(control_value);
break;
233 case tElevator: fdmex->
GetFCS()->SetDeCmd(control_value);
break;
235 case tAileron: fdmex->
GetFCS()->SetDaCmd(control_value);
break;
237 case tRudder: fdmex->
GetFCS()->SetDrCmd(control_value);
break;
240 case tPhi: fgic->
SetPhiRadIC(control_value);
break;
242 case tHeading: fgic->
SetPsiRadIC(control_value);
break;
250 double last_state_value;
259 last_state_value=state_value;
264 if((fabs(last_state_value - state_value) < tolerance) || (i >= 100) )
269 its_to_stable_value=i;
270 total_stability_iterations+=its_to_stable_value;
276void FGTrimAxis::setThrottlesPct(
void) {
278 for(
unsigned i=0;i<fdmex->
GetPropulsion()->GetNumEngines();i++) {
284 fdmex->
GetFCS()->SetThrottleCmd(i,tMin+control_value*(tMax-tMin));
285 fdmex->
GetPropulsion()->in.ThrottlePos[i] = tMin +control_value*(tMax - tMin);
295void FGTrimAxis::AxisReport(
void) {
296 FGLogging out(LogLevel::STDOUT);
297 out <<
" " << left << setw(20) << GetControlName() <<
": ";
298 out << setw(6) << setprecision(2) << GetControl()*control_convert <<
' ';
299 out << setw(5) << GetStateName() <<
": ";
300 out << setw(9) << setprecision(2) << scientific << GetState()+state_target;
301 out <<
" Tolerance: " << setw(3) << setprecision(0) << scientific << GetTolerance();
303 if( fabs(GetState()+state_target) < fabs(GetTolerance()) )
311double FGTrimAxis::GetAvgStability(
void ) {
312 if(total_iterations > 0) {
313 return double(total_stability_iterations)/double(total_iterations);
337void FGTrimAxis::Debug(
int from)
340 if (debug_lvl <= 0)
return;
341 if (debug_lvl & 1 ) {
346 if (debug_lvl & 2 ) {
347 FGLogging log(LogLevel::DEBUG);
348 if (from == 0) log <<
"Instantiated: FGTrimAxis\n";
349 if (from == 1) log <<
"Destroyed: FGTrimAxis\n";
351 if (debug_lvl & 4 ) {
353 if (debug_lvl & 8 ) {
355 if (debug_lvl & 16) {
357 if (debug_lvl & 64) {
Encapsulates the JSBSim simulation executive.
std::shared_ptr< FGFCS > GetFCS(void) const
Returns the FGFCS pointer.
std::shared_ptr< FGPropagate > GetPropagate(void) const
Returns the FGPropagate pointer.
std::shared_ptr< FGAerodynamics > GetAerodynamics(void) const
Returns the FGAerodynamics pointer.
bool Run(void)
This function executes each scheduled model in succession.
std::shared_ptr< FGPropulsion > GetPropulsion(void) const
Returns the FGPropulsion pointer.
void Initialize(const FGInitialCondition *FGIC)
Initializes the simulation with initial conditions.
std::shared_ptr< FGAuxiliary > GetAuxiliary(void) const
Returns the FGAuxiliary pointer.
std::shared_ptr< FGAccelerations > GetAccelerations(void) const
Returns the FGAccelerations pointer.
Initializes the simulation run.
void SetPsiRadIC(double psi)
Sets the initial heading angle.
double GetPhiRadIC(void) const
Gets the initial roll angle.
void SetFlightPathAngleRadIC(double gamma)
Sets the initial flight path angle.
void SetBetaRadIC(double beta)
Sets the initial sideslip angle.
void SetAltitudeAGLFtIC(double agl)
Sets the initial Altitude above ground level.
double GetAltitudeAGLFtIC(void) const
Gets the initial altitude above ground level.
void SetThetaRadIC(double theta)
Sets the initial pitch angle.
void SetAlphaRadIC(double alpha)
Sets the initial angle of attack.
double GetPsiRadIC(void) const
Gets the initial heading angle.
double GetThetaRadIC(void) const
Gets the initial pitch angle.
void SetPhiRadIC(double phi)
Sets the initial roll angle.
void Run(void)
This function iterates through a call to the FGFDMExec::RunIC() function until the desired trimming c...
FGTrimAxis(FGFDMExec *fdmex, FGInitialCondition *IC, State state, Control control)
Constructor for Trim Axis class.
Main namespace for the JSBSim Flight Dynamics Model.
State
Models an aircraft axis for purposes of trimming.