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
// << " 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);
// 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 );
<< " 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;
}
/******************************************************************************/
+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 );
-
- 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;
- }
-
- 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();
-
-
- FDMExec.GetPosition()->SetRunwayRadius(scenery.cur_radius*METER_TO_FEET);
- FDMExec.GetPosition()->SetSeaLevelRadius(get_Sea_level_radius());
+ result = fdmex->LoadModel( aircraft_path.str(),
+ engine_path.str(),
+ globals->get_options()->get_aircraft() );
+#endif
- 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() );
+ if (result) {
+ FG_LOG( FG_FLIGHT, FG_INFO, " loaded aircraft" << globals->get_options()->get_aircraft() );
+ } else {
+ FG_LOG( FG_FLIGHT, FG_INFO, " aircraft "
+ << globals->get_options()->get_aircraft()
+ << " does not exist" );
+ return false;
+ }
+
+ fdmex->GetAtmosphere()->UseInternal();
- FG_LOG( FG_FLIGHT, FG_INFO, " 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, " Initializing JSBSim with:" );
+ switch(fgic->GetSpeedSet()) {
+ case setned:
+ FG_LOG(FG_FLIGHT,FG_INFO, " Vn,Ve,Vd= "
+ << fdmex->GetPosition()->GetVn()
+ << ", " << fdmex->GetPosition()->GetVe()
+ << ", " << fdmex->GetPosition()->GetVd()
+ << " ft/s");
+ break;
+ case setuvw:
+ FG_LOG(FG_FLIGHT,FG_INFO, " U,V,W= "
+ << fdmex->GetTranslation()->GetUVW()(1)
+ << ", " << fdmex->GetTranslation()->GetUVW()(2)
+ << ", " << fdmex->GetTranslation()->GetUVW()(3)
+ << " ft/s");
+ break;
+ case setmach:
+ FG_LOG(FG_FLIGHT,FG_INFO, " Mach: "
+ << fdmex->GetTranslation()->GetMach() );
+ break;
+ case setvc:
+ default:
+ FG_LOG(FG_FLIGHT,FG_INFO, " Indicated Airspeed: "
+ << fdmex->GetAuxiliary()->GetVcalibratedKTS() << " knots" );
+
+ }
+
+ //FG_LOG( FG_FLIGHT, FG_INFO, " gamma: " << globals->get_options()->get_Gamma());
+ FG_LOG( FG_FLIGHT, FG_INFO, " Bank Angle: "
+ << fdmex->GetRotation()->Getphi()*RADTODEG << " deg");
+ FG_LOG( FG_FLIGHT, FG_INFO, " Pitch Angle: "
+ << fdmex->GetRotation()->Gettht()*RADTODEG << " deg" );
+ FG_LOG( FG_FLIGHT, FG_INFO, " True Heading: "
+ << fdmex->GetRotation()->Getpsi()*RADTODEG << " deg" );
+ FG_LOG( FG_FLIGHT, FG_INFO, " Latitude: "
+ << fdmex->GetPosition()->GetLatitude() << " deg" );
+ FG_LOG( FG_FLIGHT, FG_INFO, " Longitude: "
+ << fdmex->GetPosition()->GetLongitude() << " deg" );
- 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();
-
-
- 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
-
- delete fgtrim;
- }
- FG_LOG( FG_FLIGHT, FG_INFO, " Trim complete." );
- } else {
- FG_LOG( FG_FLIGHT, FG_INFO, " Initializing without trim" );
- FDMExec.GetState()->Initialize(fgic);
-
- }
+ // 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() );
- delete fgic;
+ FG_LOG( FG_FLIGHT, FG_DEBUG, " Calculated Aircraft AGL: " << endl
+ << " " << "get_Altitude() + get_Sea_level_radius() - scenery.cur_radius*METER_TO_FEET= "
+ << get_Altitude() + get_Sea_level_radius()- scenery.cur_radius*METER_TO_FEET );
+ FG_LOG( FG_FLIGHT, FG_DEBUG, " globals->get_options()->get_altitude(): "
+ << globals->get_options()->get_altitude() );
+ FG_LOG( FG_FLIGHT, FG_DEBUG, " FGBFI::getAltitude(): "
+ << FGBFI::getAltitude() ); */
- FG_LOG( FG_FLIGHT, FG_INFO, " loaded initial conditions" );
- FG_LOG( FG_FLIGHT, FG_INFO, " set dt" );
+ FG_LOG( FG_FLIGHT, FG_INFO, " loaded initial conditions" );
- FG_LOG( FG_FLIGHT, FG_INFO, "Finished initializing JSBSim" );
+ FG_LOG( FG_FLIGHT, FG_INFO, " set dt" );
- copy_from_JSBsim();
+ FG_LOG( FG_FLIGHT, FG_INFO, "Finished initializing JSBSim" );
- return true;
+ return true;
}
/******************************************************************************/
// 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) {
+ if(needTrim) {
+ FGTrim *fgtrim=new FGTrim(fdmex,fgic,tLongitudinal);
+ if(!fgtrim->DoTrim()) {
+ fgtrim->Report();
+ fgtrim->TrimStats();
+ }
+ fgtrim->ReportState();
+ delete fgtrim;
- controls.set_elevator_trim(trim_elev);
- controls.set_throttle(FGControls::ALL_ENGINES,trim_throttle);
+ needTrim=false;
- controls.set_elevator(0.0);
- controls.set_aileron(0.0);
- controls.set_rudder(0.0);
- trimmed=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" );
+ }
- copy_to_JSBsim();
-
- 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);
-
- // translate JSBsim back to FG structure so that the
- // autopilot (and the rest of the sim can use the updated values
+ 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();
+ }
- copy_from_JSBsim();
+ // printf("%d FG_Altitude = %.2f\n", i, FG_Altitude * 0.3048);
+ // printf("%d Altitude = %.2f\n", i, Altitude * 0.3048);
- // but lets restore our original bogus altitude when we are done
+ // translate JSBsim back to FG structure so that the
+ // autopilot (and the rest of the sim can use the updated values
- if ( save_alt < -9000.0 ) {
- set_Altitude( save_alt );
- }
+ copy_from_JSBsim();
- double end_elev = get_Altitude();
+ // but lets restore our original bogus altitude when we are done
- return true;
+ if ( save_alt < -9000.0 ) {
+ set_Altitude( save_alt );
+ }
+
+ //climb rate now set from FDM in copy_from_x()
+ return true;
}
/******************************************************************************/
// Convert from the FGInterface struct to the JSBsim generic_ struct
bool FGJSBsim::copy_to_JSBsim() {
- // 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 );
-
- FDMExec.GetFCS()->SetLBrake( controls.get_brake( 0 ) );
- FDMExec.GetFCS()->SetRBrake( controls.get_brake( 1 ) );
- FDMExec.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());
-
- 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());
-
- return true;
+ // copy control positions into the JSBsim structure
+
+ fdmex->GetFCS()->SetDaCmd( controls.get_aileron());
+ fdmex->GetFCS()->SetDeCmd( controls.get_elevator());
+ fdmex->GetFCS()->SetPitchTrimCmd(controls.get_elevator_trim());
+ fdmex->GetFCS()->SetDrCmd( -1*controls.get_rudder());
+ fdmex->GetFCS()->SetDfCmd( controls.get_flaps() );
+ fdmex->GetFCS()->SetDsbCmd( 0.0 ); //speedbrakes
+ fdmex->GetFCS()->SetDspCmd( 0.0 ); //spoilers
+ fdmex->GetFCS()->SetThrottleCmd( FGControls::ALL_ENGINES,
+ controls.get_throttle( 0 ) * 100.0 );
+
+ fdmex->GetFCS()->SetLBrake( controls.get_brake( 0 ) );
+ fdmex->GetFCS()->SetRBrake( controls.get_brake( 1 ) );
+ fdmex->GetFCS()->SetCBrake( controls.get_brake( 2 ) );
+
+ fdmex->GetPosition()->SetRunwayRadius(scenery.cur_radius*METER_TO_FEET);
+ fdmex->GetPosition()->SetSeaLevelRadius(get_Sea_level_radius());
+
+ fdmex->GetAtmosphere()->SetExTemperature(get_Static_temperature());
+ fdmex->GetAtmosphere()->SetExPressure(get_Static_pressure());
+ fdmex->GetAtmosphere()->SetExDensity(get_Density());
+ fdmex->GetAtmosphere()->SetWindNED(get_V_north_airmass(),
+ get_V_east_airmass(),
+ get_V_down_airmass());
+
+ return true;
}
/******************************************************************************/
// Convert from the JSBsim generic_ struct to the FGInterface struct
bool FGJSBsim::copy_from_JSBsim() {
-
- set_Inertias( FDMExec.GetAircraft()->GetMass(),
- FDMExec.GetAircraft()->GetIxx(),
- FDMExec.GetAircraft()->GetIyy(),
- FDMExec.GetAircraft()->GetIzz(),
- FDMExec.GetAircraft()->GetIxz() );
-
- set_CG_Position ( FDMExec.GetAircraft()->GetXYZcg()(1),
- FDMExec.GetAircraft()->GetXYZcg()(2),
- FDMExec.GetAircraft()->GetXYZcg()(3) );
+ unsigned i, j;
- set_Accels_Body ( FDMExec.GetTranslation()->GetUVWdot()(1),
- FDMExec.GetTranslation()->GetUVWdot()(2),
- FDMExec.GetTranslation()->GetUVWdot()(3) );
+ _set_Inertias( fdmex->GetAircraft()->GetMass(),
+ fdmex->GetAircraft()->GetIxx(),
+ fdmex->GetAircraft()->GetIyy(),
+ fdmex->GetAircraft()->GetIzz(),
+ fdmex->GetAircraft()->GetIxz() );
- set_Accels_CG_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_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_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( fdmex->GetTranslation()->GetUVWdot()(1),
+ fdmex->GetTranslation()->GetUVWdot()(2),
+ fdmex->GetTranslation()->GetUVWdot()(3) );
-
+ //_set_Accels_CG_Body_N ( fdmex->GetTranslation()->GetNcg()(1),
+ // fdmex->GetTranslation()->GetNcg()(2),
+ // fdmex->GetTranslation()->GetNcg()(3) );
+ //
+ _set_Accels_Pilot_Body( fdmex->GetAuxiliary()->GetPilotAccel()(1),
+ fdmex->GetAuxiliary()->GetPilotAccel()(2),
+ fdmex->GetAuxiliary()->GetPilotAccel()(3) );
- set_Nlf( FDMExec.GetAircraft()->GetNlf());
+ //_set_Accels_Pilot_Body_N( fdmex->GetAuxiliary()->GetNpilot()(1),
+ // fdmex->GetAuxiliary()->GetNpilot()(2),
+ // fdmex->GetAuxiliary()->GetNpilot()(3) );
+ _set_Nlf( fdmex->GetAircraft()->GetNlf() );
-
- // Velocities
+ // Velocities
- set_Velocities_Local( FDMExec.GetPosition()->GetVn(),
- FDMExec.GetPosition()->GetVe(),
- FDMExec.GetPosition()->GetVd() );
+ _set_Velocities_Local( fdmex->GetPosition()->GetVn(),
+ fdmex->GetPosition()->GetVe(),
+ fdmex->GetPosition()->GetVd() );
- set_Velocities_Wind_Body( FDMExec.GetTranslation()->GetUVW()(1),
- FDMExec.GetTranslation()->GetUVW()(2),
- FDMExec.GetTranslation()->GetUVW()(3) );
+ _set_Velocities_Wind_Body( fdmex->GetTranslation()->GetUVW()(1),
+ fdmex->GetTranslation()->GetUVW()(2),
+ fdmex->GetTranslation()->GetUVW()(3) );
- set_V_equiv_kts( FDMExec.GetAuxiliary()->GetVequivalentKTS() );
+ _set_V_equiv_kts( fdmex->GetAuxiliary()->GetVequivalentKTS() );
- //set_V_calibrated( FDMExec.GetAuxiliary()->GetVcalibratedFPS() );
+ // _set_V_calibrated( fdmex->GetAuxiliary()->GetVcalibratedFPS() );
- set_V_calibrated_kts( FDMExec.GetAuxiliary()->GetVcalibratedKTS() );
+ _set_V_calibrated_kts( fdmex->GetAuxiliary()->GetVcalibratedKTS() );
- set_V_ground_speed ( FDMExec.GetPosition()->GetVground() );
+ _set_V_ground_speed( fdmex->GetPosition()->GetVground() );
+
+ _set_Omega_Body( fdmex->GetRotation()->GetPQR()(1),
+ fdmex->GetRotation()->GetPQR()(2),
+ fdmex->GetRotation()->GetPQR()(3) );
- set_Omega_Body( FDMExec.GetState()->GetParameter(FG_ROLLRATE),
- FDMExec.GetState()->GetParameter(FG_PITCHRATE),
- FDMExec.GetState()->GetParameter(FG_YAWRATE) );
+ _set_Euler_Rates( fdmex->GetRotation()->GetEulerRates()(1),
+ fdmex->GetRotation()->GetEulerRates()(2),
+ fdmex->GetRotation()->GetEulerRates()(3) );
- set_Euler_Rates( FDMExec.GetRotation()->GetEulerRates()(2),
- FDMExec.GetRotation()->GetEulerRates()(1),
- FDMExec.GetRotation()->GetEulerRates()(3));
+ _set_Geocentric_Rates(fdmex->GetPosition()->GetLatitudeDot(),
+ fdmex->GetPosition()->GetLongitudeDot(),
+ fdmex->GetPosition()->Gethdot() );
- // ***FIXME*** set_Geocentric_Rates( Latitude_dot, Longitude_dot,
- // Radius_dot );
+ _set_Mach_number( fdmex->GetTranslation()->GetMach() );
- set_Mach_number( FDMExec.GetTranslation()->GetMach());
+ // Positions
- // 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;
- 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 );
- 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 );
- 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( fdmex->GetRotation()->Getphi(),
+ fdmex->GetRotation()->Gettht(),
+ fdmex->GetRotation()->Getpsi() );
- 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( fdmex->GetTranslation()->Getalpha() );
+ _set_Beta( fdmex->GetTranslation()->Getbeta() );
- set_Alpha( FDMExec.GetTranslation()->Getalpha() );
- set_Beta( FDMExec.GetTranslation()->Getbeta() );
+ _set_Gamma_vert_rad( fdmex->GetPosition()->GetGamma() );
+ // set_Gamma_horiz_rad( Gamma_horiz_rad );
- 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( fdmex->GetAuxiliary()->
+ GetEarthPositionAngle() );
- /* **FIXME*** */ set_Sea_level_radius( sl_radius2 * METER_TO_FEET );
- /* **FIXME*** */ set_Earth_position_angle( 0.0 );
+ /* ***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() );
- // /* ***FIXME*** */ set_Runway_altitude( 0.0 );
+ for ( i = 0; i < 3; i++ ) {
+ for ( j = 0; j < 3; j++ ) {
+ _set_T_Local_to_Body( i, j, fdmex->GetState()->GetTl2b()(i,j) );
+ }
+ }
- 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;
+}
+//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;
+}
- set_Climb_Rate(FDMExec.GetPosition()->Gethdot());
+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;
+}
+
- return 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;
+}
#define _JSBSIM_HXX
#include <FDM/JSBSim/FGFDMExec.h>
+#include <FDM/JSBSim/FGInitialCondition.h>
#undef MAX_ENGINES
#include <Aircraft/aircraft.hxx>
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();
// 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 );
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; }
#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
static const char *IdSrc = "$Header$";
static const char *IdHdr = ID_INITIALCONDITION;
+
FGInitialCondition::FGInitialCondition(FGFDMExec *FDMExec) {
vt=vc=ve=0;
mach=0;
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);
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;
}
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();
}
void FGInitialCondition::SetVtrueKtsIC(float tt) {
- vt=tt*KTSTOFPS;
+ vt=tt*jsbKTSTOFPS;
lastSpeedSet=setvt;
mach=vt/fdmex->GetAtmosphere()->GetSoundSpeed();
vc=calcVcas(mach);
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) {
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;
}
//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);
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) +
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) {
calcUVWfromNED();
vt=sqrt(u*u + v*v + w*w);
SetClimbRateFpsIC(-1*vdown);
- lastSpeedSet=setvt;
+ lastSpeedSet=setned;
}
bool FGInitialCondition::getMachFromVcas(float *Mach,float vcas) {
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;
}
*y=x2;
}
- //cout << "Success= " << success << " Vcas: " << vcas*FPSTOKTS << " Mach: " << x2 << endl;
+ //cout << "Success= " << success << " Vcas: " << vcas*jsbFPSTOKTS << " Mach: " << x2 << endl;
return success;
}
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
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);
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);
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; }
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; }
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;
#include "FGPosition.h"
#include "FGAuxiliary.h"
#include "FGOutput.h"
+#include "FGInitialCondition.h"
#ifdef FGFS
#include <simgear/compiler.h>
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)
{
FDMExec->Run();
}
+ */
delete FDMExec;
#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)
+
+ // update the engines interface
+ FGEngInterface e;
+ add_engine( e );
+
- 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 );
- }
-
- // cout << "FGLaRCsim::init()" << endl;
+ // FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::init()" );
double save_alt = 0.0;
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() );
// 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
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 ) {
}
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
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);
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;
}
// 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();
// 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();
// 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();
// 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();
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 );
// 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,
// 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
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 );
// 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 );
// 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",
// 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" );
+
+}
+
#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();
// 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 );
};
#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 */
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)
{
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);
$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.
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 */
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.
$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.
/* 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,
#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 );
void ls_geod_to_geoc( SCALAR lat_geod, SCALAR alt, SCALAR *sl_radius,
SCALAR *lat_geoc );
+#ifdef __cplusplus
+}
+#endif
#endif /* _LS_GEODESY_H */
}
#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"); */
/* 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
/* 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);
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.
//
$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.
/* 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 */
--- /dev/null
+/*******************************************************************************
+
+ 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;
+}
--- /dev/null
+/*******************************************************************************
+
+ 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
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)
// 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;
}
IO360.cxx IO360.hxx \
JSBSim.cxx JSBSim.hxx \
LaRCsim.cxx LaRCsim.hxx \
+ LaRCsimIC.cxx LaRCsimIC.hxx \
MagicCarpet.cxx MagicCarpet.hxx
bin_PROGRAMS = engine pstest
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);
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;
}
&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 ) {
// 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 );
+}
+
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; }
// This is based heavily on LaRCsim/ls_generic.h
class FGInterface {
+protected:
+
+ void busdump(void);
+
private:
// Pilot location rel to ref pt
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;
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);
// 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
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
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() {
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 ==========
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]; }
// 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]; }
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() {
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; }
// 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]; }
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 ==========
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 ==========
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; }
// }
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; }
// 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; }
// 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; }
// 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; }
} */
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(); }
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;
}
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;
}
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;
}
FGBFI::setSpeedNorth (double speed)
{
if (getSpeedNorth() != speed) {
- globals->get_options()->set_uBody(speed);
current_aircraft.fdm_state->set_Velocities_Local(speed,
getSpeedEast(),
getSpeedDown());
FGBFI::setSpeedEast (double speed)
{
if (getSpeedEast() != speed) {
- globals->get_options()->set_vBody(speed);
current_aircraft.fdm_state->set_Velocities_Local(getSpeedNorth(),
speed,
getSpeedDown());
FGBFI::setSpeedDown (double speed)
{
if (getSpeedDown() != speed) {
- globals->get_options()->set_wBody(speed);
current_aircraft.fdm_state->set_Velocities_Local(getSpeedNorth(),
getSpeedEast(),
speed);
"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",
}
+// 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.
// 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();
"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 = " <<
// 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,
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();
// 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,
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 );
<< 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",
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),
}
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) );
// 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");
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:
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
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;}
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(),
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);
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
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(),
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);
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
// 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) );
#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); */
+
}