From 5fe0f047022bd168c7685169a8a3cedc8e93430e Mon Sep 17 00:00:00 2001 From: curt Date: Tue, 6 Nov 2001 22:33:05 +0000 Subject: [PATCH] Updates to JSBSim and FDM interface. --- src/FDM/ADA.cxx | 7 +- src/FDM/Balloon.cxx | 8 +- src/FDM/JSBSim.cxx | 404 ++++++++++--------------------- src/FDM/JSBSim.hxx | 101 +------- src/FDM/JSBSim/FGAircraft.cpp | 14 +- src/FDM/JSBSim/FGAircraft.h | 6 + src/FDM/JSBSim/FGAtmosphere.h | 16 +- src/FDM/JSBSim/FGForce.cpp | 13 +- src/FDM/JSBSim/FGForce.h | 4 + src/FDM/JSBSim/FGLGear.h | 3 + src/FDM/JSBSim/FGPropeller.cpp | 30 ++- src/FDM/JSBSim/FGPropeller.h | 2 + src/FDM/JSBSim/FGPropulsion.cpp | 39 ++- src/FDM/JSBSim/FGPropulsion.h | 7 +- src/FDM/JSBSim/FGState.cpp | 2 +- src/FDM/JSBSim/FGTranslation.cpp | 5 +- src/FDM/JSBSim/FGTranslation.h | 3 - src/FDM/JSBSim/FGTrimAxis.cpp | 11 +- src/FDM/LaRCsim.cxx | 6 +- src/FDM/MagicCarpet.cxx | 4 +- src/FDM/flight.cxx | 169 +++++++------ src/FDM/flight.hxx | 59 ++++- 22 files changed, 421 insertions(+), 492 deletions(-) diff --git a/src/FDM/ADA.cxx b/src/FDM/ADA.cxx index ae8e33ed3..1dd27bae8 100644 --- a/src/FDM/ADA.cxx +++ b/src/FDM/ADA.cxx @@ -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; diff --git a/src/FDM/Balloon.cxx b/src/FDM/Balloon.cxx index 86e0f7156..4bde1049f 100644 --- a/src/FDM/Balloon.cxx +++ b/src/FDM/Balloon.cxx @@ -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; diff --git a/src/FDM/JSBSim.cxx b/src/FDM/JSBSim.cxx index e7ff9c291..ba30c9e41 100644 --- a/src/FDM/JSBSim.cxx +++ b/src/FDM/JSBSim.cxx @@ -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 @@ -190,7 +198,9 @@ void FGJSBsim::init() { << Auxiliary->GetVcalibratedKTS() << " knots" ); 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,51 +237,33 @@ 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()); + if ( needTrim ) { + if ( startup_trim->getBoolValue() ) { + do_trim(); + } else { + fdmex->RunIC(fgic); //apply any changes made through the set_ functions + } + needTrim = false; + } - SG_LOG( SG_FLIGHT, SG_INFO, " Trim complete" ); - } - for( i=0; iGetEngine(i); 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; iGetEngine(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( Auxiliary->GetPilotAccel()(1), + Auxiliary->GetPilotAccel()(2), + Auxiliary->GetPilotAccel()(3) ); - //_set_Accels_Pilot_Body_N( Auxiliary->GetNpilot(1), - // Auxiliary->GetNpilot(2), - // Auxiliary->GetNpilot(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; } - -//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; -} - -void FGJSBsim::update_Longitude(double lon) { - - 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; -} - -void FGJSBsim::update_Altitude(double alt) { - double sea_level_radius_meters,lat_geoc; - - SG_LOG(SG_FLIGHT,SG_INFO, "FGJSBsim::update_Altitude: " << alt ); - - 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; -} - -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::init_gear(void ) { + + FGGearInterface *gear; + FGGroundReactions* gr=fdmex->GetGroundReactions(); + int Ngear=GroundReactions->GetNumGearUnits(); + for (int i=0;iSetX( 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_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_gear(void) { + + FGGearInterface* gear; + FGGroundReactions* gr=fdmex->GetGroundReactions(); + int Ngear=GroundReactions->GetNumGearUnits(); + for (int i=0;iSetWoW( gr->GetGearUnit(i)->GetWOW() ); + if ( gr->GetGearUp() ) { + gear->SetPosition( 0.0 ); + } + } } -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::do_trim(void) { -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; -} - + 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() ); -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; -} - + 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)); -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 ); + globals->get_controls()->set_aileron(FCS->GetDaCmd()); + globals->get_controls()->set_rudder( FCS->GetDrCmd()); - _set_Velocities_Local_Airmass( wnorth, weast, wdown ); - snap_shot(); - Atmosphere->SetWindNED(wnorth, weast, wdown ); - if(Atmosphere->External() == true) - needTrim=true; -} - + SG_LOG( SG_FLIGHT, SG_INFO, " Trim complete" ); +} diff --git a/src/FDM/JSBSim.hxx b/src/FDM/JSBSim.hxx index c3ee32905..b8097093f 100644 --- a/src/FDM/JSBSim.hxx +++ b/src/FDM/JSBSim.hxx @@ -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); }; diff --git a/src/FDM/JSBSim/FGAircraft.cpp b/src/FDM/JSBSim/FGAircraft.cpp index 0701474f3..b5cfca1c0 100644 --- a/src/FDM/JSBSim/FGAircraft.cpp +++ b/src/FDM/JSBSim/FGAircraft.cpp @@ -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; diff --git a/src/FDM/JSBSim/FGAircraft.h b/src/FDM/JSBSim/FGAircraft.h index 055373cc1..710401f36 100644 --- a/src/FDM/JSBSim/FGAircraft.h +++ b/src/FDM/JSBSim/FGAircraft.h @@ -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); } @@ -198,6 +199,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 { @@ -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; diff --git a/src/FDM/JSBSim/FGAtmosphere.h b/src/FDM/JSBSim/FGAtmosphere.h index 6b61ce0b5..024969310 100644 --- a/src/FDM/JSBSim/FGAtmosphere.h +++ b/src/FDM/JSBSim/FGAtmosphere.h @@ -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); diff --git a/src/FDM/JSBSim/FGForce.cpp b/src/FDM/JSBSim/FGForce.cpp index 9c2945f1b..00ac43a7a 100644 --- a/src/FDM/JSBSim/FGForce.cpp +++ b/src/FDM/JSBSim/FGForce.cpp @@ -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; } diff --git a/src/FDM/JSBSim/FGForce.h b/src/FDM/JSBSim/FGForce.h index 58c48af41..c64d93149 100644 --- a/src/FDM/JSBSim/FGForce.h +++ b/src/FDM/JSBSim/FGForce.h @@ -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); diff --git a/src/FDM/JSBSim/FGLGear.h b/src/FDM/JSBSim/FGLGear.h index b6c7ab0ed..16331004d 100644 --- a/src/FDM/JSBSim/FGLGear.h +++ b/src/FDM/JSBSim/FGLGear.h @@ -228,6 +228,9 @@ public: inline bool GetReport(void) { return ReportEnable; } 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; diff --git a/src/FDM/JSBSim/FGPropeller.cpp b/src/FDM/JSBSim/FGPropeller.cpp index 36b7e0e93..06c30b82d 100644 --- a/src/FDM/JSBSim/FGPropeller.cpp +++ b/src/FDM/JSBSim/FGPropeller.cpp @@ -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; diff --git a/src/FDM/JSBSim/FGPropeller.h b/src/FDM/JSBSim/FGPropeller.h index cd014c76f..f133d79f5 100644 --- a/src/FDM/JSBSim/FGPropeller.h +++ b/src/FDM/JSBSim/FGPropeller.h @@ -150,6 +150,8 @@ private: float Diameter; float MaxPitch; float MinPitch; + float P_Factor; + float Sense; float Pitch; float Torque; FGTable *Efficiency; diff --git a/src/FDM/JSBSim/FGPropulsion.cpp b/src/FDM/JSBSim/FGPropulsion.cpp index 2434228e1..16be1ffdf 100644 --- a/src/FDM/JSBSim/FGPropulsion.cpp +++ b/src/FDM/JSBSim/FGPropulsion.cpp @@ -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; iSetTrimMode(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; iSetTrimMode(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; diff --git a/src/FDM/JSBSim/FGPropulsion.h b/src/FDM/JSBSim/FGPropulsion.h index cc3d37115..4070128fc 100644 --- a/src/FDM/JSBSim/FGPropulsion.h +++ b/src/FDM/JSBSim/FGPropulsion.h @@ -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); diff --git a/src/FDM/JSBSim/FGState.cpp b/src/FDM/JSBSim/FGState.cpp index 19bb8edc7..84ef65274 100644 --- a/src/FDM/JSBSim/FGState.cpp +++ b/src/FDM/JSBSim/FGState.cpp @@ -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", diff --git a/src/FDM/JSBSim/FGTranslation.cpp b/src/FDM/JSBSim/FGTranslation.cpp index 2e7cfca2b..871c8a3f5 100644 --- a/src/FDM/JSBSim/FGTranslation.cpp +++ b/src/FDM/JSBSim/FGTranslation.cpp @@ -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(); diff --git a/src/FDM/JSBSim/FGTranslation.h b/src/FDM/JSBSim/FGTranslation.h index 43c69b6ff..21dbd2aeb 100644 --- a/src/FDM/JSBSim/FGTranslation.h +++ b/src/FDM/JSBSim/FGTranslation.h @@ -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; diff --git a/src/FDM/JSBSim/FGTrimAxis.cpp b/src/FDM/JSBSim/FGTrimAxis.cpp index 221a8ce30..d59977b0b 100644 --- a/src/FDM/JSBSim/FGTrimAxis.cpp +++ b/src/FDM/JSBSim/FGTrimAxis.cpp @@ -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(); } } diff --git a/src/FDM/LaRCsim.cxx b/src/FDM/LaRCsim.cxx index f6343d676..fedef5a21 100644 --- a/src/FDM/LaRCsim.cxx +++ b/src/FDM/LaRCsim.cxx @@ -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 } diff --git a/src/FDM/MagicCarpet.cxx b/src/FDM/MagicCarpet.cxx index b78d76474..624ae51e2 100644 --- a/src/FDM/MagicCarpet.cxx +++ b/src/FDM/MagicCarpet.cxx @@ -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(); } diff --git a/src/FDM/flight.cxx b/src/FDM/flight.cxx index 2adf802db..673faaf04 100644 --- a/src/FDM/flight.cxx +++ b/src/FDM/flight.cxx @@ -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"); - - inited = true; - - 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")); + SG_LOG( SG_FLIGHT, SG_INFO, "Start common FDM init" ); + + set_inited( true ); + + 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(); + 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..." ); + 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 + 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 { - SG_LOG(SG_FLIGHT, SG_ALERT, - "Unrecognized value for /sim/startup/speed-set: " << speedset); - set_V_calibrated_kts(0.0); + 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); + // 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 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 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(); } - diff --git a/src/FDM/flight.hxx b/src/FDM/flight.hxx index e23a28c75..f37ada9ee 100644 --- a/src/FDM/flight.hxx +++ b/src/FDM/flight.hxx @@ -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 { @@ -302,6 +339,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); -- 2.39.5