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
|
// for each subsequent iteration through the EOM
|
||||||
void FGADA::init() {
|
void FGADA::init() {
|
||||||
|
|
||||||
// explicitly call the superclass's
|
//do init common to all FDM"s
|
||||||
// init() method first.
|
common_init();
|
||||||
FGInterface::init();
|
|
||||||
|
//now do ADA-specific init.
|
||||||
|
|
||||||
// cout << "FGADA::init()" << endl;
|
// cout << "FGADA::init()" << endl;
|
||||||
|
|
||||||
|
|
|
@ -75,9 +75,11 @@ FGBalloonSim::~FGBalloonSim() {
|
||||||
// Initialize the BalloonSim flight model, dt is the time increment for
|
// Initialize the BalloonSim flight model, dt is the time increment for
|
||||||
// each subsequent iteration through the EOM
|
// each subsequent iteration through the EOM
|
||||||
void FGBalloonSim::init() {
|
void FGBalloonSim::init() {
|
||||||
// explicitly call the superclass's
|
|
||||||
// init method first.
|
//do init common to all the FDM's
|
||||||
FGInterface::init();
|
common_init();
|
||||||
|
|
||||||
|
//now do init specific to the Balloon
|
||||||
|
|
||||||
sgVec3 temp;
|
sgVec3 temp;
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,8 @@ FGJSBsim::FGJSBsim( double dt )
|
||||||
Position = fdmex->GetPosition();
|
Position = fdmex->GetPosition();
|
||||||
Auxiliary = fdmex->GetAuxiliary();
|
Auxiliary = fdmex->GetAuxiliary();
|
||||||
Aerodynamics = fdmex->GetAerodynamics();
|
Aerodynamics = fdmex->GetAerodynamics();
|
||||||
|
GroundReactions = fdmex->GetGroundReactions();
|
||||||
|
|
||||||
|
|
||||||
Atmosphere->UseInternal();
|
Atmosphere->UseInternal();
|
||||||
|
|
||||||
|
@ -113,9 +115,9 @@ FGJSBsim::FGJSBsim( double dt )
|
||||||
add_engine( FGEngInterface() );
|
add_engine( FGEngInterface() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( fdmex->GetGroundReactions()->GetNumGearUnits() <= 0 ) {
|
if ( GroundReactions->GetNumGearUnits() <= 0 ) {
|
||||||
SG_LOG( SG_FLIGHT, SG_ALERT, "num gear units = "
|
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, "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, "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!");
|
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/pitch-trim", FCS->GetPitchTrimCmd());
|
||||||
fgSetDouble("/fdm/trim/throttle", FCS->GetThrottleCmd(0));
|
fgSetDouble("/fdm/trim/throttle", FCS->GetThrottleCmd(0));
|
||||||
fgSetDouble("/fdm/trim/aileron", FCS->GetDaCmd());
|
fgSetDouble("/fdm/trim/aileron", FCS->GetDaCmd());
|
||||||
|
@ -137,6 +141,10 @@ FGJSBsim::FGJSBsim( double dt )
|
||||||
throttle_trim = fgGetNode("/fdm/trim/throttle", true );
|
throttle_trim = fgGetNode("/fdm/trim/throttle", true );
|
||||||
aileron_trim = fgGetNode("/fdm/trim/aileron", true );
|
aileron_trim = fgGetNode("/fdm/trim/aileron", true );
|
||||||
rudder_trim = fgGetNode("/fdm/trim/rudder", 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
|
// Explicitly call the superclass's
|
||||||
// init method first.
|
// init method first.
|
||||||
FGInterface::init();
|
common_init();
|
||||||
|
|
||||||
fdmex->GetState()->Initialize(fgic);
|
fdmex->GetState()->Initialize(fgic);
|
||||||
fdmex->RunIC(fgic); //loop JSBSim once w/o integrating
|
fdmex->RunIC(fgic); //loop JSBSim once w/o integrating
|
||||||
|
@ -191,6 +199,8 @@ void FGJSBsim::init() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stall_warning->setBoolValue(false);
|
||||||
|
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, " Bank Angle: "
|
SG_LOG( SG_FLIGHT, SG_INFO, " Bank Angle: "
|
||||||
<< Rotation->Getphi()*RADTODEG << " deg" );
|
<< Rotation->Getphi()*RADTODEG << " deg" );
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, " Pitch Angle: "
|
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, " set dt" );
|
||||||
|
|
||||||
SG_LOG( SG_FLIGHT, SG_INFO, "Finished initializing JSBSim" );
|
SG_LOG( SG_FLIGHT, SG_INFO, "Finished initializing JSBSim" );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -224,43 +237,13 @@ bool FGJSBsim::update( int multiloop ) {
|
||||||
|
|
||||||
trimmed->setBoolValue(false);
|
trimmed->setBoolValue(false);
|
||||||
|
|
||||||
if ( needTrim && startup_trim->getBoolValue() ) {
|
if ( needTrim ) {
|
||||||
cout << "num gear units = " << fdmex->GetGroundReactions()->GetNumGearUnits() << endl;
|
if ( startup_trim->getBoolValue() ) {
|
||||||
//fgic->SetSeaLevelRadiusFtIC( get_Sea_level_radius() );
|
do_trim();
|
||||||
//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 {
|
} else {
|
||||||
fgtrim=new FGTrim(fdmex,fgic,tLongitudinal);
|
fdmex->RunIC(fgic); //apply any changes made through the set_ functions
|
||||||
}
|
}
|
||||||
if(!fgtrim->DoTrim()) {
|
needTrim = false;
|
||||||
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" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for( i=0; i<get_num_engines(); i++ ) {
|
for( i=0; i<get_num_engines(); i++ ) {
|
||||||
|
@ -269,6 +252,18 @@ bool FGJSBsim::update( int multiloop ) {
|
||||||
FGThruster * thrust = Propulsion->GetThruster(i);
|
FGThruster * thrust = Propulsion->GetThruster(i);
|
||||||
eng->SetMagnetos( globals->get_controls()->get_magnetos(i) );
|
eng->SetMagnetos( globals->get_controls()->get_magnetos(i) );
|
||||||
eng->SetStarter( globals->get_controls()->get_starter(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_Manifold_Pressure( eng->getManifoldPressure_inHg() );
|
||||||
e->set_RPM( thrust->GetRPM() );
|
e->set_RPM( thrust->GetRPM() );
|
||||||
e->set_EGT( eng->getExhaustGasTemp_degF() );
|
e->set_EGT( eng->getExhaustGasTemp_degF() );
|
||||||
|
@ -276,19 +271,15 @@ bool FGJSBsim::update( int multiloop ) {
|
||||||
e->set_Oil_Temp( eng->getOilTemp_degF() );
|
e->set_Oil_Temp( eng->getOilTemp_degF() );
|
||||||
e->set_Running_Flag( eng->GetRunning() );
|
e->set_Running_Flag( eng->GetRunning() );
|
||||||
e->set_Cranking_Flag( eng->GetCranking() );
|
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);
|
update_gear();
|
||||||
// printf("%d Altitude = %.2f\n", i, Altitude * 0.3048);
|
|
||||||
|
stall_warning->setDoubleValue( Aircraft->GetStallWarn() );
|
||||||
|
|
||||||
// translate JSBsim back to FG structure so that the
|
// translate JSBsim back to FG structure so that the
|
||||||
// autopilot (and the rest of the sim can use the updated values
|
// autopilot (and the rest of the sim can use the updated values
|
||||||
|
|
||||||
copy_from_JSBsim();
|
copy_from_JSBsim();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -350,25 +341,25 @@ bool FGJSBsim::copy_from_JSBsim() {
|
||||||
MassBalance->GetXYZcg(2),
|
MassBalance->GetXYZcg(2),
|
||||||
MassBalance->GetXYZcg(3) );
|
MassBalance->GetXYZcg(3) );
|
||||||
|
|
||||||
_set_Accels_Body( Translation->GetUVWdot(1),
|
_set_Accels_Body( Aircraft->GetBodyAccel()(1),
|
||||||
Translation->GetUVWdot(2),
|
Aircraft->GetBodyAccel()(2),
|
||||||
Translation->GetUVWdot(3) );
|
Aircraft->GetBodyAccel()(3) );
|
||||||
|
|
||||||
_set_Accels_CG_Body( Translation->GetUVWdot(1),
|
//_set_Accels_CG_Body( Aircraft->GetBodyAccel()(1),
|
||||||
Translation->GetUVWdot(2),
|
// Aircraft->GetBodyAccel()(2),
|
||||||
Translation->GetUVWdot(3) );
|
// Aircraft->GetBodyAccel()(3) );
|
||||||
|
|
||||||
//_set_Accels_CG_Body_N ( Translation->GetNcg(1),
|
|
||||||
// Translation->GetNcg(2),
|
|
||||||
// Translation->GetNcg(3) );
|
|
||||||
//
|
//
|
||||||
_set_Accels_Pilot_Body( Auxiliary->GetPilotAccel(1),
|
_set_Accels_CG_Body_N ( Aircraft->GetNcg()(1),
|
||||||
Auxiliary->GetPilotAccel(2),
|
Aircraft->GetNcg()(2),
|
||||||
Auxiliary->GetPilotAccel(3) );
|
Aircraft->GetNcg()(3) );
|
||||||
|
|
||||||
//_set_Accels_Pilot_Body_N( Auxiliary->GetNpilot(1),
|
_set_Accels_Pilot_Body( Auxiliary->GetPilotAccel()(1),
|
||||||
// Auxiliary->GetNpilot(2),
|
Auxiliary->GetPilotAccel()(2),
|
||||||
// Auxiliary->GetNpilot(3) );
|
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() );
|
_set_Nlf( Aerodynamics->GetNlf() );
|
||||||
|
|
||||||
|
@ -437,19 +428,6 @@ bool FGJSBsim::copy_from_JSBsim() {
|
||||||
return true;
|
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) {
|
bool FGJSBsim::ToggleDataLogging(void) {
|
||||||
return fdmex->GetOutput()->Toggle();
|
return fdmex->GetOutput()->Toggle();
|
||||||
}
|
}
|
||||||
|
@ -484,6 +462,7 @@ void FGJSBsim::set_Latitude(double lat) {
|
||||||
|
|
||||||
sgGeodToGeoc( lat, alt * SG_FEET_TO_METER,
|
sgGeodToGeoc( lat, alt * SG_FEET_TO_METER,
|
||||||
&sea_level_radius_meters, &lat_geoc );
|
&sea_level_radius_meters, &lat_geoc );
|
||||||
|
|
||||||
_set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET );
|
_set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET );
|
||||||
fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET );
|
fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET );
|
||||||
fgic->SetLatitudeRadIC( lat_geoc );
|
fgic->SetLatitudeRadIC( lat_geoc );
|
||||||
|
@ -617,7 +596,6 @@ void FGJSBsim::set_Density(double rho) {
|
||||||
needTrim=true;
|
needTrim=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void FGJSBsim::set_Velocities_Local_Airmass (double wnorth,
|
void FGJSBsim::set_Velocities_Local_Airmass (double wnorth,
|
||||||
double weast,
|
double weast,
|
||||||
double wdown ) {
|
double wdown ) {
|
||||||
|
@ -630,194 +608,70 @@ void FGJSBsim::set_Velocities_Local_Airmass (double wnorth,
|
||||||
needTrim=true;
|
needTrim=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FGJSBsim::init_gear(void ) {
|
||||||
|
|
||||||
//Positions
|
FGGearInterface *gear;
|
||||||
void FGJSBsim::update_Latitude(double lat) {
|
FGGroundReactions* gr=fdmex->GetGroundReactions();
|
||||||
double sea_level_radius_meters, lat_geoc;
|
int Ngear=GroundReactions->GetNumGearUnits();
|
||||||
|
for (int i=0;i<Ngear;i++) {
|
||||||
SG_LOG(SG_FLIGHT,SG_INFO,"FGJSBsim::update_Latitude: " << lat );
|
add_gear_unit( FGGearInterface() );
|
||||||
SG_LOG(SG_FLIGHT,SG_INFO," cur alt = " << get_Altitude() );
|
gear=get_gear_unit(i);
|
||||||
|
gear->SetX( gr->GetGearUnit(i)->GetBodyLocation()(1) );
|
||||||
snap_shot();
|
gear->SetY( gr->GetGearUnit(i)->GetBodyLocation()(2) );
|
||||||
sgGeodToGeoc( lat, get_Altitude(), &sea_level_radius_meters, &lat_geoc);
|
gear->SetZ( gr->GetGearUnit(i)->GetBodyLocation()(3) );
|
||||||
_set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET );
|
gear->SetWoW( gr->GetGearUnit(i)->GetWOW() );
|
||||||
fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET );
|
if ( gr->GetGearUnit(i)->GetBrakeGroup() > 0 ) {
|
||||||
fgic->SetLatitudeRadIC( lat_geoc );
|
gear->SetBrake(true);
|
||||||
fdmex->RunIC(fgic); //loop JSBSim once
|
}
|
||||||
copy_from_JSBsim(); //update the bus
|
if ( gr->GetGearUp() ) {
|
||||||
needTrim=true;
|
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 );
|
FGGearInterface* gear;
|
||||||
SG_LOG(SG_FLIGHT,SG_INFO," cur alt = " << get_Altitude() );
|
FGGroundReactions* gr=fdmex->GetGroundReactions();
|
||||||
|
int Ngear=GroundReactions->GetNumGearUnits();
|
||||||
snap_shot();
|
for (int i=0;i<Ngear;i++) {
|
||||||
fgic->SetLongitudeRadIC(lon);
|
gear=get_gear_unit(i);
|
||||||
fdmex->RunIC(fgic); //loop JSBSim once
|
gear->SetWoW( gr->GetGearUnit(i)->GetWOW() );
|
||||||
copy_from_JSBsim(); //update the bus
|
if ( gr->GetGearUp() ) {
|
||||||
needTrim=true;
|
gear->SetPosition( 0.0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGJSBsim::update_Altitude(double alt) {
|
void FGJSBsim::do_trim(void) {
|
||||||
double sea_level_radius_meters,lat_geoc;
|
|
||||||
|
|
||||||
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();
|
globals->get_controls()->set_elevator_trim(FCS->GetPitchTrimCmd());
|
||||||
sgGeodToGeoc( get_Latitude(), alt , &sea_level_radius_meters, &lat_geoc);
|
globals->get_controls()->set_elevator(FCS->GetDeCmd());
|
||||||
_set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET );
|
globals->get_controls()->set_throttle(FGControls::ALL_ENGINES,
|
||||||
fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET );
|
FCS->GetThrottleCmd(0));
|
||||||
fgic->SetLatitudeRadIC( lat_geoc );
|
|
||||||
fgic->SetAltitudeFtIC(alt);
|
globals->get_controls()->set_aileron(FCS->GetDaCmd());
|
||||||
fdmex->RunIC(fgic); //loop JSBSim once
|
globals->get_controls()->set_rudder( FCS->GetDrCmd());
|
||||||
copy_from_JSBsim(); //update the bus
|
|
||||||
needTrim=true;
|
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 );
|
double wdown );
|
||||||
/// @name Position Parameter Update
|
/// @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.
|
/** Update the position based on inputs, positions, velocities, etc.
|
||||||
@param multiloop number of times to loop through the FDM
|
@param multiloop number of times to loop through the FDM
|
||||||
|
@ -309,6 +215,7 @@ public:
|
||||||
bool update( int multiloop );
|
bool update( int multiloop );
|
||||||
bool ToggleDataLogging(bool state);
|
bool ToggleDataLogging(bool state);
|
||||||
bool ToggleDataLogging(void);
|
bool ToggleDataLogging(void);
|
||||||
|
void do_trim(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FGFDMExec *fdmex;
|
FGFDMExec *fdmex;
|
||||||
|
@ -326,6 +233,7 @@ private:
|
||||||
FGPosition* Position;
|
FGPosition* Position;
|
||||||
FGAuxiliary* Auxiliary;
|
FGAuxiliary* Auxiliary;
|
||||||
FGAerodynamics* Aerodynamics;
|
FGAerodynamics* Aerodynamics;
|
||||||
|
FGGroundReactions *GroundReactions;
|
||||||
|
|
||||||
int runcount;
|
int runcount;
|
||||||
float trim_elev;
|
float trim_elev;
|
||||||
|
@ -337,8 +245,11 @@ private:
|
||||||
SGPropertyNode *throttle_trim;
|
SGPropertyNode *throttle_trim;
|
||||||
SGPropertyNode *aileron_trim;
|
SGPropertyNode *aileron_trim;
|
||||||
SGPropertyNode *rudder_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),
|
vXYZrp(3),
|
||||||
vXYZep(3),
|
vXYZep(3),
|
||||||
vDXYZcg(3),
|
vDXYZcg(3),
|
||||||
vBodyAccel(3)
|
vBodyAccel(3),
|
||||||
|
vNcg(3)
|
||||||
{
|
{
|
||||||
Name = "FGAircraft";
|
Name = "FGAircraft";
|
||||||
alphaclmin = alphaclmax = 0;
|
alphaclmin = alphaclmax = 0;
|
||||||
HTailArea = VTailArea = HTailArm = VTailArm = 0.0;
|
HTailArea = VTailArea = HTailArm = VTailArm = 0.0;
|
||||||
lbarh = lbarv = vbarh = vbarv = 0.0;
|
lbarh = lbarv = vbarh = vbarv = 0.0;
|
||||||
WingIncidence=0;
|
WingIncidence=0;
|
||||||
|
impending_stall = 0;
|
||||||
|
|
||||||
if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
|
if (debug_lvl & 2) cout << "Instantiated: " << Name << endl;
|
||||||
}
|
}
|
||||||
|
@ -176,6 +178,16 @@ bool FGAircraft::Run(void)
|
||||||
|
|
||||||
vBodyAccel = vForces/MassBalance->GetMass();
|
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;
|
return false;
|
||||||
} else { // skip Run() execution this time
|
} else { // skip Run() execution this time
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -189,6 +189,7 @@ public:
|
||||||
inline FGColumnVector3& GetMoments(void) { return vMoments; }
|
inline FGColumnVector3& GetMoments(void) { return vMoments; }
|
||||||
inline FGColumnVector3& GetForces(void) { return vForces; }
|
inline FGColumnVector3& GetForces(void) { return vForces; }
|
||||||
inline FGColumnVector3& GetBodyAccel(void) { return vBodyAccel; }
|
inline FGColumnVector3& GetBodyAccel(void) { return vBodyAccel; }
|
||||||
|
inline FGColumnVector3& GetNcg (void) { return vNcg; }
|
||||||
inline FGColumnVector3& GetXYZrp(void) { return vXYZrp; }
|
inline FGColumnVector3& GetXYZrp(void) { return vXYZrp; }
|
||||||
inline FGColumnVector3& GetXYZep(void) { return vXYZep; }
|
inline FGColumnVector3& GetXYZep(void) { return vXYZep; }
|
||||||
inline float GetXYZrp(int idx) { return vXYZrp(idx); }
|
inline float GetXYZrp(int idx) { return vXYZrp(idx); }
|
||||||
|
@ -199,6 +200,8 @@ public:
|
||||||
inline void SetAlphaCLMax(float tt) { alphaclmax=tt; }
|
inline void SetAlphaCLMax(float tt) { alphaclmax=tt; }
|
||||||
inline void SetAlphaCLMin(float tt) { alphaclmin=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
|
/// Subsystem types for specifying which will be output in the FDM data logging
|
||||||
enum SubSystems {
|
enum SubSystems {
|
||||||
/** Subsystem: Simulation (= 1) */ ssSimulation = 1,
|
/** Subsystem: Simulation (= 1) */ ssSimulation = 1,
|
||||||
|
@ -224,10 +227,13 @@ private:
|
||||||
FGColumnVector3 vEuler;
|
FGColumnVector3 vEuler;
|
||||||
FGColumnVector3 vDXYZcg;
|
FGColumnVector3 vDXYZcg;
|
||||||
FGColumnVector3 vBodyAccel;
|
FGColumnVector3 vBodyAccel;
|
||||||
|
FGColumnVector3 vNcg;
|
||||||
|
|
||||||
float WingArea, WingSpan, cbar, WingIncidence;
|
float WingArea, WingSpan, cbar, WingIncidence;
|
||||||
float HTailArea, VTailArea, HTailArm, VTailArm;
|
float HTailArea, VTailArea, HTailArm, VTailArm;
|
||||||
float lbarh,lbarv,vbarh,vbarv;
|
float lbarh,lbarv,vbarh,vbarv;
|
||||||
float alphaclmax,alphaclmin;
|
float alphaclmax,alphaclmin;
|
||||||
|
float impending_stall;
|
||||||
string CFGVersion;
|
string CFGVersion;
|
||||||
string AircraftName;
|
string AircraftName;
|
||||||
|
|
||||||
|
|
|
@ -141,19 +141,19 @@ public:
|
||||||
inline float GetWindPsi(void) { return psiw; }
|
inline float GetWindPsi(void) { return psiw; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float rho;
|
double rho;
|
||||||
|
|
||||||
int lastIndex;
|
int lastIndex;
|
||||||
float h;
|
double h;
|
||||||
float htab[8];
|
double htab[8];
|
||||||
float SLtemperature,SLdensity,SLpressure,SLsoundspeed;
|
double SLtemperature,SLdensity,SLpressure,SLsoundspeed;
|
||||||
float rSLtemperature,rSLdensity,rSLpressure,rSLsoundspeed; //reciprocals
|
double rSLtemperature,rSLdensity,rSLpressure,rSLsoundspeed; //reciprocals
|
||||||
float temperature,density,pressure,soundspeed;
|
double temperature,density,pressure,soundspeed;
|
||||||
bool useExternal;
|
bool useExternal;
|
||||||
float exTemperature,exDensity,exPressure;
|
double exTemperature,exDensity,exPressure;
|
||||||
|
|
||||||
FGColumnVector3 vWindNED;
|
FGColumnVector3 vWindNED;
|
||||||
float psiw;
|
double psiw;
|
||||||
|
|
||||||
void Calculate(float altitude);
|
void Calculate(float altitude);
|
||||||
void Debug(void);
|
void Debug(void);
|
||||||
|
|
|
@ -63,12 +63,13 @@ FGForce::FGForce(FGFDMExec *FDMExec) :
|
||||||
vXYZn(3),
|
vXYZn(3),
|
||||||
vDXYZ(3),
|
vDXYZ(3),
|
||||||
mT(3,3),
|
mT(3,3),
|
||||||
|
vH(3),
|
||||||
vSense(3),
|
vSense(3),
|
||||||
ttype(tNone)
|
ttype(tNone)
|
||||||
{
|
{
|
||||||
mT(1,1)=1; //identity matrix
|
mT(1,1) = 1; //identity matrix
|
||||||
mT(2,2)=1;
|
mT(2,2) = 1;
|
||||||
mT(3,3)=1;
|
mT(3,3) = 1;
|
||||||
vSense.InitMatrix(1);
|
vSense.InitMatrix(1);
|
||||||
if (debug_lvl & 2) cout << "Instantiated: FGForce" << endl;
|
if (debug_lvl & 2) cout << "Instantiated: FGForce" << endl;
|
||||||
}
|
}
|
||||||
|
@ -84,7 +85,7 @@ FGForce::~FGForce()
|
||||||
|
|
||||||
FGColumnVector3& FGForce::GetBodyForces(void) {
|
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
|
//find the distance from this vector's location to the cg
|
||||||
//needs to be done like this to convert from structural to body coords
|
//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(2) = (vXYZn(2) - fdmex->GetMassBalance()->GetXYZcg(2))*INCHTOFT; //cg and rp values are in inches
|
||||||
vDXYZ(3) = -(vXYZn(3) - fdmex->GetMassBalance()->GetXYZcg(3))*INCHTOFT;
|
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;
|
return vFb;
|
||||||
}
|
}
|
||||||
|
|
|
@ -256,6 +256,9 @@ public:
|
||||||
vXYZn(2) = y;
|
vXYZn(2) = y;
|
||||||
vXYZn(3) = z;
|
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; }
|
inline void SetLocation(FGColumnVector3 vv) { vXYZn = vv; }
|
||||||
FGColumnVector3& GetLocation(void) { return vXYZn; }
|
FGColumnVector3& GetLocation(void) { return vXYZn; }
|
||||||
|
|
||||||
|
@ -282,6 +285,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
FGColumnVector3 vFn;
|
FGColumnVector3 vFn;
|
||||||
FGColumnVector3 vMn;
|
FGColumnVector3 vMn;
|
||||||
|
FGColumnVector3 vH;
|
||||||
FGFDMExec *fdmex;
|
FGFDMExec *fdmex;
|
||||||
virtual void Debug(void);
|
virtual void Debug(void);
|
||||||
|
|
||||||
|
|
|
@ -229,6 +229,9 @@ public:
|
||||||
inline float GetSteerAngle(void) { return SteerAngle;}
|
inline float GetSteerAngle(void) { return SteerAngle;}
|
||||||
inline float GetstaticFCoeff(void) { return staticFCoeff;}
|
inline float GetstaticFCoeff(void) { return staticFCoeff;}
|
||||||
|
|
||||||
|
inline int GetBrakeGroup(void) { return (int)eBrakeGrp; }
|
||||||
|
inline int GetSteerType(void) { return (int)eSteerType; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FGColumnVector3 vXYZ;
|
FGColumnVector3 vXYZ;
|
||||||
FGColumnVector3 vMoment;
|
FGColumnVector3 vMoment;
|
||||||
|
|
|
@ -50,7 +50,7 @@ FGPropeller::FGPropeller(FGFDMExec* exec, FGConfigFile* Prop_cfg) : FGThruster(e
|
||||||
string token;
|
string token;
|
||||||
int rows, cols;
|
int rows, cols;
|
||||||
|
|
||||||
MaxPitch = MinPitch = 0.0;
|
MaxPitch = MinPitch = P_Factor = Sense = 0.0;
|
||||||
|
|
||||||
Name = Prop_cfg->GetValue("NAME");
|
Name = Prop_cfg->GetValue("NAME");
|
||||||
Prop_cfg->GetNextConfigLine();
|
Prop_cfg->GetNextConfigLine();
|
||||||
|
@ -67,6 +67,10 @@ FGPropeller::FGPropeller(FGFDMExec* exec, FGConfigFile* Prop_cfg) : FGThruster(e
|
||||||
*Prop_cfg >> MinPitch;
|
*Prop_cfg >> MinPitch;
|
||||||
} else if (token == "MAXPITCH") {
|
} else if (token == "MAXPITCH") {
|
||||||
*Prop_cfg >> MaxPitch;
|
*Prop_cfg >> MaxPitch;
|
||||||
|
} else if (token == "P_FACTOR") {
|
||||||
|
*Prop_cfg >> P_Factor;
|
||||||
|
} else if (token == "SENSE") {
|
||||||
|
*Prop_cfg >> Sense;
|
||||||
} else if (token == "EFFICIENCY") {
|
} else if (token == "EFFICIENCY") {
|
||||||
*Prop_cfg >> rows >> cols;
|
*Prop_cfg >> rows >> cols;
|
||||||
if (cols == 1) Efficiency = new FGTable(rows);
|
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 << " Number of Blades = " << numBlades << endl;
|
||||||
cout << " Minimum Pitch = " << MinPitch << endl;
|
cout << " Minimum Pitch = " << MinPitch << endl;
|
||||||
cout << " Maximum Pitch = " << MaxPitch << 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;
|
cout << " Efficiency: " << endl;
|
||||||
Efficiency->Print();
|
Efficiency->Print();
|
||||||
cout << " Thrust Coefficient: " << endl;
|
cout << " Thrust Coefficient: " << endl;
|
||||||
|
@ -141,6 +153,7 @@ float FGPropeller::Calculate(float PowerAvailable)
|
||||||
float Vel = (fdmex->GetTranslation()->GetvAero())(1);
|
float Vel = (fdmex->GetTranslation()->GetvAero())(1);
|
||||||
float rho = fdmex->GetAtmosphere()->GetDensity();
|
float rho = fdmex->GetAtmosphere()->GetDensity();
|
||||||
float RPS = RPM/60.0;
|
float RPS = RPM/60.0;
|
||||||
|
float alpha, beta;
|
||||||
|
|
||||||
if (RPM > 0.10) {
|
if (RPM > 0.10) {
|
||||||
J = Vel / (Diameter * RPM / 60.0);
|
J = Vel / (Diameter * RPM / 60.0);
|
||||||
|
@ -154,10 +167,25 @@ float FGPropeller::Calculate(float PowerAvailable)
|
||||||
C_Thrust = cThrust->GetValue(J, Pitch);
|
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;
|
Thrust = C_Thrust*RPS*RPS*Diameter*Diameter*Diameter*Diameter*rho;
|
||||||
vFn(1) = Thrust;
|
vFn(1) = Thrust;
|
||||||
omega = RPS*2.0*M_PI;
|
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;
|
if (omega <= 5) omega = 1.0;
|
||||||
|
|
||||||
Torque = PowerAvailable / omega;
|
Torque = PowerAvailable / omega;
|
||||||
|
|
|
@ -150,6 +150,8 @@ private:
|
||||||
float Diameter;
|
float Diameter;
|
||||||
float MaxPitch;
|
float MaxPitch;
|
||||||
float MinPitch;
|
float MinPitch;
|
||||||
|
float P_Factor;
|
||||||
|
float Sense;
|
||||||
float Pitch;
|
float Pitch;
|
||||||
float Torque;
|
float Torque;
|
||||||
FGTable *Efficiency;
|
FGTable *Efficiency;
|
||||||
|
|
|
@ -115,6 +115,8 @@ bool FGPropulsion::GetSteadyState(void) {
|
||||||
float PowerAvailable;
|
float PowerAvailable;
|
||||||
float currentThrust = 0, lastThrust=-1;
|
float currentThrust = 0, lastThrust=-1;
|
||||||
dt = State->Getdt();
|
dt = State->Getdt();
|
||||||
|
int steady_count,j=0;
|
||||||
|
bool steady=false;
|
||||||
|
|
||||||
Forces->InitMatrix();
|
Forces->InitMatrix();
|
||||||
Moments->InitMatrix();
|
Moments->InitMatrix();
|
||||||
|
@ -123,10 +125,18 @@ bool FGPropulsion::GetSteadyState(void) {
|
||||||
for (unsigned int i=0; i<numEngines; i++) {
|
for (unsigned int i=0; i<numEngines; i++) {
|
||||||
Engines[i]->SetTrimMode(true);
|
Engines[i]->SetTrimMode(true);
|
||||||
Thrusters[i]->SetdeltaT(dt*rate);
|
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());
|
PowerAvailable = Engines[i]->Calculate(Thrusters[i]->GetPowerRequired());
|
||||||
lastThrust = currentThrust;
|
lastThrust = currentThrust;
|
||||||
currentThrust = Thrusters[i]->Calculate(PowerAvailable);
|
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
|
*Forces += Thrusters[i]->GetBodyForces(); // sum body frame forces
|
||||||
*Moments += Thrusters[i]->GetMoments(); // sum body frame moments
|
*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)
|
bool FGPropulsion::Load(FGConfigFile* AC_cfg)
|
||||||
{
|
{
|
||||||
string token, fullpath;
|
string token, fullpath;
|
||||||
|
|
|
@ -158,8 +158,13 @@ public:
|
||||||
/** Returns the number of oxidizer tanks currently actively supplying oxidizer */
|
/** Returns the number of oxidizer tanks currently actively supplying oxidizer */
|
||||||
inline int GetnumSelectedOxiTanks(void) {return numSelectedOxiTanks;}
|
inline int GetnumSelectedOxiTanks(void) {return numSelectedOxiTanks;}
|
||||||
|
|
||||||
|
/** Loops the engines/thrusters until thrust output steady (used for trimming) */
|
||||||
bool GetSteadyState(void);
|
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 GetPropulsionStrings(void);
|
||||||
string GetPropulsionValues(void);
|
string GetPropulsionValues(void);
|
||||||
|
|
||||||
|
|
|
@ -739,7 +739,7 @@ void FGState::ReportState(void) {
|
||||||
GetParameter(FG_RUDDER_POS)*RADTODEG );
|
GetParameter(FG_RUDDER_POS)*RADTODEG );
|
||||||
cout << out;
|
cout << out;
|
||||||
snprintf(out,80, " Throttle: %5.2f%c\n",
|
snprintf(out,80, " Throttle: %5.2f%c\n",
|
||||||
FCS->GetThrottlePos(0),'%' );
|
FCS->GetThrottlePos(0)*100,'%' );
|
||||||
cout << out;
|
cout << out;
|
||||||
|
|
||||||
snprintf(out,80, " Wind Components: %5.2f kts head wind, %5.2f kts cross wind\n",
|
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),
|
FGTranslation::FGTranslation(FGFDMExec* fdmex) : FGModel(fdmex),
|
||||||
vUVW(3),
|
vUVW(3),
|
||||||
vUVWdot(3),
|
vUVWdot(3),
|
||||||
vNcg(3),
|
|
||||||
vlastUVWdot(3),
|
vlastUVWdot(3),
|
||||||
mVel(3,3),
|
mVel(3,3),
|
||||||
vAero(3)
|
vAero(3)
|
||||||
|
@ -120,9 +119,7 @@ bool FGTranslation::Run(void)
|
||||||
mVel(3,2) = vUVW(eU);
|
mVel(3,2) = vUVW(eU);
|
||||||
mVel(3,3) = 0.0;
|
mVel(3,3) = 0.0;
|
||||||
|
|
||||||
vUVWdot = mVel*Rotation->GetPQR() + Aircraft->GetForces()/MassBalance->GetMass();
|
vUVWdot = mVel*Rotation->GetPQR() + Aircraft->GetBodyAccel();
|
||||||
|
|
||||||
vNcg = vUVWdot*INVGRAVITY;
|
|
||||||
|
|
||||||
vUVW += Tc * (vlastUVWdot + vUVWdot);
|
vUVW += Tc * (vlastUVWdot + vUVWdot);
|
||||||
vAero = vUVW + State->GetTl2b()*Atmosphere->GetWindNED();
|
vAero = vUVW + State->GetTl2b()*Atmosphere->GetWindNED();
|
||||||
|
|
|
@ -91,8 +91,6 @@ public:
|
||||||
inline float GetUVW (int idx) { return vUVW(idx); }
|
inline float GetUVW (int idx) { return vUVW(idx); }
|
||||||
inline FGColumnVector3& GetUVWdot(void) { return vUVWdot; }
|
inline FGColumnVector3& GetUVWdot(void) { return vUVWdot; }
|
||||||
inline float GetUVWdot(int idx) { return vUVWdot(idx); }
|
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 FGColumnVector3& GetvAero (void) { return vAero; }
|
||||||
inline float GetvAero (int idx) { return vAero(idx); }
|
inline float GetvAero (int idx) { return vAero(idx); }
|
||||||
|
|
||||||
|
@ -121,7 +119,6 @@ public:
|
||||||
private:
|
private:
|
||||||
FGColumnVector3 vUVW;
|
FGColumnVector3 vUVW;
|
||||||
FGColumnVector3 vUVWdot;
|
FGColumnVector3 vUVWdot;
|
||||||
FGColumnVector3 vNcg;
|
|
||||||
FGColumnVector3 vlastUVWdot;
|
FGColumnVector3 vlastUVWdot;
|
||||||
FGMatrix33 mVel;
|
FGMatrix33 mVel;
|
||||||
FGColumnVector3 vAero;
|
FGColumnVector3 vAero;
|
||||||
|
|
|
@ -150,9 +150,9 @@ FGTrimAxis::~FGTrimAxis()
|
||||||
|
|
||||||
void FGTrimAxis::getState(void) {
|
void FGTrimAxis::getState(void) {
|
||||||
switch(state) {
|
switch(state) {
|
||||||
case tUdot: state_value=fdmex->GetTranslation()->GetUVWdot(1); break;
|
case tUdot: state_value=fdmex->GetAircraft()->GetBodyAccel()(1); break;
|
||||||
case tVdot: state_value=fdmex->GetTranslation()->GetUVWdot(2); break;
|
case tVdot: state_value=fdmex->GetAircraft()->GetBodyAccel()(2); break;
|
||||||
case tWdot: state_value=fdmex->GetTranslation()->GetUVWdot(3); break;
|
case tWdot: state_value=fdmex->GetAircraft()->GetBodyAccel()(3); break;
|
||||||
case tQdot: state_value=fdmex->GetRotation()->GetPQRdot(2);break;
|
case tQdot: state_value=fdmex->GetRotation()->GetPQRdot(2);break;
|
||||||
case tPdot: state_value=fdmex->GetRotation()->GetPQRdot(1); break;
|
case tPdot: state_value=fdmex->GetRotation()->GetPQRdot(1); break;
|
||||||
case tRdot: state_value=fdmex->GetRotation()->GetPQRdot(3); break;
|
case tRdot: state_value=fdmex->GetRotation()->GetPQRdot(3); break;
|
||||||
|
@ -397,7 +397,10 @@ void FGTrimAxis::setThrottlesPct(void) {
|
||||||
tMin=fdmex->GetPropulsion()->GetEngine(i)->GetThrottleMin();
|
tMin=fdmex->GetPropulsion()->GetEngine(i)->GetThrottleMin();
|
||||||
tMax=fdmex->GetPropulsion()->GetEngine(i)->GetThrottleMax();
|
tMax=fdmex->GetPropulsion()->GetEngine(i)->GetThrottleMax();
|
||||||
//cout << "setThrottlespct: " << i << ", " << control_min << ", " << control_max << ", " << control_value;
|
//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
|
// Initialize the LaRCsim flight model, dt is the time increment for
|
||||||
// each subsequent iteration through the EOM
|
// each subsequent iteration through the EOM
|
||||||
void FGLaRCsim::init() {
|
void FGLaRCsim::init() {
|
||||||
|
//do init common to all FDM's
|
||||||
|
common_init();
|
||||||
|
|
||||||
// Explicitly call the superclass's
|
//now do any specific to LaRCsim
|
||||||
// init method first.
|
|
||||||
FGInterface::init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -44,9 +44,7 @@ FGMagicCarpet::~FGMagicCarpet() {
|
||||||
// Initialize the Magic Carpet flight model, dt is the time increment
|
// Initialize the Magic Carpet flight model, dt is the time increment
|
||||||
// for each subsequent iteration through the EOM
|
// for each subsequent iteration through the EOM
|
||||||
void FGMagicCarpet::init() {
|
void FGMagicCarpet::init() {
|
||||||
// explicitly call the superclass's
|
common_init();
|
||||||
// init method first
|
|
||||||
FGInterface::init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,14 @@ FGEngInterface::FGEngInterface() {
|
||||||
FGEngInterface::~FGEngInterface(void) {
|
FGEngInterface::~FGEngInterface(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FGGearInterface::FGGearInterface(void) {
|
||||||
|
x=y=z=0.0;
|
||||||
|
brake=rolls=WoW=false;
|
||||||
|
position=1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FGGearInterface::~FGGearInterface() {
|
||||||
|
}
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
FGInterface::FGInterface() {
|
FGInterface::FGInterface() {
|
||||||
|
@ -167,86 +175,101 @@ FGInterface::_setup ()
|
||||||
altitude_agl=0;
|
altitude_agl=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FGInterface::init () {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the state of the FDM.
|
* Initialize the state of the FDM.
|
||||||
*
|
*
|
||||||
* Subclasses of FGInterface may do their own, additional initialization,
|
* Subclasses of FGInterface may do their own, additional initialization,
|
||||||
* but normally they should invoke this method explicitly first as
|
* but there is some that is common to all. Normally, they should call
|
||||||
* FGInterface::init() to make sure the basic structures are set up
|
* this before they begin their own init to make sure the basic structures
|
||||||
* properly.
|
* are set up properly.
|
||||||
*/
|
*/
|
||||||
void
|
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();
|
stamp();
|
||||||
set_remainder(0);
|
set_remainder( 0 );
|
||||||
|
|
||||||
// Set initial position
|
// Set initial position
|
||||||
SG_LOG(SG_FLIGHT, SG_INFO, "...initializing position...");
|
SG_LOG( SG_FLIGHT, SG_INFO, "...initializing position..." );
|
||||||
set_Longitude(fgGetDouble("/position/longitude-deg") * SGD_DEGREES_TO_RADIANS);
|
set_Longitude( fgGetDouble("/position/longitude-deg")
|
||||||
set_Latitude(fgGetDouble("/position/latitude-deg") * SGD_DEGREES_TO_RADIANS);
|
* SGD_DEGREES_TO_RADIANS );
|
||||||
double ground_elev_m = scenery.get_cur_elev() + 1;
|
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;
|
double ground_elev_ft = ground_elev_m * METERS_TO_FEET;
|
||||||
if (fgGetBool("/sim/startup/onground") ||
|
if ( fgGetBool("/sim/startup/onground")
|
||||||
fgGetDouble("/position/altitude-ft") < ground_elev_ft)
|
|| fgGetDouble("/position/altitude-ft") < ground_elev_ft ) {
|
||||||
fgSetDouble("/position/altitude-ft", ground_elev_ft);
|
fgSetDouble("/position/altitude-ft", ground_elev_ft);
|
||||||
set_Altitude(fgGetDouble("/position/altitude-ft"));
|
}
|
||||||
|
set_Altitude( fgGetDouble("/position/altitude-ft") );
|
||||||
|
|
||||||
// Set ground elevation
|
// Set ground elevation
|
||||||
SG_LOG(SG_FLIGHT, SG_INFO,
|
SG_LOG( SG_FLIGHT, SG_INFO,
|
||||||
"...initializing ground elevation to "
|
"...initializing ground elevation to " << ground_elev_ft
|
||||||
<< ground_elev_ft << "ft...");
|
<< "ft..." );
|
||||||
fgFDMSetGroundElevation("jsb", ground_elev_m);
|
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 );
|
||||||
|
|
||||||
// Set sea-level radius
|
// Set sea-level radius
|
||||||
SG_LOG(SG_FLIGHT, SG_INFO, "...initializing sea-level radius...");
|
SG_LOG( SG_FLIGHT, SG_INFO, "...initializing sea-level radius..." );
|
||||||
SG_LOG(SG_FLIGHT, SG_INFO, " lat = " << fgGetDouble("/position/latitude-deg")
|
SG_LOG( SG_FLIGHT, SG_INFO, " lat = "
|
||||||
|
<< fgGetDouble("/position/latitude-deg")
|
||||||
<< " alt = " << fgGetDouble("/position/altitude-ft") );
|
<< " alt = " << fgGetDouble("/position/altitude-ft") );
|
||||||
double sea_level_radius_meters;
|
double sea_level_radius_meters;
|
||||||
double lat_geoc;
|
double lat_geoc;
|
||||||
sgGeodToGeoc(fgGetDouble("/position/latitude-deg") * SGD_DEGREES_TO_RADIANS,
|
sgGeodToGeoc( fgGetDouble("/position/latitude-deg")
|
||||||
|
* SGD_DEGREES_TO_RADIANS,
|
||||||
fgGetDouble("/position/altitude-ft") * SG_FEET_TO_METER,
|
fgGetDouble("/position/altitude-ft") * SG_FEET_TO_METER,
|
||||||
&sea_level_radius_meters, &lat_geoc);
|
&sea_level_radius_meters, &lat_geoc );
|
||||||
set_Sea_level_radius(sea_level_radius_meters * SG_METER_TO_FEET);
|
set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET );
|
||||||
|
|
||||||
// Set initial velocities
|
// Set initial velocities
|
||||||
SG_LOG(SG_FLIGHT, SG_INFO, "...initializing velocities...");
|
SG_LOG( SG_FLIGHT, SG_INFO, "...initializing velocities..." );
|
||||||
if (!fgHasNode("/sim/startup/speed-set")) {
|
if ( !fgHasNode("/sim/startup/speed-set") ) {
|
||||||
set_V_calibrated_kts(0.0);
|
set_V_calibrated_kts(0.0);
|
||||||
} else {
|
} else {
|
||||||
const string speedset = fgGetString("/sim/startup/speed-set");
|
const string speedset = fgGetString("/sim/startup/speed-set");
|
||||||
if (speedset == "knots" || speedset == "KNOTS") {
|
if ( speedset == "knots" || speedset == "KNOTS" ) {
|
||||||
set_V_calibrated_kts(fgGetDouble("/velocities/airspeed-kt"));
|
set_V_calibrated_kts( fgGetDouble("/velocities/airspeed-kt") );
|
||||||
} else if (speedset == "mach" || speedset == "MACH") {
|
} else if ( speedset == "mach" || speedset == "MACH" ) {
|
||||||
set_Mach_number(fgGetDouble("/velocities/mach"));
|
set_Mach_number( fgGetDouble("/velocities/mach") );
|
||||||
} else if (speedset == "UVW" || speedset == "uvw") {
|
} else if ( speedset == "UVW" || speedset == "uvw" ) {
|
||||||
set_Velocities_Wind_Body(fgGetDouble("/velocities/uBody-fps"),
|
set_Velocities_Wind_Body(
|
||||||
|
fgGetDouble("/velocities/uBody-fps"),
|
||||||
fgGetDouble("/velocities/vBody-fps"),
|
fgGetDouble("/velocities/vBody-fps"),
|
||||||
fgGetDouble("/velocities/wBody-fps"));
|
fgGetDouble("/velocities/wBody-fps") );
|
||||||
} else if (speedset == "NED" || speedset == "ned") {
|
} else if ( speedset == "NED" || speedset == "ned" ) {
|
||||||
set_Velocities_Local(fgGetDouble("/velocities/speed-north-fps"),
|
set_Velocities_Local(
|
||||||
|
fgGetDouble("/velocities/speed-north-fps"),
|
||||||
fgGetDouble("/velocities/speed-east-fps"),
|
fgGetDouble("/velocities/speed-east-fps"),
|
||||||
fgGetDouble("/velocities/speed-down-fps"));
|
fgGetDouble("/velocities/speed-down-fps") );
|
||||||
} else {
|
} else {
|
||||||
SG_LOG(SG_FLIGHT, SG_ALERT,
|
SG_LOG( SG_FLIGHT, SG_ALERT,
|
||||||
"Unrecognized value for /sim/startup/speed-set: " << speedset);
|
"Unrecognized value for /sim/startup/speed-set: "
|
||||||
set_V_calibrated_kts(0.0);
|
<< speedset);
|
||||||
|
set_V_calibrated_kts( 0.0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set initial Euler angles
|
// Set initial Euler angles
|
||||||
SG_LOG(SG_FLIGHT, SG_INFO, "...initializing Euler angles...");
|
SG_LOG( SG_FLIGHT, SG_INFO, "...initializing Euler angles..." );
|
||||||
set_Euler_Angles
|
set_Euler_Angles( fgGetDouble("/orientation/roll-deg")
|
||||||
(fgGetDouble("/orientation/roll-deg") * SGD_DEGREES_TO_RADIANS,
|
* SGD_DEGREES_TO_RADIANS,
|
||||||
fgGetDouble("/orientation/pitch-deg") * SGD_DEGREES_TO_RADIANS,
|
fgGetDouble("/orientation/pitch-deg")
|
||||||
fgGetDouble("/orientation/heading-deg") * SGD_DEGREES_TO_RADIANS);
|
* SGD_DEGREES_TO_RADIANS,
|
||||||
|
fgGetDouble("/orientation/heading-deg")
|
||||||
|
* SGD_DEGREES_TO_RADIANS );
|
||||||
|
|
||||||
SG_LOG(SG_FLIGHT, SG_INFO, "End initializing FGInterface");
|
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
|
// Positions
|
||||||
void FGInterface::set_Latitude(double lat) {
|
void FGInterface::set_Latitude(double lat) {
|
||||||
geodetic_position_v[0] = lat;
|
geodetic_position_v[0] = lat;
|
||||||
|
@ -723,4 +737,3 @@ void FGInterface::_busdump(void) {
|
||||||
void fgToggleFDMdataLogging(void) {
|
void fgToggleFDMdataLogging(void) {
|
||||||
cur_fdm_state->ToggleDataLogging();
|
cur_fdm_state->ToggleDataLogging();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -177,6 +177,43 @@ public:
|
||||||
|
|
||||||
typedef vector < FGEngInterface > engine_list;
|
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
|
// This is based heavily on LaRCsim/ls_generic.h
|
||||||
class FGInterface : public FGSubsystem {
|
class FGInterface : public FGSubsystem {
|
||||||
|
@ -303,6 +340,9 @@ private:
|
||||||
// Engine list
|
// Engine list
|
||||||
engine_list engines;
|
engine_list engines;
|
||||||
|
|
||||||
|
//gear list
|
||||||
|
gear_list gear;
|
||||||
|
|
||||||
// SGTimeStamp valid_stamp; // time this record is valid
|
// SGTimeStamp valid_stamp; // time this record is valid
|
||||||
// SGTimeStamp next_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; }
|
inline bool get_bound() const { return bound; }
|
||||||
|
|
||||||
|
//perform initializion that is common to all FDM's
|
||||||
|
void common_init();
|
||||||
|
|
||||||
// time and update management values
|
// time and update management values
|
||||||
inline double get_delta_t() const { return delta_t; }
|
inline double get_delta_t() const { return delta_t; }
|
||||||
inline void set_delta_t( double dt ) { delta_t = dt; }
|
inline void set_delta_t( double dt ) { delta_t = dt; }
|
||||||
|
@ -1179,6 +1222,19 @@ public:
|
||||||
inline void add_engine( FGEngInterface e ) {
|
inline void add_engine( FGEngInterface e ) {
|
||||||
engines.push_back( 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)
|
// Set the altitude (force)
|
||||||
void fgFDMForceAltitude(const string &model, double alt_meters);
|
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
|
// Toggle data logging on/off
|
||||||
void fgToggleFDMdataLogging(void);
|
void fgToggleFDMdataLogging(void);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue