// entry in the enum eParam definition in FGJSBBase.h. The ID is what must be used
// in any config file entry which references that item.
-FGState::FGState(FGFDMExec* fdex) : mTb2l(3,3),
- mTl2b(3,3),
- mTs2b(3,3),
- vQtrn(4),
- vlastQdot(4),
- vQdot(4),
- vTmp(4),
- vEuler(3),
- vUVW(3),
- vLocalVelNED(3),
- vLocalEuler(3)
+FGState::FGState(FGFDMExec* fdex)
{
FDMExec = fdex;
RegisterVariable(FG_SPDBRAKE_POS, " speedbrake_pos " );
RegisterVariable(FG_SPOILERS_POS, " spoiler_pos " );
RegisterVariable(FG_FLAPS_POS, " flaps_pos " );
+ RegisterVariable(FG_GEAR_POS, " gear_pos " );
RegisterVariable(FG_ELEVATOR_CMD, " elevator_cmd " );
RegisterVariable(FG_AILERON_CMD, " aileron_cmd " );
RegisterVariable(FG_RUDDER_CMD, " rudder_cmd " );
RegisterVariable(FG_SPOILERS_CMD, " spoiler_cmd " );
RegisterVariable(FG_FLAPS_CMD, " flaps_cmd " );
RegisterVariable(FG_THROTTLE_CMD, " throttle_cmd " );
+ RegisterVariable(FG_GEAR_CMD, " gear_cmd " );
RegisterVariable(FG_THROTTLE_POS, " throttle_pos " );
- RegisterVariable(FG_MIXTURE_CMD, " mixture_cmd " );
- RegisterVariable(FG_MIXTURE_POS, " mixture_pos " );
- RegisterVariable(FG_MAGNETO_CMD, " magneto_cmd " );
- RegisterVariable(FG_STARTER_CMD, " starter_cmd " );
+ RegisterVariable(FG_MIXTURE_CMD, " mixture_cmd " );
+ RegisterVariable(FG_MIXTURE_POS, " mixture_pos " );
+ RegisterVariable(FG_MAGNETO_CMD, " magneto_cmd " );
+ RegisterVariable(FG_STARTER_CMD, " starter_cmd " );
RegisterVariable(FG_ACTIVE_ENGINE, " active_engine " );
RegisterVariable(FG_HOVERB, " height/span " );
RegisterVariable(FG_PITCH_TRIM_CMD, " pitch_trim_cmd " );
RegisterVariable(FG_VBARV, " v-tail volume " );
RegisterVariable(FG_SET_LOGGING, " data_logging " );
- if (debug_lvl & 2) cout << "Instantiated: FGState" << endl;
+ Debug(0);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FGState::~FGState()
{
- if (debug_lvl & 2) cout << "Destroyed: FGState" << endl;
+ Debug(1);
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
return Rotation->GetPQR(eP);
case FG_YAWRATE:
return Rotation->GetPQR(eR);
- case FG_AEROQ:
- return Rotation->GetPQR(eQ) + Atmosphere->GetTurbPQR(eQ); // add aero turbulence effects
case FG_AEROP:
- return Rotation->GetPQR(eP) + Atmosphere->GetTurbPQR(eP); // add aero turbulence effects
+ return Rotation->GetAeroPQR(eP);
+ case FG_AEROQ:
+ return Rotation->GetAeroPQR(eQ);
case FG_AEROR:
- return Rotation->GetPQR(eR) + Atmosphere->GetTurbPQR(eR); // add aero turbulence effects
+ return Rotation->GetAeroPQR(eR);
case FG_CL_SQRD:
if (Translation->Getqbar() > 0.00)
scratch = Aerodynamics->GetvLastFs(eLift)/(Aircraft->GetWingArea()*Translation->Getqbar());
if (ActiveEngine < 0) return FCS->GetMixturePos(0);
else return FCS->GetMixturePos(ActiveEngine);
case FG_HOVERB:
- return Position->GetHOverB();
+ return Position->GetHOverBMAC();
case FG_PITCH_TRIM_CMD:
return FCS->GetPitchTrimCmd();
+ case FG_GEAR_CMD:
+ return FCS->GetGearCmd();
+ case FG_GEAR_POS:
+ return FCS->GetGearPos();
default:
cerr << "FGState::GetParameter() - No handler for parameter " << paramdef[val_idx] << endl;
return 0.0;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-eParam FGState::GetParameterIndex(string val_string) {
+eParam FGState::GetParameterIndex(string val_string)
+{
return coeffdef[val_string];
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-void FGState::SetParameter(eParam val_idx, double val) {
+void FGState::SetParameter(eParam val_idx, double val)
+{
+ int i;
+
switch(val_idx) {
case FG_ELEVATOR_POS:
FCS->SetDePos(val);
FCS->SetDfPos(val);
break;
case FG_THROTTLE_POS:
- FCS->SetThrottlePos(ActiveEngine,val);
+ if (ActiveEngine == -1) {
+ for (i=0; i<Propulsion->GetNumEngines(); i++) {
+ FCS->SetThrottlePos(i,val);
+ }
+ } else {
+ FCS->SetThrottlePos(ActiveEngine,val);
+ }
break;
case FG_MIXTURE_POS:
- FCS->SetMixturePos(ActiveEngine,val);
+ if (ActiveEngine == -1) {
+ for (i=0; i<Propulsion->GetNumEngines(); i++) {
+ FCS->SetMixturePos(i,val);
+ }
+ } else {
+ FCS->SetMixturePos(ActiveEngine,val);
+ }
break;
case FG_ELEVATOR_CMD:
FCS->SetDfCmd(val);
break;
case FG_THROTTLE_CMD:
- FCS->SetThrottleCmd(ActiveEngine,val);
+ if (ActiveEngine == -1) {
+ for (i=0; i<Propulsion->GetNumEngines(); i++) {
+ FCS->SetThrottleCmd(i,val);
+ }
+ } else {
+ FCS->SetThrottleCmd(ActiveEngine,val);
+ }
break;
case FG_MIXTURE_CMD:
- FCS->SetMixtureCmd(ActiveEngine,val);
+ if (ActiveEngine == -1) {
+ for (i=0; i<Propulsion->GetNumEngines(); i++) {
+ FCS->SetMixtureCmd(i,val);
+ }
+ } else {
+ FCS->SetMixtureCmd(ActiveEngine,val);
+ }
break;
case FG_MAGNETO_CMD:
- Propulsion->GetEngine(ActiveEngine)->SetMagnetos(val); // need to account for -1
+ if (ActiveEngine == -1) {
+ for (i=0; i<Propulsion->GetNumEngines(); i++) {
+ Propulsion->GetEngine(i)->SetMagnetos((int)val);
+ }
+ } else {
+ Propulsion->GetEngine(ActiveEngine)->SetMagnetos((int)val);
+ }
break;
case FG_STARTER_CMD:
- if (val < 0.001)
- Propulsion->GetEngine(ActiveEngine)->SetStarter(false); // need to account for -1
- else if (val >= 0.001)
- Propulsion->GetEngine(ActiveEngine)->SetStarter(true); // need to account for -1
+ if (ActiveEngine == -1) {
+ for (i=0; i<Propulsion->GetNumEngines(); i++) {
+ if (val < 0.001)
+ Propulsion->GetEngine(i)->SetStarter(false);
+ else if (val >= 0.001)
+ Propulsion->GetEngine(i)->SetStarter(true);
+ }
+ } else {
+ Propulsion->GetEngine(ActiveEngine)->SetStarter(true);
+ }
break;
case FG_ACTIVE_ENGINE:
ActiveEngine = (int)val;
case FG_RIGHT_BRAKE_CMD:
FCS->SetRBrake(val);
break;
-
+ case FG_GEAR_CMD:
+ FCS->SetGearCmd(val);
+ break;
+ case FG_GEAR_POS:
+ FCS->SetGearPos(val);
+ break;
case FG_SET_LOGGING:
if (val < -0.01) Output->Disable();
else if (val > 0.01) Output->Enable();
resetfile.GetNextConfigLine();
token = resetfile.GetValue();
- if (token != "initialize") {
+ if (token != string("initialize")) {
cerr << "The reset file " << resetDef
<< " does not appear to be a reset file" << endl;
return false;
+ } else {
+ resetfile.GetNextConfigLine();
+ resetfile >> token;
+ cout << "Resetting using: " << token << endl << endl;
}
- resetfile.GetNextConfigLine();
- resetfile >> token;
- while (token != "/initialize" && token != "EOF") {
+ while (token != string("/initialize") && token != string("EOF")) {
if (token == "UBODY") resetfile >> U;
if (token == "VBODY") resetfile >> V;
if (token == "WBODY") resetfile >> W;
{
double alpha, beta;
double qbar, Vt;
- FGColumnVector3 vAero;
+ FGColumnVector3 vAeroUVW;
Position->SetLatitude(Latitude);
Position->SetLongitude(Longitude);
Atmosphere->SetWindNED(wnorth, weast, wdown);
- vAero = vUVW + mTl2b*Atmosphere->GetWindNED();
+ vAeroUVW = vUVW + mTl2b*Atmosphere->GetWindNED();
- if (vAero(eW) != 0.0)
- alpha = vAero(eU)*vAero(eU) > 0.0 ? atan2(vAero(eW), vAero(eU)) : 0.0;
+ if (vAeroUVW(eW) != 0.0)
+ alpha = vAeroUVW(eU)*vAeroUVW(eU) > 0.0 ? atan2(vAeroUVW(eW), vAeroUVW(eU)) : 0.0;
else
alpha = 0.0;
- if (vAero(eV) != 0.0)
- beta = vAero(eU)*vAero(eU)+vAero(eW)*vAero(eW) > 0.0 ? atan2(vAero(eV), (fabs(vAero(eU))/vAero(eU))*sqrt(vAero(eU)*vAero(eU) + vAero(eW)*vAero(eW))) : 0.0;
+ if (vAeroUVW(eV) != 0.0)
+ beta = vAeroUVW(eU)*vAeroUVW(eU)+vAeroUVW(eW)*vAeroUVW(eW) > 0.0 ? atan2(vAeroUVW(eV), (fabs(vAeroUVW(eU))/vAeroUVW(eU))*sqrt(vAeroUVW(eU)*vAeroUVW(eU) + vAeroUVW(eW)*vAeroUVW(eW))) : 0.0;
else
beta = 0.0;
cb = cos(beta);
sb = sin(beta);
- mTs2b(1,1) = -ca*cb;
+ mTs2b(1,1) = ca*cb;
mTs2b(1,2) = -ca*sb;
- mTs2b(1,3) = sa;
- mTs2b(2,1) = -sb;
+ mTs2b(1,3) = -sa;
+ mTs2b(2,1) = sb;
mTs2b(2,2) = cb;
mTs2b(2,3) = 0.0;
- mTs2b(3,1) = -sa*cb;
+ mTs2b(3,1) = sa*cb;
mTs2b(3,2) = -sa*sb;
- mTs2b(3,3) = -ca;
+ mTs2b(3,3) = ca;
return mTs2b;
}
+//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+FGMatrix33& FGState::GetTb2s(void)
+{
+ float alpha,beta;
+ float ca, cb, sa, sb;
+
+ alpha = Translation->Getalpha();
+ beta = Translation->Getbeta();
+
+ ca = cos(alpha);
+ sa = sin(alpha);
+ cb = cos(beta);
+ sb = sin(beta);
+
+ mTb2s(1,1) = ca*cb;
+ mTb2s(1,2) = sb;
+ mTb2s(1,3) = sa*cb;
+ mTb2s(2,1) = -ca*sb;
+ mTb2s(2,2) = cb;
+ mTb2s(2,3) = -sa*sb;
+ mTb2s(3,1) = -sa;
+ mTb2s(3,2) = 0.0;
+ mTb2s(3,3) = ca;
+
+ return mTb2s;
+}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void FGState::ReportState(void) {
- char out[80], flap[10], gear[10];
+ char out[80], flap[10], gear[12];
cout << endl << " JSBSim State" << endl;
snprintf(out,80," Weight: %7.0f lbs. CG: %5.1f, %5.1f, %5.1f inches\n",
snprintf(flap,10,"Up");
else
snprintf(flap,10,"%2.0f",FCS->GetDfPos());
- if(GroundReactions->GetGearUp() == true)
- snprintf(gear,10,"Up");
+ if(FCS->GetGearPos() < 0.01)
+ snprintf(gear,12,"Up");
+ else if(FCS->GetGearPos() > 0.99)
+ snprintf(gear,12,"Down");
else
- snprintf(gear,10,"Down");
- snprintf(out,80, " Flaps: %3s Gear: %4s\n",flap,gear);
+ snprintf(gear,12,"In Transit");
+ snprintf(out,80, " Flaps: %3s Gear: %12s\n",flap,gear);
cout << out;
snprintf(out,80, " Speed: %4.0f KCAS Mach: %5.2f\n",
FDMExec->GetAuxiliary()->GetVcalibratedKTS(),
Position->Gethdot()*60 );
cout << out;
snprintf(out,80, " Normal Load Factor: %4.2f g's Pitch Rate: %5.2f deg/s\n",
- Aerodynamics->GetNlf(),
+ Aircraft->GetNlf(),
GetParameter(FG_PITCHRATE)*radtodeg );
cout << out;
snprintf(out,80, " Heading: %3.0f deg true Sideslip: %5.2f deg\n",
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-void FGState::Debug(void)
+// The bitmasked value choices are as follows:
+// unset: In this case (the default) JSBSim would only print
+// out the normally expected messages, essentially echoing
+// the config files as they are read. If the environment
+// variable is not set, debug_lvl is set to 1 internally
+// 0: This requests JSBSim not to output any messages
+// whatsoever.
+// 1: This value explicity requests the normal JSBSim
+// startup messages
+// 2: This value asks for a message to be printed out when
+// a class is instantiated
+// 4: When this value is set, a message is displayed when a
+// FGModel object executes its Run() method
+// 8: When this value is set, various runtime state variables
+// are printed out periodically
+// 16: When set various parameters are sanity checked and
+// a message is printed out when they go out of bounds
+
+void FGState::Debug(int from)
{
- //TODO: Add your source code here
+ if (debug_lvl <= 0) return;
+
+ if (debug_lvl & 1) { // Standard console startup message output
+ if (from == 0) { // Constructor
+
+ }
+ }
+ if (debug_lvl & 2 ) { // Instantiation/Destruction notification
+ if (from == 0) cout << "Instantiated: FGState" << endl;
+ if (from == 1) cout << "Destroyed: FGState" << endl;
+ }
+ if (debug_lvl & 4 ) { // Run() method entry print for FGModel-derived objects
+ }
+ if (debug_lvl & 8 ) { // Runtime state variables
+ }
+ if (debug_lvl & 16) { // Sanity checking
+ }
}