diff --git a/src/FDM/ADA.cxx b/src/FDM/ADA.cxx index 35612a185..d2e1963a9 100644 --- a/src/FDM/ADA.cxx +++ b/src/FDM/ADA.cxx @@ -213,12 +213,12 @@ bool FGADA::copy_to_FGADA () { bool FGADA::copy_from_FGADA() { // Velocities - set_Velocities_Local( V_north, V_east, V_down ); - set_V_calibrated_kts( V_calibrated_kts ); + _set_Velocities_Local( V_north, V_east, V_down ); + _set_V_calibrated_kts( V_calibrated_kts ); // Angular rates - set_Omega_Body( P_body, Q_body, R_body ); - set_Geocentric_Rates( Latitude_dot, Longitude_dot, Radius_dot ); + _set_Omega_Body( P_body, Q_body, R_body ); + _set_Geocentric_Rates( Latitude_dot, Longitude_dot, Radius_dot ); // FG_LOG( FG_FLIGHT, FG_DEBUG, "lon = " << Longitude // << " lat_geoc = " << Lat_geocentric << " lat_geod = " << Latitude @@ -226,25 +226,26 @@ bool FGADA::copy_from_FGADA() { // << " radius_to_vehicle = " << Radius_to_vehicle ); // Positions - set_Geocentric_Position( Lat_geocentric, Lon_geocentric,Radius_to_vehicle ); - set_Geodetic_Position( Latitude, Longitude, Altitude ); - set_Euler_Angles( Phi, Theta, Psi ); + _set_Geocentric_Position( Lat_geocentric, Lon_geocentric, + Radius_to_vehicle ); + _set_Geodetic_Position( Latitude, Longitude, Altitude ); + _set_Euler_Angles( Phi, Theta, Psi ); // Miscellaneous quantities - set_Alpha( Alpha ); - set_Beta( Beta ); - set_Gamma_vert_rad( Gamma_vert_rad ); - set_Sea_level_radius( Sea_level_radius ); - set_Earth_position_angle( Earth_position_angle ); - set_Runway_altitude( Runway_altitude ); - set_sin_lat_geocentric(Lat_geocentric); - set_cos_lat_geocentric(Lat_geocentric); - set_sin_cos_longitude(Longitude); - set_sin_cos_latitude(Latitude); - set_Accels_Local( U_dot_local, V_dot_local, W_dot_local ); - set_Velocities_Ground( U_local, V_local, W_local ); - set_Accels_CG_Body_N( anxg,anyg,anzg); - set_Mach_number( Machno); + _set_Alpha( Alpha ); + _set_Beta( Beta ); + _set_Gamma_vert_rad( Gamma_vert_rad ); + _set_Sea_level_radius( Sea_level_radius ); + _set_Earth_position_angle( Earth_position_angle ); + _set_Runway_altitude( Runway_altitude ); + _set_sin_lat_geocentric(Lat_geocentric); + _set_cos_lat_geocentric(Lat_geocentric); + _set_sin_cos_longitude(Longitude); + _set_sin_cos_latitude(Latitude); + _set_Accels_Local( U_dot_local, V_dot_local, W_dot_local ); + _set_Velocities_Ground( U_local, V_local, W_local ); + _set_Accels_CG_Body_N( anxg,anyg,anzg); + _set_Mach_number( Machno); // printf("sr=%f\n",Sea_level_radius); // printf("psi = %f %f\n",Psi,Psi*RAD_TO_DEG); diff --git a/src/FDM/Balloon.cxx b/src/FDM/Balloon.cxx index 581bce04e..7ea20dd59 100644 --- a/src/FDM/Balloon.cxx +++ b/src/FDM/Balloon.cxx @@ -168,11 +168,11 @@ bool FGBalloonSim::copy_from_BalloonSim() { // Velocities current_balloon.getVelocity( temp ); - set_Velocities_Local( temp[0], temp[1], temp[2] ); + _set_Velocities_Local( temp[0], temp[1], temp[2] ); - /* ***FIXME*** */ set_V_equiv_kts( sgLengthVec3 ( temp ) ); + /* ***FIXME*** */ _set_V_equiv_kts( sgLengthVec3 ( temp ) ); - set_Omega_Body( 0.0, 0.0, 0.0 ); + _set_Omega_Body( 0.0, 0.0, 0.0 ); // Positions current_balloon.getPosition( temp ); @@ -192,27 +192,22 @@ bool FGBalloonSim::copy_from_BalloonSim() { << " sl_radius2 = " << sl_radius2 * METER_TO_FEET << " Equator = " << EQUATORIAL_RADIUS_FT ); - set_Geocentric_Position( lat_geoc, lon, + _set_Geocentric_Position( lat_geoc, lon, sl_radius2 * METER_TO_FEET + alt ); - set_Geodetic_Position( lat_geod, lon, alt ); + _set_Geodetic_Position( lat_geod, lon, alt ); current_balloon.getHPR( temp ); - set_Euler_Angles( temp[0], temp[1], temp[2] ); - set_Euler_Rates(0,0,0); + /* **FIXME*** */ _set_Sea_level_radius( sl_radius2 * METER_TO_FEET ); + /* **FIXME*** */ _set_Earth_position_angle( 0.0 ); - set_Alpha( 0.0/*FDMExec.GetTranslation()->Getalpha()*/ ); - set_Beta( 0.0/*FDMExec.GetTranslation()->Getbeta()*/ ); - - /* **FIXME*** */ set_Sea_level_radius( sl_radius2 * METER_TO_FEET ); - /* **FIXME*** */ set_Earth_position_angle( 0.0 ); - - /* ***FIXME*** */ set_Runway_altitude( 0.0 ); - - set_sin_lat_geocentric( lat_geoc ); - set_cos_lat_geocentric( lat_geoc ); - set_sin_cos_longitude( lon ); - set_sin_cos_latitude( lat_geod ); + /* ***FIXME*** */ _set_Runway_altitude( 0.0 ); + _set_sin_lat_geocentric( lat_geoc ); + _set_cos_lat_geocentric( lat_geoc ); + + _set_sin_cos_longitude( lon ); + _set_sin_cos_latitude( lat_geod ); + return true; } diff --git a/src/FDM/JSBSim.cxx b/src/FDM/JSBSim.cxx index 88aa60670..9285fb35f 100644 --- a/src/FDM/JSBSim.cxx +++ b/src/FDM/JSBSim.cxx @@ -57,140 +57,140 @@ /******************************************************************************/ +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" ); + + 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;i<Neng;i++) { + add_engine( FGEngInterface() ); + } + +} + +/******************************************************************************/ +FGJSBsim::~FGJSBsim(void) { + if(fdmex != NULL) { + delete fdmex; + delete fgic; + } +} + +/******************************************************************************/ + // Initialize the JSBsim flight model, dt is the time increment for // each subsequent iteration through the EOM bool FGJSBsim::init( double dt ) { - bool result; + bool result; - FG_LOG( FG_FLIGHT, FG_INFO, "Starting and initializing JSBsim" ); - FG_LOG( FG_FLIGHT, FG_INFO, " created FDMExec" ); + FG_LOG( FG_FLIGHT, FG_INFO, "Starting and initializing JSBsim" ); - FGPath aircraft_path( globals->get_options()->get_fg_root() ); - aircraft_path.append( "Aircraft" ); +#if 0 + FGPath aircraft_path( globals->get_options()->get_fg_root() ); + aircraft_path.append( "Aircraft" ); - FGPath engine_path( globals->get_options()->get_fg_root() ); - engine_path.append( "Engine" ); + FGPath engine_path( globals->get_options()->get_fg_root() ); + engine_path.append( "Engine" ); - //FDMExec.GetState()->Setdt( dt ); + fdmex->GetState()->Setdt( dt ); - result = FDMExec.LoadModel( aircraft_path.str(), - engine_path.str(), - globals->get_options()->get_aircraft() ); - FDMExec.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(); - 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; - } + 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" ); + + } - FDMExec.GetAtmosphere()->SetExTemperature(get_Static_temperature()); - FDMExec.GetAtmosphere()->SetExPressure(get_Static_pressure()); - FDMExec.GetAtmosphere()->SetExDensity(get_Density()); - FDMExec.GetAtmosphere()->SetWindNED(get_V_north_airmass(), - get_V_east_airmass(), - get_V_down_airmass()); - - FDMExec.GetAtmosphere()->UseInternal(); + //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" ); - - FDMExec.GetPosition()->SetRunwayRadius(scenery.cur_radius*METER_TO_FEET); - FDMExec.GetPosition()->SetSeaLevelRadius(get_Sea_level_radius()); + // 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_INFO, " Initializing JSBSim with:" ); - - FGInitialCondition *fgic = new FGInitialCondition(&FDMExec); - fgic->SetAltitudeFtIC(get_Altitude()); - if ( (globals->get_options()->get_mach() < 0) && - (globals->get_options()->get_vc() < 0 ) ) - { - fgic->SetUBodyFpsIC(globals->get_options()->get_uBody()); - fgic->SetVBodyFpsIC(globals->get_options()->get_vBody()); - fgic->SetWBodyFpsIC(globals->get_options()->get_wBody()); - FG_LOG(FG_FLIGHT,FG_INFO, " u,v,w= " << globals->get_options()->get_uBody() - << ", " << globals->get_options()->get_vBody() - << ", " << globals->get_options()->get_wBody()); - } else if (globals->get_options()->get_vc() < 0) { - fgic->SetMachIC(globals->get_options()->get_mach()); - FG_LOG( FG_FLIGHT,FG_INFO, " mach: " - << globals->get_options()->get_mach() ); - } else { - fgic->SetVcalibratedKtsIC(globals->get_options()->get_vc()); - FG_LOG(FG_FLIGHT,FG_INFO, " vc: " << globals->get_options()->get_vc() ); - //this should cover the case in which no speed switches are used - //globals->get_options()->get_vc() will return zero by default - } - - //fgic->SetFlightPathAngleDegIC(globals->get_options()->get_Gamma()); - fgic->SetRollAngleRadIC(get_Phi()); - fgic->SetPitchAngleRadIC(get_Theta()); - fgic->SetHeadingRadIC(get_Psi()); - fgic->SetLatitudeRadIC(get_Lat_geocentric()); - fgic->SetLongitudeRadIC(get_Longitude()); - - // FG_LOG( FG_FLIGHT, FG_INFO, " gamma: " - // << globals->get_options()->get_Gamma()); - FG_LOG( FG_FLIGHT, FG_INFO, " phi: " << get_Phi()); - //FG_LOG( FG_FLIGHT, FG_INFO, " theta: " << get_Theta() ); - FG_LOG( FG_FLIGHT, FG_INFO, " psi: " << get_Psi() ); - FG_LOG( FG_FLIGHT, FG_INFO, " lat: " << get_Latitude() ); - FG_LOG( FG_FLIGHT, FG_INFO, " lon: " << get_Longitude() ); - - FG_LOG( FG_FLIGHT, FG_INFO, " Pressure Altiude: " << get_Altitude() ); - FG_LOG( FG_FLIGHT, FG_INFO, " Terrain Altitude: " - << scenery.cur_radius*METER_TO_FEET ); - FG_LOG( FG_FLIGHT, FG_INFO, " AGL Altitude: " - << get_Altitude() + get_Sea_level_radius() - - scenery.cur_radius*METER_TO_FEET ); - - FG_LOG( FG_FLIGHT, FG_INFO, " globals->get_options()->get_altitude(): " - << globals->get_options()->get_altitude() ); - //must check > 0, != 0 will give bad result if --notrim set - if(globals->get_options()->get_trim_mode() > 0) { - if(fgic->GetVcalibratedKtsIC() > 50) { - FDMExec.RunIC(fgic); - FG_LOG( FG_FLIGHT, FG_INFO, " Starting trim..." ); - FGTrim *fgtrim=new FGTrim(&FDMExec,fgic,tLongitudinal); - fgtrim->DoTrim(); - fgtrim->Report(); - fgtrim->TrimStats(); - fgtrim->ReportState(); + 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() ); */ - controls.set_elevator_trim(FDMExec.GetFCS()->GetPitchTrimCmd()); - controls.set_throttle( FGControls::ALL_ENGINES, - FDMExec.GetFCS()->GetThrottleCmd(0)/100 ); - trimmed=true; - trim_elev=FDMExec.GetFCS()->GetPitchTrimCmd(); - trim_throttle=FDMExec.GetFCS()->GetThrottleCmd(0)/100; - //the trimming routine only knows how to get 1 value for throttle + FG_LOG( FG_FLIGHT, FG_INFO, " loaded initial conditions" ); - delete fgtrim; - } - FG_LOG( FG_FLIGHT, FG_INFO, " Trim complete." ); - } else { - FG_LOG( FG_FLIGHT, FG_INFO, " Initializing without trim" ); - FDMExec.GetState()->Initialize(fgic); + FG_LOG( FG_FLIGHT, FG_INFO, " set dt" ); - } + FG_LOG( FG_FLIGHT, FG_INFO, "Finished initializing JSBSim" ); - delete fgic; - - FG_LOG( FG_FLIGHT, FG_INFO, " loaded initial conditions" ); - - FG_LOG( FG_FLIGHT, FG_INFO, " set dt" ); - - FG_LOG( FG_FLIGHT, FG_INFO, "Finished initializing JSBSim" ); - - copy_from_JSBsim(); - - return true; + return true; } /******************************************************************************/ @@ -198,52 +198,67 @@ bool FGJSBsim::init( double dt ) { // Run an iteration of the EOM (equations of motion) bool FGJSBsim::update( int multiloop ) { - double save_alt = 0.0; - double time_step = (1.0 / globals->get_options()->get_model_hz()) * multiloop; - double start_elev = get_Altitude(); + + int i; + + double save_alt = 0.0; - // lets try to avoid really screwing up the JSBsim model - if ( get_Altitude() < -9000 ) { - save_alt = get_Altitude(); - set_Altitude( 0.0 ); - } + // lets try to avoid really screwing up the JSBsim model + if ( get_Altitude() < -9000 ) { + save_alt = get_Altitude(); + set_Altitude( 0.0 ); + } + - if(trimmed) { - - controls.set_elevator_trim(trim_elev); - controls.set_throttle(FGControls::ALL_ENGINES,trim_throttle); - - controls.set_elevator(0.0); - controls.set_aileron(0.0); - controls.set_rudder(0.0); - trimmed=false; - - } - copy_to_JSBsim(); + if(needTrim) { + FGTrim *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; i<get_num_engines(); i++ ) { + get_engine(i)->set_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++ ) { + fdmex->Run(); + } - for ( int i = 0; i < multiloop; i++ ) { - FDMExec.Run(); - } + // printf("%d FG_Altitude = %.2f\n", i, FG_Altitude * 0.3048); + // printf("%d Altitude = %.2f\n", i, Altitude * 0.3048); - // 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 - // translate JSBsim back to FG structure so that the - // autopilot (and the rest of the sim can use the updated values + copy_from_JSBsim(); - copy_from_JSBsim(); + // but lets restore our original bogus altitude when we are done - // but lets restore our original bogus altitude when we are done - - if ( save_alt < -9000.0 ) { - set_Altitude( save_alt ); - } - - double end_elev = get_Altitude(); - - return true; + if ( save_alt < -9000.0 ) { + set_Altitude( save_alt ); + } + + //climb rate now set from FDM in copy_from_x() + return true; } /******************************************************************************/ @@ -251,35 +266,33 @@ bool FGJSBsim::update( int multiloop ) { // Convert from the FGInterface struct to the JSBsim generic_ struct bool FGJSBsim::copy_to_JSBsim() { - // copy control positions into the JSBsim structure + // copy control positions into the JSBsim structure - FDMExec.GetFCS()->SetDaCmd( controls.get_aileron()); - FDMExec.GetFCS()->SetDeCmd( controls.get_elevator()); - FDMExec.GetFCS()->SetPitchTrimCmd(controls.get_elevator_trim()); - FDMExec.GetFCS()->SetDrCmd( -1*controls.get_rudder()); - FDMExec.GetFCS()->SetDfCmd( controls.get_flaps() ); - FDMExec.GetFCS()->SetDsbCmd( 0.0 ); //speedbrakes - FDMExec.GetFCS()->SetDspCmd( 0.0 ); //spoilers - FDMExec.GetFCS()->SetThrottleCmd( FGControls::ALL_ENGINES, - controls.get_throttle( 0 ) * 100.0 ); + 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 ); - FDMExec.GetFCS()->SetLBrake( controls.get_brake( 0 ) ); - FDMExec.GetFCS()->SetRBrake( controls.get_brake( 1 ) ); - FDMExec.GetFCS()->SetCBrake( controls.get_brake( 2 ) ); + fdmex->GetFCS()->SetLBrake( controls.get_brake( 0 ) ); + fdmex->GetFCS()->SetRBrake( controls.get_brake( 1 ) ); + fdmex->GetFCS()->SetCBrake( controls.get_brake( 2 ) ); - // Inform JSBsim of the local terrain altitude; uncommented 5/3/00 - // FDMExec.GetPosition()->SetRunwayElevation(get_Runway_altitude()); // seems to work - FDMExec.GetPosition()->SetRunwayRadius(scenery.cur_radius*METER_TO_FEET); - FDMExec.GetPosition()->SetSeaLevelRadius(get_Sea_level_radius()); + fdmex->GetPosition()->SetRunwayRadius(scenery.cur_radius*METER_TO_FEET); + fdmex->GetPosition()->SetSeaLevelRadius(get_Sea_level_radius()); - FDMExec.GetAtmosphere()->SetExTemperature(get_Static_temperature()); - FDMExec.GetAtmosphere()->SetExPressure(get_Static_pressure()); - FDMExec.GetAtmosphere()->SetExDensity(get_Density()); - FDMExec.GetAtmosphere()->SetWindNED(get_V_north_airmass(), - get_V_east_airmass(), - get_V_down_airmass()); + 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; + return true; } /******************************************************************************/ @@ -287,116 +300,271 @@ bool FGJSBsim::copy_to_JSBsim() { // Convert from the JSBsim generic_ struct to the FGInterface struct bool FGJSBsim::copy_from_JSBsim() { - - set_Inertias( FDMExec.GetAircraft()->GetMass(), - FDMExec.GetAircraft()->GetIxx(), - FDMExec.GetAircraft()->GetIyy(), - FDMExec.GetAircraft()->GetIzz(), - FDMExec.GetAircraft()->GetIxz() ); + unsigned i, j; - set_CG_Position ( FDMExec.GetAircraft()->GetXYZcg()(1), - FDMExec.GetAircraft()->GetXYZcg()(2), - FDMExec.GetAircraft()->GetXYZcg()(3) ); + _set_Inertias( fdmex->GetAircraft()->GetMass(), + fdmex->GetAircraft()->GetIxx(), + fdmex->GetAircraft()->GetIyy(), + fdmex->GetAircraft()->GetIzz(), + fdmex->GetAircraft()->GetIxz() ); - set_Accels_Body ( FDMExec.GetTranslation()->GetUVWdot()(1), - FDMExec.GetTranslation()->GetUVWdot()(2), - FDMExec.GetTranslation()->GetUVWdot()(3) ); + _set_CG_Position( fdmex->GetAircraft()->GetXYZcg()(1), + fdmex->GetAircraft()->GetXYZcg()(2), + fdmex->GetAircraft()->GetXYZcg()(3) ); - set_Accels_CG_Body ( FDMExec.GetTranslation()->GetUVWdot()(1), - FDMExec.GetTranslation()->GetUVWdot()(2), - FDMExec.GetTranslation()->GetUVWdot()(3) ); + _set_Accels_Body( fdmex->GetTranslation()->GetUVWdot()(1), + fdmex->GetTranslation()->GetUVWdot()(2), + fdmex->GetTranslation()->GetUVWdot()(3) ); - //set_Accels_CG_Body_N ( FDMExec.GetTranslation()->GetNcg()(1), - // FDMExec.GetTranslation()->GetNcg()(2), - // FDMExec.GetTranslation()->GetNcg()(3) ); - // - set_Accels_Pilot_Body( FDMExec.GetAuxiliary()->GetPilotAccel()(1), - FDMExec.GetAuxiliary()->GetPilotAccel()(2), - FDMExec.GetAuxiliary()->GetPilotAccel()(3) ); + _set_Accels_CG_Body( fdmex->GetTranslation()->GetUVWdot()(1), + fdmex->GetTranslation()->GetUVWdot()(2), + fdmex->GetTranslation()->GetUVWdot()(3) ); - //set_Accels_Pilot_Body_N( FDMExec.GetAuxiliary()->GetNpilot()(1), - // FDMExec.GetAuxiliary()->GetNpilot()(2), - // FDMExec.GetAuxiliary()->GetNpilot()(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( FDMExec.GetAircraft()->GetNlf()); + _set_Nlf( fdmex->GetAircraft()->GetNlf() ); + // Velocities + + _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) ); - - // Velocities + _set_V_equiv_kts( fdmex->GetAuxiliary()->GetVequivalentKTS() ); - set_Velocities_Local( FDMExec.GetPosition()->GetVn(), - FDMExec.GetPosition()->GetVe(), - FDMExec.GetPosition()->GetVd() ); + // _set_V_calibrated( fdmex->GetAuxiliary()->GetVcalibratedFPS() ); - set_Velocities_Wind_Body( FDMExec.GetTranslation()->GetUVW()(1), - FDMExec.GetTranslation()->GetUVW()(2), - FDMExec.GetTranslation()->GetUVW()(3) ); + _set_V_calibrated_kts( fdmex->GetAuxiliary()->GetVcalibratedKTS() ); - set_V_equiv_kts( FDMExec.GetAuxiliary()->GetVequivalentKTS() ); + _set_V_ground_speed( fdmex->GetPosition()->GetVground() ); - //set_V_calibrated( FDMExec.GetAuxiliary()->GetVcalibratedFPS() ); + _set_Omega_Body( fdmex->GetRotation()->GetPQR()(1), + fdmex->GetRotation()->GetPQR()(2), + fdmex->GetRotation()->GetPQR()(3) ); - set_V_calibrated_kts( FDMExec.GetAuxiliary()->GetVcalibratedKTS() ); + _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 = fdmex->GetPosition()->GetLatitude(); + double lon = fdmex->GetPosition()->GetLongitude(); + double alt = fdmex->GetPosition()->Geth(); + double lat_geod, tmp_alt, sl_radius1, sl_radius2, tmp_lat_geoc; + + sgGeocToGeod( lat_geoc, EQUATORIAL_RADIUS_M + alt * FEET_TO_METER, + &lat_geod, &tmp_alt, &sl_radius1 ); + sgGeodToGeoc( 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 ); + + _set_Geocentric_Position( lat_geoc, lon, sl_radius2 * METER_TO_FEET + alt ); - set_V_ground_speed ( FDMExec.GetPosition()->GetVground() ); - - set_Omega_Body( FDMExec.GetState()->GetParameter(FG_ROLLRATE), - FDMExec.GetState()->GetParameter(FG_PITCHRATE), - FDMExec.GetState()->GetParameter(FG_YAWRATE) ); - - set_Euler_Rates( FDMExec.GetRotation()->GetEulerRates()(2), - FDMExec.GetRotation()->GetEulerRates()(1), - FDMExec.GetRotation()->GetEulerRates()(3)); - - // ***FIXME*** set_Geocentric_Rates( Latitude_dot, Longitude_dot, - // Radius_dot ); - - set_Mach_number( FDMExec.GetTranslation()->GetMach()); - - // Positions - - double lat_geoc = FDMExec.GetPosition()->GetLatitude(); - double lon = FDMExec.GetPosition()->GetLongitude(); - double alt = FDMExec.GetPosition()->Geth(); - double lat_geod, tmp_alt, sl_radius1, sl_radius2, tmp_lat_geoc; - - sgGeocToGeod( lat_geoc, EQUATORIAL_RADIUS_M + alt * FEET_TO_METER, - &lat_geod, &tmp_alt, &sl_radius1 ); - sgGeodToGeoc( 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 ); - - set_Geocentric_Position( lat_geoc, lon, - sl_radius2 * METER_TO_FEET + alt ); - set_Geodetic_Position( lat_geod, lon, alt ); - set_Euler_Angles( FDMExec.GetRotation()->Getphi(), - FDMExec.GetRotation()->Gettht(), - FDMExec.GetRotation()->Getpsi() ); - - set_Alpha( FDMExec.GetTranslation()->Getalpha() ); - set_Beta( FDMExec.GetTranslation()->Getbeta() ); - - set_Gamma_vert_rad( FDMExec.GetPosition()->GetGamma() ); - // set_Gamma_horiz_rad( Gamma_horiz_rad ); - - /* **FIXME*** */ set_Sea_level_radius( sl_radius2 * METER_TO_FEET ); - /* **FIXME*** */ set_Earth_position_angle( 0.0 ); - - // /* ***FIXME*** */ set_Runway_altitude( 0.0 ); - - set_sin_lat_geocentric( lat_geoc ); - set_cos_lat_geocentric( lat_geoc ); - set_sin_cos_longitude( lon ); - set_sin_cos_latitude( lat_geod ); + _set_Geodetic_Position( lat_geod, lon, alt ); - set_Climb_Rate(FDMExec.GetPosition()->Gethdot()); + _set_Euler_Angles( fdmex->GetRotation()->Getphi(), + fdmex->GetRotation()->Gettht(), + fdmex->GetRotation()->Getpsi() ); - return true; + _set_Alpha( fdmex->GetTranslation()->Getalpha() ); + _set_Beta( fdmex->GetTranslation()->Getbeta() ); + + _set_Gamma_vert_rad( fdmex->GetPosition()->GetGamma() ); + // set_Gamma_horiz_rad( Gamma_horiz_rad ); + + /* **FIXME*** */ _set_Sea_level_radius( sl_radius2 * METER_TO_FEET ); + /* **FIXME*** */ _set_Earth_position_angle( fdmex->GetAuxiliary()-> + GetEarthPositionAngle() ); + + /* ***FIXME*** */ _set_Runway_altitude( scenery.cur_radius * METERS_TO_FEET - + get_Sea_level_radius() ); + + _set_sin_lat_geocentric( lat_geoc ); + _set_cos_lat_geocentric( lat_geoc ); + + _set_sin_cos_longitude( lon ); + + _set_sin_cos_latitude( lat_geod ); + + _set_Climb_Rate( fdmex->GetPosition()->Gethdot() ); + + for ( i = 0; i < 3; i++ ) { + for ( j = 0; j < 3; j++ ) { + _set_T_Local_to_Body( i, j, fdmex->GetState()->GetTl2b()(i,j) ); + } + } + + return true; } +//Positions +void FGJSBsim::set_Latitude(double lat) { + FG_LOG(FG_FLIGHT,FG_INFO,"FGJSBsim::set_Latitude: " << lat); + fgic->SetLatitudeRadIC(lat); + 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); + fgic->SetLongitudeRadIC(lon); + fdmex->RunIC(fgic); //loop JSBSim once + copy_from_JSBsim(); //update the bus + needTrim=true; +} + +void FGJSBsim::set_Altitude(double alt) { + FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Altitude: " << alt ); + 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 ); + 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 ); + 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 ); + fgic->SetVnorthFpsIC(north); + fgic->SetVeastFpsIC(east); + fgic->SetVdownFpsIC(down); + fdmex->RunIC(fgic); //loop JSBSim once + cout << "fdmex->GetTranslation()->GetVt(): " << fdmex->GetTranslation()->GetVt() << endl; + cout << "fdmex->GetPosition()->GetVn(): " << fdmex->GetPosition()->GetVn() << endl; + + copy_from_JSBsim(); //update the bus + busdump(); + 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 ); + + 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 ); + 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 ); + 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 ); + 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 ); + 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 ); + _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 ); + 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 ); + 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 ); + 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 ); + fdmex->GetAtmosphere()->SetWindNED(wnorth, weast, wdown ); + if(fdmex->GetAtmosphere()->External() == true) + needTrim=true; +} diff --git a/src/FDM/JSBSim.hxx b/src/FDM/JSBSim.hxx index 0091e4623..66ca44dc4 100644 --- a/src/FDM/JSBSim.hxx +++ b/src/FDM/JSBSim.hxx @@ -25,6 +25,7 @@ #define _JSBSIM_HXX #include <FDM/JSBSim/FGFDMExec.h> +#include <FDM/JSBSim/FGInitialCondition.h> #undef MAX_ENGINES #include <Aircraft/aircraft.hxx> @@ -34,13 +35,19 @@ class FGJSBsim: public FGInterface { // The aircraft for this instance - FGFDMExec FDMExec; + FGFDMExec *fdmex; + FGInitialCondition *fgic; + bool needTrim; + bool trimmed; float trim_elev; float trim_throttle; public: + FGJSBsim::FGJSBsim(void); + FGJSBsim::~FGJSBsim(); + // copy FDM state to LaRCsim structures bool copy_to_JSBsim(); @@ -49,6 +56,37 @@ public: // reset flight params to a specific position bool init( double dt ); + + // Positions + void set_Latitude(double lat); // geocentric + void set_Longitude(double lon); + void set_Altitude(double alt); // triggers re-calc of AGL altitude + //void set_AltitudeAGL(double altagl); // and vice-versa + + // Speeds -- setting any of these will trigger a re-calc of the rest + void set_V_calibrated_kts(double vc); + void set_Mach_number(double mach); + void set_Velocities_Local( double north, double east, double down ); + void set_Velocities_Wind_Body( double u, double v, double w); + + // Euler angles + void set_Euler_Angles( double phi, double theta, double psi ); + + // Flight Path + void set_Climb_Rate( double roc); + void set_Gamma_vert_rad( double gamma); + + // Earth + void set_Sea_level_radius(double slr); + void set_Runway_altitude(double ralt); + + // Atmosphere + void set_Static_pressure(double p); + void set_Static_temperature(double T); + void set_Density(double rho); + void set_Velocities_Local_Airmass (double wnorth, + double weast, + double wdown ); // update position based on inputs, positions, velocities, etc. bool update( int multiloop ); diff --git a/src/FDM/JSBSim/FGAtmosphere.h b/src/FDM/JSBSim/FGAtmosphere.h index 678c1761e..964c0a5dd 100644 --- a/src/FDM/JSBSim/FGAtmosphere.h +++ b/src/FDM/JSBSim/FGAtmosphere.h @@ -82,6 +82,7 @@ public: inline void UseExternal(void) { useExternal=true; } inline void UseInternal(void) { useExternal=false; } //this is the default + bool External(void) { return useExternal; } inline void SetExTemperature(float t) { exTemperature=t; } inline void SetExDensity(float d) { exDensity=d; } diff --git a/src/FDM/JSBSim/FGDefs.h b/src/FDM/JSBSim/FGDefs.h index 56ca313bf..5379593af 100644 --- a/src/FDM/JSBSim/FGDefs.h +++ b/src/FDM/JSBSim/FGDefs.h @@ -46,7 +46,6 @@ SENTRY #define ECCENTSQRD 0.99330561 #define INVECCENTSQRD 1.0067395 #define INVECCENTSQRDM1 0.0067395 -#define EPS 0.081819221 #define Reng 1716 //Specific Gas Constant,ft^2/(sec^2*R) #define SHRATIO 1.4 //Specific Heat Ratio #define RADTODEG 57.29578 diff --git a/src/FDM/JSBSim/FGInitialCondition.cpp b/src/FDM/JSBSim/FGInitialCondition.cpp index a792b4c60..284cddb23 100644 --- a/src/FDM/JSBSim/FGInitialCondition.cpp +++ b/src/FDM/JSBSim/FGInitialCondition.cpp @@ -58,6 +58,7 @@ INCLUDES static const char *IdSrc = "$Header$"; static const char *IdHdr = ID_INITIALCONDITION; + FGInitialCondition::FGInitialCondition(FGFDMExec *FDMExec) { vt=vc=ve=0; mach=0; @@ -68,6 +69,9 @@ FGInitialCondition::FGInitialCondition(FGFDMExec *FDMExec) { u=v=w=0; vnorth=veast=vdown=0; lastSpeedSet=setvt; + sea_level_radius = EARTHRAD; + radius_to_vehicle = EARTHRAD; + terrain_altitude = 0; if(FDMExec != NULL ) { fdmex=FDMExec; fdmex->GetPosition()->Seth(altitude); @@ -84,13 +88,13 @@ FGInitialCondition::~FGInitialCondition(void) {} void FGInitialCondition::SetVcalibratedKtsIC(float tt) { - if(getMachFromVcas(&mach,tt*KTSTOFPS)) { + if(getMachFromVcas(&mach,tt*jsbKTSTOFPS)) { //cout << "Mach: " << mach << endl; lastSpeedSet=setvc; - vc=tt*KTSTOFPS; + vc=tt*jsbKTSTOFPS; vt=mach*fdmex->GetAtmosphere()->GetSoundSpeed(); ve=vt*sqrt(fdmex->GetAtmosphere()->GetDensityRatio()); - //cout << "Vt: " << vt*FPSTOKTS << " Vc: " << vc*FPSTOKTS << endl; + //cout << "Vt: " << vt*jsbFPSTOKTS << " Vc: " << vc*jsbFPSTOKTS << endl; } else { cout << "Failed to get Mach number for given Vc and altitude, Vc unchanged." << endl; @@ -99,7 +103,7 @@ void FGInitialCondition::SetVcalibratedKtsIC(float tt) { } void FGInitialCondition::SetVequivalentKtsIC(float tt) { - ve=tt*KTSTOFPS; + ve=tt*jsbKTSTOFPS; lastSpeedSet=setve; vt=ve*1/sqrt(fdmex->GetAtmosphere()->GetDensityRatio()); mach=vt/fdmex->GetAtmosphere()->GetSoundSpeed(); @@ -107,7 +111,7 @@ void FGInitialCondition::SetVequivalentKtsIC(float tt) { } void FGInitialCondition::SetVtrueKtsIC(float tt) { - vt=tt*KTSTOFPS; + vt=tt*jsbKTSTOFPS; lastSpeedSet=setvt; mach=vt/fdmex->GetAtmosphere()->GetSoundSpeed(); vc=calcVcas(mach); @@ -120,7 +124,7 @@ void FGInitialCondition::SetMachIC(float tt) { vt=mach*fdmex->GetAtmosphere()->GetSoundSpeed(); vc=calcVcas(mach); ve=vt*sqrt(fdmex->GetAtmosphere()->GetDensityRatio()); - //cout << "Vt: " << vt*FPSTOKTS << " Vc: " << vc*FPSTOKTS << endl; + //cout << "Vt: " << vt*jsbFPSTOKTS << " Vc: " << vc*jsbFPSTOKTS << endl; } void FGInitialCondition::SetClimbRateFpmIC(float tt) { @@ -145,20 +149,20 @@ void FGInitialCondition::SetFlightPathAngleRadIC(float tt) { void FGInitialCondition::SetUBodyFpsIC(float tt) { u=tt; vt=sqrt(u*u+v*v+w*w); - lastSpeedSet=setvt; + lastSpeedSet=setuvw; } void FGInitialCondition::SetVBodyFpsIC(float tt) { v=tt; vt=sqrt(u*u+v*v+w*w); - lastSpeedSet=setvt; + lastSpeedSet=setuvw; } void FGInitialCondition::SetWBodyFpsIC(float tt) { w=tt; vt=sqrt(u*u+v*v+w*w); - lastSpeedSet=setvt; + lastSpeedSet=setuvw; } @@ -170,14 +174,16 @@ void FGInitialCondition::SetAltitudeFtIC(float tt) { //lets try to make sure the user gets what they intended switch(lastSpeedSet) { + case setned: + case setuvw: case setvt: - SetVtrueKtsIC(vt*FPSTOKTS); + SetVtrueKtsIC(vt*jsbFPSTOKTS); break; case setvc: - SetVcalibratedKtsIC(vc*FPSTOKTS); + SetVcalibratedKtsIC(vc*jsbFPSTOKTS); break; case setve: - SetVequivalentKtsIC(ve*FPSTOKTS); + SetVequivalentKtsIC(ve*jsbFPSTOKTS); break; case setmach: SetMachIC(mach); @@ -190,6 +196,15 @@ void FGInitialCondition::SetAltitudeAGLFtIC(float tt) { altitude=fdmex->GetPosition()->Geth(); SetAltitudeFtIC(altitude); } +void FGInitialCondition::SetSeaLevelRadiusFtIC(double tt) { + sea_level_radius = tt; +} + +void FGInitialCondition::SetTerrainAltitudeFtIC(double tt) { + terrain_altitude=tt; + fdmex->GetPosition()->SetDistanceAGL(altitude-terrain_altitude); + fdmex->GetPosition()->SetRunwayRadius(sea_level_radius + terrain_altitude); +} void FGInitialCondition::calcUVWfromNED(void) { u=vnorth*cos(theta)*cos(psi) + @@ -207,14 +222,14 @@ void FGInitialCondition::SetVnorthFpsIC(float tt) { vnorth=tt; calcUVWfromNED(); vt=sqrt(u*u + v*v + w*w); - lastSpeedSet=setvt; + lastSpeedSet=setned; } void FGInitialCondition::SetVeastFpsIC(float tt) { veast=tt; calcUVWfromNED(); vt=sqrt(u*u + v*v + w*w); - lastSpeedSet=setvt; + lastSpeedSet=setned; } void FGInitialCondition::SetVdownFpsIC(float tt) { @@ -222,7 +237,7 @@ void FGInitialCondition::SetVdownFpsIC(float tt) { calcUVWfromNED(); vt=sqrt(u*u + v*v + w*w); SetClimbRateFpsIC(-1*vdown); - lastSpeedSet=setvt; + lastSpeedSet=setned; } bool FGInitialCondition::getMachFromVcas(float *Mach,float vcas) { @@ -324,7 +339,7 @@ float FGInitialCondition::calcVcas(float Mach) { A = pow(((pt-p)/psl+1),0.28571); vcas = sqrt(7*psl/rhosl*(A-1)); - //cout << "calcVcas: vcas= " << vcas*FPSTOKTS << " mach= " << Mach << " pressure: " << pt << endl; + //cout << "calcVcas: vcas= " << vcas*jsbFPSTOKTS << " mach= " << Mach << " pressure: " << pt << endl; return vcas; } @@ -412,6 +427,6 @@ bool FGInitialCondition::solve(float *y,float x) { *y=x2; } - //cout << "Success= " << success << " Vcas: " << vcas*FPSTOKTS << " Mach: " << x2 << endl; + //cout << "Success= " << success << " Vcas: " << vcas*jsbFPSTOKTS << " Mach: " << x2 << endl; return success; } diff --git a/src/FDM/JSBSim/FGInitialCondition.h b/src/FDM/JSBSim/FGInitialCondition.h index 00f195c5b..7303bbad1 100644 --- a/src/FDM/JSBSim/FGInitialCondition.h +++ b/src/FDM/JSBSim/FGInitialCondition.h @@ -59,7 +59,10 @@ INCLUDES CLASS DECLARATION *******************************************************************************/ -typedef enum { setvt, setvc, setve, setmach } speedset; +typedef enum { setvt, setvc, setve, setmach, setuvw, setned } speedset; + +#define jsbFPSTOKTS 0.5924838 +#define jsbKTSTOFPS 1.6878099 /* USAGE NOTES @@ -105,12 +108,13 @@ typedef enum { setvt, setvc, setve, setmach } speedset; considered equivalent to setting gamma. */ - class FGInitialCondition { public: FGInitialCondition(FGFDMExec *fdmex); ~FGInitialCondition(void); + + inline speedset GetSpeedSet(void) { return lastSpeedSet; } void SetVcalibratedKtsIC(float tt); void SetVequivalentKtsIC(float tt); @@ -127,7 +131,10 @@ public: void SetAltitudeFtIC(float tt); void SetAltitudeAGLFtIC(float tt); - + + void SetSeaLevelRadiusFtIC(double tt); + void SetTerrainAltitudeFtIC(double tt); + //"vertical" flight path, recalculate theta inline void SetFlightPathAngleDegIC(float tt) { SetFlightPathAngleRadIC(tt*DEGTORAD); } void SetFlightPathAngleRadIC(float tt); @@ -147,8 +154,8 @@ public: inline void SetRollAngleDegIC(float tt) { phi=tt*DEGTORAD; getTheta(); } inline void SetRollAngleRadIC(float tt) { phi=tt; getTheta(); } - inline void SetHeadingDegIC(float tt) { psi=tt*DEGTORAD; } - inline void SetHeadingRadIC(float tt) { psi=tt; } + inline void SetTrueHeadingDegIC(float tt) { psi=tt*DEGTORAD; } + inline void SetTrueHeadingRadIC(float tt) { psi=tt; } inline void SetLatitudeDegIC(float tt) { latitude=tt*DEGTORAD; } inline void SetLatitudeRadIC(float tt) { latitude=tt; } @@ -156,9 +163,9 @@ public: inline void SetLongitudeDegIC(float tt) { longitude=tt*DEGTORAD; } inline void SetLongitudeRadIC(float tt) { longitude=tt; } - inline float GetVcalibratedKtsIC(void) { return vc*FPSTOKTS; } - inline float GetVequivalentKtsIC(void) { return ve*FPSTOKTS; } - inline float GetVtrueKtsIC(void) { return vt*FPSTOKTS; } + inline float GetVcalibratedKtsIC(void) { return vc*jsbFPSTOKTS; } + inline float GetVequivalentKtsIC(void) { return ve*jsbFPSTOKTS; } + inline float GetVtrueKtsIC(void) { return vt*jsbFPSTOKTS; } inline float GetVtrueFpsIC(void) { return vt; } inline float GetMachIC(void) { return mach; } @@ -210,6 +217,9 @@ private: float latitude,longitude; float u,v,w; float vnorth,veast,vdown; + double sea_level_radius; + double terrain_altitude; + double radius_to_vehicle; float xlo, xhi,xmin,xmax; diff --git a/src/FDM/JSBSim/JSBSim.cpp b/src/FDM/JSBSim/JSBSim.cpp index 43850a69c..a41a51e27 100644 --- a/src/FDM/JSBSim/JSBSim.cpp +++ b/src/FDM/JSBSim/JSBSim.cpp @@ -101,6 +101,7 @@ USEUNIT("FGAerodynamics.cpp"); #include "FGPosition.h" #include "FGAuxiliary.h" #include "FGOutput.h" +#include "FGInitialCondition.h" #ifdef FGFS #include <simgear/compiler.h> @@ -131,17 +132,38 @@ int main(int argc, char** argv) FDMExec = new FGFDMExec(); - result = FDMExec->LoadModel("aircraft", "engine", string(argv[1])); + result = FDMExec->LoadModel("/home/tony/FlightGear/Aircraft", + "/home/tony/FlightGear/Engine", + string(argv[1])); if (!result) { cerr << "Aircraft file " << argv[1] << " was not found" << endl; exit(-1); } - if ( ! FDMExec->GetState()->Reset("aircraft", string(argv[1]), string(argv[2]))) + if ( ! FDMExec->GetState()->Reset("/home/tony/FlightGear/Aircraft", + string(argv[1]), string(argv[2]))) FDMExec->GetState()->Initialize(2000,0,0,0,0,0,0.5,0.5,40000); - - float cmd = 0.0; + + FGInitialCondition *fgic= new FGInitialCondition(FDMExec); + fgic->SetUBodyFpsIC(170); + fgic->SetTrueHeadingDegIC(275); + FDMExec->RunIC(fgic); + cout << "FDMExec->GetTranslation()->GetVt(): " << FDMExec->GetTranslation()->GetVt() << endl; + cout << "FDMExec->GetPosition()->GetVn(): " << FDMExec->GetPosition()->GetVn() << endl; + cout << "FDMExec->GetPosition()->GetVe(): " << FDMExec->GetPosition()->GetVe() << endl; + cout << "FDMExec->GetAuxiliary()->GetVcalibratedKTS(): " << FDMExec->GetAuxiliary()->GetVcalibratedKTS() << endl; + fgic->SetVnorthFpsIC(170); + cout << "fgic->GetUBodyFpsIC(): " << fgic->GetUBodyFpsIC() << endl; + cout << "fgic->GetVBodyFpsIC(): " << fgic->GetVBodyFpsIC() << endl; + cout << "fgic->GetWBodyFpsIC(): " << fgic->GetWBodyFpsIC() << endl; + FDMExec->RunIC(fgic); + cout << "FDMExec->GetTranslation()->GetVt(): " << FDMExec->GetTranslation()->GetVt() << endl; + cout << "FDMExec->GetPosition()->GetVn(): " << FDMExec->GetPosition()->GetVn() << endl; + cout << "FDMExec->GetPosition()->GetVe(): " << FDMExec->GetPosition()->GetVe() << endl; + cout << "FDMExec->GetAuxiliary()->GetVcalibratedKTS(): " << FDMExec->GetAuxiliary()->GetVcalibratedKTS() << endl; + + /* float cmd = 0.0; while (FDMExec->GetState()->Getsim_time() <= 10.0) { @@ -166,6 +188,7 @@ int main(int argc, char** argv) FDMExec->Run(); } + */ delete FDMExec; diff --git a/src/FDM/LaRCsim.cxx b/src/FDM/LaRCsim.cxx index 86c17b6c8..e3134d337 100644 --- a/src/FDM/LaRCsim.cxx +++ b/src/FDM/LaRCsim.cxx @@ -24,33 +24,56 @@ #include <simgear/constants.h> #include <simgear/debug/logstream.hxx> +#include <Scenery/scenery.hxx> + #include <Aircraft/aircraft.hxx> #include <Controls/controls.hxx> #include <FDM/flight.hxx> #include <FDM/LaRCsim/ls_cockpit.h> #include <FDM/LaRCsim/ls_generic.h> #include <FDM/LaRCsim/ls_interface.h> +#include <FDM/LaRCsimIC.hxx> #include "IO360.hxx" #include "LaRCsim.hxx" +FGLaRCsim::FGLaRCsim(void) { + ls_toplevel_init( 0.0, (char *)globals->get_options()->get_aircraft().c_str() ); + lsic=new LaRCsimIC; //this needs to be brought up after LaRCsim is + copy_to_LaRCsim(); // initialize all of LaRCsim's vars + //this should go away someday -- formerly done in fg_init.cxx + Mass = 8.547270E+01; + I_xx = 1.048000E+03; + I_yy = 3.000000E+03; + I_zz = 3.530000E+03; + I_xz = 0.000000E+00; + + + +} + +FGLaRCsim::~FGLaRCsim(void) { + if(lsic != NULL) { + delete lsic; + } +} // Initialize the LaRCsim flight model, dt is the time increment for // each subsequent iteration through the EOM bool FGLaRCsim::init( double dt ) { + + ls_set_model_dt(dt); + // Initialize our little engine that hopefully might + eng.init(dt); + // dcl - in passing dt to init rather than update I am assuming + // that the LaRCsim dt is fixed at one value (yes it is 120hz CLO) - if ( globals->get_options()->get_aircraft() == "c172" ) { - // Initialize our little engine that hopefully might - eng.init(dt); - // dcl - in passing dt to init rather than update I am assuming - // that the LaRCsim dt is fixed at one value (yes it is 120hz CLO) + // update the engines interface + FGEngInterface e; + add_engine( e ); + - // update the engines interface - FGEngInterface e; - add_engine( e ); - } - - // cout << "FGLaRCsim::init()" << endl; + // FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::init()" ); double save_alt = 0.0; @@ -63,7 +86,8 @@ bool FGLaRCsim::init( double dt ) { copy_to_LaRCsim(); // actual LaRCsim top level init - ls_toplevel_init( dt, (char *)globals->get_options()->get_aircraft().c_str() ); + // ls_toplevel_init( dt, (char *)globals->get_options()->get_aircraft().c_str() ); + FG_LOG( FG_FLIGHT, FG_INFO, "FG pos = " << get_Latitude() ); @@ -85,7 +109,6 @@ bool FGLaRCsim::init( double dt ) { // Run an iteration of the EOM (equations of motion) bool FGLaRCsim::update( int multiloop ) { - // cout << "FGLaRCsim::update()" << endl; if ( globals->get_options()->get_aircraft() == "c172" ) { // set control inputs @@ -114,24 +137,20 @@ bool FGLaRCsim::update( int multiloop ) { e->set_prop_thrust( eng.get_prop_thrust_SI() ); #if 0 - cout << "Throttle = " << controls.get_throttle( 0 ) * 100.0; - cout << " Mixture = " << controls.get_mixture( 0 ) * 100.0; - cout << " RPM = " << eng.get_RPM(); - cout << " MP = " << eng.get_Manifold_Pressure(); - cout << " HP = " << ( eng.get_MaxHP() * eng.get_Percentage_Power() - / 100.0 ); - cout << " EGT = " << eng.get_EGT(); - cout << " Thrust (N) " << eng.get_prop_thrust_SI(); // Thrust in Newtons - cout << '\n'; + FG_LOG( FG_FLIGHT, FG_INFO, "Throttle = " << controls.get_throttle( 0 ) * 100.0); + FG_LOG( FG_FLIGHT, FG_INFO, " Mixture = " << 80); + FG_LOG( FG_FLIGHT, FG_INFO, " RPM = " << eng.get_RPM()); + FG_LOG( FG_FLIGHT, FG_INFO, " MP = " << eng.get_Manifold_Pressure()); + FG_LOG( FG_FLIGHT, FG_INFO, " HP = " << ( eng.get_MaxHP() * eng.get_Percentage_Power()/ 100.0) ); + FG_LOG( FG_FLIGHT, FG_INFO, " EGT = " << eng.get_EGT()); + FG_LOG( FG_FLIGHT, FG_INFO, " Thrust (N) " << eng.get_prop_thrust_SI()); // Thrust in Newtons + FG_LOG( FG_FLIGHT, FG_INFO, '\n'); #endif - + // Hmm .. Newtons to lbs is 0.2248 ... F_X_engine = eng.get_prop_thrust_SI() * 0.07; } double save_alt = 0.0; - double time_step = (1.0 / globals->get_options()->get_model_hz()) - * multiloop; - double start_elev = get_Altitude(); // lets try to avoid really screwing up the LaRCsim model if ( get_Altitude() < -9000.0 ) { @@ -155,16 +174,19 @@ bool FGLaRCsim::update( int multiloop ) { } Throttle_pct = controls.get_throttle( 0 ) * 1.0; + Brake_pct[0] = controls.get_brake( 1 ); Brake_pct[1] = controls.get_brake( 0 ); // Inform LaRCsim of the local terrain altitude - Runway_altitude = get_Runway_altitude(); + // Runway_altitude = get_Runway_altitude(); + Runway_altitude = scenery.cur_elev * METER_TO_FEET; // Weather - V_north_airmass = get_V_north_airmass(); + /* V_north_airmass = get_V_north_airmass(); V_east_airmass = get_V_east_airmass(); - V_down_airmass = get_V_down_airmass(); + V_down_airmass = get_V_down_airmass(); */ + // old -- FGInterface_2_LaRCsim() not needed except for Init() // translate FG to LaRCsim structure @@ -175,6 +197,11 @@ bool FGLaRCsim::update( int multiloop ) { ls_update(multiloop); + if(isnan(Phi)) { + busdump(); + exit(1); + } + // printf("%d FG_Altitude = %.2f\n", i, FG_Altitude * 0.3048); // printf("%d Altitude = %.2f\n", i, Altitude * 0.3048); @@ -188,12 +215,6 @@ bool FGLaRCsim::update( int multiloop ) { set_Altitude( save_alt ); } - double end_elev = get_Altitude(); - if ( time_step > 0.0 ) { - // feet per second - set_Climb_Rate( (end_elev - start_elev) / time_step ); - } - return true; } @@ -262,9 +283,9 @@ bool FGLaRCsim::copy_to_LaRCsim () { // P_dot_body = get_P_dot_body(); // Q_dot_body = get_Q_dot_body(); // R_dot_body = get_R_dot_body(); - V_north = get_V_north(); - V_east = get_V_east(); - V_down = get_V_down(); + // V_north = get_V_north(); + // V_east = get_V_east(); + // V_down = get_V_down(); // V_north_rel_ground = get_V_north_rel_ground(); // V_east_rel_ground = get_V_east_rel_ground(); // V_down_rel_ground = get_V_down_rel_ground(); @@ -289,9 +310,9 @@ bool FGLaRCsim::copy_to_LaRCsim () { // V_equiv_kts = get_V_equiv_kts(); // V_calibrated = get_V_calibrated(); // V_calibrated_kts = get_V_calibrated_kts(); - P_body = get_P_body(); - Q_body = get_Q_body(); - R_body = get_R_body(); + // P_body = get_P_body(); + // Q_body = get_Q_body(); + // R_body = get_R_body(); // P_local = get_P_local(); // Q_local = get_Q_local(); // R_local = get_R_local(); @@ -304,15 +325,15 @@ bool FGLaRCsim::copy_to_LaRCsim () { // Latitude_dot = get_Latitude_dot(); // Longitude_dot = get_Longitude_dot(); // Radius_dot = get_Radius_dot(); - Lat_geocentric = get_Lat_geocentric(); - Lon_geocentric = get_Lon_geocentric(); - Radius_to_vehicle = get_Radius_to_vehicle(); - Latitude = get_Latitude(); - Longitude = get_Longitude(); - Altitude = get_Altitude(); - Phi = get_Phi(); - Theta = get_Theta(); - Psi = get_Psi(); + // Lat_geocentric = get_Lat_geocentric(); + // Lon_geocentric = get_Lon_geocentric(); + // Radius_to_vehicle = get_Radius_to_vehicle(); + // Latitude = get_Latitude(); + // Longitude = get_Longitude(); + // Altitude = get_Altitude(); + // Phi = get_Phi(); + // Theta = get_Theta(); + // Psi = get_Psi(); // T_local_to_body_11 = get_T_local_to_body_11(); // T_local_to_body_12 = get_T_local_to_body_12(); // T_local_to_body_13 = get_T_local_to_body_13(); @@ -350,9 +371,9 @@ bool FGLaRCsim::copy_to_LaRCsim () { // Dynamic_pressure = get_Dynamic_pressure(); // Static_temperature = get_Static_temperature(); // Total_temperature = get_Total_temperature(); - Sea_level_radius = get_Sea_level_radius(); - Earth_position_angle = get_Earth_position_angle(); - Runway_altitude = get_Runway_altitude(); + // Sea_level_radius = get_Sea_level_radius(); + // Earth_position_angle = get_Earth_position_angle(); + // Runway_altitude = get_Runway_altitude(); // Runway_latitude = get_Runway_latitude(); // Runway_longitude = get_Runway_longitude(); // Runway_heading = get_Runway_heading(); @@ -378,9 +399,9 @@ bool FGLaRCsim::copy_to_LaRCsim () { bool FGLaRCsim::copy_from_LaRCsim() { // Mass properties and geometry values - set_Inertias( Mass, I_xx, I_yy, I_zz, I_xz ); + _set_Inertias( Mass, I_xx, I_yy, I_zz, I_xz ); // set_Pilot_Location( Dx_pilot, Dy_pilot, Dz_pilot ); - set_CG_Position( Dx_cg, Dy_cg, Dz_cg ); + _set_CG_Position( Dx_cg, Dy_cg, Dz_cg ); // Forces // set_Forces_Body_Total( F_X, F_Y, F_Z ); @@ -397,16 +418,16 @@ bool FGLaRCsim::copy_from_LaRCsim() { // set_Moments_Gear( M_l_gear, M_m_gear, M_n_gear ); // Accelerations - set_Accels_Local( V_dot_north, V_dot_east, V_dot_down ); - set_Accels_Body( U_dot_body, V_dot_body, W_dot_body ); - set_Accels_CG_Body( A_X_cg, A_Y_cg, A_Z_cg ); - set_Accels_Pilot_Body( A_X_pilot, A_Y_pilot, A_Z_pilot ); + _set_Accels_Local( V_dot_north, V_dot_east, V_dot_down ); + _set_Accels_Body( U_dot_body, V_dot_body, W_dot_body ); + _set_Accels_CG_Body( A_X_cg, A_Y_cg, A_Z_cg ); + _set_Accels_Pilot_Body( A_X_pilot, A_Y_pilot, A_Z_pilot ); // set_Accels_CG_Body_N( N_X_cg, N_Y_cg, N_Z_cg ); // set_Accels_Pilot_Body_N( N_X_pilot, N_Y_pilot, N_Z_pilot ); // set_Accels_Omega( P_dot_body, Q_dot_body, R_dot_body ); // Velocities - set_Velocities_Local( V_north, V_east, V_down ); + _set_Velocities_Local( V_north, V_east, V_down ); // set_Velocities_Ground( V_north_rel_ground, V_east_rel_ground, // V_down_rel_ground ); // set_Velocities_Local_Airmass( V_north_airmass, V_east_airmass, @@ -414,26 +435,26 @@ bool FGLaRCsim::copy_from_LaRCsim() { // set_Velocities_Local_Rel_Airmass( V_north_rel_airmass, // V_east_rel_airmass, V_down_rel_airmass ); // set_Velocities_Gust( U_gust, V_gust, W_gust ); - set_Velocities_Wind_Body( U_body, V_body, W_body ); + _set_Velocities_Wind_Body( U_body, V_body, W_body ); // set_V_rel_wind( V_rel_wind ); // set_V_true_kts( V_true_kts ); // set_V_rel_ground( V_rel_ground ); // set_V_inertial( V_inertial ); - set_V_ground_speed( V_ground_speed ); + _set_V_ground_speed( V_ground_speed ); // set_V_equiv( V_equiv ); - set_V_equiv_kts( V_equiv_kts ); + _set_V_equiv_kts( V_equiv_kts ); // set_V_calibrated( V_calibrated ); - set_V_calibrated_kts( V_calibrated_kts ); + _set_V_calibrated_kts( V_calibrated_kts ); - set_Omega_Body( P_body, Q_body, R_body ); + _set_Omega_Body( P_body, Q_body, R_body ); // set_Omega_Local( P_local, Q_local, R_local ); // set_Omega_Total( P_total, Q_total, R_total ); - set_Euler_Rates( Phi_dot, Theta_dot, Psi_dot ); - set_Geocentric_Rates( Latitude_dot, Longitude_dot, Radius_dot ); + _set_Euler_Rates( Phi_dot, Theta_dot, Psi_dot ); + _set_Geocentric_Rates( Latitude_dot, Longitude_dot, Radius_dot ); - set_Mach_number( Mach_number ); + _set_Mach_number( Mach_number ); FG_LOG( FG_FLIGHT, FG_DEBUG, "lon = " << Longitude << " lat_geoc = " << Lat_geocentric << " lat_geod = " << Latitude @@ -449,18 +470,20 @@ bool FGLaRCsim::copy_from_LaRCsim() { while ( tmp_lon > FG_PI ) { tmp_lon -= FG_2PI; } // Positions - set_Geocentric_Position( Lat_geocentric, tmp_lon_geoc, + _set_Geocentric_Position( Lat_geocentric, tmp_lon_geoc, Radius_to_vehicle ); - set_Geodetic_Position( Latitude, tmp_lon, Altitude ); - set_Euler_Angles( Phi, Theta, Psi ); + _set_Geodetic_Position( Latitude, tmp_lon, Altitude ); + _set_Euler_Angles( Phi, Theta, Psi ); + + _set_Altitude_AGL( Altitude-Runway_altitude ); // Miscellaneous quantities - set_T_Local_to_Body(T_local_to_body_m); + _set_T_Local_to_Body(T_local_to_body_m); // set_Gravity( Gravity ); // set_Centrifugal_relief( Centrifugal_relief ); - set_Alpha( Alpha ); - set_Beta( Beta ); + _set_Alpha( Alpha ); + _set_Beta( Beta ); // set_Alpha_dot( Alpha_dot ); // set_Beta_dot( Beta_dot ); @@ -469,33 +492,33 @@ bool FGLaRCsim::copy_from_LaRCsim() { // set_Cos_beta( Cos_beta ); // set_Sin_beta( Sin_beta ); - set_Cos_phi( Cos_phi ); + _set_Cos_phi( Cos_phi ); // set_Sin_phi( Sin_phi ); - set_Cos_theta( Cos_theta ); + _set_Cos_theta( Cos_theta ); // set_Sin_theta( Sin_theta ); // set_Cos_psi( Cos_psi ); // set_Sin_psi( Sin_psi ); - set_Gamma_vert_rad( Gamma_vert_rad ); + _set_Gamma_vert_rad( Gamma_vert_rad ); // set_Gamma_horiz_rad( Gamma_horiz_rad ); // set_Sigma( Sigma ); - set_Density( Density ); + _set_Density( Density ); // set_V_sound( V_sound ); // set_Mach_number( Mach_number ); - set_Static_pressure( Static_pressure ); + _set_Static_pressure( Static_pressure ); // set_Total_pressure( Total_pressure ); // set_Impact_pressure( Impact_pressure ); // set_Dynamic_pressure( Dynamic_pressure ); - set_Static_temperature( Static_temperature ); + _set_Static_temperature( Static_temperature ); // set_Total_temperature( Total_temperature ); - set_Sea_level_radius( Sea_level_radius ); - set_Earth_position_angle( Earth_position_angle ); + _set_Sea_level_radius( Sea_level_radius ); + _set_Earth_position_angle( Earth_position_angle ); - set_Runway_altitude( Runway_altitude ); + _set_Runway_altitude( Runway_altitude ); // set_Runway_latitude( Runway_latitude ); // set_Runway_longitude( Runway_longitude ); // set_Runway_heading( Runway_heading ); @@ -507,10 +530,10 @@ bool FGLaRCsim::copy_from_LaRCsim() { // D_pilot_above_rwy ); // set_Pilot_Rwy_Rwy( X_pilot_rwy, Y_pilot_rwy, H_pilot_rwy ); - set_sin_lat_geocentric(Lat_geocentric); - set_cos_lat_geocentric(Lat_geocentric); - set_sin_cos_longitude(Longitude); - set_sin_cos_latitude(Latitude); + _set_sin_lat_geocentric(Lat_geocentric); + _set_cos_lat_geocentric(Lat_geocentric); + _set_sin_cos_longitude(Longitude); + _set_sin_cos_latitude(Latitude); // printf("sin_lat_geo %f cos_lat_geo %f\n", sin_Lat_geoc, cos_Lat_geoc); // printf("sin_lat %f cos_lat %f\n", @@ -518,5 +541,166 @@ bool FGLaRCsim::copy_from_LaRCsim() { // printf("sin_lon %f cos_lon %f\n", // get_sin_longitude(), get_cos_longitude()); + _set_Climb_Rate( -1 * V_down ); + return true; } + + +void FGLaRCsim::set_ls(void) { + Phi=lsic->GetRollAngleRadIC(); + Theta=lsic->GetPitchAngleRadIC(); + Psi=lsic->GetHeadingRadIC(); + V_north=lsic->GetVnorthFpsIC(); + V_east=lsic->GetVeastFpsIC(); + V_down=lsic->GetVdownFpsIC(); + Altitude=lsic->GetAltitudeFtIC(); + Latitude=lsic->GetLatitudeGDRadIC(); + Longitude=lsic->GetLongitudeRadIC(); + Runway_altitude=lsic->GetRunwayAltitudeFtIC(); + V_north_airmass = lsic->GetVnorthAirmassFpsIC(); + V_east_airmass = lsic->GetVeastAirmassFpsIC(); + V_down_airmass = lsic->GetVdownAirmassFpsIC(); + ls_loop(0.0,-1); + copy_from_LaRCsim(); + FG_LOG( FG_FLIGHT, FG_INFO, " FGLaRCsim::set_ls(): " ); + FG_LOG( FG_FLIGHT, FG_INFO, " Phi: " << Phi ); + FG_LOG( FG_FLIGHT, FG_INFO, " Theta: " << Theta ); + FG_LOG( FG_FLIGHT, FG_INFO, " Psi: " << Psi ); + FG_LOG( FG_FLIGHT, FG_INFO, " V_north: " << V_north ); + FG_LOG( FG_FLIGHT, FG_INFO, " V_east: " << V_east ); + FG_LOG( FG_FLIGHT, FG_INFO, " V_down: " << V_down ); + FG_LOG( FG_FLIGHT, FG_INFO, " Altitude: " << Altitude ); + FG_LOG( FG_FLIGHT, FG_INFO, " Latitude: " << Latitude ); + FG_LOG( FG_FLIGHT, FG_INFO, " Longitude: " << Longitude ); + FG_LOG( FG_FLIGHT, FG_INFO, " Runway_altitude: " << Runway_altitude ); + FG_LOG( FG_FLIGHT, FG_INFO, " V_north_airmass: " << V_north_airmass ); + FG_LOG( FG_FLIGHT, FG_INFO, " V_east_airmass: " << V_east_airmass ); + FG_LOG( FG_FLIGHT, FG_INFO, " V_down_airmass: " << V_down_airmass ); +} + + //Positions +void FGLaRCsim::set_Latitude(double lat) { + FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Latitude: " << lat ); + lsic->SetLatitudeGDRadIC(lat); + set_ls(); + copy_from_LaRCsim(); //update the bus +} + +void FGLaRCsim::set_Longitude(double lon) { + FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Longitude: " << lon ); + lsic->SetLongitudeRadIC(lon); + set_ls(); + copy_from_LaRCsim(); //update the bus +} + +void FGLaRCsim::set_Altitude(double alt) { + FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Altitude: " << alt ); + lsic->SetAltitudeFtIC(alt); + set_ls(); + copy_from_LaRCsim(); //update the bus +} + +void FGLaRCsim::set_V_calibrated_kts(double vc) { + FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_V_calibrated_kts: " << vc ); + lsic->SetVcalibratedKtsIC(vc); + set_ls(); + copy_from_LaRCsim(); //update the bus +} + +void FGLaRCsim::set_Mach_number(double mach) { + FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Mach_number: " << mach ); + lsic->SetMachIC(mach); + set_ls(); + copy_from_LaRCsim(); //update the bus +} + +void FGLaRCsim::set_Velocities_Local( double north, double east, double down ){ + FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Velocities_local: " + << north << " " << east << " " << down ); + lsic->SetVnorthFpsIC(north); + lsic->SetVeastFpsIC(east); + lsic->SetVdownFpsIC(down); + set_ls(); + copy_from_LaRCsim(); //update the bus +} + +void FGLaRCsim::set_Velocities_Wind_Body( double u, double v, double w){ + FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Velocities_Wind_Body: " + << u << " " << v << " " << w ); + + lsic->SetUBodyFpsIC(u); + lsic->SetVBodyFpsIC(v); + lsic->SetWBodyFpsIC(w); + set_ls(); + copy_from_LaRCsim(); //update the bus +} + +//Euler angles +void FGLaRCsim::set_Euler_Angles( double phi, double theta, double psi ) { + FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Euler_angles: " + << phi << " " << theta << " " << psi ); + + lsic->SetPitchAngleRadIC(theta); + lsic->SetRollAngleRadIC(phi); + lsic->SetHeadingRadIC(psi); + set_ls(); + copy_from_LaRCsim(); //update the bus +} + +//Flight Path +void FGLaRCsim::set_Climb_Rate( double roc) { + FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Climb_rate: " << roc ); + lsic->SetClimbRateFpsIC(roc); + set_ls(); + copy_from_LaRCsim(); //update the bus +} + +void FGLaRCsim::set_Gamma_vert_rad( double gamma) { + FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Gamma_vert_rad: " << gamma ); + lsic->SetFlightPathAngleRadIC(gamma); + set_ls(); + copy_from_LaRCsim(); //update the bus +} + +void FGLaRCsim::set_Runway_altitude(double ralt) { + FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Runway_altitude: " << ralt ); + lsic->SetRunwayAltitudeFtIC(ralt); + set_ls(); + copy_from_LaRCsim(); //update the bus +} + +void FGLaRCsim::set_AltitudeAGL(double altagl) { + FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_AltitudeAGL: " << altagl ); + lsic->SetAltitudeAGLFtIC(altagl); + set_ls(); + copy_from_LaRCsim(); +} + +void FGLaRCsim::set_Velocities_Local_Airmass (double wnorth, + double weast, + double wdown ) { + FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Velocities_Local_Airmass: " + << wnorth << " " << weast << " " << wdown ); + _set_Velocities_Local_Airmass( wnorth, weast, wdown ); + set_ls(); + copy_from_LaRCsim(); +} + +void FGLaRCsim::set_Static_pressure(double p) { + FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Static_pressure: " << p ); + FG_LOG( FG_FLIGHT, FG_INFO, "LaRCsim does not support externally supplied atmospheric data" ); +} + +void FGLaRCsim::set_Static_temperature(double T) { + FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Static_temperature: " << T ); + FG_LOG( FG_FLIGHT, FG_INFO, "LaRCsim does not support externally supplied atmospheric data" ); + +} + +void FGLaRCsim::set_Density(double rho) { + FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Density: " << rho ); + FG_LOG( FG_FLIGHT, FG_INFO, "LaRCsim does not support externally supplied atmospheric data" ); + +} + diff --git a/src/FDM/LaRCsim.hxx b/src/FDM/LaRCsim.hxx index 0be365291..837eaba00 100644 --- a/src/FDM/LaRCsim.hxx +++ b/src/FDM/LaRCsim.hxx @@ -29,14 +29,19 @@ #include "IO360.hxx" #include "flight.hxx" - +#include <FDM/LaRCsimIC.hxx> class FGLaRCsim: public FGInterface { FGNewEngine eng; - + LaRCsimIC* lsic; + void set_ls(void); + double time_step; + public: - + FGLaRCsim(void); + ~FGLaRCsim(void); + // copy FDM state to LaRCsim structures bool copy_to_LaRCsim(); @@ -48,6 +53,35 @@ public: // update position based on inputs, positions, velocities, etc. bool update( int multiloop ); + + // Positions + void set_Latitude(double lat); //geocentric + void set_Longitude(double lon); + void set_Altitude(double alt); // triggers re-calc of AGL altitude + void set_AltitudeAGL(double altagl); // and vice-versa + + // Speeds -- setting any of these will trigger a re-calc of the rest + void set_V_calibrated_kts(double vc); + void set_Mach_number(double mach); + void set_Velocities_Local( double north, double east, double down ); + void set_Velocities_Wind_Body( double u, double v, double w); + + // Euler angles + void set_Euler_Angles( double phi, double theta, double psi ); + + // Flight Path + void set_Climb_Rate( double roc); + void set_Gamma_vert_rad( double gamma); + + // Earth + void set_Runway_altitude(double ralt); + void set_Static_pressure(double p); + void set_Static_temperature(double T); + void set_Density(double rho); + + void set_Velocities_Local_Airmass (double wnorth, + double weast, + double wdown ); }; diff --git a/src/FDM/LaRCsim/atmos_62.h b/src/FDM/LaRCsim/atmos_62.h index f192cac11..9752b131d 100644 --- a/src/FDM/LaRCsim/atmos_62.h +++ b/src/FDM/LaRCsim/atmos_62.h @@ -4,9 +4,16 @@ #ifndef _ATMOS_62_H #define _ATMOS_62_H +#ifdef __cplusplus +extern "C" { +#endif + void ls_atmos( SCALAR altitude, SCALAR * sigma, SCALAR * v_sound, SCALAR * t_amb, SCALAR * p_amb ); +#ifdef __cplusplus +} +#endif #endif /* _ATMOS_62_H */ diff --git a/src/FDM/LaRCsim/c172_main.c b/src/FDM/LaRCsim/c172_main.c index 67e3944b5..1305f2eea 100644 --- a/src/FDM/LaRCsim/c172_main.c +++ b/src/FDM/LaRCsim/c172_main.c @@ -262,7 +262,7 @@ int wave_stats(float *var,float *var_rate,int N,FILE *out) if(Nmaxima > 2) { ld=log(varmaxima[1]/varmaxima[2]); //logarithmic decrement - zeta=ld/sqrt(4*PI*PI +ld*ld); //damping ratio + zeta=ld/sqrt(4*LS_PI*LS_PI +ld*ld); //damping ratio omegad=1/(vm_times[2]-vm_times[1]); //damped natural frequency Hz if(zeta < 1) { diff --git a/src/FDM/LaRCsim/cherokee_aero.c b/src/FDM/LaRCsim/cherokee_aero.c index 8c72ac2ba..e74f2e5dc 100644 --- a/src/FDM/LaRCsim/cherokee_aero.c +++ b/src/FDM/LaRCsim/cherokee_aero.c @@ -141,7 +141,7 @@ void cherokee_aero() Cz = Cz0 + Cza*Alpha + Czat*(Alpha_dot*c/2.0/V) + Czq*(q*c/2.0/V) + Czde * elevator; Cm = Cm0 + Cma*Alpha + Cmat*(Alpha_dot*c/2.0/V) + Cmq*(q*c/2.0/V) + Cmde * elevator; - Cx = Cx0 - (Cza*Alpha)*(Cza*Alpha)/(PI*5.71*0.6); + Cx = Cx0 - (Cza*Alpha)*(Cza*Alpha)/(LS_PI*5.71*0.6); Cl = Clb*Beta + Clp*(p*b/2.0/V) + Clr*(r*b/2.0/V) + Clda * aileron; Cy = Cyb*Beta + Cyr*(r*b/2.0/V); diff --git a/src/FDM/LaRCsim/ls_aux.c b/src/FDM/LaRCsim/ls_aux.c index 9d4e2ddd7..226eea64f 100644 --- a/src/FDM/LaRCsim/ls_aux.c +++ b/src/FDM/LaRCsim/ls_aux.c @@ -47,8 +47,156 @@ $Header$ $Log$ -Revision 1.1 1999/06/17 18:07:33 curt -Initial revision +Revision 1.2 2000/10/23 22:34:54 curt +I tested: +LaRCsim c172 on-ground and in-air starts, reset: all work +UIUC Cessna172 on-ground and in-air starts work as expected, reset +results in an aircraft that is upside down but does not crash FG. I +don't know what it was like before, so it may well be no change. +JSBSim c172 and X15 in-air starts work fine, resets now work (and are +trimmed), on-ground starts do not -- the c172 ends up on its back. I +suspect this is no worse than before. + +I did not test: +Balloon (the weather code returns nan's for the atmosphere data --this +is in the weather module and apparently is a linux only bug) +ADA (don't know how) +MagicCarpet (needs work yet) +External (don't know how) + +known to be broken: +LaRCsim c172 on-ground starts with a negative terrain altitude (this +happens at KPAO when the scenery is not present). The FDM inits to +about 50 feet AGL and the model falls to the ground. It does stay +upright, however, and seems to be fine once it settles out, FWIW. + +To do: +--implement set_Model on the bus +--bring Christian's weather data into JSBSim +-- add default method to bus for updating things like the sin and cos of +latitude (for Balloon, MagicCarpet) +-- lots of cleanup + +The files: +src/FDM/flight.cxx +src/FDM/flight.hxx +-- all data members now declared protected instead of private. +-- eliminated all but a small set of 'setters', no change to getters. +-- that small set is declared virtual, the default implementation +provided preserves the old behavior +-- all of the vector data members are now initialized. +-- added busdump() method -- FG_LOG's all the bus data when called, +useful for diagnostics. + +src/FDM/ADA.cxx +-- bus data members now directly assigned to + +src/FDM/Balloon.cxx +-- bus data members now directly assigned to +-- changed V_equiv_kts to V_calibrated_kts + +src/FDM/JSBSim.cxx +src/FDM/JSBSim.hxx +-- bus data members now directly assigned to +-- implemented the FGInterface virtual setters with JSBSim specific +logic +-- changed the static FDMExec to a dynamic fdmex (needed so that the +JSBSim object can be deleted when a model change is called for) +-- implemented constructor and destructor, moved some of the logic +formerly in init() to constructor +-- added logic to bring up FGEngInterface objects and set the RPM and +throttle values. + +src/FDM/LaRCsim.cxx +src/FDM/LaRCsim.hxx +-- bus data members now directly assigned to +-- implemented the FGInterface virtual setters with LaRCsim specific +logic, uses LaRCsimIC +-- implemented constructor and destructor, moved some of the logic +formerly in init() to constructor +-- moved default inertias to here from fg_init.cxx +-- eliminated the climb rate calculation. The equivalent, climb_rate = +-1*vdown, is now in copy_from_LaRCsim(). + +src/FDM/LaRCsimIC.cxx +src/FDM/LaRCsimIC.hxx +-- similar to FGInitialCondition, this class has all the logic needed to +turn data like Vc and Mach into the more fundamental quantities LaRCsim +needs to initialize. +-- put it in src/FDM since it is a class + +src/FDM/MagicCarpet.cxx + -- bus data members now directly assigned to + +src/FDM/Makefile.am +-- adds LaRCsimIC.hxx and cxx + +src/FDM/JSBSim/FGAtmosphere.h +src/FDM/JSBSim/FGDefs.h +src/FDM/JSBSim/FGInitialCondition.cpp +src/FDM/JSBSim/FGInitialCondition.h +src/FDM/JSBSim/JSBSim.cpp +-- changes to accomodate the new bus + +src/FDM/LaRCsim/atmos_62.h +src/FDM/LaRCsim/ls_geodesy.h +-- surrounded prototypes with #ifdef __cplusplus ... #endif , functions +here are needed in LaRCsimIC + +src/FDM/LaRCsim/c172_main.c +src/FDM/LaRCsim/cherokee_aero.c +src/FDM/LaRCsim/ls_aux.c +src/FDM/LaRCsim/ls_constants.h +src/FDM/LaRCsim/ls_geodesy.c +src/FDM/LaRCsim/ls_geodesy.h +src/FDM/LaRCsim/ls_step.c +src/FDM/UIUCModel/uiuc_betaprobe.cpp +-- changed PI to LS_PI, eliminates preprocessor naming conflict with +weather module + +src/FDM/LaRCsim/ls_interface.c +src/FDM/LaRCsim/ls_interface.h +-- added function ls_set_model_dt() + +src/Main/bfi.cxx +-- eliminated calls that set the NED speeds to body components. They +are no longer needed and confuse the new bus. + +src/Main/fg_init.cxx +-- eliminated calls that just brought the bus data up-to-date (e.g. +set_sin_cos_latitude). or set default values. The bus now handles the +defaults and updates itself when the setters are called (for LaRCsim and +JSBSim). A default method for doing this needs to be added to the bus. +-- added fgVelocityInit() to set the speed the user asked for. Both +JSBSim and LaRCsim can now be initialized using any of: +vc,mach, NED components, UVW components. + +src/Main/main.cxx +--eliminated call to fgFDMSetGroundElevation, this data is now 'pulled' +onto the bus every update() + +src/Main/options.cxx +src/Main/options.hxx +-- added enum to keep track of the speed requested by the user +-- eliminated calls to set NED velocity properties to body speeds, they +are no longer needed. +-- added options for the NED components. + +src/Network/garmin.cxx +src/Network/nmea.cxx +--eliminated calls that just brought the bus data up-to-date (e.g. +set_sin_cos_latitude). The bus now updates itself when the setters are +called (for LaRCsim and JSBSim). A default method for doing this needs +to be added to the bus. +-- changed set_V_equiv_kts to set_V_calibrated_kts. set_V_equiv_kts no +longer exists ( get_V_equiv_kts still does, though) + +src/WeatherCM/FGLocalWeatherDatabase.cpp +-- commented out the code to put the weather data on the bus, a +different scheme for this is needed. + +Revision 1.1.1.1 1999/06/17 18:07:33 curt +Start of 0.7.x branch Revision 1.1.1.1 1999/04/05 21:32:45 curt Start of 0.6.x branch. @@ -247,7 +395,7 @@ void ls_aux( void ) { Gamma_horiz_rad = atan2( V_east_rel_ground, V_north_rel_ground ); if (Gamma_horiz_rad < 0) - Gamma_horiz_rad = Gamma_horiz_rad + 2*PI; + Gamma_horiz_rad = Gamma_horiz_rad + 2*LS_PI; /* Calculate local gravity */ diff --git a/src/FDM/LaRCsim/ls_constants.h b/src/FDM/LaRCsim/ls_constants.h index 2393f4c5d..ef2da935d 100644 --- a/src/FDM/LaRCsim/ls_constants.h +++ b/src/FDM/LaRCsim/ls_constants.h @@ -84,10 +84,7 @@ systems of measure) */ /* Value of Pi from ref [3] */ -#ifdef PI -# undef PI /* avoid a harmless compiler warning */ -#endif -#define PI 3.14159265358979323846264338327950288419716939967511 +#define LS_PI 3.14159265358979323846264338327950288419716939967511 /* Value of earth radius from [8], ft */ #define EQUATORIAL_RADIUS 20925650. diff --git a/src/FDM/LaRCsim/ls_geodesy.c b/src/FDM/LaRCsim/ls_geodesy.c index 918e2f00e..4d8fde96c 100644 --- a/src/FDM/LaRCsim/ls_geodesy.c +++ b/src/FDM/LaRCsim/ls_geodesy.c @@ -40,8 +40,156 @@ $Header$ $Log$ -Revision 1.1 1999/06/17 18:07:34 curt -Initial revision +Revision 1.2 2000/10/23 22:34:54 curt +I tested: +LaRCsim c172 on-ground and in-air starts, reset: all work +UIUC Cessna172 on-ground and in-air starts work as expected, reset +results in an aircraft that is upside down but does not crash FG. I +don't know what it was like before, so it may well be no change. +JSBSim c172 and X15 in-air starts work fine, resets now work (and are +trimmed), on-ground starts do not -- the c172 ends up on its back. I +suspect this is no worse than before. + +I did not test: +Balloon (the weather code returns nan's for the atmosphere data --this +is in the weather module and apparently is a linux only bug) +ADA (don't know how) +MagicCarpet (needs work yet) +External (don't know how) + +known to be broken: +LaRCsim c172 on-ground starts with a negative terrain altitude (this +happens at KPAO when the scenery is not present). The FDM inits to +about 50 feet AGL and the model falls to the ground. It does stay +upright, however, and seems to be fine once it settles out, FWIW. + +To do: +--implement set_Model on the bus +--bring Christian's weather data into JSBSim +-- add default method to bus for updating things like the sin and cos of +latitude (for Balloon, MagicCarpet) +-- lots of cleanup + +The files: +src/FDM/flight.cxx +src/FDM/flight.hxx +-- all data members now declared protected instead of private. +-- eliminated all but a small set of 'setters', no change to getters. +-- that small set is declared virtual, the default implementation +provided preserves the old behavior +-- all of the vector data members are now initialized. +-- added busdump() method -- FG_LOG's all the bus data when called, +useful for diagnostics. + +src/FDM/ADA.cxx +-- bus data members now directly assigned to + +src/FDM/Balloon.cxx +-- bus data members now directly assigned to +-- changed V_equiv_kts to V_calibrated_kts + +src/FDM/JSBSim.cxx +src/FDM/JSBSim.hxx +-- bus data members now directly assigned to +-- implemented the FGInterface virtual setters with JSBSim specific +logic +-- changed the static FDMExec to a dynamic fdmex (needed so that the +JSBSim object can be deleted when a model change is called for) +-- implemented constructor and destructor, moved some of the logic +formerly in init() to constructor +-- added logic to bring up FGEngInterface objects and set the RPM and +throttle values. + +src/FDM/LaRCsim.cxx +src/FDM/LaRCsim.hxx +-- bus data members now directly assigned to +-- implemented the FGInterface virtual setters with LaRCsim specific +logic, uses LaRCsimIC +-- implemented constructor and destructor, moved some of the logic +formerly in init() to constructor +-- moved default inertias to here from fg_init.cxx +-- eliminated the climb rate calculation. The equivalent, climb_rate = +-1*vdown, is now in copy_from_LaRCsim(). + +src/FDM/LaRCsimIC.cxx +src/FDM/LaRCsimIC.hxx +-- similar to FGInitialCondition, this class has all the logic needed to +turn data like Vc and Mach into the more fundamental quantities LaRCsim +needs to initialize. +-- put it in src/FDM since it is a class + +src/FDM/MagicCarpet.cxx + -- bus data members now directly assigned to + +src/FDM/Makefile.am +-- adds LaRCsimIC.hxx and cxx + +src/FDM/JSBSim/FGAtmosphere.h +src/FDM/JSBSim/FGDefs.h +src/FDM/JSBSim/FGInitialCondition.cpp +src/FDM/JSBSim/FGInitialCondition.h +src/FDM/JSBSim/JSBSim.cpp +-- changes to accomodate the new bus + +src/FDM/LaRCsim/atmos_62.h +src/FDM/LaRCsim/ls_geodesy.h +-- surrounded prototypes with #ifdef __cplusplus ... #endif , functions +here are needed in LaRCsimIC + +src/FDM/LaRCsim/c172_main.c +src/FDM/LaRCsim/cherokee_aero.c +src/FDM/LaRCsim/ls_aux.c +src/FDM/LaRCsim/ls_constants.h +src/FDM/LaRCsim/ls_geodesy.c +src/FDM/LaRCsim/ls_geodesy.h +src/FDM/LaRCsim/ls_step.c +src/FDM/UIUCModel/uiuc_betaprobe.cpp +-- changed PI to LS_PI, eliminates preprocessor naming conflict with +weather module + +src/FDM/LaRCsim/ls_interface.c +src/FDM/LaRCsim/ls_interface.h +-- added function ls_set_model_dt() + +src/Main/bfi.cxx +-- eliminated calls that set the NED speeds to body components. They +are no longer needed and confuse the new bus. + +src/Main/fg_init.cxx +-- eliminated calls that just brought the bus data up-to-date (e.g. +set_sin_cos_latitude). or set default values. The bus now handles the +defaults and updates itself when the setters are called (for LaRCsim and +JSBSim). A default method for doing this needs to be added to the bus. +-- added fgVelocityInit() to set the speed the user asked for. Both +JSBSim and LaRCsim can now be initialized using any of: +vc,mach, NED components, UVW components. + +src/Main/main.cxx +--eliminated call to fgFDMSetGroundElevation, this data is now 'pulled' +onto the bus every update() + +src/Main/options.cxx +src/Main/options.hxx +-- added enum to keep track of the speed requested by the user +-- eliminated calls to set NED velocity properties to body speeds, they +are no longer needed. +-- added options for the NED components. + +src/Network/garmin.cxx +src/Network/nmea.cxx +--eliminated calls that just brought the bus data up-to-date (e.g. +set_sin_cos_latitude). The bus now updates itself when the setters are +called (for LaRCsim and JSBSim). A default method for doing this needs +to be added to the bus. +-- changed set_V_equiv_kts to set_V_calibrated_kts. set_V_equiv_kts no +longer exists ( get_V_equiv_kts still does, though) + +src/WeatherCM/FGLocalWeatherDatabase.cpp +-- commented out the code to put the weather data on the bus, a +different scheme for this is needed. + +Revision 1.1.1.1 1999/06/17 18:07:34 curt +Start of 0.7.x branch Revision 1.1.1.1 1999/04/05 21:32:45 curt Start of 0.6.x branch. @@ -108,7 +256,7 @@ Initial Flight Gear revision. /* ONE_SECOND is pi/180/60/60, or about 100 feet at earths' equator */ #define ONE_SECOND 4.848136811E-6 -#define HALF_PI 0.5*PI +#define HALF_PI 0.5*LS_PI void ls_geoc_to_geod( SCALAR lat_geoc, SCALAR radius, SCALAR *lat_geod, diff --git a/src/FDM/LaRCsim/ls_geodesy.h b/src/FDM/LaRCsim/ls_geodesy.h index 5443c0484..5cb2675b6 100644 --- a/src/FDM/LaRCsim/ls_geodesy.h +++ b/src/FDM/LaRCsim/ls_geodesy.h @@ -4,6 +4,9 @@ #ifndef _LS_GEODESY_H #define _LS_GEODESY_H +#ifdef __cplusplus +extern "C" { +#endif void ls_geoc_to_geod( SCALAR lat_geoc, SCALAR radius, SCALAR *lat_geod, SCALAR *alt, SCALAR *sea_level_r ); @@ -11,5 +14,8 @@ void ls_geoc_to_geod( SCALAR lat_geoc, SCALAR radius, void ls_geod_to_geoc( SCALAR lat_geod, SCALAR alt, SCALAR *sl_radius, SCALAR *lat_geoc ); +#ifdef __cplusplus +} +#endif #endif /* _LS_GEODESY_H */ diff --git a/src/FDM/LaRCsim/ls_interface.c b/src/FDM/LaRCsim/ls_interface.c index f95ff9b4a..4f735a77d 100644 --- a/src/FDM/LaRCsim/ls_interface.c +++ b/src/FDM/LaRCsim/ls_interface.c @@ -486,6 +486,9 @@ int ls_checkopts(argc, argv) /* check and set options flags */ } #endif /* COMPILE_THIS_CODE_THIS_USELESS_CODE */ +void ls_set_model_dt(double dt) { + model_dt = dt; +} void ls_loop( SCALAR dt, int initialize ) { /* printf (" In ls_loop()\n"); */ @@ -575,6 +578,154 @@ int ls_ForceAltitude(double alt_feet) { /* Flight Gear Modification Log * * $Log$ + * Revision 1.3 2000/10/23 22:34:54 curt + * I tested: + * LaRCsim c172 on-ground and in-air starts, reset: all work + * UIUC Cessna172 on-ground and in-air starts work as expected, reset + * results in an aircraft that is upside down but does not crash FG. I + * don't know what it was like before, so it may well be no change. + * JSBSim c172 and X15 in-air starts work fine, resets now work (and are + * trimmed), on-ground starts do not -- the c172 ends up on its back. I + * suspect this is no worse than before. + * + * I did not test: + * Balloon (the weather code returns nan's for the atmosphere data --this + * is in the weather module and apparently is a linux only bug) + * ADA (don't know how) + * MagicCarpet (needs work yet) + * External (don't know how) + * + * known to be broken: + * LaRCsim c172 on-ground starts with a negative terrain altitude (this + * happens at KPAO when the scenery is not present). The FDM inits to + * about 50 feet AGL and the model falls to the ground. It does stay + * upright, however, and seems to be fine once it settles out, FWIW. + * + * To do: + * --implement set_Model on the bus + * --bring Christian's weather data into JSBSim + * -- add default method to bus for updating things like the sin and cos of + * latitude (for Balloon, MagicCarpet) + * -- lots of cleanup + * + * The files: + * src/FDM/flight.cxx + * src/FDM/flight.hxx + * -- all data members now declared protected instead of private. + * -- eliminated all but a small set of 'setters', no change to getters. + * -- that small set is declared virtual, the default implementation + * provided preserves the old behavior + * -- all of the vector data members are now initialized. + * -- added busdump() method -- FG_LOG's all the bus data when called, + * useful for diagnostics. + * + * src/FDM/ADA.cxx + * -- bus data members now directly assigned to + * + * src/FDM/Balloon.cxx + * -- bus data members now directly assigned to + * -- changed V_equiv_kts to V_calibrated_kts + * + * src/FDM/JSBSim.cxx + * src/FDM/JSBSim.hxx + * -- bus data members now directly assigned to + * -- implemented the FGInterface virtual setters with JSBSim specific + * logic + * -- changed the static FDMExec to a dynamic fdmex (needed so that the + * JSBSim object can be deleted when a model change is called for) + * -- implemented constructor and destructor, moved some of the logic + * formerly in init() to constructor + * -- added logic to bring up FGEngInterface objects and set the RPM and + * throttle values. + * + * src/FDM/LaRCsim.cxx + * src/FDM/LaRCsim.hxx + * -- bus data members now directly assigned to + * -- implemented the FGInterface virtual setters with LaRCsim specific + * logic, uses LaRCsimIC + * -- implemented constructor and destructor, moved some of the logic + * formerly in init() to constructor + * -- moved default inertias to here from fg_init.cxx + * -- eliminated the climb rate calculation. The equivalent, climb_rate = + * -1*vdown, is now in copy_from_LaRCsim(). + * + * src/FDM/LaRCsimIC.cxx + * src/FDM/LaRCsimIC.hxx + * -- similar to FGInitialCondition, this class has all the logic needed to + * turn data like Vc and Mach into the more fundamental quantities LaRCsim + * needs to initialize. + * -- put it in src/FDM since it is a class + * + * src/FDM/MagicCarpet.cxx + * -- bus data members now directly assigned to + * + * src/FDM/Makefile.am + * -- adds LaRCsimIC.hxx and cxx + * + * src/FDM/JSBSim/FGAtmosphere.h + * src/FDM/JSBSim/FGDefs.h + * src/FDM/JSBSim/FGInitialCondition.cpp + * src/FDM/JSBSim/FGInitialCondition.h + * src/FDM/JSBSim/JSBSim.cpp + * -- changes to accomodate the new bus + * + * src/FDM/LaRCsim/atmos_62.h + * src/FDM/LaRCsim/ls_geodesy.h + * -- surrounded prototypes with #ifdef __cplusplus ... #endif , functions + * here are needed in LaRCsimIC + * + * src/FDM/LaRCsim/c172_main.c + * src/FDM/LaRCsim/cherokee_aero.c + * src/FDM/LaRCsim/ls_aux.c + * src/FDM/LaRCsim/ls_constants.h + * src/FDM/LaRCsim/ls_geodesy.c + * src/FDM/LaRCsim/ls_geodesy.h + * src/FDM/LaRCsim/ls_step.c + * src/FDM/UIUCModel/uiuc_betaprobe.cpp + * -- changed PI to LS_PI, eliminates preprocessor naming conflict with + * weather module + * + * src/FDM/LaRCsim/ls_interface.c + * src/FDM/LaRCsim/ls_interface.h + * -- added function ls_set_model_dt() + * + * src/Main/bfi.cxx + * -- eliminated calls that set the NED speeds to body components. They + * are no longer needed and confuse the new bus. + * + * src/Main/fg_init.cxx + * -- eliminated calls that just brought the bus data up-to-date (e.g. + * set_sin_cos_latitude). or set default values. The bus now handles the + * defaults and updates itself when the setters are called (for LaRCsim and + * JSBSim). A default method for doing this needs to be added to the bus. + * -- added fgVelocityInit() to set the speed the user asked for. Both + * JSBSim and LaRCsim can now be initialized using any of: + * vc,mach, NED components, UVW components. + * + * src/Main/main.cxx + * --eliminated call to fgFDMSetGroundElevation, this data is now 'pulled' + * onto the bus every update() + * + * src/Main/options.cxx + * src/Main/options.hxx + * -- added enum to keep track of the speed requested by the user + * -- eliminated calls to set NED velocity properties to body speeds, they + * are no longer needed. + * -- added options for the NED components. + * + * src/Network/garmin.cxx + * src/Network/nmea.cxx + * --eliminated calls that just brought the bus data up-to-date (e.g. + * set_sin_cos_latitude). The bus now updates itself when the setters are + * called (for LaRCsim and JSBSim). A default method for doing this needs + * to be added to the bus. + * -- changed set_V_equiv_kts to set_V_calibrated_kts. set_V_equiv_kts no + * longer exists ( get_V_equiv_kts still does, though) + * + * src/WeatherCM/FGLocalWeatherDatabase.cpp + * -- commented out the code to put the weather data on the bus, a + * different scheme for this is needed. + * * Revision 1.2 2000/04/10 18:09:41 curt * David Megginson made a few (mostly minor) mods to the LaRCsim files, and * it's now possible to choose the LaRCsim model at runtime, as in diff --git a/src/FDM/LaRCsim/ls_interface.h b/src/FDM/LaRCsim/ls_interface.h index 533d13281..4bb496e88 100644 --- a/src/FDM/LaRCsim/ls_interface.h +++ b/src/FDM/LaRCsim/ls_interface.h @@ -42,6 +42,8 @@ int ls_toplevel_init(double dt, char * aircraft); /* update position based on inputs, positions, velocities, etc. */ int ls_update(int multiloop); +void ls_set_model_dt(double dt); + #if 0 /* Convert from the fgFLIGHT struct to the LaRCsim generic_ struct */ int fgFlight_2_LaRCsim (fgFLIGHT *f); @@ -56,15 +58,162 @@ void ls_loop( SCALAR dt, int initialize ); int ls_ForceAltitude(double alt_feet); -#endif /* _LS_INTERFACE_H */ - - #ifdef __cplusplus } #endif +#endif /* _LS_INTERFACE_H */ + // $Log$ +// Revision 1.4 2000/10/23 22:34:54 curt +// I tested: +// LaRCsim c172 on-ground and in-air starts, reset: all work +// UIUC Cessna172 on-ground and in-air starts work as expected, reset +// results in an aircraft that is upside down but does not crash FG. I +// don't know what it was like before, so it may well be no change. +// JSBSim c172 and X15 in-air starts work fine, resets now work (and are +// trimmed), on-ground starts do not -- the c172 ends up on its back. I +// suspect this is no worse than before. +// +// I did not test: +// Balloon (the weather code returns nan's for the atmosphere data --this +// is in the weather module and apparently is a linux only bug) +// ADA (don't know how) +// MagicCarpet (needs work yet) +// External (don't know how) +// +// known to be broken: +// LaRCsim c172 on-ground starts with a negative terrain altitude (this +// happens at KPAO when the scenery is not present). The FDM inits to +// about 50 feet AGL and the model falls to the ground. It does stay +// upright, however, and seems to be fine once it settles out, FWIW. +// +// To do: +// --implement set_Model on the bus +// --bring Christian's weather data into JSBSim +// -- add default method to bus for updating things like the sin and cos of +// latitude (for Balloon, MagicCarpet) +// -- lots of cleanup +// +// The files: +// src/FDM/flight.cxx +// src/FDM/flight.hxx +// -- all data members now declared protected instead of private. +// -- eliminated all but a small set of 'setters', no change to getters. +// -- that small set is declared virtual, the default implementation +// provided preserves the old behavior +// -- all of the vector data members are now initialized. +// -- added busdump() method -- FG_LOG's all the bus data when called, +// useful for diagnostics. +// +// src/FDM/ADA.cxx +// -- bus data members now directly assigned to +// +// src/FDM/Balloon.cxx +// -- bus data members now directly assigned to +// -- changed V_equiv_kts to V_calibrated_kts +// +// src/FDM/JSBSim.cxx +// src/FDM/JSBSim.hxx +// -- bus data members now directly assigned to +// -- implemented the FGInterface virtual setters with JSBSim specific +// logic +// -- changed the static FDMExec to a dynamic fdmex (needed so that the +// JSBSim object can be deleted when a model change is called for) +// -- implemented constructor and destructor, moved some of the logic +// formerly in init() to constructor +// -- added logic to bring up FGEngInterface objects and set the RPM and +// throttle values. +// +// src/FDM/LaRCsim.cxx +// src/FDM/LaRCsim.hxx +// -- bus data members now directly assigned to +// -- implemented the FGInterface virtual setters with LaRCsim specific +// logic, uses LaRCsimIC +// -- implemented constructor and destructor, moved some of the logic +// formerly in init() to constructor +// -- moved default inertias to here from fg_init.cxx +// -- eliminated the climb rate calculation. The equivalent, climb_rate = +// -1*vdown, is now in copy_from_LaRCsim(). +// +// src/FDM/LaRCsimIC.cxx +// src/FDM/LaRCsimIC.hxx +// -- similar to FGInitialCondition, this class has all the logic needed to +// turn data like Vc and Mach into the more fundamental quantities LaRCsim +// needs to initialize. +// -- put it in src/FDM since it is a class +// +// src/FDM/MagicCarpet.cxx +// -- bus data members now directly assigned to +// +// src/FDM/Makefile.am +// -- adds LaRCsimIC.hxx and cxx +// +// src/FDM/JSBSim/FGAtmosphere.h +// src/FDM/JSBSim/FGDefs.h +// src/FDM/JSBSim/FGInitialCondition.cpp +// src/FDM/JSBSim/FGInitialCondition.h +// src/FDM/JSBSim/JSBSim.cpp +// -- changes to accomodate the new bus +// +// src/FDM/LaRCsim/atmos_62.h +// src/FDM/LaRCsim/ls_geodesy.h +// -- surrounded prototypes with #ifdef __cplusplus ... #endif , functions +// here are needed in LaRCsimIC +// +// src/FDM/LaRCsim/c172_main.c +// src/FDM/LaRCsim/cherokee_aero.c +// src/FDM/LaRCsim/ls_aux.c +// src/FDM/LaRCsim/ls_constants.h +// src/FDM/LaRCsim/ls_geodesy.c +// src/FDM/LaRCsim/ls_geodesy.h +// src/FDM/LaRCsim/ls_step.c +// src/FDM/UIUCModel/uiuc_betaprobe.cpp +// -- changed PI to LS_PI, eliminates preprocessor naming conflict with +// weather module +// +// src/FDM/LaRCsim/ls_interface.c +// src/FDM/LaRCsim/ls_interface.h +// -- added function ls_set_model_dt() +// +// src/Main/bfi.cxx +// -- eliminated calls that set the NED speeds to body components. They +// are no longer needed and confuse the new bus. +// +// src/Main/fg_init.cxx +// -- eliminated calls that just brought the bus data up-to-date (e.g. +// set_sin_cos_latitude). or set default values. The bus now handles the +// defaults and updates itself when the setters are called (for LaRCsim and +// JSBSim). A default method for doing this needs to be added to the bus. +// -- added fgVelocityInit() to set the speed the user asked for. Both +// JSBSim and LaRCsim can now be initialized using any of: +// vc,mach, NED components, UVW components. +// +// src/Main/main.cxx +// --eliminated call to fgFDMSetGroundElevation, this data is now 'pulled' +// onto the bus every update() +// +// src/Main/options.cxx +// src/Main/options.hxx +// -- added enum to keep track of the speed requested by the user +// -- eliminated calls to set NED velocity properties to body speeds, they +// are no longer needed. +// -- added options for the NED components. +// +// src/Network/garmin.cxx +// src/Network/nmea.cxx +// --eliminated calls that just brought the bus data up-to-date (e.g. +// set_sin_cos_latitude). The bus now updates itself when the setters are +// called (for LaRCsim and JSBSim). A default method for doing this needs +// to be added to the bus. +// -- changed set_V_equiv_kts to set_V_calibrated_kts. set_V_equiv_kts no +// longer exists ( get_V_equiv_kts still does, though) +// +// src/WeatherCM/FGLocalWeatherDatabase.cpp +// -- commented out the code to put the weather data on the bus, a +// different scheme for this is needed. +// // Revision 1.3 2000/04/27 19:57:08 curt // MacOS build updates. // diff --git a/src/FDM/LaRCsim/ls_step.c b/src/FDM/LaRCsim/ls_step.c index 9531521da..79502fe02 100644 --- a/src/FDM/LaRCsim/ls_step.c +++ b/src/FDM/LaRCsim/ls_step.c @@ -50,6 +50,154 @@ $Header$ $Log$ +Revision 1.3 2000/10/23 22:34:55 curt +I tested: +LaRCsim c172 on-ground and in-air starts, reset: all work +UIUC Cessna172 on-ground and in-air starts work as expected, reset +results in an aircraft that is upside down but does not crash FG. I +don't know what it was like before, so it may well be no change. +JSBSim c172 and X15 in-air starts work fine, resets now work (and are +trimmed), on-ground starts do not -- the c172 ends up on its back. I +suspect this is no worse than before. + +I did not test: +Balloon (the weather code returns nan's for the atmosphere data --this +is in the weather module and apparently is a linux only bug) +ADA (don't know how) +MagicCarpet (needs work yet) +External (don't know how) + +known to be broken: +LaRCsim c172 on-ground starts with a negative terrain altitude (this +happens at KPAO when the scenery is not present). The FDM inits to +about 50 feet AGL and the model falls to the ground. It does stay +upright, however, and seems to be fine once it settles out, FWIW. + +To do: +--implement set_Model on the bus +--bring Christian's weather data into JSBSim +-- add default method to bus for updating things like the sin and cos of +latitude (for Balloon, MagicCarpet) +-- lots of cleanup + +The files: +src/FDM/flight.cxx +src/FDM/flight.hxx +-- all data members now declared protected instead of private. +-- eliminated all but a small set of 'setters', no change to getters. +-- that small set is declared virtual, the default implementation +provided preserves the old behavior +-- all of the vector data members are now initialized. +-- added busdump() method -- FG_LOG's all the bus data when called, +useful for diagnostics. + +src/FDM/ADA.cxx +-- bus data members now directly assigned to + +src/FDM/Balloon.cxx +-- bus data members now directly assigned to +-- changed V_equiv_kts to V_calibrated_kts + +src/FDM/JSBSim.cxx +src/FDM/JSBSim.hxx +-- bus data members now directly assigned to +-- implemented the FGInterface virtual setters with JSBSim specific +logic +-- changed the static FDMExec to a dynamic fdmex (needed so that the +JSBSim object can be deleted when a model change is called for) +-- implemented constructor and destructor, moved some of the logic +formerly in init() to constructor +-- added logic to bring up FGEngInterface objects and set the RPM and +throttle values. + +src/FDM/LaRCsim.cxx +src/FDM/LaRCsim.hxx +-- bus data members now directly assigned to +-- implemented the FGInterface virtual setters with LaRCsim specific +logic, uses LaRCsimIC +-- implemented constructor and destructor, moved some of the logic +formerly in init() to constructor +-- moved default inertias to here from fg_init.cxx +-- eliminated the climb rate calculation. The equivalent, climb_rate = +-1*vdown, is now in copy_from_LaRCsim(). + +src/FDM/LaRCsimIC.cxx +src/FDM/LaRCsimIC.hxx +-- similar to FGInitialCondition, this class has all the logic needed to +turn data like Vc and Mach into the more fundamental quantities LaRCsim +needs to initialize. +-- put it in src/FDM since it is a class + +src/FDM/MagicCarpet.cxx + -- bus data members now directly assigned to + +src/FDM/Makefile.am +-- adds LaRCsimIC.hxx and cxx + +src/FDM/JSBSim/FGAtmosphere.h +src/FDM/JSBSim/FGDefs.h +src/FDM/JSBSim/FGInitialCondition.cpp +src/FDM/JSBSim/FGInitialCondition.h +src/FDM/JSBSim/JSBSim.cpp +-- changes to accomodate the new bus + +src/FDM/LaRCsim/atmos_62.h +src/FDM/LaRCsim/ls_geodesy.h +-- surrounded prototypes with #ifdef __cplusplus ... #endif , functions +here are needed in LaRCsimIC + +src/FDM/LaRCsim/c172_main.c +src/FDM/LaRCsim/cherokee_aero.c +src/FDM/LaRCsim/ls_aux.c +src/FDM/LaRCsim/ls_constants.h +src/FDM/LaRCsim/ls_geodesy.c +src/FDM/LaRCsim/ls_geodesy.h +src/FDM/LaRCsim/ls_step.c +src/FDM/UIUCModel/uiuc_betaprobe.cpp +-- changed PI to LS_PI, eliminates preprocessor naming conflict with +weather module + +src/FDM/LaRCsim/ls_interface.c +src/FDM/LaRCsim/ls_interface.h +-- added function ls_set_model_dt() + +src/Main/bfi.cxx +-- eliminated calls that set the NED speeds to body components. They +are no longer needed and confuse the new bus. + +src/Main/fg_init.cxx +-- eliminated calls that just brought the bus data up-to-date (e.g. +set_sin_cos_latitude). or set default values. The bus now handles the +defaults and updates itself when the setters are called (for LaRCsim and +JSBSim). A default method for doing this needs to be added to the bus. +-- added fgVelocityInit() to set the speed the user asked for. Both +JSBSim and LaRCsim can now be initialized using any of: +vc,mach, NED components, UVW components. + +src/Main/main.cxx +--eliminated call to fgFDMSetGroundElevation, this data is now 'pulled' +onto the bus every update() + +src/Main/options.cxx +src/Main/options.hxx +-- added enum to keep track of the speed requested by the user +-- eliminated calls to set NED velocity properties to body speeds, they +are no longer needed. +-- added options for the NED components. + +src/Network/garmin.cxx +src/Network/nmea.cxx +--eliminated calls that just brought the bus data up-to-date (e.g. +set_sin_cos_latitude). The bus now updates itself when the setters are +called (for LaRCsim and JSBSim). A default method for doing this needs +to be added to the bus. +-- changed set_V_equiv_kts to set_V_calibrated_kts. set_V_equiv_kts no +longer exists ( get_V_equiv_kts still does, though) + +src/WeatherCM/FGLocalWeatherDatabase.cpp +-- commented out the code to put the weather data on the bus, a +different scheme for this is needed. + Revision 1.2 1999/10/29 16:08:33 curt Added flaps support to c172 model. @@ -347,7 +495,7 @@ void ls_step( SCALAR dt, int Initialize ) { /* Resolve Psi to 0 - 359.9999 */ - if (Psi < 0 ) Psi = Psi + 2*PI; + if (Psi < 0 ) Psi = Psi + 2*LS_PI; /* L I N E A R P O S I T I O N S */ diff --git a/src/FDM/LaRCsimIC.cxx b/src/FDM/LaRCsimIC.cxx new file mode 100644 index 000000000..9b00c3b58 --- /dev/null +++ b/src/FDM/LaRCsimIC.cxx @@ -0,0 +1,411 @@ +/******************************************************************************* + + Header: LaRCsimIC.cxx + Author: Tony Peden + Date started: 10/9/99 + + ------------- Copyright (C) 1999 Anthony K. Peden (apeden@earthlink.net) ------------- + + This program is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 Temple + Place - Suite 330, Boston, MA 02111-1307, USA. + + Further information about the GNU General Public License can also be found on + the world wide web at http://www.gnu.org. +*/ + + +#include "FDM/LaRCsimIC.hxx" +#include <FDM/LaRCsim/ls_cockpit.h> +#include <FDM/LaRCsim/ls_generic.h> +#include <FDM/LaRCsim/ls_interface.h> +#include <FDM/LaRCsim/atmos_62.h> +#include <FDM/LaRCsim/ls_constants.h> +#include <FDM/LaRCsim/ls_geodesy.h> +#include <math.h> +#include <iostream> + +LaRCsimIC::LaRCsimIC(void) { + vt=vtg=vw=vc=ve=0; + mach=0; + alpha=beta=gamma=0; + theta=phi=psi=0; + altitude=runway_altitude=hdot=alt_agl=0; + latitude_gd=latitude_gc=longitude=0; + u=v=w=0; + vnorth=veast=vdown=0; + vnorthwind=veastwind=vdownwind=0; + lastSpeedSet=lssetvt; + lastAltSet=lssetasl; + get_atmosphere(); + ls_geod_to_geoc( latitude_gd,altitude,&sea_level_radius,&latitude_gc); + +} + + +LaRCsimIC::~LaRCsimIC(void) {} + +void LaRCsimIC::get_atmosphere(void) { + Altitude=altitude; //set LaRCsim variable + ls_atmos(Altitude, &density_ratio, &soundspeed, &T, &p); + rho=density_ratio*SEA_LEVEL_DENSITY; +} + +void LaRCsimIC::SetVcalibratedKtsIC( SCALAR tt) { + vc=tt*KTS_TO_FPS; + lastSpeedSet=lssetvc; + vt=sqrt(1/density_ratio*vc*vc); +} + +void LaRCsimIC::SetVtrueFpsIC( SCALAR tt) { + vt=tt; + lastSpeedSet=lssetvt; +} + +void LaRCsimIC::SetMachIC( SCALAR tt) { + mach=tt; + vt=mach*soundspeed; + lastSpeedSet=lssetmach; +} + +void LaRCsimIC::SetVequivalentKtsIC(SCALAR tt) { + ve=tt*KTS_TO_FPS; + lastSpeedSet=lssetve; + vt=sqrt(SEA_LEVEL_DENSITY/rho)*ve; +} + +void LaRCsimIC::SetClimbRateFpmIC( SCALAR tt) { + SetClimbRateFpsIC(tt/60.0); +} + +void LaRCsimIC::SetClimbRateFpsIC( SCALAR tt) { + vtg=vt+vw; + cout << "vtg: " << vtg << endl; + if(vtg > 0.1) { + hdot = tt - vdownwind; + gamma=asin(hdot/vtg); + getTheta(); + vdown=-1*hdot; + cout << "hdot: " << hdot << endl; + cout << "gamma: " << gamma*RAD_TO_DEG << endl; + cout << "vdown: " << vdown << endl; + } +} + +void LaRCsimIC::SetFlightPathAngleRadIC( SCALAR tt) { + gamma=tt; + getTheta(); + vtg=vt+vw; + hdot=vtg*sin(tt); + cout << "hdot: " << hdot << endl; + vdown=-1*hdot; +} + +void LaRCsimIC::SetPitchAngleRadIC(SCALAR tt) { + if(alt_agl < (DEFAULT_AGL_ALT + 0.1) || vt < 10 ) + theta=DEFAULT_PITCH_ON_GROUND; + else + theta=tt; + getAlpha(); +} + +void LaRCsimIC::SetUBodyFpsIC( SCALAR tt) { + u=tt; + vt=sqrt(u*u+v*v+w*w); + lastSpeedSet=lssetuvw; +} + + +void LaRCsimIC::SetVBodyFpsIC( SCALAR tt) { + v=tt; + vt=sqrt(u*u+v*v+w*w); + lastSpeedSet=lssetuvw; +} + +void LaRCsimIC::SetWBodyFpsIC( SCALAR tt) { + w=tt; + vt=sqrt(u*u+v*v+w*w); + lastSpeedSet=lssetuvw; +} + +void LaRCsimIC::SetVNorthAirmassFpsIC(SCALAR tt) { + vnorthwind=tt; + vw=sqrt(vnorthwind*vnorthwind + veastwind*veastwind + vdownwind*vdownwind); +} + +void LaRCsimIC::SetVEastAirmassFpsIC(SCALAR tt) { + veastwind=tt; + vw=sqrt(vnorthwind*vnorthwind + veastwind*veastwind + vdownwind*vdownwind); +} + +void LaRCsimIC::SetVDownAirmassFpsIC(SCALAR tt){ + vdownwind=tt; + vw=sqrt(vnorthwind*vnorthwind + veastwind*veastwind + vdownwind*vdownwind); + vtg=vt+vw; + hdot=-vtg*sin(gamma); +} + +void LaRCsimIC::SetAltitudeFtIC( SCALAR tt) { + if(tt > (runway_altitude + DEFAULT_AGL_ALT)) { + altitude=tt; + } else { + altitude=runway_altitude + DEFAULT_AGL_ALT; + alt_agl=DEFAULT_AGL_ALT; + theta=DEFAULT_PITCH_ON_GROUND; + } + lastAltSet=lssetasl; + get_atmosphere(); + //lets try to make sure the user gets what they intended + + switch(lastSpeedSet) { + case lssetned: + calcVtfromNED(); + break; + case lssetuvw: + case lssetvt: + SetVtrueFpsIC(vt); + break; + case lssetvc: + SetVcalibratedKtsIC(vc*V_TO_KNOTS); + break; + case lssetve: + SetVequivalentKtsIC(ve*V_TO_KNOTS); + break; + case lssetmach: + SetMachIC(mach); + break; + } +} + +void LaRCsimIC::SetAltitudeAGLFtIC( SCALAR tt) { + alt_agl=tt; + lastAltSet=lssetagl; + altitude=runway_altitude + alt_agl; +} + +void LaRCsimIC::SetRunwayAltitudeFtIC( SCALAR tt) { + runway_altitude=tt; + if(lastAltSet == lssetagl) + altitude = runway_altitude + alt_agl; +} + +void LaRCsimIC::calcVtfromNED(void) { + //take the earth's rotation out of veast first + //float veastner = veast- OMEGA_EARTH*sea_level_radius*cos( latitude_gd ); + float veastner=veast; + u = (vnorth - vnorthwind)*cos(theta)*cos(psi) + + (veastner - veastwind)*cos(theta)*sin(psi) - + (vdown - vdownwind)*sin(theta); + v = (vnorth - vnorthwind)*(sin(phi)*sin(theta)*cos(psi) - cos(phi)*sin(psi)) + + (veastner - veastwind)*(sin(phi)*sin(theta)*sin(psi) + cos(phi)*cos(psi)) + + (vdown - vdownwind)*sin(phi)*cos(theta); + w = (vnorth - vnorthwind)*(cos(phi)*sin(theta)*cos(psi) + sin(phi)*sin(psi)) + + (veastner - veastwind)*(cos(phi)*sin(theta)*sin(psi) - sin(phi)*cos(psi)) + + (vdown - vdownwind)*cos(phi)*cos(theta); + vt = sqrt(u*u + v*v + w*w); +} + +void LaRCsimIC::calcNEDfromVt(void) { + float veastner; + + //get the body components of vt + u = GetUBodyFpsIC(); + v = GetVBodyFpsIC(); + w = GetWBodyFpsIC(); + + //transform them to local axes and add on the wind components + vnorth = u*cos(theta)*cos(psi) + + v*(sin(phi)*sin(theta)*cos(psi) - cos(phi)*sin(psi)) + + w*(cos(phi)*sin(theta)*cos(psi) + sin(phi)*sin(psi)) + + vnorthwind; + + //need to account for the earth's rotation here + veastner = u*cos(theta)*sin(psi) + + v*(sin(phi)*sin(theta)*sin(psi) + cos(phi)*cos(psi)) + + w*(cos(phi)*sin(theta)*sin(psi) - sin(phi)*cos(psi)) + + veastwind; + veast = veastner; + //veast = veastner + OMEGA_EARTH*sea_level_radius*cos( latitude_gd ); + + vdown = u*sin(theta) + + v*sin(phi)*cos(theta) + + w*cos(phi)*cos(theta) + + vdownwind; +} + +void LaRCsimIC::SetVnorthFpsIC( SCALAR tt) { + vnorth=tt; + lastSpeedSet=lssetned; + calcVtfromNED(); +} + +void LaRCsimIC::SetVeastFpsIC( SCALAR tt) { + veast=tt; + lastSpeedSet=lssetned; + calcVtfromNED(); +} + +void LaRCsimIC::SetVdownFpsIC( SCALAR tt) { + vdown=tt; + calcVtfromNED(); + SetClimbRateFpsIC(-1*vdown); + lastSpeedSet=lssetned; +} + +void LaRCsimIC::SetLatitudeGDRadIC(SCALAR tt) { + latitude_gd=tt; + ls_geod_to_geoc(latitude_gd,altitude,&sea_level_radius, &latitude_gc); +} + +bool LaRCsimIC::getAlpha(void) { + bool result=false; + float guess=theta-gamma; + xlo=xhi=0; + xmin=-89; + xmax=89; + sfunc=&LaRCsimIC::GammaEqOfAlpha; + if(findInterval(0,guess)){ + if(solve(&alpha,0)){ + result=true; + } + } + return result; +} + + +bool LaRCsimIC::getTheta(void) { + bool result=false; + float guess=alpha+gamma; + xlo=xhi=0; + xmin=-89;xmax=89; + sfunc=&LaRCsimIC::GammaEqOfTheta; + if(findInterval(0,guess)){ + if(solve(&theta,0)){ + result=true; + } + } + return result; +} + + + +SCALAR LaRCsimIC::GammaEqOfTheta( SCALAR theta_arg) { + SCALAR a,b,c; + + a=cos(alpha)*cos(beta)*sin(theta_arg); + b=sin(beta)*sin(phi); + c=sin(alpha)*cos(beta)*cos(phi); + return sin(gamma)-a+(b+c)*cos(theta_arg); +} + +SCALAR LaRCsimIC::GammaEqOfAlpha( SCALAR alpha_arg) { + float a,b,c; + + a=cos(alpha_arg)*cos(beta)*sin(theta); + b=sin(beta)*sin(phi); + c=sin(alpha_arg)*cos(beta)*cos(phi); + return sin(gamma)-a+(b+c)*cos(theta); +} + + + + + + +bool LaRCsimIC::findInterval( SCALAR x,SCALAR guess) { + //void find_interval(inter_params &ip,eqfunc f,float y,float constant, int &flag){ + + int i=0; + bool found=false; + float flo,fhi,fguess; + float lo,hi,step; + step=0.1; + fguess=(this->*sfunc)(guess)-x; + lo=hi=guess; + do { + step=2*step; + lo-=step; + hi+=step; + if(lo < xmin) lo=xmin; + if(hi > xmax) hi=xmax; + i++; + flo=(this->*sfunc)(lo)-x; + fhi=(this->*sfunc)(hi)-x; + if(flo*fhi <=0) { //found interval with root + found=true; + if(flo*fguess <= 0) { //narrow interval down a bit + hi=lo+step; //to pass solver interval that is as + //small as possible + } + else if(fhi*fguess <= 0) { + lo=hi-step; + } + } + //cout << "findInterval: i=" << i << " Lo= " << lo << " Hi= " << hi << endl; + } + while((found == 0) && (i <= 100)); + xlo=lo; + xhi=hi; + return found; +} + + + + +bool LaRCsimIC::solve( SCALAR *y,SCALAR x) { + float x1,x2,x3,f1,f2,f3,d,d0; + float eps=1E-5; + float const relax =0.9; + int i; + bool success=false; + + //initializations + d=1; + + x1=xlo;x3=xhi; + f1=(this->*sfunc)(x1)-x; + f3=(this->*sfunc)(x3)-x; + d0=fabs(x3-x1); + + //iterations + i=0; + while ((fabs(d) > eps) && (i < 100)) { + d=(x3-x1)/d0; + x2=x1-d*d0*f1/(f3-f1); + + f2=(this->*sfunc)(x2)-x; + //cout << "solve x1,x2,x3: " << x1 << "," << x2 << "," << x3 << endl; + //cout << " " << f1 << "," << f2 << "," << f3 << endl; + + if(fabs(f2) <= 0.001) { + x1=x3=x2; + } else if(f1*f2 <= 0.0) { + x3=x2; + f3=f2; + f1=relax*f1; + } else if(f2*f3 <= 0) { + x1=x2; + f1=f2; + f3=relax*f3; + } + //cout << i << endl; + i++; + }//end while + if(i < 100) { + success=true; + *y=x2; + } + + //cout << "Success= " << success << " Vcas: " << vcas*V_TO_KNOTS << " Mach: " << x2 << endl; + return success; +} diff --git a/src/FDM/LaRCsimIC.hxx b/src/FDM/LaRCsimIC.hxx new file mode 100644 index 000000000..366f6bb07 --- /dev/null +++ b/src/FDM/LaRCsimIC.hxx @@ -0,0 +1,203 @@ +/******************************************************************************* + + Header: LaRCsimIC.hxx + Author: Tony Peden + Date started: 10/9/00 + + ------------- Copyright (C) 2000 Anthony K. Peden (apeden@earthlink.net) ------------- + + This program is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 Temple + Place - Suite 330, Boston, MA 02111-1307, USA. + + Further information about the GNU General Public License can also be found on + the world wide web at http://www.gnu.org. +*/ +#ifndef _LARCSIMIC_HXX +#define _LARCSIMIC_HXX + +/******************************************************************************* +INCLUDES +*******************************************************************************/ + +#include <FDM/LaRCsim/ls_constants.h> +#include <FDM/LaRCsim/ls_types.h> + +/******************************************************************************* +CLASS DECLARATION +*******************************************************************************/ + +#define KTS_TO_FPS 1.6889 +#define M_TO_FT 3.2808399 +#define DEFAULT_AGL_ALT 3.758099 +#define DEFAULT_PITCH_ON_GROUND 0.0074002 + +typedef enum lsspeedset { lssetvt, lssetvc, lssetve, lssetmach, lssetuvw, lssetned }; +typedef enum lsaltset { lssetasl, lssetagl }; + + +class LaRCsimIC { +public: + + LaRCsimIC(void); + ~LaRCsimIC(void); + + void SetVcalibratedKtsIC(SCALAR tt); + void SetMachIC(SCALAR tt); + + void SetVtrueFpsIC(SCALAR tt); + + void SetVequivalentKtsIC(SCALAR tt); + + void SetUBodyFpsIC(SCALAR tt); + void SetVBodyFpsIC(SCALAR tt); + void SetWBodyFpsIC(SCALAR tt); + + void SetVnorthFpsIC(SCALAR tt); + void SetVeastFpsIC(SCALAR tt); + void SetVdownFpsIC(SCALAR tt); + + void SetVNorthAirmassFpsIC(SCALAR tt); + void SetVEastAirmassFpsIC(SCALAR tt); + void SetVDownAirmassFpsIC(SCALAR tt); + + void SetAltitudeFtIC(SCALAR tt); + void SetAltitudeAGLFtIC(SCALAR tt); + + //"vertical" flight path, recalculate theta + inline void SetFlightPathAngleDegIC(SCALAR tt) { SetFlightPathAngleRadIC(tt*DEG_TO_RAD); } + void SetFlightPathAngleRadIC(SCALAR tt); + + //set speed first + void SetClimbRateFpmIC(SCALAR tt); + void SetClimbRateFpsIC(SCALAR tt); + + //use currently stored gamma, recalcualte theta + inline void SetAlphaDegIC(SCALAR tt) { alpha=tt*DEG_TO_RAD; getTheta(); } + inline void SetAlphaRadIC(SCALAR tt) { alpha=tt; getTheta(); } + + //use currently stored gamma, recalcualte alpha + inline void SetPitchAngleDegIC(SCALAR tt) { SetPitchAngleRadIC(tt*DEG_TO_RAD); } + void SetPitchAngleRadIC(SCALAR tt); + + inline void SetBetaDegIC(SCALAR tt) { beta=tt*DEG_TO_RAD; getTheta();} + inline void SetBetaRadIC(SCALAR tt) { beta=tt; getTheta(); } + + inline void SetRollAngleDegIC(SCALAR tt) { phi=tt*DEG_TO_RAD; getTheta(); } + inline void SetRollAngleRadIC(SCALAR tt) { phi=tt; getTheta(); } + + inline void SetHeadingDegIC(SCALAR tt) { psi=tt*DEG_TO_RAD; } + inline void SetHeadingRadIC(SCALAR tt) { psi=tt; } + + inline void SetLatitudeGDDegIC(SCALAR tt) { SetLatitudeGDRadIC(tt*DEG_TO_RAD); } + void SetLatitudeGDRadIC(SCALAR tt); + + inline void SetLongitudeDegIC(SCALAR tt) { longitude=tt*DEG_TO_RAD; } + inline void SetLongitudeRadIC(SCALAR tt) { longitude=tt; } + + void SetRunwayAltitudeFtIC(SCALAR tt); + + inline SCALAR GetVcalibratedKtsIC(void) { return sqrt(density_ratio*vt*vt)*V_TO_KNOTS; } + inline SCALAR GetVequivalentKtsIC(void) { return sqrt(density_ratio)*vt*V_TO_KNOTS; } + inline SCALAR GetVtrueKtsIC(void) { return vt*V_TO_KNOTS; } + inline SCALAR GetVtrueFpsIC(void) { return vt; } + inline SCALAR GetMachIC(void) { return vt/soundspeed; } + + inline SCALAR GetAltitudeFtIC(void) { return altitude; } + inline SCALAR GetAltitudeAGLFtIC(void) { return alt_agl; } + + inline SCALAR GetRunwayAltitudeFtIC(void) { return runway_altitude; } + + inline SCALAR GetFlightPathAngleDegIC(void) { return gamma*RAD_TO_DEG; } + inline SCALAR GetFlightPathAngleRadIC(void) { return gamma; } + + inline SCALAR GetClimbRateFpmIC(void) { return hdot*60; } + inline SCALAR GetClimbRateFpsIC(void) { return hdot; } + + inline SCALAR GetAlphaDegIC(void) { return alpha*RAD_TO_DEG; } + inline SCALAR GetAlphaRadIC(void) { return alpha; } + + inline SCALAR GetPitchAngleDegIC(void) { return theta*RAD_TO_DEG; } + inline SCALAR GetPitchAngleRadIC(void) { return theta; } + + + inline SCALAR GetBetaDegIC(void) { return beta*RAD_TO_DEG; } + inline SCALAR GetBetaRadIC(void) { return beta*RAD_TO_DEG; } + + inline SCALAR GetRollAngleDegIC(void) { return phi*RAD_TO_DEG; } + inline SCALAR GetRollAngleRadIC(void) { return phi; } + + inline SCALAR GetHeadingDegIC(void) { return psi*RAD_TO_DEG; } + inline SCALAR GetHeadingRadIC(void) { return psi; } + + inline SCALAR GetLatitudeGDDegIC(void) { return latitude_gd*RAD_TO_DEG; } + inline SCALAR GetLatitudeGDRadIC(void) { return latitude_gd; } + + inline SCALAR GetLongitudeDegIC(void) { return longitude*RAD_TO_DEG; } + inline SCALAR GetLongitudeRadIC(void) { return longitude; } + + inline SCALAR GetUBodyFpsIC(void) { return vt*cos(alpha)*cos(beta); } + inline SCALAR GetVBodyFpsIC(void) { return vt*sin(beta); } + inline SCALAR GetWBodyFpsIC(void) { return vt*sin(alpha)*cos(beta); } + + inline SCALAR GetVnorthFpsIC(void) { calcNEDfromVt();return vnorth; } + inline SCALAR GetVeastFpsIC(void) { calcNEDfromVt();return veast; } + inline SCALAR GetVdownFpsIC(void) { calcNEDfromVt();return vdown; } + + inline SCALAR GetVnorthAirmassFpsIC(void) { return vnorthwind; } + inline SCALAR GetVeastAirmassFpsIC(void) { return veastwind; } + inline SCALAR GetVdownAirmassFpsIC(void) { return vdownwind; } + + inline SCALAR GetThetaRadIC(void) { return theta; } + inline SCALAR GetPhiRadIC(void) { return phi; } + inline SCALAR GetPsiRadIC(void) { return psi; } + + + +private: + SCALAR vt,vtg,vw,vc,ve; + SCALAR alpha,beta,gamma,theta,phi,psi; + SCALAR mach; + SCALAR altitude,runway_altitude,hdot,alt_agl,sea_level_radius; + SCALAR latitude_gd,latitude_gc,longitude; + SCALAR u,v,w; + SCALAR vnorth,veast,vdown; + SCALAR vnorthwind, veastwind, vdownwind; + SCALAR p,T,soundspeed,density_ratio,rho; + + SCALAR xlo, xhi,xmin,xmax; + + typedef SCALAR (LaRCsimIC::*fp)(SCALAR x); + fp sfunc; + + lsspeedset lastSpeedSet; + lsaltset lastAltSet; + + + void calcVtfromNED(void); + void calcNEDfromVt(void); + void calcSpeeds(void); + + + bool getAlpha(void); + bool getTheta(void); + SCALAR GammaEqOfTheta(SCALAR tt); + SCALAR GammaEqOfAlpha(SCALAR tt); + void get_atmosphere(void); + + + bool findInterval(SCALAR x,SCALAR guess); + bool solve(SCALAR *y, SCALAR x); +}; + +#endif diff --git a/src/FDM/MagicCarpet.cxx b/src/FDM/MagicCarpet.cxx index 034b79259..ca4af1096 100644 --- a/src/FDM/MagicCarpet.cxx +++ b/src/FDM/MagicCarpet.cxx @@ -52,28 +52,30 @@ bool FGMagicCarpet::update( int multiloop ) { double speed = controls.get_throttle( 0 ) * 2000; // meters/sec double dist = speed * time_step; double kts = speed * METER_TO_NM * 3600.0; - set_V_equiv_kts( kts ); - set_V_calibrated_kts( kts ); - set_V_ground_speed( kts ); - set_Mach_number(0); + _set_V_equiv_kts( kts ); + _set_V_calibrated_kts( kts ); + _set_V_ground_speed( kts ); // angle of turn double turn_rate = controls.get_aileron() * FG_PI_4; // radians/sec double turn = turn_rate * time_step; // update euler angles - set_Euler_Angles( get_Phi(), get_Theta(), fmod(get_Psi() + turn, FG_2PI) ); - set_Euler_Rates(0,0,0); + _set_Euler_Angles( get_Phi(), get_Theta(), fmod(get_Psi() + turn, FG_2PI) ); + _set_Euler_Rates(0,0,0); // update (lon/lat) position double lat2, lon2, az2; - geo_direct_wgs_84 ( get_Altitude(), - get_Latitude() * RAD_TO_DEG, - get_Longitude() * RAD_TO_DEG, - get_Psi() * RAD_TO_DEG, - dist, &lat2, &lon2, &az2 ); - set_Longitude( lon2 * DEG_TO_RAD ); - set_Latitude( lat2 * DEG_TO_RAD ); + if ( speed > FG_EPSILON ) { + geo_direct_wgs_84 ( get_Altitude(), + get_Latitude() * RAD_TO_DEG, + get_Longitude() * RAD_TO_DEG, + get_Psi() * RAD_TO_DEG, + dist, &lat2, &lon2, &az2 ); + + _set_Longitude( lon2 * DEG_TO_RAD ); + _set_Latitude( lat2 * DEG_TO_RAD ); + } // cout << "lon error = " << fabs(end.x()*RAD_TO_DEG - lon2) // << " lat error = " << fabs(end.y()*RAD_TO_DEG - lat2) @@ -84,15 +86,15 @@ bool FGMagicCarpet::update( int multiloop ) { // update altitude double real_climb_rate = -controls.get_elevator() * 5000; // feet/sec - set_Climb_Rate( real_climb_rate / 500.0 ); + _set_Climb_Rate( real_climb_rate / 500.0 ); double climb = real_climb_rate * time_step; - set_Geocentric_Position( lat_geoc, get_Longitude(), + _set_Geocentric_Position( lat_geoc, get_Longitude(), sl_radius + get_Altitude() + climb ); // cout << "sea level radius (ft) = " << sl_radius << endl; // cout << "(setto) sea level radius (ft) = " << get_Sea_level_radius() << endl; - set_Sea_level_radius( sl_radius * METER_TO_FEET); - set_Altitude( get_Altitude() + climb ); + _set_Sea_level_radius( sl_radius * METER_TO_FEET); + _set_Altitude( get_Altitude() + climb ); return true; } diff --git a/src/FDM/Makefile.am b/src/FDM/Makefile.am index c52f3a7d7..6e4aca857 100644 --- a/src/FDM/Makefile.am +++ b/src/FDM/Makefile.am @@ -10,6 +10,7 @@ libFlight_a_SOURCES = \ IO360.cxx IO360.hxx \ JSBSim.cxx JSBSim.hxx \ LaRCsim.cxx LaRCsim.hxx \ + LaRCsimIC.cxx LaRCsimIC.hxx \ MagicCarpet.cxx MagicCarpet.hxx bin_PROGRAMS = engine pstest diff --git a/src/FDM/UIUCModel/uiuc_betaprobe.cpp b/src/FDM/UIUCModel/uiuc_betaprobe.cpp index 5e2afb075..c2b3fcae4 100644 --- a/src/FDM/UIUCModel/uiuc_betaprobe.cpp +++ b/src/FDM/UIUCModel/uiuc_betaprobe.cpp @@ -91,36 +91,36 @@ void uiuc_betaprobe() Gamma_clean_tail = Lift_clean_tail / (Density * V_rel_wind); Gamma_iced_tail = Lift_iced_tail / (Density * V_rel_wind); - w_clean_wing = Gamma_clean_wing / (2 * PI * x_probe_wing); - w_iced_wing = Gamma_iced_wing / (2 * PI * x_probe_wing); - w_clean_tail = Gamma_clean_tail / (2 * PI * x_probe_tail); - w_iced_tail = Gamma_iced_tail / (2 * PI * x_probe_tail); + w_clean_wing = Gamma_clean_wing / (2 * LS_PI * x_probe_wing); + w_iced_wing = Gamma_iced_wing / (2 * LS_PI * x_probe_wing); + w_clean_tail = Gamma_clean_tail / (2 * LS_PI * x_probe_tail); + w_iced_tail = Gamma_iced_tail / (2 * LS_PI * x_probe_tail); V_total_clean_wing = sqrt(w_clean_wing*w_clean_wing + V_rel_wind*V_rel_wind - 2*w_clean_wing*V_rel_wind * - cos(PI/2 + Alpha)); + cos(LS_PI/2 + Alpha)); V_total_iced_wing = sqrt(w_iced_wing*w_iced_wing + V_rel_wind*V_rel_wind - 2*w_iced_wing*V_rel_wind * - cos(PI/2 + Alpha)); + cos(LS_PI/2 + Alpha)); V_total_clean_tail = sqrt(w_clean_tail*w_clean_tail + V_rel_wind*V_rel_wind - 2*w_clean_tail*V_rel_wind * - cos(PI/2 + Alpha)); + cos(LS_PI/2 + Alpha)); V_total_iced_tail = sqrt(w_iced_tail*w_iced_tail + V_rel_wind*V_rel_wind - 2*w_iced_tail*V_rel_wind * - cos(PI/2 + Alpha)); + cos(LS_PI/2 + Alpha)); beta_flow_clean_wing = asin((w_clean_wing / V_total_clean_wing) * - sin (PI/2 + Alpha)); + sin (LS_PI/2 + Alpha)); beta_flow_iced_wing = asin((w_iced_wing / V_total_iced_wing) * - sin (PI/2 + Alpha)); + sin (LS_PI/2 + Alpha)); beta_flow_clean_tail = asin((w_clean_tail / V_total_clean_tail) * - sin (PI/2 + Alpha)); + sin (LS_PI/2 + Alpha)); beta_flow_iced_tail = asin((w_iced_tail / V_total_iced_tail) * - sin (PI/2 + Alpha)); + sin (LS_PI/2 + Alpha)); Dbeta_flow_wing = fabs(beta_flow_clean_wing - beta_flow_iced_wing); Dbeta_flow_tail = fabs(beta_flow_clean_tail - beta_flow_iced_tail); diff --git a/src/FDM/flight.cxx b/src/FDM/flight.cxx index 544f9b672..cbdd1f7bd 100644 --- a/src/FDM/flight.cxx +++ b/src/FDM/flight.cxx @@ -46,31 +46,99 @@ FGInterface *cur_fdm_state; FGInterface base_fdm_state; +inline void init_vec(FG_VECTOR_3 vec) { + vec[0] = 0.0; vec[1] = 0.0; vec[2] = 0.0; +} + +FGEngInterface::FGEngInterface(void) { + + // inputs + Throttle=0; + Mixture=0; + Prop_Advance=0; + + // outputs + RPM=0; + Manifold_Pressure=0; + MaxHP=0; + Percentage_Power=0; + EGT=0; + prop_thrust=0; +} + +FGEngInterface::~FGEngInterface(void) { +} + // Constructor FGInterface::FGInterface(void) { - mass=i_xx=i_yy=i_zz=i_xz=0; - nlf=0; - v_rel_wind=v_true_kts=v_rel_ground=v_inertial=0; - v_ground_speed=v_equiv=v_equiv_kts=0; - v_calibrated=v_calibrated_kts=0; - gravity=0; - centrifugal_relief=0; - alpha=beta=alpha_dot=beta_dot=0; - cos_alpha=sin_alpha=cos_beta=sin_beta=0; - cos_phi=sin_phi=cos_theta=sin_theta=cos_psi=sin_psi=0; - gamma_vert_rad=gamma_horiz_rad=0; - sigma=density=v_sound=mach_number=0; - static_pressure=total_pressure=impact_pressure=0; - dynamic_pressure=0; - static_temperature=total_temperature=0; - sea_level_radius=earth_position_angle=0; - runway_altitude=runway_latitude=runway_longitude=0; - runway_heading=0; - radius_to_rwy=0; - climb_rate=0; - sin_lat_geocentric=cos_lat_geocentric=0; - sin_longitude=cos_longitude=0; + init_vec( d_pilot_rp_body_v ); + init_vec( d_cg_rp_body_v ); + init_vec( f_body_total_v ); + init_vec( f_local_total_v ); + init_vec( f_aero_v ); + init_vec( f_engine_v ); + init_vec( f_gear_v ); + init_vec( m_total_rp_v ); + init_vec( m_total_cg_v ); + init_vec( m_aero_v ); + init_vec( m_engine_v ); + init_vec( m_gear_v ); + init_vec( v_dot_local_v ); + init_vec( v_dot_body_v ); + init_vec( a_cg_body_v ); + init_vec( a_pilot_body_v ); + init_vec( n_cg_body_v ); + init_vec( n_pilot_body_v ); + init_vec( omega_dot_body_v ); + init_vec( v_local_v ); + init_vec( v_local_rel_ground_v ); + init_vec( v_local_airmass_v ); + init_vec( v_local_rel_airmass_v ); + init_vec( v_local_gust_v ); + init_vec( v_wind_body_v ); + init_vec( omega_body_v ); + init_vec( omega_local_v ); + init_vec( omega_total_v ); + init_vec( euler_rates_v ); + init_vec( geocentric_rates_v ); + init_vec( geocentric_position_v ); + init_vec( geodetic_position_v ); + init_vec( euler_angles_v ); + init_vec( d_cg_rwy_local_v ); + init_vec( d_cg_rwy_rwy_v ); + init_vec( d_pilot_rwy_local_v ); + init_vec( d_pilot_rwy_rwy_v ); + init_vec( t_local_to_body_m[0] ); + init_vec( t_local_to_body_m[1] ); + init_vec( t_local_to_body_m[2] ); + + mass=i_xx=i_yy=i_zz=i_xz=0; + nlf=0; + v_rel_wind=v_true_kts=v_rel_ground=v_inertial=0; + v_ground_speed=v_equiv=v_equiv_kts=0; + v_calibrated=v_calibrated_kts=0; + gravity=0; + centrifugal_relief=0; + alpha=beta=alpha_dot=beta_dot=0; + cos_alpha=sin_alpha=cos_beta=sin_beta=0; + cos_phi=sin_phi=cos_theta=sin_theta=cos_psi=sin_psi=0; + gamma_vert_rad=gamma_horiz_rad=0; + sigma=density=v_sound=mach_number=0; + static_pressure=total_pressure=impact_pressure=0; + dynamic_pressure=0; + static_temperature=total_temperature=0; + sea_level_radius=earth_position_angle=0; + runway_altitude=runway_latitude=runway_longitude=0; + runway_heading=0; + radius_to_rwy=0; + climb_rate=0; + sin_lat_geocentric=cos_lat_geocentric=0; + sin_latitude=cos_latitude=0; + sin_longitude=cos_longitude=0; + altitude_agl=0; + + resetNeeded=false; } @@ -131,9 +199,9 @@ void fgFDMForceAltitude(int model, double alt_meters) { &sea_level_radius_meters, &lat_geoc); base_fdm_state.set_Altitude( alt_meters * METER_TO_FEET ); - base_fdm_state.set_Radius_to_vehicle( base_fdm_state.get_Altitude() + - (sea_level_radius_meters * - METER_TO_FEET) ); + base_fdm_state.set_Sea_level_radius( sea_level_radius_meters * + METER_TO_FEET ); + // additional work needed for some flight models if ( model == FGInterface::FG_LARCSIM ) { @@ -144,8 +212,196 @@ void fgFDMForceAltitude(int model, double alt_meters) { // Set the local ground elevation void fgFDMSetGroundElevation(int model, double ground_meters) { + FG_LOG( FG_FLIGHT,FG_INFO, "fgFDMSetGroundElevation: " + << ground_meters*METER_TO_FEET ); base_fdm_state.set_Runway_altitude( ground_meters * METER_TO_FEET ); cur_fdm_state->set_Runway_altitude( ground_meters * METER_TO_FEET ); } +// Positions +void FGInterface::set_Latitude(double lat) { + geodetic_position_v[0] = lat; +} + +void FGInterface::set_Longitude(double lon) { + geodetic_position_v[1] = lon; +} + +void FGInterface::set_Altitude(double alt) { + geodetic_position_v[2] = alt; +} + +void FGInterface::set_AltitudeAGL(double altagl) { + altitude_agl=altagl; +} + +// Velocities +void FGInterface::set_V_calibrated_kts(double vc) { + v_calibrated_kts = vc; +} + +void FGInterface::set_Mach_number(double mach) { + mach_number = mach; +} + +void FGInterface::set_Velocities_Local( double north, + double east, + double down ){ + v_local_v[0] = north; + v_local_v[1] = east; + v_local_v[2] = down; +} + +void FGInterface::set_Velocities_Wind_Body( double u, + double v, + double w){ + v_wind_body_v[0] = u; + v_wind_body_v[1] = v; + v_wind_body_v[2] = w; +} + +// Euler angles +void FGInterface::set_Euler_Angles( double phi, + double theta, + double psi ) { + euler_angles_v[0] = phi; + euler_angles_v[1] = theta; + euler_angles_v[2] = psi; +} + +// Flight Path +void FGInterface::set_Climb_Rate( double roc) { + climb_rate = roc; +} + +void FGInterface::set_Gamma_vert_rad( double gamma) { + gamma_vert_rad = gamma; +} + +// Earth +void FGInterface::set_Sea_level_radius(double slr) { + sea_level_radius = slr; +} + +void FGInterface::set_Runway_altitude(double ralt) { + runway_altitude = ralt; +} + +void FGInterface::set_Static_pressure(double p) { static_pressure = p; } +void FGInterface::set_Static_temperature(double T) { static_temperature = T; } +void FGInterface::set_Density(double rho) { density = rho; } + +void FGInterface::set_Velocities_Local_Airmass (double wnorth, + double weast, + double wdown ) { + v_local_airmass_v[0] = wnorth; + v_local_airmass_v[1] = weast; + v_local_airmass_v[2] = wdown; +} + + +void FGInterface::busdump(void) { + + FG_LOG(FG_FLIGHT,FG_INFO,"d_pilot_rp_body_v[3]: " << d_pilot_rp_body_v[0] << ", " << d_pilot_rp_body_v[1] << ", " << d_pilot_rp_body_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"d_cg_rp_body_v[3]: " << d_cg_rp_body_v[0] << ", " << d_cg_rp_body_v[1] << ", " << d_cg_rp_body_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"f_body_total_v[3]: " << f_body_total_v[0] << ", " << f_body_total_v[1] << ", " << f_body_total_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"f_local_total_v[3]: " << f_local_total_v[0] << ", " << f_local_total_v[1] << ", " << f_local_total_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"f_aero_v[3]: " << f_aero_v[0] << ", " << f_aero_v[1] << ", " << f_aero_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"f_engine_v[3]: " << f_engine_v[0] << ", " << f_engine_v[1] << ", " << f_engine_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"f_gear_v[3]: " << f_gear_v[0] << ", " << f_gear_v[1] << ", " << f_gear_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"m_total_rp_v[3]: " << m_total_rp_v[0] << ", " << m_total_rp_v[1] << ", " << m_total_rp_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"m_total_cg_v[3]: " << m_total_cg_v[0] << ", " << m_total_cg_v[1] << ", " << m_total_cg_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"m_aero_v[3]: " << m_aero_v[0] << ", " << m_aero_v[1] << ", " << m_aero_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"m_engine_v[3]: " << m_engine_v[0] << ", " << m_engine_v[1] << ", " << m_engine_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"m_gear_v[3]: " << m_gear_v[0] << ", " << m_gear_v[1] << ", " << m_gear_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"v_dot_local_v[3]: " << v_dot_local_v[0] << ", " << v_dot_local_v[1] << ", " << v_dot_local_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"v_dot_body_v[3]: " << v_dot_body_v[0] << ", " << v_dot_body_v[1] << ", " << v_dot_body_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"a_cg_body_v[3]: " << a_cg_body_v[0] << ", " << a_cg_body_v[1] << ", " << a_cg_body_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"a_pilot_body_v[3]: " << a_pilot_body_v[0] << ", " << a_pilot_body_v[1] << ", " << a_pilot_body_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"n_cg_body_v[3]: " << n_cg_body_v[0] << ", " << n_cg_body_v[1] << ", " << n_cg_body_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"n_pilot_body_v[3]: " << n_pilot_body_v[0] << ", " << n_pilot_body_v[1] << ", " << n_pilot_body_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"omega_dot_body_v[3]: " << omega_dot_body_v[0] << ", " << omega_dot_body_v[1] << ", " << omega_dot_body_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"v_local_v[3]: " << v_local_v[0] << ", " << v_local_v[1] << ", " << v_local_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"v_local_rel_ground_v[3]: " << v_local_rel_ground_v[0] << ", " << v_local_rel_ground_v[1] << ", " << v_local_rel_ground_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"v_local_airmass_v[3]: " << v_local_airmass_v[0] << ", " << v_local_airmass_v[1] << ", " << v_local_airmass_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"v_local_rel_airmass_v[3]: " << v_local_rel_airmass_v[0] << ", " << v_local_rel_airmass_v[1] << ", " << v_local_rel_airmass_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"v_local_gust_v[3]: " << v_local_gust_v[0] << ", " << v_local_gust_v[1] << ", " << v_local_gust_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"v_wind_body_v[3]: " << v_wind_body_v[0] << ", " << v_wind_body_v[1] << ", " << v_wind_body_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"omega_body_v[3]: " << omega_body_v[0] << ", " << omega_body_v[1] << ", " << omega_body_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"omega_local_v[3]: " << omega_local_v[0] << ", " << omega_local_v[1] << ", " << omega_local_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"omega_total_v[3]: " << omega_total_v[0] << ", " << omega_total_v[1] << ", " << omega_total_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"euler_rates_v[3]: " << euler_rates_v[0] << ", " << euler_rates_v[1] << ", " << euler_rates_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"geocentric_rates_v[3]: " << geocentric_rates_v[0] << ", " << geocentric_rates_v[1] << ", " << geocentric_rates_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"geocentric_position_v[3]: " << geocentric_position_v[0] << ", " << geocentric_position_v[1] << ", " << geocentric_position_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"geodetic_position_v[3]: " << geodetic_position_v[0] << ", " << geodetic_position_v[1] << ", " << geodetic_position_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"euler_angles_v[3]: " << euler_angles_v[0] << ", " << euler_angles_v[1] << ", " << euler_angles_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"d_cg_rwy_local_v[3]: " << d_cg_rwy_local_v[0] << ", " << d_cg_rwy_local_v[1] << ", " << d_cg_rwy_local_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"d_cg_rwy_rwy_v[3]: " << d_cg_rwy_rwy_v[0] << ", " << d_cg_rwy_rwy_v[1] << ", " << d_cg_rwy_rwy_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"d_pilot_rwy_local_v[3]: " << d_pilot_rwy_local_v[0] << ", " << d_pilot_rwy_local_v[1] << ", " << d_pilot_rwy_local_v[2]); + FG_LOG(FG_FLIGHT,FG_INFO,"d_pilot_rwy_rwy_v[3]: " << d_pilot_rwy_rwy_v[0] << ", " << d_pilot_rwy_rwy_v[1] << ", " << d_pilot_rwy_rwy_v[2]); + + FG_LOG(FG_FLIGHT,FG_INFO,"t_local_to_body_m[0][3]: " << t_local_to_body_m[0][0] << ", " << t_local_to_body_m[0][1] << ", " << t_local_to_body_m[0][2]); + FG_LOG(FG_FLIGHT,FG_INFO,"t_local_to_body_m[1][3]: " << t_local_to_body_m[1][0] << ", " << t_local_to_body_m[1][1] << ", " << t_local_to_body_m[1][2]); + FG_LOG(FG_FLIGHT,FG_INFO,"t_local_to_body_m[2][3]: " << t_local_to_body_m[2][0] << ", " << t_local_to_body_m[2][1] << ", " << t_local_to_body_m[2][2]); + + FG_LOG(FG_FLIGHT,FG_INFO,"mass: " << mass ); + FG_LOG(FG_FLIGHT,FG_INFO,"i_xx: " << i_xx ); + FG_LOG(FG_FLIGHT,FG_INFO,"i_yy: " << i_yy ); + FG_LOG(FG_FLIGHT,FG_INFO,"i_zz: " << i_zz ); + FG_LOG(FG_FLIGHT,FG_INFO,"i_xz: " << i_xz ); + FG_LOG(FG_FLIGHT,FG_INFO,"nlf: " << nlf ); + FG_LOG(FG_FLIGHT,FG_INFO,"v_rel_wind: " << v_rel_wind ); + FG_LOG(FG_FLIGHT,FG_INFO,"v_true_kts: " << v_true_kts ); + FG_LOG(FG_FLIGHT,FG_INFO,"v_rel_ground: " << v_rel_ground ); + FG_LOG(FG_FLIGHT,FG_INFO,"v_inertial: " << v_inertial ); + FG_LOG(FG_FLIGHT,FG_INFO,"v_ground_speed: " << v_ground_speed ); + FG_LOG(FG_FLIGHT,FG_INFO,"v_equiv: " << v_equiv ); + FG_LOG(FG_FLIGHT,FG_INFO,"v_equiv_kts: " << v_equiv_kts ); + FG_LOG(FG_FLIGHT,FG_INFO,"v_calibrated: " << v_calibrated ); + FG_LOG(FG_FLIGHT,FG_INFO,"v_calibrated_kts: " << v_calibrated_kts ); + FG_LOG(FG_FLIGHT,FG_INFO,"gravity: " << gravity ); + FG_LOG(FG_FLIGHT,FG_INFO,"centrifugal_relief: " << centrifugal_relief ); + FG_LOG(FG_FLIGHT,FG_INFO,"alpha: " << alpha ); + FG_LOG(FG_FLIGHT,FG_INFO,"beta: " << beta ); + FG_LOG(FG_FLIGHT,FG_INFO,"alpha_dot: " << alpha_dot ); + FG_LOG(FG_FLIGHT,FG_INFO,"beta_dot: " << beta_dot ); + FG_LOG(FG_FLIGHT,FG_INFO,"cos_alpha: " << cos_alpha ); + FG_LOG(FG_FLIGHT,FG_INFO,"sin_alpha: " << sin_alpha ); + FG_LOG(FG_FLIGHT,FG_INFO,"cos_beta: " << cos_beta ); + FG_LOG(FG_FLIGHT,FG_INFO,"sin_beta: " << sin_beta ); + FG_LOG(FG_FLIGHT,FG_INFO,"cos_phi: " << cos_phi ); + FG_LOG(FG_FLIGHT,FG_INFO,"sin_phi: " << sin_phi ); + FG_LOG(FG_FLIGHT,FG_INFO,"cos_theta: " << cos_theta ); + FG_LOG(FG_FLIGHT,FG_INFO,"sin_theta: " << sin_theta ); + FG_LOG(FG_FLIGHT,FG_INFO,"cos_psi: " << cos_psi ); + FG_LOG(FG_FLIGHT,FG_INFO,"sin_psi: " << sin_psi ); + FG_LOG(FG_FLIGHT,FG_INFO,"gamma_vert_rad: " << gamma_vert_rad ); + FG_LOG(FG_FLIGHT,FG_INFO,"gamma_horiz_rad: " << gamma_horiz_rad ); + FG_LOG(FG_FLIGHT,FG_INFO,"sigma: " << sigma ); + FG_LOG(FG_FLIGHT,FG_INFO,"density: " << density ); + FG_LOG(FG_FLIGHT,FG_INFO,"v_sound: " << v_sound ); + FG_LOG(FG_FLIGHT,FG_INFO,"mach_number: " << mach_number ); + FG_LOG(FG_FLIGHT,FG_INFO,"static_pressure: " << static_pressure ); + FG_LOG(FG_FLIGHT,FG_INFO,"total_pressure: " << total_pressure ); + FG_LOG(FG_FLIGHT,FG_INFO,"impact_pressure: " << impact_pressure ); + FG_LOG(FG_FLIGHT,FG_INFO,"dynamic_pressure: " << dynamic_pressure ); + FG_LOG(FG_FLIGHT,FG_INFO,"static_temperature: " << static_temperature ); + FG_LOG(FG_FLIGHT,FG_INFO,"total_temperature: " << total_temperature ); + FG_LOG(FG_FLIGHT,FG_INFO,"sea_level_radius: " << sea_level_radius ); + FG_LOG(FG_FLIGHT,FG_INFO,"earth_position_angle: " << earth_position_angle ); + FG_LOG(FG_FLIGHT,FG_INFO,"runway_altitude: " << runway_altitude ); + FG_LOG(FG_FLIGHT,FG_INFO,"runway_latitude: " << runway_latitude ); + FG_LOG(FG_FLIGHT,FG_INFO,"runway_longitude: " << runway_longitude ); + FG_LOG(FG_FLIGHT,FG_INFO,"runway_heading: " << runway_heading ); + FG_LOG(FG_FLIGHT,FG_INFO,"radius_to_rwy: " << radius_to_rwy ); + FG_LOG(FG_FLIGHT,FG_INFO,"climb_rate: " << climb_rate ); + FG_LOG(FG_FLIGHT,FG_INFO,"sin_lat_geocentric: " << sin_lat_geocentric ); + FG_LOG(FG_FLIGHT,FG_INFO,"cos_lat_geocentric: " << cos_lat_geocentric ); + FG_LOG(FG_FLIGHT,FG_INFO,"sin_longitude: " << sin_longitude ); + FG_LOG(FG_FLIGHT,FG_INFO,"cos_longitude: " << cos_longitude ); + FG_LOG(FG_FLIGHT,FG_INFO,"sin_latitude: " << sin_latitude ); + FG_LOG(FG_FLIGHT,FG_INFO,"cos_latitude: " << cos_latitude ); + FG_LOG(FG_FLIGHT,FG_INFO,"altitude_agl: " << altitude_agl ); +} + diff --git a/src/FDM/flight.hxx b/src/FDM/flight.hxx index 81a15cabb..0e333d2af 100644 --- a/src/FDM/flight.hxx +++ b/src/FDM/flight.hxx @@ -113,9 +113,22 @@ private: double Percentage_Power; double EGT; double prop_thrust; + + /* others... + double PercentN1,N1; //GE,CFM + double PercentN2,N2; + double EPR; //P&W, RR? + double FuelFlow; + bool AfterBurner; + double InletAngles[3]; + double InletPosition[3]; + double ThrustVector[3]; + */ public: - + FGEngInterface(void); + ~FGEngInterface(void); + inline double get_Throttle() const { return Throttle; } inline double get_Mixture() const { return Mixture; } inline double get_Prop_Advance() const { return Prop_Advance; } @@ -144,6 +157,10 @@ typedef vector < FGEngInterface > engine_list; // This is based heavily on LaRCsim/ls_generic.h class FGInterface { +protected: + + void busdump(void); + private: // Pilot location rel to ref pt @@ -231,6 +248,10 @@ private: double sin_lat_geocentric, cos_lat_geocentric; double sin_longitude, cos_longitude; double sin_latitude, cos_latitude; + double altitude_agl; + + //change flag + bool resetNeeded; // Engine list engine_list engines; @@ -238,6 +259,157 @@ private: FGTimeStamp valid_stamp; // time this record is valid FGTimeStamp next_stamp; // time this record is valid +protected: + + inline void _set_Inertias( double m, double xx, double yy, + double zz, double xz) + { + mass = m; + i_xx = xx; + i_yy = yy; + i_zz = zz; + i_xz = xz; + } + inline void _set_CG_Position( double dx, double dy, double dz ) { + d_cg_rp_body_v[0] = dx; + d_cg_rp_body_v[1] = dy; + d_cg_rp_body_v[2] = dz; + } + inline void _set_Accels_Local( double north, double east, double down ) { + v_dot_local_v[0] = north; + v_dot_local_v[1] = east; + v_dot_local_v[2] = down; + } + inline void _set_Accels_Body( double u, double v, double w ) { + v_dot_body_v[0] = u; + v_dot_body_v[1] = v; + v_dot_body_v[2] = w; + } + inline void _set_Accels_CG_Body( double x, double y, double z ) { + a_cg_body_v[0] = x; + a_cg_body_v[1] = y; + a_cg_body_v[2] = z; + } + inline void _set_Accels_Pilot_Body( double x, double y, double z ) { + a_pilot_body_v[0] = x; + a_pilot_body_v[1] = y; + a_pilot_body_v[2] = z; + } + inline void _set_Accels_CG_Body_N( double x, double y, double z ) { + n_cg_body_v[0] = x; + n_cg_body_v[1] = y; + n_cg_body_v[2] = z; + } + void _set_Nlf(double n) { nlf=n; } + inline void _set_Velocities_Local( double north, double east, double down ){ + v_local_v[0] = north; + v_local_v[1] = east; + v_local_v[2] = down; + } + inline void _set_Velocities_Ground(double north, double east, double down) { + v_local_rel_ground_v[0] = north; + v_local_rel_ground_v[1] = east; + v_local_rel_ground_v[2] = down; + } + inline void _set_Velocities_Local_Airmass( double north, double east, + double down) + { + v_local_airmass_v[0] = north; + v_local_airmass_v[1] = east; + v_local_airmass_v[2] = down; + } + inline void _set_Velocities_Wind_Body( double u, double v, double w) { + v_wind_body_v[0] = u; + v_wind_body_v[1] = v; + v_wind_body_v[2] = w; + } + inline void _set_V_ground_speed( double v) { v_ground_speed = v; } + inline void _set_V_equiv_kts( double kts ) { v_equiv_kts = kts; } + inline void _set_V_calibrated_kts( double kts ) { v_calibrated_kts = kts; } + inline void _set_Omega_Body( double p, double q, double r ) { + omega_body_v[0] = p; + omega_body_v[1] = q; + omega_body_v[2] = r; + } + inline void _set_Euler_Rates( double phi, double theta, double psi ) { + euler_rates_v[0] = phi; + euler_rates_v[1] = theta; + euler_rates_v[2] = psi; + } + inline void _set_Geocentric_Rates( double lat, double lon, double rad ) { + geocentric_rates_v[0] = lat; + geocentric_rates_v[1] = lon; + geocentric_rates_v[2] = rad; + } +#if 0 + inline void _set_Radius_to_vehicle(double radius) { + geocentric_position_v[2] = radius; + } +#endif + inline void _set_Geocentric_Position( double lat, double lon, double rad ) { + geocentric_position_v[0] = lat; + geocentric_position_v[1] = lon; + geocentric_position_v[2] = rad; + } + inline void _set_Latitude(double lat) { geodetic_position_v[0] = lat; } + inline void _set_Longitude(double lon) { geodetic_position_v[1] = lon; } + inline void _set_Altitude(double altitude) { + geodetic_position_v[2] = altitude; + } + inline void _set_Altitude_AGL(double agl) { + altitude_agl = agl; + } + inline void _set_Geodetic_Position( double lat, double lon, double alt ) { + geodetic_position_v[0] = lat; + geodetic_position_v[1] = lon; + geodetic_position_v[2] = alt; + } + inline void _set_Euler_Angles( double phi, double theta, double psi ) { + euler_angles_v[0] = phi; + euler_angles_v[1] = theta; + euler_angles_v[2] = psi; + } + inline void _set_T_Local_to_Body( int i, int j, double value) { + t_local_to_body_m[i-1][j-1] = value; + } + inline void _set_T_Local_to_Body( double m[3][3] ) { + int i, j; + for ( i = 0; i < 3; i++ ) { + for ( j = 0; j < 3; j++ ) { + t_local_to_body_m[i][j] = m[i][j]; + } + } + } + inline void _set_Alpha( double a ) { alpha = a; } + inline void _set_Beta( double b ) { beta = b; } + inline void _set_Cos_phi( double cp ) { cos_phi = cp; } + inline void _set_Cos_theta( double ct ) { cos_theta = ct; } + inline void _set_Gamma_vert_rad( double gv ) { gamma_vert_rad = gv; } + inline void _set_Density( double d ) { density = d; } + inline void _set_Mach_number( double m ) { mach_number = m; } + inline void _set_Static_pressure( double sp ) { static_pressure = sp; } + inline void _set_Static_temperature( double t ) { static_temperature = t; } + inline void _set_Sea_level_radius( double r ) { sea_level_radius = r; } + inline void _set_Earth_position_angle(double a) { + earth_position_angle = a; + } + inline void _set_Runway_altitude( double alt ) { runway_altitude = alt; } + inline void _set_Climb_Rate(double rate) { climb_rate = rate; } + inline void _set_sin_lat_geocentric(double parm) { + sin_lat_geocentric = sin(parm); + } + inline void _set_cos_lat_geocentric(double parm) { + cos_lat_geocentric = cos(parm); + } + inline void _set_sin_cos_longitude(double parm) { + sin_longitude = sin(parm); + cos_longitude = cos(parm); + } + inline void _set_sin_cos_latitude(double parm) { + sin_latitude = sin(parm); + cos_latitude = cos(parm); + } + public: FGInterface(void); @@ -260,7 +432,7 @@ public: // Christian's hot air balloon simulation FG_BALLOONSIM = 3, - // AEronautical DEvelopment AGEncy, Bangalore India + // Aeronautical DEvelopment AGEncy, Bangalore India FG_ADA = 4, // The following aren't implemented but are here to spark @@ -275,6 +447,38 @@ public: FG_EXTERNAL = 10 }; + // Positions + virtual void set_Latitude(double lat); // geocentric + virtual void set_Longitude(double lon); + virtual void set_Altitude(double alt); // triggers re-calc of AGL altitude + virtual void set_AltitudeAGL(double altagl); // and vice-versa + + // Speeds -- setting any of these will trigger a re-calc of the rest + virtual void set_V_calibrated_kts(double vc); + virtual void set_Mach_number(double mach); + virtual void set_Velocities_Local( double north, double east, double down ); + virtual void set_Velocities_Wind_Body( double u, double v, double w); + + // Euler angles + virtual void set_Euler_Angles( double phi, double theta, double psi ); + + // Flight Path + virtual void set_Climb_Rate( double roc); + virtual void set_Gamma_vert_rad( double gamma); + + // Earth + virtual void set_Sea_level_radius(double slr); + virtual void set_Runway_altitude(double ralt); + + virtual void set_Static_pressure(double p); + virtual void set_Static_temperature(double T); + virtual void set_Density(double rho); + + virtual void set_Velocities_Local_Airmass (double wnorth, + double weast, + double wdown ); + + // ========== Mass properties and geometry values ========== // Inertias @@ -283,15 +487,6 @@ public: inline double get_I_yy() const { return i_yy; } inline double get_I_zz() const { return i_zz; } inline double get_I_xz() const { return i_xz; } - inline void set_Inertias( double m, double xx, double yy, - double zz, double xz) - { - mass = m; - i_xx = xx; - i_yy = yy; - i_zz = zz; - i_xz = xz; - } // Pilot location rel to ref pt // inline double * get_D_pilot_rp_body_v() { @@ -311,11 +506,6 @@ public: inline double get_Dx_cg() const { return d_cg_rp_body_v[0]; } inline double get_Dy_cg() const { return d_cg_rp_body_v[1]; } inline double get_Dz_cg() const { return d_cg_rp_body_v[2]; } - inline void set_CG_Position( double dx, double dy, double dz ) { - d_cg_rp_body_v[0] = dx; - d_cg_rp_body_v[1] = dy; - d_cg_rp_body_v[2] = dz; - } // ========== Forces ========== @@ -427,51 +617,26 @@ public: inline double get_V_dot_north() const { return v_dot_local_v[0]; } inline double get_V_dot_east() const { return v_dot_local_v[1]; } inline double get_V_dot_down() const { return v_dot_local_v[2]; } - inline void set_Accels_Local( double north, double east, double down ) { - v_dot_local_v[0] = north; - v_dot_local_v[1] = east; - v_dot_local_v[2] = down; - } // inline double * get_V_dot_body_v() { return v_dot_body_v; } inline double get_U_dot_body() const { return v_dot_body_v[0]; } inline double get_V_dot_body() const { return v_dot_body_v[1]; } inline double get_W_dot_body() const { return v_dot_body_v[2]; } - inline void set_Accels_Body( double u, double v, double w ) { - v_dot_body_v[0] = u; - v_dot_body_v[1] = v; - v_dot_body_v[2] = w; - } // inline double * get_A_cg_body_v() { return a_cg_body_v; } inline double get_A_X_cg() const { return a_cg_body_v[0]; } inline double get_A_Y_cg() const { return a_cg_body_v[1]; } inline double get_A_Z_cg() const { return a_cg_body_v[2]; } - inline void set_Accels_CG_Body( double x, double y, double z ) { - a_cg_body_v[0] = x; - a_cg_body_v[1] = y; - a_cg_body_v[2] = z; - } // inline double * get_A_pilot_body_v() { return a_pilot_body_v; } inline double get_A_X_pilot() const { return a_pilot_body_v[0]; } inline double get_A_Y_pilot() const { return a_pilot_body_v[1]; } inline double get_A_Z_pilot() const { return a_pilot_body_v[2]; } - inline void set_Accels_Pilot_Body( double x, double y, double z ) { - a_pilot_body_v[0] = x; - a_pilot_body_v[1] = y; - a_pilot_body_v[2] = z; - } // inline double * get_N_cg_body_v() { return n_cg_body_v; } inline double get_N_X_cg() const { return n_cg_body_v[0]; } inline double get_N_Y_cg() const { return n_cg_body_v[1]; } inline double get_N_Z_cg() const { return n_cg_body_v[2]; } - inline void set_Accels_CG_Body_N( double x, double y, double z ) { - n_cg_body_v[0] = x; - n_cg_body_v[1] = y; - n_cg_body_v[2] = z; - } // inline double * get_N_pilot_body_v() { return n_pilot_body_v; } // inline double get_N_X_pilot() const { return n_pilot_body_v[0]; } @@ -483,8 +648,7 @@ public: // n_pilot_body_v[2] = z; // } - double get_Nlf(void) { return nlf; } - void set_Nlf(double n) { nlf=n; } + inline double get_Nlf(void) { return nlf; } // inline double * get_Omega_dot_body_v() { return omega_dot_body_v; } // inline double get_P_dot_body() const { return omega_dot_body_v[0]; } @@ -503,41 +667,24 @@ public: inline double get_V_north() const { return v_local_v[0]; } inline double get_V_east() const { return v_local_v[1]; } inline double get_V_down() const { return v_local_v[2]; } - inline void set_Velocities_Local( double north, double east, double down ) { - v_local_v[0] = north; - v_local_v[1] = east; - v_local_v[2] = down; - } // inline double * get_V_local_rel_ground_v() { // return v_local_rel_ground_v; // } - inline double get_V_north_rel_ground() const { - return v_local_rel_ground_v[0]; - } - inline double get_V_east_rel_ground() const { - return v_local_rel_ground_v[1]; - } - inline double get_V_down_rel_ground() const { - return v_local_rel_ground_v[2]; - } - inline void set_Velocities_Ground(double north, double east, double down) { - v_local_rel_ground_v[0] = north; - v_local_rel_ground_v[1] = east; - v_local_rel_ground_v[2] = down; - } + // inline double get_V_north_rel_ground() const { + // return v_local_rel_ground_v[0]; + // } + // inline double get_V_east_rel_ground() const { + // return v_local_rel_ground_v[1]; + // } + // inline double get_V_down_rel_ground() const { + // return v_local_rel_ground_v[2]; + // } // inline double * get_V_local_airmass_v() { return v_local_airmass_v; } inline double get_V_north_airmass() const { return v_local_airmass_v[0]; } inline double get_V_east_airmass() const { return v_local_airmass_v[1]; } inline double get_V_down_airmass() const { return v_local_airmass_v[2]; } - inline void set_Velocities_Local_Airmass( double north, double east, - double down) - { - v_local_airmass_v[0] = north; - v_local_airmass_v[1] = east; - v_local_airmass_v[2] = down; - } // airmass // inline double * get_V_local_rel_airmass_v() { @@ -575,11 +722,6 @@ public: inline double get_U_body() const { return v_wind_body_v[0]; } inline double get_V_body() const { return v_wind_body_v[1]; } inline double get_W_body() const { return v_wind_body_v[2]; } - inline void set_Velocities_Wind_Body( double u, double v, double w) { - v_wind_body_v[0] = u; - v_wind_body_v[1] = v; - v_wind_body_v[2] = w; - } // inline double get_V_rel_wind() const { return v_rel_wind; } // inline void set_V_rel_wind(double wind) { v_rel_wind = wind; } @@ -594,29 +736,21 @@ public: // inline void set_V_inertial(double v) { v_inertial = v; } inline double get_V_ground_speed() const { return v_ground_speed; } - inline void set_V_ground_speed( double v) { v_ground_speed = v; } // inline double get_V_equiv() const { return v_equiv; } // inline void set_V_equiv( double v ) { v_equiv = v; } inline double get_V_equiv_kts() const { return v_equiv_kts; } - inline void set_V_equiv_kts( double kts ) { v_equiv_kts = kts; } //inline double get_V_calibrated() const { return v_calibrated; } //inline void set_V_calibrated( double v ) { v_calibrated = v; } inline double get_V_calibrated_kts() const { return v_calibrated_kts; } - inline void set_V_calibrated_kts( double kts ) { v_calibrated_kts = kts; } // inline double * get_Omega_body_v() { return omega_body_v; } inline double get_P_body() const { return omega_body_v[0]; } inline double get_Q_body() const { return omega_body_v[1]; } inline double get_R_body() const { return omega_body_v[2]; } - inline void set_Omega_Body( double p, double q, double r ) { - omega_body_v[0] = p; - omega_body_v[1] = q; - omega_body_v[2] = r; - } // inline double * get_Omega_local_v() { return omega_local_v; } // inline double get_P_local() const { return omega_local_v[0]; } @@ -642,21 +776,11 @@ public: inline double get_Phi_dot() const { return euler_rates_v[0]; } inline double get_Theta_dot() const { return euler_rates_v[1]; } inline double get_Psi_dot() const { return euler_rates_v[2]; } - inline void set_Euler_Rates( double phi, double theta, double psi ) { - euler_rates_v[0] = phi; - euler_rates_v[1] = theta; - euler_rates_v[2] = psi; - } // inline double * get_Geocentric_rates_v() { return geocentric_rates_v; } inline double get_Latitude_dot() const { return geocentric_rates_v[0]; } inline double get_Longitude_dot() const { return geocentric_rates_v[1]; } inline double get_Radius_dot() const { return geocentric_rates_v[2]; } - inline void set_Geocentric_Rates( double lat, double lon, double rad ) { - geocentric_rates_v[0] = lat; - geocentric_rates_v[1] = lon; - geocentric_rates_v[2] = rad; - } // ========== Positions ========== @@ -672,40 +796,17 @@ public: inline double get_Radius_to_vehicle() const { return geocentric_position_v[2]; } - inline void set_Radius_to_vehicle(double radius) { - geocentric_position_v[2] = radius; - } - - inline void set_Geocentric_Position( double lat, double lon, double rad ) { - geocentric_position_v[0] = lat; - geocentric_position_v[1] = lon; - geocentric_position_v[2] = rad; - } // inline double * get_Geodetic_position_v() { return geodetic_position_v; } inline double get_Latitude() const { return geodetic_position_v[0]; } - inline void set_Latitude(double lat) { geodetic_position_v[0] = lat; } inline double get_Longitude() const { return geodetic_position_v[1]; } - inline void set_Longitude(double lon) { geodetic_position_v[1] = lon; } inline double get_Altitude() const { return geodetic_position_v[2]; } - inline void set_Altitude(double altitude) { - geodetic_position_v[2] = altitude; - } - inline void set_Geodetic_Position( double lat, double lon, double alt ) { - geodetic_position_v[0] = lat; - geodetic_position_v[1] = lon; - geodetic_position_v[2] = alt; - } + inline double get_Altitude_AGL(void) { return altitude_agl; } // inline double * get_Euler_angles_v() { return euler_angles_v; } inline double get_Phi() const { return euler_angles_v[0]; } inline double get_Theta() const { return euler_angles_v[1]; } inline double get_Psi() const { return euler_angles_v[2]; } - inline void set_Euler_Angles( double phi, double theta, double psi ) { - euler_angles_v[0] = phi; - euler_angles_v[1] = theta; - euler_angles_v[2] = psi; - } // ========== Miscellaneous quantities ========== @@ -738,17 +839,6 @@ public: inline double get_T_local_to_body_33() const { return t_local_to_body_m[2][2]; } - inline void set_T_Local_to_Body( int i, int j, double value) { - t_local_to_body_m[i-1][j-1] = value; - } - inline void set_T_Local_to_Body( double m[3][3] ) { - int i, j; - for ( i = 0; i < 3; i++ ) { - for ( j = 0; j < 3; j++ ) { - t_local_to_body_m[i][j] = m[i][j]; - } - } - } // inline double get_Gravity() const { return gravity; } // inline void set_Gravity(double g) { gravity = g; } @@ -761,9 +851,7 @@ public: // } inline double get_Alpha() const { return alpha; } - inline void set_Alpha( double a ) { alpha = a; } inline double get_Beta() const { return beta; } - inline void set_Beta( double b ) { beta = b; } // inline double get_Alpha_dot() const { return alpha_dot; } // inline void set_Alpha_dot( double ad ) { alpha_dot = ad; } // inline double get_Beta_dot() const { return beta_dot; } @@ -779,11 +867,9 @@ public: // inline void set_Sin_beta( double sb ) { sin_beta = sb; } inline double get_Cos_phi() const { return cos_phi; } - inline void set_Cos_phi( double cp ) { cos_phi = cp; } // inline double get_Sin_phi() const { return sin_phi; } // inline void set_Sin_phi( double sp ) { sin_phi = sp; } inline double get_Cos_theta() const { return cos_theta; } - inline void set_Cos_theta( double ct ) { cos_theta = ct; } // inline double get_Sin_theta() const { return sin_theta; } // inline void set_Sin_theta( double st ) { sin_theta = st; } // inline double get_Cos_psi() const { return cos_psi; } @@ -792,21 +878,17 @@ public: // inline void set_Sin_psi( double sp ) { sin_psi = sp; } inline double get_Gamma_vert_rad() const { return gamma_vert_rad; } - inline void set_Gamma_vert_rad( double gv ) { gamma_vert_rad = gv; } // inline double get_Gamma_horiz_rad() const { return gamma_horiz_rad; } // inline void set_Gamma_horiz_rad( double gh ) { gamma_horiz_rad = gh; } // inline double get_Sigma() const { return sigma; } // inline void set_Sigma( double s ) { sigma = s; } inline double get_Density() const { return density; } - inline void set_Density( double d ) { density = d; } // inline double get_V_sound() const { return v_sound; } // inline void set_V_sound( double v ) { v_sound = v; } inline double get_Mach_number() const { return mach_number; } - inline void set_Mach_number( double m ) { mach_number = m; } inline double get_Static_pressure() const { return static_pressure; } - inline void set_Static_pressure( double sp ) { static_pressure = sp; } // inline double get_Total_pressure() const { return total_pressure; } // inline void set_Total_pressure( double tp ) { total_pressure = tp; } // inline double get_Impact_pressure() const { return impact_pressure; } @@ -815,21 +897,15 @@ public: // inline void set_Dynamic_pressure( double dp ) { dynamic_pressure = dp; } inline double get_Static_temperature() const { return static_temperature; } - inline void set_Static_temperature( double t ) { static_temperature = t; } // inline double get_Total_temperature() const { return total_temperature; } // inline void set_Total_temperature( double t ) { total_temperature = t; } inline double get_Sea_level_radius() const { return sea_level_radius; } - inline void set_Sea_level_radius( double r ) { sea_level_radius = r; } inline double get_Earth_position_angle() const { return earth_position_angle; } - inline void set_Earth_position_angle(double a) { - earth_position_angle = a; - } inline double get_Runway_altitude() const { return runway_altitude; } - inline void set_Runway_altitude( double alt ) { runway_altitude = alt; } // inline double get_Runway_latitude() const { return runway_latitude; } // inline void set_Runway_latitude( double lat ) { runway_latitude = lat; } // inline double get_Runway_longitude() const { return runway_longitude; } @@ -897,7 +973,6 @@ public: } */ inline double get_Climb_Rate() const { return climb_rate; } - inline void set_Climb_Rate(double rate) { climb_rate = rate; } inline FGTimeStamp get_time_stamp() const { return valid_stamp; } inline void stamp_time() { valid_stamp = next_stamp; next_stamp.stamp(); } @@ -906,12 +981,6 @@ public: void extrapolate( int time_offset ); // sin/cos lat_geocentric - inline void set_sin_lat_geocentric(double parm) { - sin_lat_geocentric = sin(parm); - } - inline void set_cos_lat_geocentric(double parm) { - cos_lat_geocentric = cos(parm); - } inline double get_sin_lat_geocentric(void) const { return sin_lat_geocentric; } @@ -919,10 +988,6 @@ public: return cos_lat_geocentric; } - inline void set_sin_cos_longitude(double parm) { - sin_longitude = sin(parm); - cos_longitude = cos(parm); - } inline double get_sin_longitude(void) const { return sin_longitude; } @@ -930,10 +995,6 @@ public: return cos_longitude; } - inline void set_sin_cos_latitude(double parm) { - sin_latitude = sin(parm); - cos_latitude = cos(parm); - } inline double get_sin_latitude(void) const { return sin_latitude; } diff --git a/src/Main/bfi.cxx b/src/Main/bfi.cxx index 00e13c061..e4fb0fb5e 100644 --- a/src/Main/bfi.cxx +++ b/src/Main/bfi.cxx @@ -768,7 +768,6 @@ void FGBFI::setSpeedNorth (double speed) { if (getSpeedNorth() != speed) { - globals->get_options()->set_uBody(speed); current_aircraft.fdm_state->set_Velocities_Local(speed, getSpeedEast(), getSpeedDown()); @@ -794,7 +793,6 @@ void FGBFI::setSpeedEast (double speed) { if (getSpeedEast() != speed) { - globals->get_options()->set_vBody(speed); current_aircraft.fdm_state->set_Velocities_Local(getSpeedNorth(), speed, getSpeedDown()); @@ -820,7 +818,6 @@ void FGBFI::setSpeedDown (double speed) { if (getSpeedDown() != speed) { - globals->get_options()->set_wBody(speed); current_aircraft.fdm_state->set_Velocities_Local(getSpeedNorth(), getSpeedEast(), speed); diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 2d2fa302f..47d91e8ba 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -342,8 +342,8 @@ bool fgInitPosition( void ) { "starting altitude is = " << globals->get_options()->get_altitude() ); f->set_Altitude( globals->get_options()->get_altitude() * METER_TO_FEET ); - fgFDMSetGroundElevation( globals->get_options()->get_flight_model(), - f->get_Altitude() * FEET_TO_METER ); + // fgFDMSetGroundElevation( globals->get_options()->get_flight_model(), + // f->get_Altitude() * FEET_TO_METER ); #if 0 current_properties.setDoubleValue("/position/longitude", @@ -404,6 +404,36 @@ bool fgInitGeneral( void ) { } +// set initial aircraft speed +bool fgVelocityInit( void ) { + switch(globals->get_options()->get_speedset()) { + case 1: //FG_VC + current_aircraft.fdm_state->set_V_calibrated_kts( + globals->get_options()->get_vc() ); + break; + case 2: //FG_MACH + current_aircraft.fdm_state->set_Mach_number( + globals->get_options()->get_mach() ); + break; + case 3: //FG_VTUVW + current_aircraft.fdm_state->set_Velocities_Wind_Body( + globals->get_options()->get_uBody(), + globals->get_options()->get_vBody(), + globals->get_options()->get_wBody() ); + break; + case 4: //FG_VTNED + current_aircraft.fdm_state->set_Velocities_Local( + globals->get_options()->get_vNorth(), + globals->get_options()->get_vEast(), + globals->get_options()->get_vDown() ); + break; + default: + current_aircraft.fdm_state->set_V_calibrated_kts( 0.0 ); + } + return true; +} + + // This is the top level init routine which calls all the other // initialization routines. If you are adding a subsystem to flight // gear, its initialization call should located in this routine. @@ -469,6 +499,9 @@ bool fgInitSubsystems( void ) { // model or control parameters are set fgAircraftInit(); // In the future this might not be the case. + fgFDMSetGroundElevation( globals->get_options()->get_flight_model(), + scenery.cur_elev ); + // set the initial position fgInitPosition(); @@ -495,9 +528,6 @@ bool fgInitSubsystems( void ) { "Altitude after update " << scenery.cur_elev ); */ - fgFDMSetGroundElevation( globals->get_options()->get_flight_model(), - scenery.cur_elev ); - // Reset our altitude if we are below ground FG_LOG( FG_GENERAL, FG_DEBUG, "Current altitude = " << cur_fdm_state->get_Altitude() ); FG_LOG( FG_GENERAL, FG_DEBUG, "Current runway altitude = " << @@ -522,24 +552,27 @@ bool fgInitSubsystems( void ) { // Set the FG variables first sgGeodToGeoc( cur_fdm_state->get_Latitude(), cur_fdm_state->get_Altitude(), &sea_level_radius_meters, &lat_geoc); - cur_fdm_state->set_Geocentric_Position( lat_geoc, cur_fdm_state->get_Longitude(), + /* cur_fdm_state->set_Geocentric_Position( lat_geoc, cur_fdm_state->get_Longitude(), cur_fdm_state->get_Altitude() + (sea_level_radius_meters * METER_TO_FEET) ); + */ cur_fdm_state->set_Sea_level_radius( sea_level_radius_meters * METER_TO_FEET ); - cur_fdm_state->set_sin_cos_longitude(cur_fdm_state->get_Longitude()); + /* cur_fdm_state->set_sin_cos_longitude(cur_fdm_state->get_Longitude()); cur_fdm_state->set_sin_cos_latitude(cur_fdm_state->get_Latitude()); cur_fdm_state->set_sin_lat_geocentric(sin(lat_geoc)); - cur_fdm_state->set_cos_lat_geocentric(cos(lat_geoc)); + cur_fdm_state->set_cos_lat_geocentric(cos(lat_geoc)); */ + // The following section sets up the flight model EOM parameters // and should really be read in from one or more files. // Initial Velocity - cur_fdm_state->set_Velocities_Local( globals->get_options()->get_uBody(), - globals->get_options()->get_vBody(), - globals->get_options()->get_wBody()); + //cur_fdm_state->set_Velocities_Local( globals->get_options()->get_uBody(), + // globals->get_options()->get_vBody(), + // globals->get_options()->get_wBody()); + fgVelocityInit(); // Initial Orientation cur_fdm_state->set_Euler_Angles( globals->get_options()->get_roll() * DEG_TO_RAD, @@ -547,16 +580,16 @@ bool fgInitSubsystems( void ) { globals->get_options()->get_heading() * DEG_TO_RAD ); // Initial Angular Body rates - cur_fdm_state->set_Omega_Body( 7.206685E-05, 0.0, 9.492658E-05 ); + //cur_fdm_state->set_Omega_Body( 7.206685E-05, 0.0, 9.492658E-05 ); - cur_fdm_state->set_Earth_position_angle( 0.0 ); + //cur_fdm_state->set_Earth_position_angle( 0.0 ); // Mass properties and geometry values - cur_fdm_state->set_Inertias( 8.547270E+01, - 1.048000E+03, 3.000000E+03, 3.530000E+03, 0.000000E+00 ); + //cur_fdm_state->set_Inertias( 8.547270E+01, + // 1.048000E+03, 3.000000E+03, 3.530000E+03, 0.000000E+00 ); // CG position w.r.t. ref. point - cur_fdm_state->set_CG_Position( 0.0, 0.0, 0.0 ); + //cur_fdm_state->set_CG_Position( 0.0, 0.0, 0.0 ); // Initialize the event manager global_events.Init(); @@ -805,24 +838,26 @@ void fgReInitSubsystems( void ) // Set the FG variables first sgGeodToGeoc( cur_fdm_state->get_Latitude(), cur_fdm_state->get_Altitude(), &sea_level_radius_meters, &lat_geoc); - cur_fdm_state->set_Geocentric_Position( lat_geoc, cur_fdm_state->get_Longitude(), + /* cur_fdm_state->set_Geocentric_Position( lat_geoc, cur_fdm_state->get_Longitude(), cur_fdm_state->get_Altitude() + (sea_level_radius_meters * METER_TO_FEET) ); + */ cur_fdm_state->set_Sea_level_radius( sea_level_radius_meters * METER_TO_FEET ); - cur_fdm_state->set_sin_cos_longitude(cur_fdm_state->get_Longitude()); - cur_fdm_state->set_sin_cos_latitude(cur_fdm_state->get_Latitude()); + //cur_fdm_state->set_sin_cos_longitude(cur_fdm_state->get_Longitude()); + //cur_fdm_state->set_sin_cos_latitude(cur_fdm_state->get_Latitude()); - cur_fdm_state->set_sin_lat_geocentric(sin(lat_geoc)); - cur_fdm_state->set_cos_lat_geocentric(cos(lat_geoc)); + //cur_fdm_state->set_sin_lat_geocentric(sin(lat_geoc)); + //cur_fdm_state->set_cos_lat_geocentric(cos(lat_geoc)); // The following section sets up the flight model EOM parameters // and should really be read in from one or more files. // Initial Velocity - cur_fdm_state->set_Velocities_Local( globals->get_options()->get_uBody(), - globals->get_options()->get_vBody(), - globals->get_options()->get_wBody()); + //cur_fdm_state->set_Velocities_Local( globals->get_options()->get_uBody(), + // globals->get_options()->get_vBody(), + // globals->get_options()->get_wBody()); + fgVelocityInit(); // Initial Orientation cur_fdm_state->set_Euler_Angles( globals->get_options()->get_roll() * DEG_TO_RAD, @@ -830,16 +865,16 @@ void fgReInitSubsystems( void ) globals->get_options()->get_heading() * DEG_TO_RAD ); // Initial Angular Body rates - cur_fdm_state->set_Omega_Body( 7.206685E-05, 0.0, 9.492658E-05 ); + //cur_fdm_state->set_Omega_Body( 7.206685E-05, 0.0, 9.492658E-05 ); - cur_fdm_state->set_Earth_position_angle( 0.0 ); + //cur_fdm_state->set_Earth_position_angle( 0.0 ); // Mass properties and geometry values - cur_fdm_state->set_Inertias( 8.547270E+01, - 1.048000E+03, 3.000000E+03, 3.530000E+03, 0.000000E+00 ); + //cur_fdm_state->set_Inertias( 8.547270E+01, + // 1.048000E+03, 3.000000E+03, 3.530000E+03, 0.000000E+00 ); // CG position w.r.t. ref. point - cur_fdm_state->set_CG_Position( 0.0, 0.0, 0.0 ); + //cur_fdm_state->set_CG_Position( 0.0, 0.0, 0.0 ); // Initialize view parameters globals->get_current_view()->set_view_offset( 0.0 ); diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 3dbf405dc..d9ec19b72 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -829,8 +829,8 @@ static void fgMainLoop( void ) { << cur_fdm_state->get_Altitude() * FEET_TO_METER << " meters" ); } - fgFDMSetGroundElevation( globals->get_options()->get_flight_model(), - scenery.cur_elev ); // meters + //fgFDMSetGroundElevation( globals->get_options()->get_flight_model(), + // scenery.cur_elev ); // meters } /* printf("Adjustment - ground = %.2f runway = %.2f alt = %.2f\n", diff --git a/src/Main/options.cxx b/src/Main/options.cxx index 89acfb168..2f1f01691 100644 --- a/src/Main/options.cxx +++ b/src/Main/options.cxx @@ -150,7 +150,10 @@ FGOptions::FGOptions() : pitch(0.424), // pitch angle in degrees (Theta) // Initialize current options velocities to 0.0 - uBody(0.0), vBody(0.0), wBody(0.0), vkcas(0.0), mach(0.0), + speedset(FG_VC), + uBody(0.0), vBody(0.0), wBody(0.0), + vNorth(0.0),vEast(0.0), vDown(0.0), + vkcas(0.0), mach(0.0), // Miscellaneous game_mode(0), @@ -696,35 +699,58 @@ int FGOptions::parse_option( const string& arg ) { } current_properties.setDoubleValue("/position/altitude", altitude); } else if ( arg.find( "--uBody=" ) != string::npos ) { - vkcas=mach=-1; + speedset = FG_VTUVW; if ( units == FG_UNITS_FEET ) { uBody = atof( arg.substr(8) ); } else { uBody = atof( arg.substr(8) ) * FEET_TO_METER; } - current_properties.setDoubleValue("/velocities/speed-north", uBody); + //current_properties.setDoubleValue("/velocities/speed-north", uBody); } else if ( arg.find( "--vBody=" ) != string::npos ) { - vkcas=mach=-1; + speedset = FG_VTUVW; if ( units == FG_UNITS_FEET ) { vBody = atof( arg.substr(8) ); } else { vBody = atof( arg.substr(8) ) * FEET_TO_METER; } - current_properties.setDoubleValue("/velocities/speed-east", vBody); + //current_properties.setDoubleValue("/velocities/speed-east", vBody); } else if ( arg.find( "--wBody=" ) != string::npos ) { - vkcas=mach=-1; + speedset = FG_VTUVW; if ( units == FG_UNITS_FEET ) { wBody = atof( arg.substr(8) ); } else { wBody = atof( arg.substr(8) ) * FEET_TO_METER; } - current_properties.setDoubleValue("/velocities/speed-down", wBody); + } else if ( arg.find( "--vNorth=" ) != string::npos ) { + speedset = FG_VTNED; + if ( units == FG_UNITS_FEET ) { + vNorth = atof( arg.substr(9) ); + } else { + vNorth = atof( arg.substr(9) ) * FEET_TO_METER; + } + current_properties.setDoubleValue("/velocities/speed-north", vNorth); + } else if ( arg.find( "--vEast=" ) != string::npos ) { + speedset = FG_VTNED; + if ( units == FG_UNITS_FEET ) { + vEast = atof( arg.substr(8) ); + } else { + vEast = atof( arg.substr(8) ) * FEET_TO_METER; + } + current_properties.setDoubleValue("/velocities/speed-east", vEast); + } else if ( arg.find( "--vDown=" ) != string::npos ) { + speedset = FG_VTNED; + if ( units == FG_UNITS_FEET ) { + vDown = atof( arg.substr(8) ); + } else { + vDown = atof( arg.substr(8) ) * FEET_TO_METER; + } + current_properties.setDoubleValue("/velocities/speed-down", vDown); } else if ( arg.find( "--vc=" ) != string::npos) { - mach=-1; + speedset = FG_VC; vkcas=atof( arg.substr(5) ); cout << "Got vc: " << vkcas << endl; } else if ( arg.find( "--mach=" ) != string::npos) { - vkcas=-1; + speedset = FG_MACH; mach=atof( arg.substr(7) ); } else if ( arg.find( "--heading=" ) != string::npos ) { heading = atof( arg.substr(10) ); @@ -926,7 +952,6 @@ int FGOptions::parse_option( const string& arg ) { // just that. int FGOptions::scan_command_line_for_root( int argc, char **argv ) { int i = 1; - int result; FG_LOG(FG_GENERAL, FG_INFO, "Processing command line arguments"); diff --git a/src/Main/options.hxx b/src/Main/options.hxx index 9f9833c5a..7418211d3 100644 --- a/src/Main/options.hxx +++ b/src/Main/options.hxx @@ -122,6 +122,13 @@ public: FG_TIME_GMT_ABSOLUTE = 4, FG_TIME_LAT_ABSOLUTE = 5 }; + + enum fgSpeedSet { + FG_VC = 1, + FG_MACH = 2, + FG_VTUVW = 3, + FG_VTNED = 4 + }; private: @@ -139,9 +146,13 @@ private: double heading; // heading (yaw) angle in degress (Psi) double roll; // roll angle in degrees (Phi) double pitch; // pitch angle in degrees (Theta) + fgSpeedSet speedset; // which speed does the user want double uBody; // Body axis X velocity (U) double vBody; // Body axis Y velocity (V) double wBody; // Body axis Z velocity (W) + double vNorth; // North component of vt + double vEast; // East component of vt + double vDown; // Down component of vt double vkcas; // Calibrated airspeed, knots double mach; // Mach number @@ -245,9 +256,13 @@ public: inline double get_heading() const { return heading; } inline double get_roll() const { return roll; } inline double get_pitch() const { return pitch; } + inline fgSpeedSet get_speedset() const { return speedset; } inline double get_uBody() const {return uBody;} inline double get_vBody() const {return vBody;} inline double get_wBody() const {return wBody;} + inline double get_vNorth() const {return vNorth;} + inline double get_vEast() const {return vEast;} + inline double get_vDown() const {return vDown;} inline double get_vc() const {return vkcas;} inline double get_mach() const {return mach;} diff --git a/src/Network/garmin.cxx b/src/Network/garmin.cxx index ca00dd414..8c4a3d3da 100644 --- a/src/Network/garmin.cxx +++ b/src/Network/garmin.cxx @@ -268,6 +268,7 @@ bool FGGarmin::parse_message() { cur_fdm_state->set_Longitude( lon * DEG_TO_RAD ); FG_LOG( FG_IO, FG_INFO, " lon = " << lon ); +#if 0 double sl_radius, lat_geoc; sgGeodToGeoc( cur_fdm_state->get_Latitude(), cur_fdm_state->get_Altitude(), @@ -275,6 +276,7 @@ bool FGGarmin::parse_message() { cur_fdm_state->set_Geocentric_Position( lat_geoc, cur_fdm_state->get_Longitude(), sl_radius + cur_fdm_state->get_Altitude() ); +#endif // speed end = msg.find(",", begin); @@ -285,8 +287,8 @@ bool FGGarmin::parse_message() { string speed_str = msg.substr(begin, end - begin); begin = end + 1; speed = atof( speed_str.c_str() ); - cur_fdm_state->set_V_equiv_kts( speed ); - cur_fdm_state->set_V_ground_speed( speed ); + cur_fdm_state->set_V_calibrated_kts( speed ); + // cur_fdm_state->set_V_ground_speed( speed ); FG_LOG( FG_IO, FG_INFO, " speed = " << speed ); // heading diff --git a/src/Network/nmea.cxx b/src/Network/nmea.cxx index 6467c2854..486dc1551 100644 --- a/src/Network/nmea.cxx +++ b/src/Network/nmea.cxx @@ -273,6 +273,7 @@ bool FGNMEA::parse_message() { cur_fdm_state->set_Longitude( lon * DEG_TO_RAD ); FG_LOG( FG_IO, FG_INFO, " lon = " << lon ); +#if 0 double sl_radius, lat_geoc; sgGeodToGeoc( cur_fdm_state->get_Latitude(), cur_fdm_state->get_Altitude(), @@ -280,6 +281,7 @@ bool FGNMEA::parse_message() { cur_fdm_state->set_Geocentric_Position( lat_geoc, cur_fdm_state->get_Longitude(), sl_radius + cur_fdm_state->get_Altitude() ); +#endif // speed end = msg.find(",", begin); @@ -290,8 +292,8 @@ bool FGNMEA::parse_message() { string speed_str = msg.substr(begin, end - begin); begin = end + 1; speed = atof( speed_str.c_str() ); - cur_fdm_state->set_V_equiv_kts( speed ); - cur_fdm_state->set_V_ground_speed( speed ); + cur_fdm_state->set_V_calibrated_kts( speed ); + // cur_fdm_state->set_V_ground_speed( speed ); FG_LOG( FG_IO, FG_INFO, " speed = " << speed ); // heading diff --git a/src/WeatherCM/FGLocalWeatherDatabase.cpp b/src/WeatherCM/FGLocalWeatherDatabase.cpp index cc4a2a15a..dc9f55212 100644 --- a/src/WeatherCM/FGLocalWeatherDatabase.cpp +++ b/src/WeatherCM/FGLocalWeatherDatabase.cpp @@ -265,7 +265,7 @@ void fgUpdateWeatherDatabase(void) // get the data on 'the bus' for the FDM - FGPhysicalProperty porperty = WeatherDatabase->get(position); + /* FGPhysicalProperty porperty = WeatherDatabase->get(position); current_aircraft.fdm_state->set_Static_temperature( Kelvin2Rankine(porperty.Temperature) ); current_aircraft.fdm_state->set_Static_pressure( Pascal2psf(porperty.AirPressure) ); @@ -275,7 +275,8 @@ void fgUpdateWeatherDatabase(void) #define MSTOFPS 3.2808 //m/s to ft/s current_aircraft.fdm_state->set_Velocities_Local_Airmass(porperty.Wind[1]*MSTOFPS, porperty.Wind[0]*MSTOFPS, - porperty.Wind[2]*MSTOFPS); + porperty.Wind[2]*MSTOFPS); */ + }