Updates to JSBSim and FDM interface.
This commit is contained in:
parent
bc20e9b490
commit
5fe0f04702
22 changed files with 420 additions and 491 deletions
|
@ -168,9 +168,10 @@ FGADA::~FGADA() {
|
|||
// for each subsequent iteration through the EOM
|
||||
void FGADA::init() {
|
||||
|
||||
// explicitly call the superclass's
|
||||
// init() method first.
|
||||
FGInterface::init();
|
||||
//do init common to all FDM"s
|
||||
common_init();
|
||||
|
||||
//now do ADA-specific init.
|
||||
|
||||
// cout << "FGADA::init()" << endl;
|
||||
|
||||
|
|
|
@ -75,9 +75,11 @@ FGBalloonSim::~FGBalloonSim() {
|
|||
// Initialize the BalloonSim flight model, dt is the time increment for
|
||||
// each subsequent iteration through the EOM
|
||||
void FGBalloonSim::init() {
|
||||
// explicitly call the superclass's
|
||||
// init method first.
|
||||
FGInterface::init();
|
||||
|
||||
//do init common to all the FDM's
|
||||
common_init();
|
||||
|
||||
//now do init specific to the Balloon
|
||||
|
||||
sgVec3 temp;
|
||||
|
||||
|
|
|
@ -66,17 +66,19 @@ FGJSBsim::FGJSBsim( double dt )
|
|||
|
||||
fdmex = new FGFDMExec;
|
||||
|
||||
State = fdmex->GetState();
|
||||
Atmosphere = fdmex->GetAtmosphere();
|
||||
FCS = fdmex->GetFCS();
|
||||
MassBalance = fdmex->GetMassBalance();
|
||||
Propulsion = fdmex->GetPropulsion();
|
||||
Aircraft = fdmex->GetAircraft();
|
||||
Translation = fdmex->GetTranslation();
|
||||
Rotation = fdmex->GetRotation();
|
||||
Position = fdmex->GetPosition();
|
||||
Auxiliary = fdmex->GetAuxiliary();
|
||||
Aerodynamics = fdmex->GetAerodynamics();
|
||||
State = fdmex->GetState();
|
||||
Atmosphere = fdmex->GetAtmosphere();
|
||||
FCS = fdmex->GetFCS();
|
||||
MassBalance = fdmex->GetMassBalance();
|
||||
Propulsion = fdmex->GetPropulsion();
|
||||
Aircraft = fdmex->GetAircraft();
|
||||
Translation = fdmex->GetTranslation();
|
||||
Rotation = fdmex->GetRotation();
|
||||
Position = fdmex->GetPosition();
|
||||
Auxiliary = fdmex->GetAuxiliary();
|
||||
Aerodynamics = fdmex->GetAerodynamics();
|
||||
GroundReactions = fdmex->GetGroundReactions();
|
||||
|
||||
|
||||
Atmosphere->UseInternal();
|
||||
|
||||
|
@ -113,9 +115,9 @@ FGJSBsim::FGJSBsim( double dt )
|
|||
add_engine( FGEngInterface() );
|
||||
}
|
||||
|
||||
if ( fdmex->GetGroundReactions()->GetNumGearUnits() <= 0 ) {
|
||||
if ( GroundReactions->GetNumGearUnits() <= 0 ) {
|
||||
SG_LOG( SG_FLIGHT, SG_ALERT, "num gear units = "
|
||||
<< fdmex->GetGroundReactions()->GetNumGearUnits() );
|
||||
<< GroundReactions->GetNumGearUnits() );
|
||||
SG_LOG( SG_FLIGHT, SG_ALERT, "This is a very bad thing because with 0 gear units, the ground trimming");
|
||||
SG_LOG( SG_FLIGHT, SG_ALERT, "routine (coming up later in the code) will core dump.");
|
||||
SG_LOG( SG_FLIGHT, SG_ALERT, "Halting the sim now, and hoping a solution will present itself soon!");
|
||||
|
@ -123,6 +125,8 @@ FGJSBsim::FGJSBsim( double dt )
|
|||
}
|
||||
|
||||
|
||||
init_gear();
|
||||
|
||||
fgSetDouble("/fdm/trim/pitch-trim", FCS->GetPitchTrimCmd());
|
||||
fgSetDouble("/fdm/trim/throttle", FCS->GetThrottleCmd(0));
|
||||
fgSetDouble("/fdm/trim/aileron", FCS->GetDaCmd());
|
||||
|
@ -137,6 +141,10 @@ FGJSBsim::FGJSBsim( double dt )
|
|||
throttle_trim = fgGetNode("/fdm/trim/throttle", true );
|
||||
aileron_trim = fgGetNode("/fdm/trim/aileron", true );
|
||||
rudder_trim = fgGetNode("/fdm/trim/rudder", true );
|
||||
|
||||
|
||||
stall_warning = fgGetNode("/sim/aircraft/alarms/stall-warning",true);
|
||||
stall_warning->setDoubleValue(0);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -158,7 +166,7 @@ void FGJSBsim::init() {
|
|||
|
||||
// Explicitly call the superclass's
|
||||
// init method first.
|
||||
FGInterface::init();
|
||||
common_init();
|
||||
|
||||
fdmex->GetState()->Initialize(fgic);
|
||||
fdmex->RunIC(fgic); //loop JSBSim once w/o integrating
|
||||
|
@ -191,6 +199,8 @@ void FGJSBsim::init() {
|
|||
break;
|
||||
}
|
||||
|
||||
stall_warning->setBoolValue(false);
|
||||
|
||||
SG_LOG( SG_FLIGHT, SG_INFO, " Bank Angle: "
|
||||
<< Rotation->Getphi()*RADTODEG << " deg" );
|
||||
SG_LOG( SG_FLIGHT, SG_INFO, " Pitch Angle: "
|
||||
|
@ -208,6 +218,9 @@ void FGJSBsim::init() {
|
|||
SG_LOG( SG_FLIGHT, SG_INFO, " set dt" );
|
||||
|
||||
SG_LOG( SG_FLIGHT, SG_INFO, "Finished initializing JSBSim" );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -224,43 +237,13 @@ bool FGJSBsim::update( int multiloop ) {
|
|||
|
||||
trimmed->setBoolValue(false);
|
||||
|
||||
if ( needTrim && startup_trim->getBoolValue() ) {
|
||||
cout << "num gear units = " << fdmex->GetGroundReactions()->GetNumGearUnits() << endl;
|
||||
//fgic->SetSeaLevelRadiusFtIC( get_Sea_level_radius() );
|
||||
//fgic->SetTerrainAltitudeFtIC( scenery.cur_elev * SG_METER_TO_FEET );
|
||||
|
||||
FGTrim *fgtrim;
|
||||
if(fgic->GetVcalibratedKtsIC() < 10 ) {
|
||||
fgic->SetVcalibratedKtsIC(0.0);
|
||||
fgtrim=new FGTrim(fdmex,fgic,tGround);
|
||||
} else {
|
||||
fgtrim=new FGTrim(fdmex,fgic,tLongitudinal);
|
||||
}
|
||||
if(!fgtrim->DoTrim()) {
|
||||
fgtrim->Report();
|
||||
fgtrim->TrimStats();
|
||||
} else {
|
||||
trimmed->setBoolValue(true);
|
||||
}
|
||||
fgtrim->ReportState();
|
||||
delete fgtrim;
|
||||
|
||||
needTrim=false;
|
||||
|
||||
pitch_trim->setDoubleValue( FCS->GetPitchTrimCmd() );
|
||||
throttle_trim->setDoubleValue( FCS->GetThrottleCmd(0) );
|
||||
aileron_trim->setDoubleValue( FCS->GetDaCmd() );
|
||||
rudder_trim->setDoubleValue( FCS->GetDrCmd() );
|
||||
|
||||
globals->get_controls()->set_elevator_trim(FCS->GetPitchTrimCmd());
|
||||
globals->get_controls()->set_elevator(FCS->GetDeCmd());
|
||||
globals->get_controls()->set_throttle(FGControls::ALL_ENGINES,
|
||||
FCS->GetThrottleCmd(0));
|
||||
|
||||
globals->get_controls()->set_aileron(FCS->GetDaCmd());
|
||||
globals->get_controls()->set_rudder( FCS->GetDrCmd());
|
||||
|
||||
SG_LOG( SG_FLIGHT, SG_INFO, " Trim complete" );
|
||||
if ( needTrim ) {
|
||||
if ( startup_trim->getBoolValue() ) {
|
||||
do_trim();
|
||||
} else {
|
||||
fdmex->RunIC(fgic); //apply any changes made through the set_ functions
|
||||
}
|
||||
needTrim = false;
|
||||
}
|
||||
|
||||
for( i=0; i<get_num_engines(); i++ ) {
|
||||
|
@ -269,6 +252,18 @@ bool FGJSBsim::update( int multiloop ) {
|
|||
FGThruster * thrust = Propulsion->GetThruster(i);
|
||||
eng->SetMagnetos( globals->get_controls()->get_magnetos(i) );
|
||||
eng->SetStarter( globals->get_controls()->get_starter(i) );
|
||||
e->set_Throttle( globals->get_controls()->get_throttle(i) );
|
||||
}
|
||||
|
||||
|
||||
for ( i=0; i < multiloop; i++ ) {
|
||||
fdmex->Run();
|
||||
}
|
||||
|
||||
for( i=0; i<get_num_engines(); i++ ) {
|
||||
FGEngInterface * e = get_engine(i);
|
||||
FGEngine * eng = Propulsion->GetEngine(i);
|
||||
FGThruster * thrust = Propulsion->GetThruster(i);
|
||||
e->set_Manifold_Pressure( eng->getManifoldPressure_inHg() );
|
||||
e->set_RPM( thrust->GetRPM() );
|
||||
e->set_EGT( eng->getExhaustGasTemp_degF() );
|
||||
|
@ -276,19 +271,15 @@ bool FGJSBsim::update( int multiloop ) {
|
|||
e->set_Oil_Temp( eng->getOilTemp_degF() );
|
||||
e->set_Running_Flag( eng->GetRunning() );
|
||||
e->set_Cranking_Flag( eng->GetCranking() );
|
||||
e->set_Throttle( globals->get_controls()->get_throttle(i) );
|
||||
}
|
||||
|
||||
for ( i=0; i < multiloop; i++ ) {
|
||||
fdmex->Run();
|
||||
}
|
||||
|
||||
// printf("%d FG_Altitude = %.2f\n", i, FG_Altitude * 0.3048);
|
||||
// printf("%d Altitude = %.2f\n", i, Altitude * 0.3048);
|
||||
update_gear();
|
||||
|
||||
stall_warning->setDoubleValue( Aircraft->GetStallWarn() );
|
||||
|
||||
// translate JSBsim back to FG structure so that the
|
||||
// autopilot (and the rest of the sim can use the updated values
|
||||
|
||||
copy_from_JSBsim();
|
||||
return true;
|
||||
}
|
||||
|
@ -350,25 +341,25 @@ bool FGJSBsim::copy_from_JSBsim() {
|
|||
MassBalance->GetXYZcg(2),
|
||||
MassBalance->GetXYZcg(3) );
|
||||
|
||||
_set_Accels_Body( Translation->GetUVWdot(1),
|
||||
Translation->GetUVWdot(2),
|
||||
Translation->GetUVWdot(3) );
|
||||
_set_Accels_Body( Aircraft->GetBodyAccel()(1),
|
||||
Aircraft->GetBodyAccel()(2),
|
||||
Aircraft->GetBodyAccel()(3) );
|
||||
|
||||
_set_Accels_CG_Body( Translation->GetUVWdot(1),
|
||||
Translation->GetUVWdot(2),
|
||||
Translation->GetUVWdot(3) );
|
||||
|
||||
//_set_Accels_CG_Body_N ( Translation->GetNcg(1),
|
||||
// Translation->GetNcg(2),
|
||||
// Translation->GetNcg(3) );
|
||||
//_set_Accels_CG_Body( Aircraft->GetBodyAccel()(1),
|
||||
// Aircraft->GetBodyAccel()(2),
|
||||
// Aircraft->GetBodyAccel()(3) );
|
||||
//
|
||||
_set_Accels_Pilot_Body( Auxiliary->GetPilotAccel(1),
|
||||
Auxiliary->GetPilotAccel(2),
|
||||
Auxiliary->GetPilotAccel(3) );
|
||||
_set_Accels_CG_Body_N ( Aircraft->GetNcg()(1),
|
||||
Aircraft->GetNcg()(2),
|
||||
Aircraft->GetNcg()(3) );
|
||||
|
||||
//_set_Accels_Pilot_Body_N( Auxiliary->GetNpilot(1),
|
||||
// Auxiliary->GetNpilot(2),
|
||||
// Auxiliary->GetNpilot(3) );
|
||||
_set_Accels_Pilot_Body( Auxiliary->GetPilotAccel()(1),
|
||||
Auxiliary->GetPilotAccel()(2),
|
||||
Auxiliary->GetPilotAccel()(3) );
|
||||
|
||||
// _set_Accels_Pilot_Body_N( Auxiliary->GetPilotAccel()(1)/32.1739,
|
||||
// Auxiliary->GetNpilot(2)/32.1739,
|
||||
// Auxiliary->GetNpilot(3)/32.1739 );
|
||||
|
||||
_set_Nlf( Aerodynamics->GetNlf() );
|
||||
|
||||
|
@ -437,19 +428,6 @@ bool FGJSBsim::copy_from_JSBsim() {
|
|||
return true;
|
||||
}
|
||||
|
||||
void FGJSBsim::snap_shot(void) {
|
||||
fgic->SetLatitudeRadIC(get_Lat_geocentric() );
|
||||
fgic->SetLongitudeRadIC( get_Longitude() );
|
||||
fgic->SetAltitudeFtIC( get_Altitude() );
|
||||
fgic->SetTerrainAltitudeFtIC( get_Runway_altitude() );
|
||||
fgic->SetVtrueFpsIC( get_V_rel_wind() );
|
||||
fgic->SetPitchAngleRadIC( get_Theta() );
|
||||
fgic->SetRollAngleRadIC( get_Phi() );
|
||||
fgic->SetTrueHeadingRadIC( get_Psi() );
|
||||
fgic->SetClimbRateFpsIC( get_Climb_Rate() );
|
||||
}
|
||||
|
||||
|
||||
bool FGJSBsim::ToggleDataLogging(void) {
|
||||
return fdmex->GetOutput()->Toggle();
|
||||
}
|
||||
|
@ -484,6 +462,7 @@ void FGJSBsim::set_Latitude(double lat) {
|
|||
|
||||
sgGeodToGeoc( lat, alt * SG_FEET_TO_METER,
|
||||
&sea_level_radius_meters, &lat_geoc );
|
||||
|
||||
_set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET );
|
||||
fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET );
|
||||
fgic->SetLatitudeRadIC( lat_geoc );
|
||||
|
@ -617,7 +596,6 @@ void FGJSBsim::set_Density(double rho) {
|
|||
needTrim=true;
|
||||
}
|
||||
|
||||
|
||||
void FGJSBsim::set_Velocities_Local_Airmass (double wnorth,
|
||||
double weast,
|
||||
double wdown ) {
|
||||
|
@ -630,194 +608,70 @@ void FGJSBsim::set_Velocities_Local_Airmass (double wnorth,
|
|||
needTrim=true;
|
||||
}
|
||||
|
||||
void FGJSBsim::init_gear(void ) {
|
||||
|
||||
//Positions
|
||||
void FGJSBsim::update_Latitude(double lat) {
|
||||
double sea_level_radius_meters, lat_geoc;
|
||||
|
||||
SG_LOG(SG_FLIGHT,SG_INFO,"FGJSBsim::update_Latitude: " << lat );
|
||||
SG_LOG(SG_FLIGHT,SG_INFO," cur alt = " << get_Altitude() );
|
||||
|
||||
snap_shot();
|
||||
sgGeodToGeoc( lat, get_Altitude(), &sea_level_radius_meters, &lat_geoc);
|
||||
_set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET );
|
||||
fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET );
|
||||
fgic->SetLatitudeRadIC( lat_geoc );
|
||||
fdmex->RunIC(fgic); //loop JSBSim once
|
||||
copy_from_JSBsim(); //update the bus
|
||||
needTrim=true;
|
||||
FGGearInterface *gear;
|
||||
FGGroundReactions* gr=fdmex->GetGroundReactions();
|
||||
int Ngear=GroundReactions->GetNumGearUnits();
|
||||
for (int i=0;i<Ngear;i++) {
|
||||
add_gear_unit( FGGearInterface() );
|
||||
gear=get_gear_unit(i);
|
||||
gear->SetX( gr->GetGearUnit(i)->GetBodyLocation()(1) );
|
||||
gear->SetY( gr->GetGearUnit(i)->GetBodyLocation()(2) );
|
||||
gear->SetZ( gr->GetGearUnit(i)->GetBodyLocation()(3) );
|
||||
gear->SetWoW( gr->GetGearUnit(i)->GetWOW() );
|
||||
if ( gr->GetGearUnit(i)->GetBrakeGroup() > 0 ) {
|
||||
gear->SetBrake(true);
|
||||
}
|
||||
if ( gr->GetGearUp() ) {
|
||||
gear->SetPosition( 0.0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FGJSBsim::update_Longitude(double lon) {
|
||||
void FGJSBsim::update_gear(void) {
|
||||
|
||||
SG_LOG(SG_FLIGHT,SG_INFO,"FGJSBsim::update_Longitude: " << lon );
|
||||
SG_LOG(SG_FLIGHT,SG_INFO," cur alt = " << get_Altitude() );
|
||||
|
||||
snap_shot();
|
||||
fgic->SetLongitudeRadIC(lon);
|
||||
fdmex->RunIC(fgic); //loop JSBSim once
|
||||
copy_from_JSBsim(); //update the bus
|
||||
needTrim=true;
|
||||
FGGearInterface* gear;
|
||||
FGGroundReactions* gr=fdmex->GetGroundReactions();
|
||||
int Ngear=GroundReactions->GetNumGearUnits();
|
||||
for (int i=0;i<Ngear;i++) {
|
||||
gear=get_gear_unit(i);
|
||||
gear->SetWoW( gr->GetGearUnit(i)->GetWOW() );
|
||||
if ( gr->GetGearUp() ) {
|
||||
gear->SetPosition( 0.0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FGJSBsim::update_Altitude(double alt) {
|
||||
double sea_level_radius_meters,lat_geoc;
|
||||
void FGJSBsim::do_trim(void) {
|
||||
|
||||
SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Altitude: " << alt );
|
||||
FGTrim *fgtrim;
|
||||
if(fgic->GetVcalibratedKtsIC() < 10 ) {
|
||||
fgic->SetVcalibratedKtsIC(0.0);
|
||||
fgtrim=new FGTrim(fdmex,fgic,tGround);
|
||||
} else {
|
||||
fgtrim=new FGTrim(fdmex,fgic,tLongitudinal);
|
||||
}
|
||||
if( !fgtrim->DoTrim() ) {
|
||||
fgtrim->Report();
|
||||
fgtrim->TrimStats();
|
||||
} else {
|
||||
trimmed->setBoolValue(true);
|
||||
}
|
||||
State->ReportState();
|
||||
delete fgtrim;
|
||||
pitch_trim->setDoubleValue( FCS->GetPitchTrimCmd() );
|
||||
throttle_trim->setDoubleValue( FCS->GetThrottleCmd(0) );
|
||||
aileron_trim->setDoubleValue( FCS->GetDaCmd() );
|
||||
rudder_trim->setDoubleValue( FCS->GetDrCmd() );
|
||||
|
||||
snap_shot();
|
||||
sgGeodToGeoc( get_Latitude(), alt , &sea_level_radius_meters, &lat_geoc);
|
||||
_set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET );
|
||||
fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET );
|
||||
fgic->SetLatitudeRadIC( lat_geoc );
|
||||
fgic->SetAltitudeFtIC(alt);
|
||||
fdmex->RunIC(fgic); //loop JSBSim once
|
||||
copy_from_JSBsim(); //update the bus
|
||||
needTrim=true;
|
||||
globals->get_controls()->set_elevator_trim(FCS->GetPitchTrimCmd());
|
||||
globals->get_controls()->set_elevator(FCS->GetDeCmd());
|
||||
globals->get_controls()->set_throttle(FGControls::ALL_ENGINES,
|
||||
FCS->GetThrottleCmd(0));
|
||||
|
||||
globals->get_controls()->set_aileron(FCS->GetDaCmd());
|
||||
globals->get_controls()->set_rudder( FCS->GetDrCmd());
|
||||
|
||||
SG_LOG( SG_FLIGHT, SG_INFO, " Trim complete" );
|
||||
}
|
||||
|
||||
void FGJSBsim::update_V_calibrated_kts(double vc) {
|
||||
SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_V_calibrated_kts: " << vc );
|
||||
|
||||
snap_shot();
|
||||
fgic->SetVcalibratedKtsIC(vc);
|
||||
fdmex->RunIC(fgic); //loop JSBSim once
|
||||
copy_from_JSBsim(); //update the bus
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
void FGJSBsim::update_Mach_number(double mach) {
|
||||
SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Mach_number: " << mach );
|
||||
|
||||
snap_shot();
|
||||
fgic->SetMachIC(mach);
|
||||
fdmex->RunIC(fgic); //loop JSBSim once
|
||||
copy_from_JSBsim(); //update the bus
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
void FGJSBsim::update_Velocities_Local( double north, double east, double down ){
|
||||
SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Velocities_Local: "
|
||||
<< north << ", " << east << ", " << down );
|
||||
|
||||
snap_shot();
|
||||
fgic->SetVnorthFpsIC(north);
|
||||
fgic->SetVeastFpsIC(east);
|
||||
fgic->SetVdownFpsIC(down);
|
||||
fdmex->RunIC(fgic); //loop JSBSim once
|
||||
copy_from_JSBsim(); //update the bus
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
void FGJSBsim::update_Velocities_Wind_Body( double u, double v, double w){
|
||||
SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Velocities_Wind_Body: "
|
||||
<< u << ", " << v << ", " << w );
|
||||
|
||||
snap_shot();
|
||||
fgic->SetUBodyFpsIC(u);
|
||||
fgic->SetVBodyFpsIC(v);
|
||||
fgic->SetWBodyFpsIC(w);
|
||||
fdmex->RunIC(fgic); //loop JSBSim once
|
||||
copy_from_JSBsim(); //update the bus
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
//Euler angles
|
||||
void FGJSBsim::update_Euler_Angles( double phi, double theta, double psi ) {
|
||||
SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Euler_Angles: "
|
||||
<< phi << ", " << theta << ", " << psi );
|
||||
|
||||
snap_shot();
|
||||
fgic->SetPitchAngleRadIC(theta);
|
||||
fgic->SetRollAngleRadIC(phi);
|
||||
fgic->SetTrueHeadingRadIC(psi);
|
||||
fdmex->RunIC(fgic); //loop JSBSim once
|
||||
copy_from_JSBsim(); //update the bus
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
//Flight Path
|
||||
void FGJSBsim::update_Climb_Rate( double roc) {
|
||||
SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Climb_Rate: " << roc );
|
||||
|
||||
snap_shot();
|
||||
fgic->SetClimbRateFpsIC(roc);
|
||||
fdmex->RunIC(fgic); //loop JSBSim once
|
||||
copy_from_JSBsim(); //update the bus
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
void FGJSBsim::update_Gamma_vert_rad( double gamma) {
|
||||
SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Gamma_vert_rad: " << gamma );
|
||||
|
||||
snap_shot();
|
||||
fgic->SetFlightPathAngleRadIC(gamma);
|
||||
fdmex->RunIC(fgic); //loop JSBSim once
|
||||
copy_from_JSBsim(); //update the bus
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
//Earth
|
||||
void FGJSBsim::update_Sea_level_radius(double slr) {
|
||||
SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Sea_level_radius: " << slr );
|
||||
|
||||
snap_shot();
|
||||
fgic->SetSeaLevelRadiusFtIC(slr);
|
||||
fdmex->RunIC(fgic); //loop JSBSim once
|
||||
copy_from_JSBsim(); //update the bus
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
void FGJSBsim::update_Runway_altitude(double ralt) {
|
||||
SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Runway_altitude: " << ralt );
|
||||
|
||||
snap_shot();
|
||||
_set_Runway_altitude( ralt );
|
||||
fgic->SetTerrainAltitudeFtIC( ralt );
|
||||
fdmex->RunIC(fgic); //loop JSBSim once
|
||||
copy_from_JSBsim(); //update the bus
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
void FGJSBsim::update_Static_pressure(double p) {
|
||||
SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Static_pressure: " << p );
|
||||
|
||||
snap_shot();
|
||||
Atmosphere->SetExPressure(p);
|
||||
if(Atmosphere->External() == true)
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
void FGJSBsim::update_Static_temperature(double T) {
|
||||
SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Static_temperature: " << T );
|
||||
|
||||
snap_shot();
|
||||
Atmosphere->SetExTemperature(T);
|
||||
if(Atmosphere->External() == true)
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
|
||||
void FGJSBsim::update_Density(double rho) {
|
||||
SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Density: " << rho );
|
||||
|
||||
snap_shot();
|
||||
Atmosphere->SetExDensity(rho);
|
||||
if(Atmosphere->External() == true)
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
|
||||
void FGJSBsim::update_Velocities_Local_Airmass (double wnorth,
|
||||
double weast,
|
||||
double wdown ) {
|
||||
SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Velocities_Local_Airmass: "
|
||||
<< wnorth << ", " << weast << ", " << wdown );
|
||||
|
||||
_set_Velocities_Local_Airmass( wnorth, weast, wdown );
|
||||
snap_shot();
|
||||
Atmosphere->SetWindNED(wnorth, weast, wdown );
|
||||
if(Atmosphere->External() == true)
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
|
|
|
@ -207,101 +207,7 @@ public:
|
|||
double wdown );
|
||||
/// @name Position Parameter Update
|
||||
//@{
|
||||
/** Update geocentric latitude
|
||||
@param lat latitude in radians measured from the 0 meridian where
|
||||
the westerly direction is positive and east is negative */
|
||||
void update_Latitude(double lat); // geocentric
|
||||
|
||||
/** Update longitude
|
||||
@param lon longitude in radians measured from the equator where
|
||||
the northerly direction is positive and south is negative */
|
||||
void update_Longitude(double lon);
|
||||
|
||||
/** Update altitude
|
||||
Note: this triggers a recalculation of AGL altitude
|
||||
@param alt altitude in feet */
|
||||
void update_Altitude(double alt); // triggers re-calc of AGL altitude
|
||||
//@}
|
||||
|
||||
//void update_AltitudeAGL(double altagl); // and vice-versa
|
||||
|
||||
/// @name Velocity Parameter Update
|
||||
//@{
|
||||
/** Updates calibrated airspeed
|
||||
Updateting this will trigger a recalc of the other velocity terms.
|
||||
@param vc Calibrated airspeed in ft/sec */
|
||||
void update_V_calibrated_kts(double vc);
|
||||
|
||||
/** Updates Mach number.
|
||||
Updateting this will trigger a recalc of the other velocity terms.
|
||||
@param mach Mach number */
|
||||
void update_Mach_number(double mach);
|
||||
|
||||
/** Updates velocity in N-E-D coordinates.
|
||||
Updateting this will trigger a recalc of the other velocity terms.
|
||||
@param north velocity northward in ft/sec
|
||||
@param east velocity eastward in ft/sec
|
||||
@param down velocity downward in ft/sec */
|
||||
void update_Velocities_Local( double north, double east, double down );
|
||||
|
||||
/** Updates aircraft velocity in stability frame.
|
||||
Updateting this will trigger a recalc of the other velocity terms.
|
||||
@param u X velocity in ft/sec
|
||||
@param v Y velocity in ft/sec
|
||||
@param w Z velocity in ft/sec */
|
||||
void update_Velocities_Wind_Body( double u, double v, double w);
|
||||
//@}
|
||||
|
||||
/** Euler Angle Parameter Update
|
||||
@param phi roll angle in radians
|
||||
@param theta pitch angle in radians
|
||||
@param psi heading angle in radians */
|
||||
void update_Euler_Angles( double phi, double theta, double psi );
|
||||
|
||||
/// @name Flight Path Parameter Update
|
||||
//@{
|
||||
/** Updates rate of climb
|
||||
@param roc Rate of climb in ft/sec */
|
||||
void update_Climb_Rate( double roc);
|
||||
|
||||
/** Updates the flight path angle in radians
|
||||
@param gamma flight path angle in radians. */
|
||||
void update_Gamma_vert_rad( double gamma);
|
||||
//@}
|
||||
|
||||
/// @name Earth Parameter Update
|
||||
//@{
|
||||
/** Updates the sea level radius in feet.
|
||||
@param slr Sea Level Radius in feet */
|
||||
void update_Sea_level_radius(double slr);
|
||||
|
||||
/** Updates the runway altitude in feet above sea level.
|
||||
@param ralt Runway altitude in feet above sea level. */
|
||||
void update_Runway_altitude(double ralt);
|
||||
//@}
|
||||
|
||||
/// @name Atmospheric Parameter Update
|
||||
//@{
|
||||
/** Updates the atmospheric static pressure
|
||||
@param p pressure in psf */
|
||||
void update_Static_pressure(double p);
|
||||
|
||||
/** Updates the atmospheric temperature
|
||||
@param T temperature in degrees rankine */
|
||||
void update_Static_temperature(double T);
|
||||
|
||||
/** Updates the atmospheric density.
|
||||
@param rho air density slugs/cubic foot */
|
||||
void update_Density(double rho);
|
||||
|
||||
/** Updates the velocity of the local airmass for wind modeling.
|
||||
@param wnorth velocity north in fps
|
||||
@param weast velocity east in fps
|
||||
@param wdown velocity down in fps*/
|
||||
void update_Velocities_Local_Airmass (double wnorth,
|
||||
double weast,
|
||||
double wdown );
|
||||
//@}
|
||||
|
||||
/** Update the position based on inputs, positions, velocities, etc.
|
||||
@param multiloop number of times to loop through the FDM
|
||||
|
@ -309,6 +215,7 @@ public:
|
|||
bool update( int multiloop );
|
||||
bool ToggleDataLogging(bool state);
|
||||
bool ToggleDataLogging(void);
|
||||
void do_trim(void);
|
||||
|
||||
private:
|
||||
FGFDMExec *fdmex;
|
||||
|
@ -326,6 +233,7 @@ private:
|
|||
FGPosition* Position;
|
||||
FGAuxiliary* Auxiliary;
|
||||
FGAerodynamics* Aerodynamics;
|
||||
FGGroundReactions *GroundReactions;
|
||||
|
||||
int runcount;
|
||||
float trim_elev;
|
||||
|
@ -337,8 +245,11 @@ private:
|
|||
SGPropertyNode *throttle_trim;
|
||||
SGPropertyNode *aileron_trim;
|
||||
SGPropertyNode *rudder_trim;
|
||||
SGPropertyNode *stall_warning;
|
||||
|
||||
void init_gear(void);
|
||||
void update_gear(void);
|
||||
|
||||
void snap_shot(void);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -104,13 +104,15 @@ FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex),
|
|||
vXYZrp(3),
|
||||
vXYZep(3),
|
||||
vDXYZcg(3),
|
||||
vBodyAccel(3)
|
||||
vBodyAccel(3),
|
||||
vNcg(3)
|
||||
{
|
||||
Name = "FGAircraft";
|
||||
alphaclmin = alphaclmax = 0;
|
||||
HTailArea = VTailArea = HTailArm = VTailArm = 0.0;
|
||||
lbarh = lbarv = vbarh = vbarv = 0.0;
|
||||
WingIncidence=0;
|
||||
impending_stall = 0;
|
||||
|
||||
if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
|
||||
}
|
||||
|
@ -176,6 +178,16 @@ bool FGAircraft::Run(void)
|
|||
|
||||
vBodyAccel = vForces/MassBalance->GetMass();
|
||||
|
||||
vNcg = vBodyAccel*INVGRAVITY;
|
||||
|
||||
if (alphaclmax != 0) {
|
||||
if (Translation->Getalpha() > 0.85*alphaclmax) {
|
||||
impending_stall = 10*(Translation->Getalpha()/alphaclmax - 0.85);
|
||||
} else {
|
||||
impending_stall = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} else { // skip Run() execution this time
|
||||
return true;
|
||||
|
|
|
@ -189,6 +189,7 @@ public:
|
|||
inline FGColumnVector3& GetMoments(void) { return vMoments; }
|
||||
inline FGColumnVector3& GetForces(void) { return vForces; }
|
||||
inline FGColumnVector3& GetBodyAccel(void) { return vBodyAccel; }
|
||||
inline FGColumnVector3& GetNcg (void) { return vNcg; }
|
||||
inline FGColumnVector3& GetXYZrp(void) { return vXYZrp; }
|
||||
inline FGColumnVector3& GetXYZep(void) { return vXYZep; }
|
||||
inline float GetXYZrp(int idx) { return vXYZrp(idx); }
|
||||
|
@ -199,6 +200,8 @@ public:
|
|||
inline void SetAlphaCLMax(float tt) { alphaclmax=tt; }
|
||||
inline void SetAlphaCLMin(float tt) { alphaclmin=tt; }
|
||||
|
||||
inline bool GetStallWarn(void) { return impending_stall; }
|
||||
|
||||
/// Subsystem types for specifying which will be output in the FDM data logging
|
||||
enum SubSystems {
|
||||
/** Subsystem: Simulation (= 1) */ ssSimulation = 1,
|
||||
|
@ -224,10 +227,13 @@ private:
|
|||
FGColumnVector3 vEuler;
|
||||
FGColumnVector3 vDXYZcg;
|
||||
FGColumnVector3 vBodyAccel;
|
||||
FGColumnVector3 vNcg;
|
||||
|
||||
float WingArea, WingSpan, cbar, WingIncidence;
|
||||
float HTailArea, VTailArea, HTailArm, VTailArm;
|
||||
float lbarh,lbarv,vbarh,vbarv;
|
||||
float alphaclmax,alphaclmin;
|
||||
float impending_stall;
|
||||
string CFGVersion;
|
||||
string AircraftName;
|
||||
|
||||
|
|
|
@ -141,19 +141,19 @@ public:
|
|||
inline float GetWindPsi(void) { return psiw; }
|
||||
|
||||
private:
|
||||
float rho;
|
||||
double rho;
|
||||
|
||||
int lastIndex;
|
||||
float h;
|
||||
float htab[8];
|
||||
float SLtemperature,SLdensity,SLpressure,SLsoundspeed;
|
||||
float rSLtemperature,rSLdensity,rSLpressure,rSLsoundspeed; //reciprocals
|
||||
float temperature,density,pressure,soundspeed;
|
||||
double h;
|
||||
double htab[8];
|
||||
double SLtemperature,SLdensity,SLpressure,SLsoundspeed;
|
||||
double rSLtemperature,rSLdensity,rSLpressure,rSLsoundspeed; //reciprocals
|
||||
double temperature,density,pressure,soundspeed;
|
||||
bool useExternal;
|
||||
float exTemperature,exDensity,exPressure;
|
||||
double exTemperature,exDensity,exPressure;
|
||||
|
||||
FGColumnVector3 vWindNED;
|
||||
float psiw;
|
||||
double psiw;
|
||||
|
||||
void Calculate(float altitude);
|
||||
void Debug(void);
|
||||
|
|
|
@ -63,12 +63,13 @@ FGForce::FGForce(FGFDMExec *FDMExec) :
|
|||
vXYZn(3),
|
||||
vDXYZ(3),
|
||||
mT(3,3),
|
||||
vH(3),
|
||||
vSense(3),
|
||||
ttype(tNone)
|
||||
{
|
||||
mT(1,1)=1; //identity matrix
|
||||
mT(2,2)=1;
|
||||
mT(3,3)=1;
|
||||
mT(1,1) = 1; //identity matrix
|
||||
mT(2,2) = 1;
|
||||
mT(3,3) = 1;
|
||||
vSense.InitMatrix(1);
|
||||
if (debug_lvl & 2) cout << "Instantiated: FGForce" << endl;
|
||||
}
|
||||
|
@ -84,7 +85,7 @@ FGForce::~FGForce()
|
|||
|
||||
FGColumnVector3& FGForce::GetBodyForces(void) {
|
||||
|
||||
vFb=Transform()*(vFn.multElementWise(vSense));
|
||||
vFb = Transform()*(vFn.multElementWise(vSense));
|
||||
|
||||
//find the distance from this vector's location to the cg
|
||||
//needs to be done like this to convert from structural to body coords
|
||||
|
@ -92,7 +93,9 @@ FGColumnVector3& FGForce::GetBodyForces(void) {
|
|||
vDXYZ(2) = (vXYZn(2) - fdmex->GetMassBalance()->GetXYZcg(2))*INCHTOFT; //cg and rp values are in inches
|
||||
vDXYZ(3) = -(vXYZn(3) - fdmex->GetMassBalance()->GetXYZcg(3))*INCHTOFT;
|
||||
|
||||
vM=vMn +vDXYZ*vFb;
|
||||
// include rotational effects. vH will be set in descendent class such as
|
||||
// FGPropeller, and in most other cases will be zero.
|
||||
vM = vMn + vDXYZ*vFb + fdmex->GetRotation()->GetPQR()*vH;
|
||||
|
||||
return vFb;
|
||||
}
|
||||
|
|
|
@ -256,6 +256,9 @@ public:
|
|||
vXYZn(2) = y;
|
||||
vXYZn(3) = z;
|
||||
}
|
||||
inline void SetLocationX(float x) {vXYZn(1) = x;}
|
||||
inline void SetLocationY(float y) {vXYZn(2) = y;}
|
||||
inline void SetLocationZ(float z) {vXYZn(3) = z;}
|
||||
inline void SetLocation(FGColumnVector3 vv) { vXYZn = vv; }
|
||||
FGColumnVector3& GetLocation(void) { return vXYZn; }
|
||||
|
||||
|
@ -282,6 +285,7 @@ public:
|
|||
protected:
|
||||
FGColumnVector3 vFn;
|
||||
FGColumnVector3 vMn;
|
||||
FGColumnVector3 vH;
|
||||
FGFDMExec *fdmex;
|
||||
virtual void Debug(void);
|
||||
|
||||
|
|
|
@ -229,6 +229,9 @@ public:
|
|||
inline float GetSteerAngle(void) { return SteerAngle;}
|
||||
inline float GetstaticFCoeff(void) { return staticFCoeff;}
|
||||
|
||||
inline int GetBrakeGroup(void) { return (int)eBrakeGrp; }
|
||||
inline int GetSteerType(void) { return (int)eSteerType; }
|
||||
|
||||
private:
|
||||
FGColumnVector3 vXYZ;
|
||||
FGColumnVector3 vMoment;
|
||||
|
|
|
@ -50,7 +50,7 @@ FGPropeller::FGPropeller(FGFDMExec* exec, FGConfigFile* Prop_cfg) : FGThruster(e
|
|||
string token;
|
||||
int rows, cols;
|
||||
|
||||
MaxPitch = MinPitch = 0.0;
|
||||
MaxPitch = MinPitch = P_Factor = Sense = 0.0;
|
||||
|
||||
Name = Prop_cfg->GetValue("NAME");
|
||||
Prop_cfg->GetNextConfigLine();
|
||||
|
@ -67,6 +67,10 @@ FGPropeller::FGPropeller(FGFDMExec* exec, FGConfigFile* Prop_cfg) : FGThruster(e
|
|||
*Prop_cfg >> MinPitch;
|
||||
} else if (token == "MAXPITCH") {
|
||||
*Prop_cfg >> MaxPitch;
|
||||
} else if (token == "P_FACTOR") {
|
||||
*Prop_cfg >> P_Factor;
|
||||
} else if (token == "SENSE") {
|
||||
*Prop_cfg >> Sense;
|
||||
} else if (token == "EFFICIENCY") {
|
||||
*Prop_cfg >> rows >> cols;
|
||||
if (cols == 1) Efficiency = new FGTable(rows);
|
||||
|
@ -97,6 +101,14 @@ FGPropeller::FGPropeller(FGFDMExec* exec, FGConfigFile* Prop_cfg) : FGThruster(e
|
|||
cout << " Number of Blades = " << numBlades << endl;
|
||||
cout << " Minimum Pitch = " << MinPitch << endl;
|
||||
cout << " Maximum Pitch = " << MaxPitch << endl;
|
||||
if (P_Factor > 0.0) cout << " P-Factor = " << P_Factor << endl;
|
||||
if (Sense > 0.0) {
|
||||
cout << " Rotation Sense = CW (viewed from pilot looking forward)" << endl;
|
||||
} else if (Sense < 0.0) {
|
||||
cout << " Rotation Sense = CCW (viewed from pilot looking forward)" << endl;
|
||||
} else {
|
||||
cout << " Rotation Sense = indeterminate" << endl;
|
||||
}
|
||||
cout << " Efficiency: " << endl;
|
||||
Efficiency->Print();
|
||||
cout << " Thrust Coefficient: " << endl;
|
||||
|
@ -141,6 +153,7 @@ float FGPropeller::Calculate(float PowerAvailable)
|
|||
float Vel = (fdmex->GetTranslation()->GetvAero())(1);
|
||||
float rho = fdmex->GetAtmosphere()->GetDensity();
|
||||
float RPS = RPM/60.0;
|
||||
float alpha, beta;
|
||||
|
||||
if (RPM > 0.10) {
|
||||
J = Vel / (Diameter * RPM / 60.0);
|
||||
|
@ -154,10 +167,25 @@ float FGPropeller::Calculate(float PowerAvailable)
|
|||
C_Thrust = cThrust->GetValue(J, Pitch);
|
||||
}
|
||||
|
||||
if (P_Factor > 0.0001) {
|
||||
alpha = fdmex->GetTranslation()->Getalpha();
|
||||
beta = fdmex->GetTranslation()->Getbeta();
|
||||
SetLocationY(P_Factor*alpha*fabs(Sense)/Sense);
|
||||
SetLocationZ(P_Factor*beta*fabs(Sense)/Sense);
|
||||
} else if (P_Factor < 0.000) {
|
||||
cerr << "P-Factor value in config file must be greater than zero" << endl;
|
||||
}
|
||||
|
||||
Thrust = C_Thrust*RPS*RPS*Diameter*Diameter*Diameter*Diameter*rho;
|
||||
vFn(1) = Thrust;
|
||||
omega = RPS*2.0*M_PI;
|
||||
|
||||
// Must consider rotated axis for propeller (V-22, helicopter case)
|
||||
// FIX THIS !!
|
||||
vH(eX) = Ixx*omega*fabs(Sense)/Sense;
|
||||
vH(eY) = 0.0;
|
||||
vH(eZ) = 0.0;
|
||||
|
||||
if (omega <= 5) omega = 1.0;
|
||||
|
||||
Torque = PowerAvailable / omega;
|
||||
|
|
|
@ -150,6 +150,8 @@ private:
|
|||
float Diameter;
|
||||
float MaxPitch;
|
||||
float MinPitch;
|
||||
float P_Factor;
|
||||
float Sense;
|
||||
float Pitch;
|
||||
float Torque;
|
||||
FGTable *Efficiency;
|
||||
|
|
|
@ -115,6 +115,8 @@ bool FGPropulsion::GetSteadyState(void) {
|
|||
float PowerAvailable;
|
||||
float currentThrust = 0, lastThrust=-1;
|
||||
dt = State->Getdt();
|
||||
int steady_count,j=0;
|
||||
bool steady=false;
|
||||
|
||||
Forces->InitMatrix();
|
||||
Moments->InitMatrix();
|
||||
|
@ -123,10 +125,18 @@ bool FGPropulsion::GetSteadyState(void) {
|
|||
for (unsigned int i=0; i<numEngines; i++) {
|
||||
Engines[i]->SetTrimMode(true);
|
||||
Thrusters[i]->SetdeltaT(dt*rate);
|
||||
while (pow(currentThrust - lastThrust, 2.0) > currentThrust*0.00010) {
|
||||
steady=false;
|
||||
while (!steady && j < 6000) {
|
||||
PowerAvailable = Engines[i]->Calculate(Thrusters[i]->GetPowerRequired());
|
||||
lastThrust = currentThrust;
|
||||
currentThrust = Thrusters[i]->Calculate(PowerAvailable);
|
||||
if(fabs(lastThrust-currentThrust) < 0.0001) {
|
||||
steady_count++;
|
||||
if(steady_count > 120) { steady=true; }
|
||||
} else {
|
||||
steady_count=0;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
*Forces += Thrusters[i]->GetBodyForces(); // sum body frame forces
|
||||
*Moments += Thrusters[i]->GetMoments(); // sum body frame moments
|
||||
|
@ -141,6 +151,33 @@ bool FGPropulsion::GetSteadyState(void) {
|
|||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
|
||||
bool FGPropulsion::ICEngineStart(void) {
|
||||
float PowerAvailable;
|
||||
int j;
|
||||
dt = State->Getdt();
|
||||
|
||||
Forces->InitMatrix();
|
||||
Moments->InitMatrix();
|
||||
|
||||
for (unsigned int i=0; i<numEngines; i++) {
|
||||
Engines[i]->SetTrimMode(true);
|
||||
Thrusters[i]->SetdeltaT(dt*rate);
|
||||
j=0;
|
||||
while (!Engines[i]->GetRunning() && j < 2000) {
|
||||
PowerAvailable = Engines[i]->Calculate(Thrusters[i]->GetPowerRequired());
|
||||
Thrusters[i]->Calculate(PowerAvailable);
|
||||
j++;
|
||||
}
|
||||
*Forces += Thrusters[i]->GetBodyForces(); // sum body frame forces
|
||||
*Moments += Thrusters[i]->GetMoments(); // sum body frame moments
|
||||
Engines[i]->SetTrimMode(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
bool FGPropulsion::Load(FGConfigFile* AC_cfg)
|
||||
{
|
||||
string token, fullpath;
|
||||
|
|
|
@ -158,8 +158,13 @@ public:
|
|||
/** Returns the number of oxidizer tanks currently actively supplying oxidizer */
|
||||
inline int GetnumSelectedOxiTanks(void) {return numSelectedOxiTanks;}
|
||||
|
||||
/** Loops the engines/thrusters until thrust output steady (used for trimming) */
|
||||
bool GetSteadyState(void);
|
||||
|
||||
/** starts the engines in IC mode (dt=0). All engine-specific setup must
|
||||
be done before calling this (i.e. magnetos, starter engage, etc.) */
|
||||
bool ICEngineStart(void);
|
||||
|
||||
string GetPropulsionStrings(void);
|
||||
string GetPropulsionValues(void);
|
||||
|
||||
|
|
|
@ -739,7 +739,7 @@ void FGState::ReportState(void) {
|
|||
GetParameter(FG_RUDDER_POS)*RADTODEG );
|
||||
cout << out;
|
||||
snprintf(out,80, " Throttle: %5.2f%c\n",
|
||||
FCS->GetThrottlePos(0),'%' );
|
||||
FCS->GetThrottlePos(0)*100,'%' );
|
||||
cout << out;
|
||||
|
||||
snprintf(out,80, " Wind Components: %5.2f kts head wind, %5.2f kts cross wind\n",
|
||||
|
|
|
@ -80,7 +80,6 @@ CLASS IMPLEMENTATION
|
|||
FGTranslation::FGTranslation(FGFDMExec* fdmex) : FGModel(fdmex),
|
||||
vUVW(3),
|
||||
vUVWdot(3),
|
||||
vNcg(3),
|
||||
vlastUVWdot(3),
|
||||
mVel(3,3),
|
||||
vAero(3)
|
||||
|
@ -120,9 +119,7 @@ bool FGTranslation::Run(void)
|
|||
mVel(3,2) = vUVW(eU);
|
||||
mVel(3,3) = 0.0;
|
||||
|
||||
vUVWdot = mVel*Rotation->GetPQR() + Aircraft->GetForces()/MassBalance->GetMass();
|
||||
|
||||
vNcg = vUVWdot*INVGRAVITY;
|
||||
vUVWdot = mVel*Rotation->GetPQR() + Aircraft->GetBodyAccel();
|
||||
|
||||
vUVW += Tc * (vlastUVWdot + vUVWdot);
|
||||
vAero = vUVW + State->GetTl2b()*Atmosphere->GetWindNED();
|
||||
|
|
|
@ -91,8 +91,6 @@ public:
|
|||
inline float GetUVW (int idx) { return vUVW(idx); }
|
||||
inline FGColumnVector3& GetUVWdot(void) { return vUVWdot; }
|
||||
inline float GetUVWdot(int idx) { return vUVWdot(idx); }
|
||||
inline FGColumnVector3& GetNcg (void) { return vNcg; }
|
||||
inline float GetNcg (int idx) { return vNcg(idx); }
|
||||
inline FGColumnVector3& GetvAero (void) { return vAero; }
|
||||
inline float GetvAero (int idx) { return vAero(idx); }
|
||||
|
||||
|
@ -121,7 +119,6 @@ public:
|
|||
private:
|
||||
FGColumnVector3 vUVW;
|
||||
FGColumnVector3 vUVWdot;
|
||||
FGColumnVector3 vNcg;
|
||||
FGColumnVector3 vlastUVWdot;
|
||||
FGMatrix33 mVel;
|
||||
FGColumnVector3 vAero;
|
||||
|
|
|
@ -150,9 +150,9 @@ FGTrimAxis::~FGTrimAxis()
|
|||
|
||||
void FGTrimAxis::getState(void) {
|
||||
switch(state) {
|
||||
case tUdot: state_value=fdmex->GetTranslation()->GetUVWdot(1); break;
|
||||
case tVdot: state_value=fdmex->GetTranslation()->GetUVWdot(2); break;
|
||||
case tWdot: state_value=fdmex->GetTranslation()->GetUVWdot(3); break;
|
||||
case tUdot: state_value=fdmex->GetAircraft()->GetBodyAccel()(1); break;
|
||||
case tVdot: state_value=fdmex->GetAircraft()->GetBodyAccel()(2); break;
|
||||
case tWdot: state_value=fdmex->GetAircraft()->GetBodyAccel()(3); break;
|
||||
case tQdot: state_value=fdmex->GetRotation()->GetPQRdot(2);break;
|
||||
case tPdot: state_value=fdmex->GetRotation()->GetPQRdot(1); break;
|
||||
case tRdot: state_value=fdmex->GetRotation()->GetPQRdot(3); break;
|
||||
|
@ -397,7 +397,10 @@ void FGTrimAxis::setThrottlesPct(void) {
|
|||
tMin=fdmex->GetPropulsion()->GetEngine(i)->GetThrottleMin();
|
||||
tMax=fdmex->GetPropulsion()->GetEngine(i)->GetThrottleMax();
|
||||
//cout << "setThrottlespct: " << i << ", " << control_min << ", " << control_max << ", " << control_value;
|
||||
fdmex -> GetFCS() -> SetThrottleCmd(i,tMin+control_value*(tMax-tMin));
|
||||
fdmex->GetFCS()->SetThrottleCmd(i,tMin+control_value*(tMax-tMin));
|
||||
//cout << "setThrottlespct: " << fdmex->GetFCS()->GetThrottleCmd(i) << endl;
|
||||
fdmex->RunIC(fgic); //apply throttle change
|
||||
fdmex->GetPropulsion()->GetSteadyState();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -88,10 +88,10 @@ FGLaRCsim::~FGLaRCsim(void) {
|
|||
// Initialize the LaRCsim flight model, dt is the time increment for
|
||||
// each subsequent iteration through the EOM
|
||||
void FGLaRCsim::init() {
|
||||
//do init common to all FDM's
|
||||
common_init();
|
||||
|
||||
// Explicitly call the superclass's
|
||||
// init method first.
|
||||
FGInterface::init();
|
||||
//now do any specific to LaRCsim
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -44,9 +44,7 @@ FGMagicCarpet::~FGMagicCarpet() {
|
|||
// Initialize the Magic Carpet flight model, dt is the time increment
|
||||
// for each subsequent iteration through the EOM
|
||||
void FGMagicCarpet::init() {
|
||||
// explicitly call the superclass's
|
||||
// init method first
|
||||
FGInterface::init();
|
||||
common_init();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -71,6 +71,14 @@ FGEngInterface::FGEngInterface() {
|
|||
FGEngInterface::~FGEngInterface(void) {
|
||||
}
|
||||
|
||||
FGGearInterface::FGGearInterface(void) {
|
||||
x=y=z=0.0;
|
||||
brake=rolls=WoW=false;
|
||||
position=1.0;
|
||||
}
|
||||
|
||||
FGGearInterface::~FGGearInterface() {
|
||||
}
|
||||
|
||||
// Constructor
|
||||
FGInterface::FGInterface() {
|
||||
|
@ -167,86 +175,101 @@ FGInterface::_setup ()
|
|||
altitude_agl=0;
|
||||
}
|
||||
|
||||
void
|
||||
FGInterface::init () {}
|
||||
|
||||
/**
|
||||
* Initialize the state of the FDM.
|
||||
*
|
||||
* Subclasses of FGInterface may do their own, additional initialization,
|
||||
* but normally they should invoke this method explicitly first as
|
||||
* FGInterface::init() to make sure the basic structures are set up
|
||||
* properly.
|
||||
* but there is some that is common to all. Normally, they should call
|
||||
* this before they begin their own init to make sure the basic structures
|
||||
* are set up properly.
|
||||
*/
|
||||
void
|
||||
FGInterface::init ()
|
||||
FGInterface::common_init ()
|
||||
{
|
||||
SG_LOG(SG_FLIGHT, SG_INFO, "Start initializing FGInterface");
|
||||
SG_LOG( SG_FLIGHT, SG_INFO, "Start common FDM init" );
|
||||
|
||||
inited = true;
|
||||
set_inited( true );
|
||||
|
||||
stamp();
|
||||
set_remainder(0);
|
||||
stamp();
|
||||
set_remainder( 0 );
|
||||
|
||||
// Set initial position
|
||||
SG_LOG(SG_FLIGHT, SG_INFO, "...initializing position...");
|
||||
set_Longitude(fgGetDouble("/position/longitude-deg") * SGD_DEGREES_TO_RADIANS);
|
||||
set_Latitude(fgGetDouble("/position/latitude-deg") * SGD_DEGREES_TO_RADIANS);
|
||||
double ground_elev_m = scenery.get_cur_elev() + 1;
|
||||
double ground_elev_ft = ground_elev_m * METERS_TO_FEET;
|
||||
if (fgGetBool("/sim/startup/onground") ||
|
||||
fgGetDouble("/position/altitude-ft") < ground_elev_ft)
|
||||
fgSetDouble("/position/altitude-ft", ground_elev_ft);
|
||||
set_Altitude(fgGetDouble("/position/altitude-ft"));
|
||||
|
||||
// Set ground elevation
|
||||
SG_LOG(SG_FLIGHT, SG_INFO,
|
||||
"...initializing ground elevation to "
|
||||
<< ground_elev_ft << "ft...");
|
||||
fgFDMSetGroundElevation("jsb", ground_elev_m);
|
||||
|
||||
// Set sea-level radius
|
||||
SG_LOG(SG_FLIGHT, SG_INFO, "...initializing sea-level radius...");
|
||||
SG_LOG(SG_FLIGHT, SG_INFO, " lat = " << fgGetDouble("/position/latitude-deg")
|
||||
<< " alt = " << fgGetDouble("/position/altitude-ft") );
|
||||
double sea_level_radius_meters;
|
||||
double lat_geoc;
|
||||
sgGeodToGeoc(fgGetDouble("/position/latitude-deg") * SGD_DEGREES_TO_RADIANS,
|
||||
fgGetDouble("/position/altitude-ft") * SG_FEET_TO_METER,
|
||||
&sea_level_radius_meters, &lat_geoc);
|
||||
set_Sea_level_radius(sea_level_radius_meters * SG_METER_TO_FEET);
|
||||
|
||||
// Set initial velocities
|
||||
SG_LOG(SG_FLIGHT, SG_INFO, "...initializing velocities...");
|
||||
if (!fgHasNode("/sim/startup/speed-set")) {
|
||||
set_V_calibrated_kts(0.0);
|
||||
} else {
|
||||
const string speedset = fgGetString("/sim/startup/speed-set");
|
||||
if (speedset == "knots" || speedset == "KNOTS") {
|
||||
set_V_calibrated_kts(fgGetDouble("/velocities/airspeed-kt"));
|
||||
} else if (speedset == "mach" || speedset == "MACH") {
|
||||
set_Mach_number(fgGetDouble("/velocities/mach"));
|
||||
} else if (speedset == "UVW" || speedset == "uvw") {
|
||||
set_Velocities_Wind_Body(fgGetDouble("/velocities/uBody-fps"),
|
||||
fgGetDouble("/velocities/vBody-fps"),
|
||||
fgGetDouble("/velocities/wBody-fps"));
|
||||
} else if (speedset == "NED" || speedset == "ned") {
|
||||
set_Velocities_Local(fgGetDouble("/velocities/speed-north-fps"),
|
||||
fgGetDouble("/velocities/speed-east-fps"),
|
||||
fgGetDouble("/velocities/speed-down-fps"));
|
||||
} else {
|
||||
SG_LOG(SG_FLIGHT, SG_ALERT,
|
||||
"Unrecognized value for /sim/startup/speed-set: " << speedset);
|
||||
set_V_calibrated_kts(0.0);
|
||||
// Set initial position
|
||||
SG_LOG( SG_FLIGHT, SG_INFO, "...initializing position..." );
|
||||
set_Longitude( fgGetDouble("/position/longitude-deg")
|
||||
* SGD_DEGREES_TO_RADIANS );
|
||||
set_Latitude( fgGetDouble("/position/latitude-deg")
|
||||
* SGD_DEGREES_TO_RADIANS );
|
||||
double ground_elev_m = scenery.get_cur_elev();
|
||||
double ground_elev_ft = ground_elev_m * METERS_TO_FEET;
|
||||
if ( fgGetBool("/sim/startup/onground")
|
||||
|| fgGetDouble("/position/altitude-ft") < ground_elev_ft ) {
|
||||
fgSetDouble("/position/altitude-ft", ground_elev_ft);
|
||||
}
|
||||
}
|
||||
set_Altitude( fgGetDouble("/position/altitude-ft") );
|
||||
|
||||
// Set initial Euler angles
|
||||
SG_LOG(SG_FLIGHT, SG_INFO, "...initializing Euler angles...");
|
||||
set_Euler_Angles
|
||||
(fgGetDouble("/orientation/roll-deg") * SGD_DEGREES_TO_RADIANS,
|
||||
fgGetDouble("/orientation/pitch-deg") * SGD_DEGREES_TO_RADIANS,
|
||||
fgGetDouble("/orientation/heading-deg") * SGD_DEGREES_TO_RADIANS);
|
||||
// Set ground elevation
|
||||
SG_LOG( SG_FLIGHT, SG_INFO,
|
||||
"...initializing ground elevation to " << ground_elev_ft
|
||||
<< "ft..." );
|
||||
SG_LOG( SG_FLIGHT, SG_INFO, "common_init(): set ground elevation "
|
||||
<< ground_elev_ft );
|
||||
base_fdm_state.set_Runway_altitude( ground_elev_ft );
|
||||
set_Runway_altitude( ground_elev_ft );
|
||||
|
||||
SG_LOG(SG_FLIGHT, SG_INFO, "End initializing FGInterface");
|
||||
// Set sea-level radius
|
||||
SG_LOG( SG_FLIGHT, SG_INFO, "...initializing sea-level radius..." );
|
||||
SG_LOG( SG_FLIGHT, SG_INFO, " lat = "
|
||||
<< fgGetDouble("/position/latitude-deg")
|
||||
<< " alt = " << fgGetDouble("/position/altitude-ft") );
|
||||
double sea_level_radius_meters;
|
||||
double lat_geoc;
|
||||
sgGeodToGeoc( fgGetDouble("/position/latitude-deg")
|
||||
* SGD_DEGREES_TO_RADIANS,
|
||||
fgGetDouble("/position/altitude-ft") * SG_FEET_TO_METER,
|
||||
&sea_level_radius_meters, &lat_geoc );
|
||||
set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET );
|
||||
|
||||
// Set initial velocities
|
||||
SG_LOG( SG_FLIGHT, SG_INFO, "...initializing velocities..." );
|
||||
if ( !fgHasNode("/sim/startup/speed-set") ) {
|
||||
set_V_calibrated_kts(0.0);
|
||||
} else {
|
||||
const string speedset = fgGetString("/sim/startup/speed-set");
|
||||
if ( speedset == "knots" || speedset == "KNOTS" ) {
|
||||
set_V_calibrated_kts( fgGetDouble("/velocities/airspeed-kt") );
|
||||
} else if ( speedset == "mach" || speedset == "MACH" ) {
|
||||
set_Mach_number( fgGetDouble("/velocities/mach") );
|
||||
} else if ( speedset == "UVW" || speedset == "uvw" ) {
|
||||
set_Velocities_Wind_Body(
|
||||
fgGetDouble("/velocities/uBody-fps"),
|
||||
fgGetDouble("/velocities/vBody-fps"),
|
||||
fgGetDouble("/velocities/wBody-fps") );
|
||||
} else if ( speedset == "NED" || speedset == "ned" ) {
|
||||
set_Velocities_Local(
|
||||
fgGetDouble("/velocities/speed-north-fps"),
|
||||
fgGetDouble("/velocities/speed-east-fps"),
|
||||
fgGetDouble("/velocities/speed-down-fps") );
|
||||
} else {
|
||||
SG_LOG( SG_FLIGHT, SG_ALERT,
|
||||
"Unrecognized value for /sim/startup/speed-set: "
|
||||
<< speedset);
|
||||
set_V_calibrated_kts( 0.0 );
|
||||
}
|
||||
}
|
||||
|
||||
// Set initial Euler angles
|
||||
SG_LOG( SG_FLIGHT, SG_INFO, "...initializing Euler angles..." );
|
||||
set_Euler_Angles( fgGetDouble("/orientation/roll-deg")
|
||||
* SGD_DEGREES_TO_RADIANS,
|
||||
fgGetDouble("/orientation/pitch-deg")
|
||||
* SGD_DEGREES_TO_RADIANS,
|
||||
fgGetDouble("/orientation/heading-deg")
|
||||
* SGD_DEGREES_TO_RADIANS );
|
||||
|
||||
SG_LOG( SG_FLIGHT, SG_INFO, "End common FDM init" );
|
||||
}
|
||||
|
||||
|
||||
|
@ -524,15 +547,6 @@ void fgFDMForceAltitude(const string &model, double alt_meters) {
|
|||
}
|
||||
|
||||
|
||||
// Set the local ground elevation
|
||||
void fgFDMSetGroundElevation(const string &model, double ground_meters) {
|
||||
SG_LOG( SG_FLIGHT,SG_INFO, "fgFDMSetGroundElevation: "
|
||||
<< ground_meters*SG_METER_TO_FEET );
|
||||
base_fdm_state.set_Runway_altitude( ground_meters * SG_METER_TO_FEET );
|
||||
cur_fdm_state->set_Runway_altitude( ground_meters * SG_METER_TO_FEET );
|
||||
}
|
||||
|
||||
|
||||
// Positions
|
||||
void FGInterface::set_Latitude(double lat) {
|
||||
geodetic_position_v[0] = lat;
|
||||
|
@ -723,4 +737,3 @@ void FGInterface::_busdump(void) {
|
|||
void fgToggleFDMdataLogging(void) {
|
||||
cur_fdm_state->ToggleDataLogging();
|
||||
}
|
||||
|
||||
|
|
|
@ -177,6 +177,43 @@ public:
|
|||
|
||||
typedef vector < FGEngInterface > engine_list;
|
||||
|
||||
class FGGearInterface {
|
||||
private:
|
||||
|
||||
string name;
|
||||
float x,y,z; // >0 forward of cg, >0 right, >0 down
|
||||
bool brake; // true if this gear unit has a brake mechanism
|
||||
bool rolls; // true if this gear unit has a wheel
|
||||
bool WoW; // true if this gear unit is touching the ground
|
||||
float position; // 0 if retracted, 1 if extended
|
||||
|
||||
public:
|
||||
FGGearInterface(void);
|
||||
~FGGearInterface(void);
|
||||
inline string GetName(void) { return name; }
|
||||
inline void SetName(string nm) { name=nm; }
|
||||
inline float GetX(void) { return x; }
|
||||
inline void SetX(float xloc) { x=xloc; }
|
||||
inline float GetY(void) { return y; }
|
||||
inline void SetY(float yloc) { y=yloc; }
|
||||
inline float GetZ(void) { return z; }
|
||||
inline void SetZ(float zloc) { z=zloc; }
|
||||
inline bool GetBrake(void) { return brake; }
|
||||
inline void SetBrake(bool brk) { brake=brk; }
|
||||
|
||||
// no good way to implement these right now
|
||||
//inline bool GetRolls(void) { return rolls; }
|
||||
//inline SetRolls(bool rl) { rolls=rl; }
|
||||
|
||||
inline bool GetWoW(void) { return WoW; }
|
||||
inline void SetWoW(bool wow) { WoW=wow; }
|
||||
inline float GetPosition(void) { return position; }
|
||||
inline void SetPosition(float pos) { position=pos; }
|
||||
};
|
||||
|
||||
typedef vector < FGGearInterface > gear_list;
|
||||
|
||||
|
||||
|
||||
// This is based heavily on LaRCsim/ls_generic.h
|
||||
class FGInterface : public FGSubsystem {
|
||||
|
@ -303,6 +340,9 @@ private:
|
|||
// Engine list
|
||||
engine_list engines;
|
||||
|
||||
//gear list
|
||||
gear_list gear;
|
||||
|
||||
// SGTimeStamp valid_stamp; // time this record is valid
|
||||
// SGTimeStamp next_stamp; // time this record is valid
|
||||
|
||||
|
@ -521,6 +561,9 @@ public:
|
|||
|
||||
inline bool get_bound() const { return bound; }
|
||||
|
||||
//perform initializion that is common to all FDM's
|
||||
void common_init();
|
||||
|
||||
// time and update management values
|
||||
inline double get_delta_t() const { return delta_t; }
|
||||
inline void set_delta_t( double dt ) { delta_t = dt; }
|
||||
|
@ -1179,6 +1222,19 @@ public:
|
|||
inline void add_engine( FGEngInterface e ) {
|
||||
engines.push_back( e );
|
||||
}
|
||||
|
||||
//gear
|
||||
inline int get_num_gear() const {
|
||||
return gear.size();
|
||||
}
|
||||
|
||||
inline FGGearInterface* get_gear_unit( int i ) {
|
||||
return &gear[i];
|
||||
}
|
||||
|
||||
inline void add_gear_unit( FGGearInterface fgi ) {
|
||||
gear.push_back( fgi );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -1195,9 +1251,6 @@ extern FGInterface * cur_fdm_state;
|
|||
// Set the altitude (force)
|
||||
void fgFDMForceAltitude(const string &model, double alt_meters);
|
||||
|
||||
// Set the local ground elevation
|
||||
void fgFDMSetGroundElevation(const string &model, double alt_meters);
|
||||
|
||||
// Toggle data logging on/off
|
||||
void fgToggleFDMdataLogging(void);
|
||||
|
||||
|
|
Loading…
Reference in a new issue