X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FFDM%2FJSBSim.cxx;h=68997a3424f31b35727eae8bcbd45ab1fed87632;hb=407dcaff6236e7217eff16ac253218d3e51bce6d;hp=b60d7870bf913f09334ffea8dd8a28c2fb0c54a5;hpb=a7abe629cfe24bdba9196aa02dd7dd0616dca930;p=flightgear.git diff --git a/src/FDM/JSBSim.cxx b/src/FDM/JSBSim.cxx index b60d7870b..68997a342 100644 --- a/src/FDM/JSBSim.cxx +++ b/src/FDM/JSBSim.cxx @@ -21,7 +21,7 @@ // $Id$ -#include +#include #ifdef FG_MATH_EXCEPTION_CLASH # include @@ -29,259 +29,574 @@ #include STL_STRING +#include +#include +#include +#include + +#include + #include #include -#include -#include -#include
-#include -#include - -#include -#include -#include -#include -#include -#include -#include +#include
+ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "JSBSim.hxx" + +/******************************************************************************/ + +FGJSBsim::FGJSBsim(void) { + bool result; + + fdmex=new FGFDMExec; + fgic=new FGInitialCondition(fdmex); + needTrim=true; + + FGPath aircraft_path( globals->get_options()->get_fg_root() ); + aircraft_path.append( "Aircraft" ); -#include "JSBsim.hxx" + FGPath engine_path( globals->get_options()->get_fg_root() ); + engine_path.append( "Engine" ); + float dt = 1.0 / globals->get_options()->get_model_hz(); + fdmex->GetState()->Setdt( dt ); + + result = fdmex->LoadModel( aircraft_path.str(), + engine_path.str(), + globals->get_options()->get_aircraft() ); + int Neng=fdmex->GetAircraft()->GetNumEngines(); + FG_LOG(FG_FLIGHT,FG_INFO, "Neng: " << Neng ); + for(int i=0;iget_options()->get_fg_root() ); aircraft_path.append( "Aircraft" ); - FGPath engine_path( current_options.get_fg_root() ); + FGPath engine_path( globals->get_options()->get_fg_root() ); engine_path.append( "Engine" ); - FDMExec.GetAircraft()->LoadAircraft(aircraft_path.str(), - engine_path.str(), "X15"); - FG_LOG( FG_FLIGHT, FG_INFO, " loaded aircraft" ); - -// FDMExec.GetState()->Reset(aircraft_path.str(), "Reset00"); - - FDMExec.GetState()->Initialize( - current_options.get_uBody(), - current_options.get_vBody(), - current_options.get_wBody(), - f.get_Phi(), - f.get_Theta(), - f.get_Psi(), - f.get_Latitude() * RAD_TO_DEG, - f.get_Longitude() * RAD_TO_DEG, - f.get_Altitude() - ); - -// FDMExec.GetState()->Setlatitude(f.get_Latitude()); -// FDMExec.GetState()->Setlongitude(f.get_Longitude()); -// FDMExec.GetState()->Seth(f.get_Altitude()); -// FDMExec.GetRotation()->Setphi(f.get_Phi()); -// FDMExec.GetRotation()->Settht(f.get_Theta()); -// FDMExec.GetRotation()->Setpsi(f.get_Psi()); + fdmex->GetState()->Setdt( dt ); + + result = fdmex->LoadModel( aircraft_path.str(), + engine_path.str(), + globals->get_options()->get_aircraft() ); +#endif + + if (result) { + FG_LOG( FG_FLIGHT, FG_INFO, " loaded aircraft " << globals->get_options()->get_aircraft() ); + } else { + FG_LOG( FG_FLIGHT, FG_INFO, " aircraft " + << globals->get_options()->get_aircraft() + << " does not exist" ); + return false; + } + + fdmex->GetAtmosphere()->UseInternal(); + + FG_LOG( FG_FLIGHT, FG_INFO, " Initializing JSBSim with:" ); + switch(fgic->GetSpeedSet()) { + case setned: + FG_LOG(FG_FLIGHT,FG_INFO, " Vn,Ve,Vd= " + << fdmex->GetPosition()->GetVn() + << ", " << fdmex->GetPosition()->GetVe() + << ", " << fdmex->GetPosition()->GetVd() + << " ft/s"); + break; + case setuvw: + FG_LOG(FG_FLIGHT,FG_INFO, " U,V,W= " + << fdmex->GetTranslation()->GetUVW()(1) + << ", " << fdmex->GetTranslation()->GetUVW()(2) + << ", " << fdmex->GetTranslation()->GetUVW()(3) + << " ft/s"); + break; + case setmach: + FG_LOG(FG_FLIGHT,FG_INFO, " Mach: " + << fdmex->GetTranslation()->GetMach() ); + break; + case setvc: + default: + FG_LOG(FG_FLIGHT,FG_INFO, " Indicated Airspeed: " + << fdmex->GetAuxiliary()->GetVcalibratedKTS() << " knots" ); + + } + + //FG_LOG( FG_FLIGHT, FG_INFO, " gamma: " << globals->get_options()->get_Gamma()); + FG_LOG( FG_FLIGHT, FG_INFO, " Bank Angle: " + << fdmex->GetRotation()->Getphi()*RADTODEG << " deg"); + FG_LOG( FG_FLIGHT, FG_INFO, " Pitch Angle: " + << fdmex->GetRotation()->Gettht()*RADTODEG << " deg" ); + FG_LOG( FG_FLIGHT, FG_INFO, " True Heading: " + << fdmex->GetRotation()->Getpsi()*RADTODEG << " deg" ); + FG_LOG( FG_FLIGHT, FG_INFO, " Latitude: " + << fdmex->GetPosition()->GetLatitude() << " deg" ); + FG_LOG( FG_FLIGHT, FG_INFO, " Longitude: " + << fdmex->GetPosition()->GetLongitude() << " deg" ); + + // for debug only + /* FG_LOG( FG_FLIGHT, FG_DEBUG, " FGJSBSim::get_Altitude(): " << get_Altitude() ); + FG_LOG( FG_FLIGHT, FG_DEBUG, " FGJSBSim::get_Sea_level_radius(): " << get_Sea_level_radius() ); + FG_LOG( FG_FLIGHT, FG_DEBUG, " scenery.cur_radius*METER_TO_FEET: " + << scenery.cur_radius*METER_TO_FEET ); + FG_LOG( FG_FLIGHT, FG_DEBUG, " Calculated Terrain ASL: " << endl + << " " << "scenery.cur_radius*METER_TO_FEET -get_Sea_level_radius()= " + << scenery.cur_radius*METER_TO_FEET - get_Sea_level_radius() ); + + FG_LOG( FG_FLIGHT, FG_DEBUG, " Calculated Aircraft AGL: " << endl + << " " << "get_Altitude() + get_Sea_level_radius() - scenery.cur_radius*METER_TO_FEET= " + << get_Altitude() + get_Sea_level_radius()- scenery.cur_radius*METER_TO_FEET ); + FG_LOG( FG_FLIGHT, FG_DEBUG, " globals->get_options()->get_altitude(): " + << globals->get_options()->get_altitude() ); + FG_LOG( FG_FLIGHT, FG_DEBUG, " FGBFI::getAltitude(): " + << FGBFI::getAltitude() ); */ + FG_LOG( FG_FLIGHT, FG_INFO, " loaded initial conditions" ); - FDMExec.GetState()->Setdt(dt); FG_LOG( FG_FLIGHT, FG_INFO, " set dt" ); - FG_LOG( FG_FLIGHT, FG_INFO, "Finished initializing JSBsim" ); + FG_LOG( FG_FLIGHT, FG_INFO, "Finished initializing JSBSim" ); - return 1; + return true; } +/******************************************************************************/ // Run an iteration of the EOM (equations of motion) -int fgJSBsimUpdate(FGInterface& f, int multiloop) { - double save_alt = 0.0; +bool FGJSBsim::update( int multiloop ) { + + int i; + + double save_alt = 0.0; + + // lets try to avoid really screwing up the JSBsim model - if ( f.get_Altitude() < -9000 ) { - save_alt = f.get_Altitude(); - f.set_Altitude( 0.0 ); + if ( get_Altitude() < -9000 ) { + save_alt = get_Altitude(); + set_Altitude( 0.0 ); } - // copy control positions into the JSBsim structure - FDMExec.GetFCS()->SetDa( controls.get_aileron() / 10.0 ); - FDMExec.GetFCS()->SetDe( controls.get_elevator() - + controls.get_elevator_trim() ); - FDMExec.GetFCS()->SetDr( controls.get_rudder() / 10.0 ); - FDMExec.GetFCS()->SetDf( 0.0 ); - FDMExec.GetFCS()->SetDs( 0.0 ); - FDMExec.GetFCS()->SetThrottle( FGControls::ALL_ENGINES, - controls.get_throttle( 0 ) * 100.0 ); - // FCS->SetBrake( controls.get_brake( 0 ) ); - - // Inform JSBsim of the local terrain altitude - // Runway_altitude = f.get_Runway_altitude(); - - // old -- FGInterface_2_JSBsim() not needed except for Init() - // translate FG to JSBsim structure - // FGInterface_2_JSBsim(f); - // printf("FG_Altitude = %.2f\n", FG_Altitude * 0.3048); - // printf("Altitude = %.2f\n", Altitude * 0.3048); - // printf("Radius to Vehicle = %.2f\n", Radius_to_vehicle * 0.3048); - - /* FDMExec.GetState()->Setsim_time(State->Getsim_time() - + State->Getdt() * multiloop); */ - + if(needTrim && (globals->get_options()->get_trim_mode() > 0)) { + 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(); + } + fgtrim->ReportState(); + delete fgtrim; + + needTrim=false; + + + controls.set_elevator_trim(fdmex->GetFCS()->GetPitchTrimCmd()); + controls.set_elevator(fdmex->GetFCS()->GetDeCmd()); + controls.set_throttle(FGControls::ALL_ENGINES, + fdmex->GetFCS()->GetThrottleCmd(0)/100.0); + controls.set_aileron(fdmex->GetFCS()->GetDaCmd()); + controls.set_rudder(fdmex->GetFCS()->GetDrCmd()); + + FG_LOG( FG_FLIGHT, FG_INFO, " Trim complete" ); + } + + for( i=0; iset_RPM( controls.get_throttle(i)*2700 ); + get_engine(i)->set_Throttle( controls.get_throttle(i) ); + } + copy_to_JSBsim(); + for ( int i = 0; i < multiloop; i++ ) { - FDMExec.Run(); + fdmex->Run(); } // printf("%d FG_Altitude = %.2f\n", i, FG_Altitude * 0.3048); // printf("%d Altitude = %.2f\n", i, Altitude * 0.3048); - + // 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 - fgJSBsim_2_FGInterface(f); + copy_from_JSBsim(); + + // but lets restore our original bogus altitude when we are done + if ( save_alt < -9000.0 ) { - f.set_Altitude( save_alt ); + set_Altitude( save_alt ); } - - return 1; + + //climb rate now set from FDM in copy_from_x() + return true; } +/******************************************************************************/ // Convert from the FGInterface struct to the JSBsim generic_ struct -int FGInterface_2_JSBsim (FGInterface& f) { - return 1; +bool FGJSBsim::copy_to_JSBsim() { + // copy control positions into the JSBsim structure + + fdmex->GetFCS()->SetDaCmd( controls.get_aileron()); + fdmex->GetFCS()->SetDeCmd( controls.get_elevator()); + fdmex->GetFCS()->SetPitchTrimCmd(controls.get_elevator_trim()); + fdmex->GetFCS()->SetDrCmd( -1*controls.get_rudder()); + fdmex->GetFCS()->SetDfCmd( controls.get_flaps() ); + fdmex->GetFCS()->SetDsbCmd( 0.0 ); //speedbrakes + fdmex->GetFCS()->SetDspCmd( 0.0 ); //spoilers + fdmex->GetFCS()->SetThrottleCmd( FGControls::ALL_ENGINES, + controls.get_throttle( 0 ) * 100.0 ); + + fdmex->GetFCS()->SetLBrake( controls.get_brake( 0 ) ); + fdmex->GetFCS()->SetRBrake( controls.get_brake( 1 ) ); + fdmex->GetFCS()->SetCBrake( controls.get_brake( 2 ) ); + + fdmex->GetPosition()->SetRunwayRadius(scenery.cur_radius*METER_TO_FEET); + fdmex->GetPosition()->SetSeaLevelRadius(get_Sea_level_radius()); + + fdmex->GetAtmosphere()->SetExTemperature(get_Static_temperature()); + fdmex->GetAtmosphere()->SetExPressure(get_Static_pressure()); + fdmex->GetAtmosphere()->SetExDensity(get_Density()); + fdmex->GetAtmosphere()->SetWindNED(get_V_north_airmass(), + get_V_east_airmass(), + get_V_down_airmass()); + + return true; } +/******************************************************************************/ // Convert from the JSBsim generic_ struct to the FGInterface struct -int fgJSBsim_2_FGInterface (FGInterface& f) { +bool FGJSBsim::copy_from_JSBsim() { + unsigned i, j; + + _set_Inertias( fdmex->GetAircraft()->GetMass(), + fdmex->GetAircraft()->GetIxx(), + fdmex->GetAircraft()->GetIyy(), + fdmex->GetAircraft()->GetIzz(), + fdmex->GetAircraft()->GetIxz() ); + + _set_CG_Position( fdmex->GetAircraft()->GetXYZcg()(1), + fdmex->GetAircraft()->GetXYZcg()(2), + fdmex->GetAircraft()->GetXYZcg()(3) ); + + _set_Accels_Body( fdmex->GetTranslation()->GetUVWdot()(1), + fdmex->GetTranslation()->GetUVWdot()(2), + fdmex->GetTranslation()->GetUVWdot()(3) ); + + _set_Accels_CG_Body( fdmex->GetTranslation()->GetUVWdot()(1), + fdmex->GetTranslation()->GetUVWdot()(2), + fdmex->GetTranslation()->GetUVWdot()(3) ); + + //_set_Accels_CG_Body_N ( fdmex->GetTranslation()->GetNcg()(1), + // fdmex->GetTranslation()->GetNcg()(2), + // fdmex->GetTranslation()->GetNcg()(3) ); + // + _set_Accels_Pilot_Body( fdmex->GetAuxiliary()->GetPilotAccel()(1), + fdmex->GetAuxiliary()->GetPilotAccel()(2), + fdmex->GetAuxiliary()->GetPilotAccel()(3) ); + + //_set_Accels_Pilot_Body_N( fdmex->GetAuxiliary()->GetNpilot()(1), + // fdmex->GetAuxiliary()->GetNpilot()(2), + // fdmex->GetAuxiliary()->GetNpilot()(3) ); + + _set_Nlf( fdmex->GetAircraft()->GetNlf() ); + // Velocities - f.set_Velocities_Local( FDMExec.GetPosition()->GetVn(), - FDMExec.GetPosition()->GetVe(), - FDMExec.GetPosition()->GetVd() ); - // f.set_Velocities_Ground( V_north_rel_ground, V_east_rel_ground, - // V_down_rel_ground ); - // f.set_Velocities_Local_Airmass( V_north_airmass, V_east_airmass, - // V_down_airmass ); - // f.set_Velocities_Local_Rel_Airmass( V_north_rel_airmass, - // V_east_rel_airmass, V_down_rel_airmass ); - // f.set_Velocities_Gust( U_gust, V_gust, W_gust ); - // f.set_Velocities_Wind_Body( U_body, V_body, W_body ); - - // f.set_V_rel_wind( V_rel_wind ); - // f.set_V_true_kts( V_true_kts ); - // f.set_V_rel_ground( V_rel_ground ); - // f.set_V_inertial( V_inertial ); - // f.set_V_ground_speed( V_ground_speed ); - // f.set_V_equiv( V_equiv ); - - /* ***FIXME*** */ f.set_V_equiv_kts( FDMExec.GetState()->GetVt() ); - // f.set_V_calibrated( V_calibrated ); - // f.set_V_calibrated_kts( V_calibrated_kts ); - - f.set_Omega_Body( FDMExec.GetRotation()->GetP(), - FDMExec.GetRotation()->GetQ(), - FDMExec.GetRotation()->GetR() ); - // f.set_Omega_Local( P_local, Q_local, R_local ); - // f.set_Omega_Total( P_total, Q_total, R_total ); + + _set_Velocities_Local( fdmex->GetPosition()->GetVn(), + fdmex->GetPosition()->GetVe(), + fdmex->GetPosition()->GetVd() ); + + _set_Velocities_Wind_Body( fdmex->GetTranslation()->GetUVW()(1), + fdmex->GetTranslation()->GetUVW()(2), + fdmex->GetTranslation()->GetUVW()(3) ); + + _set_V_rel_wind( fdmex->GetTranslation()->GetVt() ); - // f.set_Euler_Rates( Phi_dot, Theta_dot, Psi_dot ); - // ***FIXME*** f.set_Geocentric_Rates( Latitude_dot, Longitude_dot, Radius_dot ); + _set_V_equiv_kts( fdmex->GetAuxiliary()->GetVequivalentKTS() ); + + // _set_V_calibrated( fdmex->GetAuxiliary()->GetVcalibratedFPS() ); + + _set_V_calibrated_kts( fdmex->GetAuxiliary()->GetVcalibratedKTS() ); + + _set_V_ground_speed( fdmex->GetPosition()->GetVground() ); + + _set_Omega_Body( fdmex->GetRotation()->GetPQR()(1), + fdmex->GetRotation()->GetPQR()(2), + fdmex->GetRotation()->GetPQR()(3) ); + + _set_Euler_Rates( fdmex->GetRotation()->GetEulerRates()(1), + fdmex->GetRotation()->GetEulerRates()(2), + fdmex->GetRotation()->GetEulerRates()(3) ); + + _set_Geocentric_Rates(fdmex->GetPosition()->GetLatitudeDot(), + fdmex->GetPosition()->GetLongitudeDot(), + fdmex->GetPosition()->Gethdot() ); + + _set_Mach_number( fdmex->GetTranslation()->GetMach() ); // Positions - double lat_geoc = FDMExec.GetState()->Getlatitude(); - double lon = FDMExec.GetState()->Getlongitude(); - double alt = FDMExec.GetState()->Geth(); - double lat_geod, tmp_alt, sl_radius1, sl_radius2, tmp_lat_geoc; - fgGeocToGeod( lat_geoc, EQUATORIAL_RADIUS_M + alt * FEET_TO_METER, - &lat_geod, &tmp_alt, &sl_radius1 ); - fgGeodToGeoc( lat_geod, alt * FEET_TO_METER, &sl_radius2, &tmp_lat_geoc ); - - FG_LOG( FG_FLIGHT, FG_DEBUG, "lon = " << lon << " lat_geod = " << lat_geod - << " lat_geoc = " << lat_geoc - << " alt = " << alt << " tmp_alt = " << tmp_alt * METER_TO_FEET - << " sl_radius1 = " << sl_radius1 * METER_TO_FEET - << " sl_radius2 = " << sl_radius2 * METER_TO_FEET - << " Equator = " << EQUATORIAL_RADIUS_FT ); - - f.set_Geocentric_Position( lat_geoc, lon, - sl_radius2 * METER_TO_FEET + alt ); - f.set_Geodetic_Position( lat_geod, lon, alt ); - f.set_Euler_Angles( FDMExec.GetRotation()->Getphi(), - FDMExec.GetRotation()->Gettht(), - FDMExec.GetRotation()->Getpsi() ); - - // Miscellaneous quantities - // f.set_T_Local_to_Body(T_local_to_body_m); - // f.set_Gravity( Gravity ); - // f.set_Centrifugal_relief( Centrifugal_relief ); - - f.set_Alpha( FDMExec.GetTranslation()->Getalpha() ); - f.set_Beta( FDMExec.GetTranslation()->Getbeta() ); - // f.set_Alpha_dot( Alpha_dot ); - // f.set_Beta_dot( Beta_dot ); - - // f.set_Cos_alpha( Cos_alpha ); - // f.set_Sin_alpha( Sin_alpha ); - // f.set_Cos_beta( Cos_beta ); - // f.set_Sin_beta( Sin_beta ); - - // f.set_Cos_phi( Cos_phi ); - // f.set_Sin_phi( Sin_phi ); - // f.set_Cos_theta( Cos_theta ); - // f.set_Sin_theta( Sin_theta ); - // f.set_Cos_psi( Cos_psi ); - // f.set_Sin_psi( Sin_psi ); - - // ***ATTENDTOME*** f.set_Gamma_vert_rad( Gamma_vert_rad ); - // f.set_Gamma_horiz_rad( Gamma_horiz_rad ); - - // f.set_Sigma( Sigma ); - // f.set_Density( Density ); - // f.set_V_sound( V_sound ); - // f.set_Mach_number( Mach_number ); - - // f.set_Static_pressure( Static_pressure ); - // f.set_Total_pressure( Total_pressure ); - // f.set_Impact_pressure( Impact_pressure ); - // f.set_Dynamic_pressure( Dynamic_pressure ); - - // f.set_Static_temperature( Static_temperature ); - // f.set_Total_temperature( Total_temperature ); - - /* **FIXME*** */ f.set_Sea_level_radius( sl_radius2 * METER_TO_FEET ); - /* **FIXME*** */ f.set_Earth_position_angle( 0.0 ); - - /* ***FIXME*** */ f.set_Runway_altitude( 0.0 ); - // f.set_Runway_latitude( Runway_latitude ); - // f.set_Runway_longitude( Runway_longitude ); - // f.set_Runway_heading( Runway_heading ); - // f.set_Radius_to_rwy( Radius_to_rwy ); - - // f.set_CG_Rwy_Local( D_cg_north_of_rwy, D_cg_east_of_rwy, D_cg_above_rwy); - // f.set_CG_Rwy_Rwy( X_cg_rwy, Y_cg_rwy, H_cg_rwy ); - // f.set_Pilot_Rwy_Local( D_pilot_north_of_rwy, D_pilot_east_of_rwy, - // D_pilot_above_rwy ); - // f.set_Pilot_Rwy_Rwy( X_pilot_rwy, Y_pilot_rwy, H_pilot_rwy ); - - f.set_sin_lat_geocentric( lat_geoc ); - f.set_cos_lat_geocentric( lat_geoc ); - f.set_sin_cos_longitude( lon ); - f.set_sin_cos_latitude( lat_geod ); - - return 0; + _updatePosition( fdmex->GetPosition()->GetLatitude(), + fdmex->GetPosition()->GetLongitude(), + fdmex->GetPosition()->Geth() ); + + _set_Euler_Angles( fdmex->GetRotation()->Getphi(), + fdmex->GetRotation()->Gettht(), + fdmex->GetRotation()->Getpsi() ); + + _set_Alpha( fdmex->GetTranslation()->Getalpha() ); + _set_Beta( fdmex->GetTranslation()->Getbeta() ); + + + _set_Gamma_vert_rad( fdmex->GetPosition()->GetGamma() ); + // set_Gamma_horiz_rad( Gamma_horiz_rad ); + + _set_Earth_position_angle( fdmex->GetAuxiliary()->GetEarthPositionAngle() ); + + _set_Climb_Rate( fdmex->GetPosition()->Gethdot() ); + + + for ( i = 1; i <= 3; i++ ) { + for ( j = 1; j <= 3; j++ ) { + _set_T_Local_to_Body( i, j, fdmex->GetState()->GetTl2b()(i,j) ); + } + } + 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() ); +} + + +//Positions +void FGJSBsim::set_Latitude(double lat) { + double sea_level_radius_meters,lat_geoc; + + FG_LOG(FG_FLIGHT,FG_INFO,"FGJSBsim::set_Latitude: " << lat ); + + snap_shot(); + sgGeodToGeoc( lat, get_Altitude() , &sea_level_radius_meters, &lat_geoc); + fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * METER_TO_FEET ); + fgic->SetLatitudeRadIC( lat_geoc ); + fdmex->RunIC(fgic); //loop JSBSim once + copy_from_JSBsim(); //update the bus + needTrim=true; +} + +void FGJSBsim::set_Longitude(double lon) { + + FG_LOG(FG_FLIGHT,FG_INFO,"FGJSBsim::set_Longitude: " << lon ); + + snap_shot(); + fgic->SetLongitudeRadIC(lon); + fdmex->RunIC(fgic); //loop JSBSim once + copy_from_JSBsim(); //update the bus + needTrim=true; +} + +void FGJSBsim::set_Altitude(double alt) { + double sea_level_radius_meters,lat_geoc; + + FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Altitude: " << alt ); + + snap_shot(); + sgGeodToGeoc( get_Latitude(), alt , &sea_level_radius_meters, &lat_geoc); + fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * 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::set_V_calibrated_kts(double vc) { + FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_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::set_Mach_number(double mach) { + FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Mach_number: " << mach ); + + snap_shot(); + fgic->SetMachIC(mach); + fdmex->RunIC(fgic); //loop JSBSim once + copy_from_JSBsim(); //update the bus + needTrim=true; +} + +void FGJSBsim::set_Velocities_Local( double north, double east, double down ){ + FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_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::set_Velocities_Wind_Body( double u, double v, double w){ + FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_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::set_Euler_Angles( double phi, double theta, double psi ) { + FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_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::set_Climb_Rate( double roc) { + FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Climb_Rate: " << roc ); + + snap_shot(); + fgic->SetClimbRateFpsIC(roc); + fdmex->RunIC(fgic); //loop JSBSim once + copy_from_JSBsim(); //update the bus + needTrim=true; +} + +void FGJSBsim::set_Gamma_vert_rad( double gamma) { + FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_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::set_Sea_level_radius(double slr) { + FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_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::set_Runway_altitude(double ralt) { + FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Runway_altitude: " << ralt ); + + snap_shot(); + _set_Runway_altitude( ralt ); + fdmex->RunIC(fgic); //loop JSBSim once + copy_from_JSBsim(); //update the bus + needTrim=true; +} + +void FGJSBsim::set_Static_pressure(double p) { + FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Static_pressure: " << p ); + + snap_shot(); + fdmex->GetAtmosphere()->SetExPressure(p); + if(fdmex->GetAtmosphere()->External() == true) + needTrim=true; +} + +void FGJSBsim::set_Static_temperature(double T) { + FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Static_temperature: " << T ); + + snap_shot(); + fdmex->GetAtmosphere()->SetExTemperature(T); + if(fdmex->GetAtmosphere()->External() == true) + needTrim=true; +} + +void FGJSBsim::set_Density(double rho) { + FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Density: " << rho ); + + snap_shot(); + fdmex->GetAtmosphere()->SetExDensity(rho); + if(fdmex->GetAtmosphere()->External() == true) + needTrim=true; +} + + +void FGJSBsim::set_Velocities_Local_Airmass (double wnorth, + double weast, + double wdown ) { + FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Velocities_Local_Airmass: " + << wnorth << ", " << weast << ", " << wdown ); + + snap_shot(); + fdmex->GetAtmosphere()->SetWindNED(wnorth, weast, wdown ); + if(fdmex->GetAtmosphere()->External() == true) + needTrim=true; +}