1
0
Fork 0

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.
This commit is contained in:
curt 2000-10-24 00:34:50 +00:00
parent c67e0467b4
commit 7cc98ad15f
36 changed files with 2941 additions and 708 deletions

View file

@ -213,12 +213,12 @@ bool FGADA::copy_to_FGADA () {
bool FGADA::copy_from_FGADA() {
// Velocities
set_Velocities_Local( V_north, V_east, V_down );
set_V_calibrated_kts( V_calibrated_kts );
_set_Velocities_Local( V_north, V_east, V_down );
_set_V_calibrated_kts( V_calibrated_kts );
// Angular rates
set_Omega_Body( P_body, Q_body, R_body );
set_Geocentric_Rates( Latitude_dot, Longitude_dot, Radius_dot );
_set_Omega_Body( P_body, Q_body, R_body );
_set_Geocentric_Rates( Latitude_dot, Longitude_dot, Radius_dot );
// FG_LOG( FG_FLIGHT, FG_DEBUG, "lon = " << Longitude
// << " lat_geoc = " << Lat_geocentric << " lat_geod = " << Latitude
@ -226,25 +226,26 @@ bool FGADA::copy_from_FGADA() {
// << " radius_to_vehicle = " << Radius_to_vehicle );
// Positions
set_Geocentric_Position( Lat_geocentric, Lon_geocentric,Radius_to_vehicle );
set_Geodetic_Position( Latitude, Longitude, Altitude );
set_Euler_Angles( Phi, Theta, Psi );
_set_Geocentric_Position( Lat_geocentric, Lon_geocentric,
Radius_to_vehicle );
_set_Geodetic_Position( Latitude, Longitude, Altitude );
_set_Euler_Angles( Phi, Theta, Psi );
// Miscellaneous quantities
set_Alpha( Alpha );
set_Beta( Beta );
set_Gamma_vert_rad( Gamma_vert_rad );
set_Sea_level_radius( Sea_level_radius );
set_Earth_position_angle( Earth_position_angle );
set_Runway_altitude( Runway_altitude );
set_sin_lat_geocentric(Lat_geocentric);
set_cos_lat_geocentric(Lat_geocentric);
set_sin_cos_longitude(Longitude);
set_sin_cos_latitude(Latitude);
set_Accels_Local( U_dot_local, V_dot_local, W_dot_local );
set_Velocities_Ground( U_local, V_local, W_local );
set_Accels_CG_Body_N( anxg,anyg,anzg);
set_Mach_number( Machno);
_set_Alpha( Alpha );
_set_Beta( Beta );
_set_Gamma_vert_rad( Gamma_vert_rad );
_set_Sea_level_radius( Sea_level_radius );
_set_Earth_position_angle( Earth_position_angle );
_set_Runway_altitude( Runway_altitude );
_set_sin_lat_geocentric(Lat_geocentric);
_set_cos_lat_geocentric(Lat_geocentric);
_set_sin_cos_longitude(Longitude);
_set_sin_cos_latitude(Latitude);
_set_Accels_Local( U_dot_local, V_dot_local, W_dot_local );
_set_Velocities_Ground( U_local, V_local, W_local );
_set_Accels_CG_Body_N( anxg,anyg,anzg);
_set_Mach_number( Machno);
// printf("sr=%f\n",Sea_level_radius);
// printf("psi = %f %f\n",Psi,Psi*RAD_TO_DEG);

View file

@ -168,11 +168,11 @@ bool FGBalloonSim::copy_from_BalloonSim() {
// Velocities
current_balloon.getVelocity( temp );
set_Velocities_Local( temp[0], temp[1], temp[2] );
_set_Velocities_Local( temp[0], temp[1], temp[2] );
/* ***FIXME*** */ set_V_equiv_kts( sgLengthVec3 ( temp ) );
/* ***FIXME*** */ _set_V_equiv_kts( sgLengthVec3 ( temp ) );
set_Omega_Body( 0.0, 0.0, 0.0 );
_set_Omega_Body( 0.0, 0.0, 0.0 );
// Positions
current_balloon.getPosition( temp );
@ -192,27 +192,22 @@ bool FGBalloonSim::copy_from_BalloonSim() {
<< " sl_radius2 = " << sl_radius2 * METER_TO_FEET
<< " Equator = " << EQUATORIAL_RADIUS_FT );
set_Geocentric_Position( lat_geoc, lon,
_set_Geocentric_Position( lat_geoc, lon,
sl_radius2 * METER_TO_FEET + alt );
set_Geodetic_Position( lat_geod, lon, alt );
_set_Geodetic_Position( lat_geod, lon, alt );
current_balloon.getHPR( temp );
set_Euler_Angles( temp[0], temp[1], temp[2] );
set_Euler_Rates(0,0,0);
/* **FIXME*** */ _set_Sea_level_radius( sl_radius2 * METER_TO_FEET );
/* **FIXME*** */ _set_Earth_position_angle( 0.0 );
set_Alpha( 0.0/*FDMExec.GetTranslation()->Getalpha()*/ );
set_Beta( 0.0/*FDMExec.GetTranslation()->Getbeta()*/ );
/* **FIXME*** */ set_Sea_level_radius( sl_radius2 * METER_TO_FEET );
/* **FIXME*** */ set_Earth_position_angle( 0.0 );
/* ***FIXME*** */ set_Runway_altitude( 0.0 );
set_sin_lat_geocentric( lat_geoc );
set_cos_lat_geocentric( lat_geoc );
set_sin_cos_longitude( lon );
set_sin_cos_latitude( lat_geod );
/* ***FIXME*** */ _set_Runway_altitude( 0.0 );
_set_sin_lat_geocentric( lat_geoc );
_set_cos_lat_geocentric( lat_geoc );
_set_sin_cos_longitude( lon );
_set_sin_cos_latitude( lat_geod );
return true;
}

View file

@ -57,140 +57,140 @@
/******************************************************************************/
FGJSBsim::FGJSBsim(void) {
bool result;
fdmex=new FGFDMExec;
fgic=new FGInitialCondition(fdmex);
needTrim=true;
FGPath aircraft_path( globals->get_options()->get_fg_root() );
aircraft_path.append( "Aircraft" );
FGPath engine_path( globals->get_options()->get_fg_root() );
engine_path.append( "Engine" );
float dt = 1.0 / globals->get_options()->get_model_hz();
fdmex->GetState()->Setdt( dt );
result = fdmex->LoadModel( aircraft_path.str(),
engine_path.str(),
globals->get_options()->get_aircraft() );
int Neng=fdmex->GetAircraft()->GetNumEngines();
FG_LOG(FG_FLIGHT,FG_INFO, "Neng: " << Neng );
for(int i=0;i<Neng;i++) {
add_engine( FGEngInterface() );
}
}
/******************************************************************************/
FGJSBsim::~FGJSBsim(void) {
if(fdmex != NULL) {
delete fdmex;
delete fgic;
}
}
/******************************************************************************/
// Initialize the JSBsim flight model, dt is the time increment for
// each subsequent iteration through the EOM
bool FGJSBsim::init( double dt ) {
bool result;
bool result;
FG_LOG( FG_FLIGHT, FG_INFO, "Starting and initializing JSBsim" );
FG_LOG( FG_FLIGHT, FG_INFO, " created FDMExec" );
FG_LOG( FG_FLIGHT, FG_INFO, "Starting and initializing JSBsim" );
FGPath aircraft_path( globals->get_options()->get_fg_root() );
aircraft_path.append( "Aircraft" );
#if 0
FGPath aircraft_path( globals->get_options()->get_fg_root() );
aircraft_path.append( "Aircraft" );
FGPath engine_path( globals->get_options()->get_fg_root() );
engine_path.append( "Engine" );
FGPath engine_path( globals->get_options()->get_fg_root() );
engine_path.append( "Engine" );
//FDMExec.GetState()->Setdt( dt );
fdmex->GetState()->Setdt( dt );
result = FDMExec.LoadModel( aircraft_path.str(),
engine_path.str(),
globals->get_options()->get_aircraft() );
FDMExec.GetState()->Setdt( dt );
result = fdmex->LoadModel( aircraft_path.str(),
engine_path.str(),
globals->get_options()->get_aircraft() );
#endif
if (result) {
FG_LOG( FG_FLIGHT, FG_INFO, " loaded aircraft" << globals->get_options()->get_aircraft() );
} else {
FG_LOG( FG_FLIGHT, FG_INFO, " aircraft "
<< globals->get_options()->get_aircraft()
<< " does not exist" );
return false;
}
fdmex->GetAtmosphere()->UseInternal();
if (result) {
FG_LOG( FG_FLIGHT, FG_INFO, " loaded aircraft "
<< globals->get_options()->get_aircraft() );
} else {
FG_LOG( FG_FLIGHT, FG_INFO, " aircraft "
<< globals->get_options()->get_aircraft()
<< " does not exist" );
return false;
}
FG_LOG( FG_FLIGHT, FG_INFO, " Initializing JSBSim with:" );
switch(fgic->GetSpeedSet()) {
case setned:
FG_LOG(FG_FLIGHT,FG_INFO, " Vn,Ve,Vd= "
<< fdmex->GetPosition()->GetVn()
<< ", " << fdmex->GetPosition()->GetVe()
<< ", " << fdmex->GetPosition()->GetVd()
<< " ft/s");
break;
case setuvw:
FG_LOG(FG_FLIGHT,FG_INFO, " U,V,W= "
<< fdmex->GetTranslation()->GetUVW()(1)
<< ", " << fdmex->GetTranslation()->GetUVW()(2)
<< ", " << fdmex->GetTranslation()->GetUVW()(3)
<< " ft/s");
break;
case setmach:
FG_LOG(FG_FLIGHT,FG_INFO, " Mach: "
<< fdmex->GetTranslation()->GetMach() );
break;
case setvc:
default:
FG_LOG(FG_FLIGHT,FG_INFO, " Indicated Airspeed: "
<< fdmex->GetAuxiliary()->GetVcalibratedKTS() << " knots" );
}
FDMExec.GetAtmosphere()->SetExTemperature(get_Static_temperature());
FDMExec.GetAtmosphere()->SetExPressure(get_Static_pressure());
FDMExec.GetAtmosphere()->SetExDensity(get_Density());
FDMExec.GetAtmosphere()->SetWindNED(get_V_north_airmass(),
get_V_east_airmass(),
get_V_down_airmass());
FDMExec.GetAtmosphere()->UseInternal();
//FG_LOG( FG_FLIGHT, FG_INFO, " gamma: " << globals->get_options()->get_Gamma());
FG_LOG( FG_FLIGHT, FG_INFO, " Bank Angle: "
<< fdmex->GetRotation()->Getphi()*RADTODEG << " deg");
FG_LOG( FG_FLIGHT, FG_INFO, " Pitch Angle: "
<< fdmex->GetRotation()->Gettht()*RADTODEG << " deg" );
FG_LOG( FG_FLIGHT, FG_INFO, " True Heading: "
<< fdmex->GetRotation()->Getpsi()*RADTODEG << " deg" );
FG_LOG( FG_FLIGHT, FG_INFO, " Latitude: "
<< fdmex->GetPosition()->GetLatitude() << " deg" );
FG_LOG( FG_FLIGHT, FG_INFO, " Longitude: "
<< fdmex->GetPosition()->GetLongitude() << " deg" );
FDMExec.GetPosition()->SetRunwayRadius(scenery.cur_radius*METER_TO_FEET);
FDMExec.GetPosition()->SetSeaLevelRadius(get_Sea_level_radius());
// for debug only
/* FG_LOG( FG_FLIGHT, FG_DEBUG, " FGJSBSim::get_Altitude(): " << get_Altitude() );
FG_LOG( FG_FLIGHT, FG_DEBUG, " FGJSBSim::get_Sea_level_radius(): " << get_Sea_level_radius() );
FG_LOG( FG_FLIGHT, FG_DEBUG, " scenery.cur_radius*METER_TO_FEET: "
<< scenery.cur_radius*METER_TO_FEET );
FG_LOG( FG_FLIGHT, FG_DEBUG, " Calculated Terrain ASL: " << endl
<< " " << "scenery.cur_radius*METER_TO_FEET -get_Sea_level_radius()= "
<< scenery.cur_radius*METER_TO_FEET - get_Sea_level_radius() );
FG_LOG( FG_FLIGHT, FG_INFO, " Initializing JSBSim with:" );
FGInitialCondition *fgic = new FGInitialCondition(&FDMExec);
fgic->SetAltitudeFtIC(get_Altitude());
if ( (globals->get_options()->get_mach() < 0) &&
(globals->get_options()->get_vc() < 0 ) )
{
fgic->SetUBodyFpsIC(globals->get_options()->get_uBody());
fgic->SetVBodyFpsIC(globals->get_options()->get_vBody());
fgic->SetWBodyFpsIC(globals->get_options()->get_wBody());
FG_LOG(FG_FLIGHT,FG_INFO, " u,v,w= " << globals->get_options()->get_uBody()
<< ", " << globals->get_options()->get_vBody()
<< ", " << globals->get_options()->get_wBody());
} else if (globals->get_options()->get_vc() < 0) {
fgic->SetMachIC(globals->get_options()->get_mach());
FG_LOG( FG_FLIGHT,FG_INFO, " mach: "
<< globals->get_options()->get_mach() );
} else {
fgic->SetVcalibratedKtsIC(globals->get_options()->get_vc());
FG_LOG(FG_FLIGHT,FG_INFO, " vc: " << globals->get_options()->get_vc() );
//this should cover the case in which no speed switches are used
//globals->get_options()->get_vc() will return zero by default
}
//fgic->SetFlightPathAngleDegIC(globals->get_options()->get_Gamma());
fgic->SetRollAngleRadIC(get_Phi());
fgic->SetPitchAngleRadIC(get_Theta());
fgic->SetHeadingRadIC(get_Psi());
fgic->SetLatitudeRadIC(get_Lat_geocentric());
fgic->SetLongitudeRadIC(get_Longitude());
// FG_LOG( FG_FLIGHT, FG_INFO, " gamma: "
// << globals->get_options()->get_Gamma());
FG_LOG( FG_FLIGHT, FG_INFO, " phi: " << get_Phi());
//FG_LOG( FG_FLIGHT, FG_INFO, " theta: " << get_Theta() );
FG_LOG( FG_FLIGHT, FG_INFO, " psi: " << get_Psi() );
FG_LOG( FG_FLIGHT, FG_INFO, " lat: " << get_Latitude() );
FG_LOG( FG_FLIGHT, FG_INFO, " lon: " << get_Longitude() );
FG_LOG( FG_FLIGHT, FG_INFO, " Pressure Altiude: " << get_Altitude() );
FG_LOG( FG_FLIGHT, FG_INFO, " Terrain Altitude: "
<< scenery.cur_radius*METER_TO_FEET );
FG_LOG( FG_FLIGHT, FG_INFO, " AGL Altitude: "
<< get_Altitude() + get_Sea_level_radius()
- scenery.cur_radius*METER_TO_FEET );
FG_LOG( FG_FLIGHT, FG_INFO, " globals->get_options()->get_altitude(): "
<< globals->get_options()->get_altitude() );
//must check > 0, != 0 will give bad result if --notrim set
if(globals->get_options()->get_trim_mode() > 0) {
if(fgic->GetVcalibratedKtsIC() > 50) {
FDMExec.RunIC(fgic);
FG_LOG( FG_FLIGHT, FG_INFO, " Starting trim..." );
FGTrim *fgtrim=new FGTrim(&FDMExec,fgic,tLongitudinal);
fgtrim->DoTrim();
fgtrim->Report();
fgtrim->TrimStats();
fgtrim->ReportState();
FG_LOG( FG_FLIGHT, FG_DEBUG, " Calculated Aircraft AGL: " << endl
<< " " << "get_Altitude() + get_Sea_level_radius() - scenery.cur_radius*METER_TO_FEET= "
<< get_Altitude() + get_Sea_level_radius()- scenery.cur_radius*METER_TO_FEET );
FG_LOG( FG_FLIGHT, FG_DEBUG, " globals->get_options()->get_altitude(): "
<< globals->get_options()->get_altitude() );
FG_LOG( FG_FLIGHT, FG_DEBUG, " FGBFI::getAltitude(): "
<< FGBFI::getAltitude() ); */
controls.set_elevator_trim(FDMExec.GetFCS()->GetPitchTrimCmd());
controls.set_throttle( FGControls::ALL_ENGINES,
FDMExec.GetFCS()->GetThrottleCmd(0)/100 );
trimmed=true;
trim_elev=FDMExec.GetFCS()->GetPitchTrimCmd();
trim_throttle=FDMExec.GetFCS()->GetThrottleCmd(0)/100;
//the trimming routine only knows how to get 1 value for throttle
FG_LOG( FG_FLIGHT, FG_INFO, " loaded initial conditions" );
delete fgtrim;
}
FG_LOG( FG_FLIGHT, FG_INFO, " Trim complete." );
} else {
FG_LOG( FG_FLIGHT, FG_INFO, " Initializing without trim" );
FDMExec.GetState()->Initialize(fgic);
FG_LOG( FG_FLIGHT, FG_INFO, " set dt" );
}
FG_LOG( FG_FLIGHT, FG_INFO, "Finished initializing JSBSim" );
delete fgic;
FG_LOG( FG_FLIGHT, FG_INFO, " loaded initial conditions" );
FG_LOG( FG_FLIGHT, FG_INFO, " set dt" );
FG_LOG( FG_FLIGHT, FG_INFO, "Finished initializing JSBSim" );
copy_from_JSBsim();
return true;
return true;
}
/******************************************************************************/
@ -198,52 +198,67 @@ bool FGJSBsim::init( double dt ) {
// Run an iteration of the EOM (equations of motion)
bool FGJSBsim::update( int multiloop ) {
double save_alt = 0.0;
double time_step = (1.0 / globals->get_options()->get_model_hz()) * multiloop;
double start_elev = get_Altitude();
int i;
double save_alt = 0.0;
// lets try to avoid really screwing up the JSBsim model
if ( get_Altitude() < -9000 ) {
save_alt = get_Altitude();
set_Altitude( 0.0 );
}
// lets try to avoid really screwing up the JSBsim model
if ( get_Altitude() < -9000 ) {
save_alt = get_Altitude();
set_Altitude( 0.0 );
}
if(trimmed) {
controls.set_elevator_trim(trim_elev);
controls.set_throttle(FGControls::ALL_ENGINES,trim_throttle);
controls.set_elevator(0.0);
controls.set_aileron(0.0);
controls.set_rudder(0.0);
trimmed=false;
}
copy_to_JSBsim();
if(needTrim) {
FGTrim *fgtrim=new FGTrim(fdmex,fgic,tLongitudinal);
if(!fgtrim->DoTrim()) {
fgtrim->Report();
fgtrim->TrimStats();
}
fgtrim->ReportState();
delete fgtrim;
needTrim=false;
controls.set_elevator_trim(fdmex->GetFCS()->GetPitchTrimCmd());
controls.set_elevator(fdmex->GetFCS()->GetDeCmd());
controls.set_throttle(FGControls::ALL_ENGINES,
fdmex->GetFCS()->GetThrottleCmd(0)/100.0);
controls.set_aileron(fdmex->GetFCS()->GetDaCmd());
controls.set_rudder(fdmex->GetFCS()->GetDrCmd());
FG_LOG( FG_FLIGHT, FG_INFO, " Trim complete" );
}
for( i=0; i<get_num_engines(); i++ ) {
get_engine(i)->set_RPM( controls.get_throttle(i)*2700 );
get_engine(i)->set_Throttle( controls.get_throttle(i) );
}
copy_to_JSBsim();
for ( int i = 0; i < multiloop; i++ ) {
fdmex->Run();
}
for ( int i = 0; i < multiloop; i++ ) {
FDMExec.Run();
}
// printf("%d FG_Altitude = %.2f\n", i, FG_Altitude * 0.3048);
// printf("%d Altitude = %.2f\n", i, Altitude * 0.3048);
// printf("%d FG_Altitude = %.2f\n", i, FG_Altitude * 0.3048);
// printf("%d Altitude = %.2f\n", i, Altitude * 0.3048);
// translate JSBsim back to FG structure so that the
// autopilot (and the rest of the sim can use the updated values
// translate JSBsim back to FG structure so that the
// autopilot (and the rest of the sim can use the updated values
copy_from_JSBsim();
copy_from_JSBsim();
// but lets restore our original bogus altitude when we are done
// but lets restore our original bogus altitude when we are done
if ( save_alt < -9000.0 ) {
set_Altitude( save_alt );
}
double end_elev = get_Altitude();
return true;
if ( save_alt < -9000.0 ) {
set_Altitude( save_alt );
}
//climb rate now set from FDM in copy_from_x()
return true;
}
/******************************************************************************/
@ -251,35 +266,33 @@ bool FGJSBsim::update( int multiloop ) {
// Convert from the FGInterface struct to the JSBsim generic_ struct
bool FGJSBsim::copy_to_JSBsim() {
// copy control positions into the JSBsim structure
// copy control positions into the JSBsim structure
FDMExec.GetFCS()->SetDaCmd( controls.get_aileron());
FDMExec.GetFCS()->SetDeCmd( controls.get_elevator());
FDMExec.GetFCS()->SetPitchTrimCmd(controls.get_elevator_trim());
FDMExec.GetFCS()->SetDrCmd( -1*controls.get_rudder());
FDMExec.GetFCS()->SetDfCmd( controls.get_flaps() );
FDMExec.GetFCS()->SetDsbCmd( 0.0 ); //speedbrakes
FDMExec.GetFCS()->SetDspCmd( 0.0 ); //spoilers
FDMExec.GetFCS()->SetThrottleCmd( FGControls::ALL_ENGINES,
controls.get_throttle( 0 ) * 100.0 );
fdmex->GetFCS()->SetDaCmd( controls.get_aileron());
fdmex->GetFCS()->SetDeCmd( controls.get_elevator());
fdmex->GetFCS()->SetPitchTrimCmd(controls.get_elevator_trim());
fdmex->GetFCS()->SetDrCmd( -1*controls.get_rudder());
fdmex->GetFCS()->SetDfCmd( controls.get_flaps() );
fdmex->GetFCS()->SetDsbCmd( 0.0 ); //speedbrakes
fdmex->GetFCS()->SetDspCmd( 0.0 ); //spoilers
fdmex->GetFCS()->SetThrottleCmd( FGControls::ALL_ENGINES,
controls.get_throttle( 0 ) * 100.0 );
FDMExec.GetFCS()->SetLBrake( controls.get_brake( 0 ) );
FDMExec.GetFCS()->SetRBrake( controls.get_brake( 1 ) );
FDMExec.GetFCS()->SetCBrake( controls.get_brake( 2 ) );
fdmex->GetFCS()->SetLBrake( controls.get_brake( 0 ) );
fdmex->GetFCS()->SetRBrake( controls.get_brake( 1 ) );
fdmex->GetFCS()->SetCBrake( controls.get_brake( 2 ) );
// Inform JSBsim of the local terrain altitude; uncommented 5/3/00
// FDMExec.GetPosition()->SetRunwayElevation(get_Runway_altitude()); // seems to work
FDMExec.GetPosition()->SetRunwayRadius(scenery.cur_radius*METER_TO_FEET);
FDMExec.GetPosition()->SetSeaLevelRadius(get_Sea_level_radius());
fdmex->GetPosition()->SetRunwayRadius(scenery.cur_radius*METER_TO_FEET);
fdmex->GetPosition()->SetSeaLevelRadius(get_Sea_level_radius());
FDMExec.GetAtmosphere()->SetExTemperature(get_Static_temperature());
FDMExec.GetAtmosphere()->SetExPressure(get_Static_pressure());
FDMExec.GetAtmosphere()->SetExDensity(get_Density());
FDMExec.GetAtmosphere()->SetWindNED(get_V_north_airmass(),
get_V_east_airmass(),
get_V_down_airmass());
fdmex->GetAtmosphere()->SetExTemperature(get_Static_temperature());
fdmex->GetAtmosphere()->SetExPressure(get_Static_pressure());
fdmex->GetAtmosphere()->SetExDensity(get_Density());
fdmex->GetAtmosphere()->SetWindNED(get_V_north_airmass(),
get_V_east_airmass(),
get_V_down_airmass());
return true;
return true;
}
/******************************************************************************/
@ -287,116 +300,271 @@ bool FGJSBsim::copy_to_JSBsim() {
// Convert from the JSBsim generic_ struct to the FGInterface struct
bool FGJSBsim::copy_from_JSBsim() {
set_Inertias( FDMExec.GetAircraft()->GetMass(),
FDMExec.GetAircraft()->GetIxx(),
FDMExec.GetAircraft()->GetIyy(),
FDMExec.GetAircraft()->GetIzz(),
FDMExec.GetAircraft()->GetIxz() );
unsigned i, j;
set_CG_Position ( FDMExec.GetAircraft()->GetXYZcg()(1),
FDMExec.GetAircraft()->GetXYZcg()(2),
FDMExec.GetAircraft()->GetXYZcg()(3) );
_set_Inertias( fdmex->GetAircraft()->GetMass(),
fdmex->GetAircraft()->GetIxx(),
fdmex->GetAircraft()->GetIyy(),
fdmex->GetAircraft()->GetIzz(),
fdmex->GetAircraft()->GetIxz() );
set_Accels_Body ( FDMExec.GetTranslation()->GetUVWdot()(1),
FDMExec.GetTranslation()->GetUVWdot()(2),
FDMExec.GetTranslation()->GetUVWdot()(3) );
_set_CG_Position( fdmex->GetAircraft()->GetXYZcg()(1),
fdmex->GetAircraft()->GetXYZcg()(2),
fdmex->GetAircraft()->GetXYZcg()(3) );
set_Accels_CG_Body ( FDMExec.GetTranslation()->GetUVWdot()(1),
FDMExec.GetTranslation()->GetUVWdot()(2),
FDMExec.GetTranslation()->GetUVWdot()(3) );
_set_Accels_Body( fdmex->GetTranslation()->GetUVWdot()(1),
fdmex->GetTranslation()->GetUVWdot()(2),
fdmex->GetTranslation()->GetUVWdot()(3) );
//set_Accels_CG_Body_N ( FDMExec.GetTranslation()->GetNcg()(1),
// FDMExec.GetTranslation()->GetNcg()(2),
// FDMExec.GetTranslation()->GetNcg()(3) );
//
set_Accels_Pilot_Body( FDMExec.GetAuxiliary()->GetPilotAccel()(1),
FDMExec.GetAuxiliary()->GetPilotAccel()(2),
FDMExec.GetAuxiliary()->GetPilotAccel()(3) );
_set_Accels_CG_Body( fdmex->GetTranslation()->GetUVWdot()(1),
fdmex->GetTranslation()->GetUVWdot()(2),
fdmex->GetTranslation()->GetUVWdot()(3) );
//set_Accels_Pilot_Body_N( FDMExec.GetAuxiliary()->GetNpilot()(1),
// FDMExec.GetAuxiliary()->GetNpilot()(2),
// FDMExec.GetAuxiliary()->GetNpilot()(3) );
//_set_Accels_CG_Body_N ( fdmex->GetTranslation()->GetNcg()(1),
// fdmex->GetTranslation()->GetNcg()(2),
// fdmex->GetTranslation()->GetNcg()(3) );
//
_set_Accels_Pilot_Body( fdmex->GetAuxiliary()->GetPilotAccel()(1),
fdmex->GetAuxiliary()->GetPilotAccel()(2),
fdmex->GetAuxiliary()->GetPilotAccel()(3) );
//_set_Accels_Pilot_Body_N( fdmex->GetAuxiliary()->GetNpilot()(1),
// fdmex->GetAuxiliary()->GetNpilot()(2),
// fdmex->GetAuxiliary()->GetNpilot()(3) );
set_Nlf( FDMExec.GetAircraft()->GetNlf());
_set_Nlf( fdmex->GetAircraft()->GetNlf() );
// Velocities
_set_Velocities_Local( fdmex->GetPosition()->GetVn(),
fdmex->GetPosition()->GetVe(),
fdmex->GetPosition()->GetVd() );
_set_Velocities_Wind_Body( fdmex->GetTranslation()->GetUVW()(1),
fdmex->GetTranslation()->GetUVW()(2),
fdmex->GetTranslation()->GetUVW()(3) );
// Velocities
_set_V_equiv_kts( fdmex->GetAuxiliary()->GetVequivalentKTS() );
set_Velocities_Local( FDMExec.GetPosition()->GetVn(),
FDMExec.GetPosition()->GetVe(),
FDMExec.GetPosition()->GetVd() );
// _set_V_calibrated( fdmex->GetAuxiliary()->GetVcalibratedFPS() );
set_Velocities_Wind_Body( FDMExec.GetTranslation()->GetUVW()(1),
FDMExec.GetTranslation()->GetUVW()(2),
FDMExec.GetTranslation()->GetUVW()(3) );
_set_V_calibrated_kts( fdmex->GetAuxiliary()->GetVcalibratedKTS() );
set_V_equiv_kts( FDMExec.GetAuxiliary()->GetVequivalentKTS() );
_set_V_ground_speed( fdmex->GetPosition()->GetVground() );
//set_V_calibrated( FDMExec.GetAuxiliary()->GetVcalibratedFPS() );
_set_Omega_Body( fdmex->GetRotation()->GetPQR()(1),
fdmex->GetRotation()->GetPQR()(2),
fdmex->GetRotation()->GetPQR()(3) );
set_V_calibrated_kts( FDMExec.GetAuxiliary()->GetVcalibratedKTS() );
_set_Euler_Rates( fdmex->GetRotation()->GetEulerRates()(1),
fdmex->GetRotation()->GetEulerRates()(2),
fdmex->GetRotation()->GetEulerRates()(3) );
_set_Geocentric_Rates(fdmex->GetPosition()->GetLatitudeDot(),
fdmex->GetPosition()->GetLongitudeDot(),
fdmex->GetPosition()->Gethdot() );
_set_Mach_number( fdmex->GetTranslation()->GetMach() );
// Positions
double lat_geoc = fdmex->GetPosition()->GetLatitude();
double lon = fdmex->GetPosition()->GetLongitude();
double alt = fdmex->GetPosition()->Geth();
double lat_geod, tmp_alt, sl_radius1, sl_radius2, tmp_lat_geoc;
sgGeocToGeod( lat_geoc, EQUATORIAL_RADIUS_M + alt * FEET_TO_METER,
&lat_geod, &tmp_alt, &sl_radius1 );
sgGeodToGeoc( lat_geod, alt * FEET_TO_METER, &sl_radius2, &tmp_lat_geoc );
FG_LOG( FG_FLIGHT, FG_DEBUG, "lon = " << lon << " lat_geod = " << lat_geod
<< " lat_geoc = " << lat_geoc
<< " alt = " << alt << " tmp_alt = " << tmp_alt * METER_TO_FEET
<< " sl_radius1 = " << sl_radius1 * METER_TO_FEET
<< " sl_radius2 = " << sl_radius2 * METER_TO_FEET
<< " Equator = " << EQUATORIAL_RADIUS_FT );
_set_Geocentric_Position( lat_geoc, lon, sl_radius2 * METER_TO_FEET + alt );
set_V_ground_speed ( FDMExec.GetPosition()->GetVground() );
set_Omega_Body( FDMExec.GetState()->GetParameter(FG_ROLLRATE),
FDMExec.GetState()->GetParameter(FG_PITCHRATE),
FDMExec.GetState()->GetParameter(FG_YAWRATE) );
set_Euler_Rates( FDMExec.GetRotation()->GetEulerRates()(2),
FDMExec.GetRotation()->GetEulerRates()(1),
FDMExec.GetRotation()->GetEulerRates()(3));
// ***FIXME*** set_Geocentric_Rates( Latitude_dot, Longitude_dot,
// Radius_dot );
set_Mach_number( FDMExec.GetTranslation()->GetMach());
// Positions
double lat_geoc = FDMExec.GetPosition()->GetLatitude();
double lon = FDMExec.GetPosition()->GetLongitude();
double alt = FDMExec.GetPosition()->Geth();
double lat_geod, tmp_alt, sl_radius1, sl_radius2, tmp_lat_geoc;
sgGeocToGeod( lat_geoc, EQUATORIAL_RADIUS_M + alt * FEET_TO_METER,
&lat_geod, &tmp_alt, &sl_radius1 );
sgGeodToGeoc( lat_geod, alt * FEET_TO_METER, &sl_radius2, &tmp_lat_geoc );
FG_LOG( FG_FLIGHT, FG_DEBUG, "lon = " << lon << " lat_geod = " << lat_geod
<< " lat_geoc = " << lat_geoc
<< " alt = " << alt << " tmp_alt = " << tmp_alt * METER_TO_FEET
<< " sl_radius1 = " << sl_radius1 * METER_TO_FEET
<< " sl_radius2 = " << sl_radius2 * METER_TO_FEET
<< " Equator = " << EQUATORIAL_RADIUS_FT );
set_Geocentric_Position( lat_geoc, lon,
sl_radius2 * METER_TO_FEET + alt );
set_Geodetic_Position( lat_geod, lon, alt );
set_Euler_Angles( FDMExec.GetRotation()->Getphi(),
FDMExec.GetRotation()->Gettht(),
FDMExec.GetRotation()->Getpsi() );
set_Alpha( FDMExec.GetTranslation()->Getalpha() );
set_Beta( FDMExec.GetTranslation()->Getbeta() );
set_Gamma_vert_rad( FDMExec.GetPosition()->GetGamma() );
// set_Gamma_horiz_rad( Gamma_horiz_rad );
/* **FIXME*** */ set_Sea_level_radius( sl_radius2 * METER_TO_FEET );
/* **FIXME*** */ set_Earth_position_angle( 0.0 );
// /* ***FIXME*** */ set_Runway_altitude( 0.0 );
set_sin_lat_geocentric( lat_geoc );
set_cos_lat_geocentric( lat_geoc );
set_sin_cos_longitude( lon );
set_sin_cos_latitude( lat_geod );
_set_Geodetic_Position( lat_geod, lon, alt );
set_Climb_Rate(FDMExec.GetPosition()->Gethdot());
_set_Euler_Angles( fdmex->GetRotation()->Getphi(),
fdmex->GetRotation()->Gettht(),
fdmex->GetRotation()->Getpsi() );
return true;
_set_Alpha( fdmex->GetTranslation()->Getalpha() );
_set_Beta( fdmex->GetTranslation()->Getbeta() );
_set_Gamma_vert_rad( fdmex->GetPosition()->GetGamma() );
// set_Gamma_horiz_rad( Gamma_horiz_rad );
/* **FIXME*** */ _set_Sea_level_radius( sl_radius2 * METER_TO_FEET );
/* **FIXME*** */ _set_Earth_position_angle( fdmex->GetAuxiliary()->
GetEarthPositionAngle() );
/* ***FIXME*** */ _set_Runway_altitude( scenery.cur_radius * METERS_TO_FEET -
get_Sea_level_radius() );
_set_sin_lat_geocentric( lat_geoc );
_set_cos_lat_geocentric( lat_geoc );
_set_sin_cos_longitude( lon );
_set_sin_cos_latitude( lat_geod );
_set_Climb_Rate( fdmex->GetPosition()->Gethdot() );
for ( i = 0; i < 3; i++ ) {
for ( j = 0; j < 3; j++ ) {
_set_T_Local_to_Body( i, j, fdmex->GetState()->GetTl2b()(i,j) );
}
}
return true;
}
//Positions
void FGJSBsim::set_Latitude(double lat) {
FG_LOG(FG_FLIGHT,FG_INFO,"FGJSBsim::set_Latitude: " << lat);
fgic->SetLatitudeRadIC(lat);
fdmex->RunIC(fgic); //loop JSBSim once
copy_from_JSBsim(); //update the bus
needTrim=true;
}
void FGJSBsim::set_Longitude(double lon) {
FG_LOG(FG_FLIGHT,FG_INFO,"FGJSBsim::set_Longitude: " << lon);
fgic->SetLongitudeRadIC(lon);
fdmex->RunIC(fgic); //loop JSBSim once
copy_from_JSBsim(); //update the bus
needTrim=true;
}
void FGJSBsim::set_Altitude(double alt) {
FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Altitude: " << alt );
fgic->SetAltitudeFtIC(alt);
fdmex->RunIC(fgic); //loop JSBSim once
copy_from_JSBsim(); //update the bus
needTrim=true;
}
void FGJSBsim::set_V_calibrated_kts(double vc) {
FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_V_calibrated_kts: " << vc );
fgic->SetVcalibratedKtsIC(vc);
fdmex->RunIC(fgic); //loop JSBSim once
copy_from_JSBsim(); //update the bus
needTrim=true;
}
void FGJSBsim::set_Mach_number(double mach) {
FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Mach_number: " << mach );
fgic->SetMachIC(mach);
fdmex->RunIC(fgic); //loop JSBSim once
copy_from_JSBsim(); //update the bus
needTrim=true;
}
void FGJSBsim::set_Velocities_Local( double north, double east, double down ){
FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Velocities_Local: "
<< north << ", " << east << ", " << down );
fgic->SetVnorthFpsIC(north);
fgic->SetVeastFpsIC(east);
fgic->SetVdownFpsIC(down);
fdmex->RunIC(fgic); //loop JSBSim once
cout << "fdmex->GetTranslation()->GetVt(): " << fdmex->GetTranslation()->GetVt() << endl;
cout << "fdmex->GetPosition()->GetVn(): " << fdmex->GetPosition()->GetVn() << endl;
copy_from_JSBsim(); //update the bus
busdump();
needTrim=true;
}
void FGJSBsim::set_Velocities_Wind_Body( double u, double v, double w){
FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Velocities_Wind_Body: "
<< u << ", " << v << ", " << w );
fgic->SetUBodyFpsIC(u);
fgic->SetVBodyFpsIC(v);
fgic->SetWBodyFpsIC(w);
fdmex->RunIC(fgic); //loop JSBSim once
copy_from_JSBsim(); //update the bus
needTrim=true;
}
//Euler angles
void FGJSBsim::set_Euler_Angles( double phi, double theta, double psi ) {
FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Euler_Angles: "
<< phi << ", " << theta << ", " << psi );
fgic->SetPitchAngleRadIC(theta);
fgic->SetRollAngleRadIC(phi);
fgic->SetTrueHeadingRadIC(psi);
fdmex->RunIC(fgic); //loop JSBSim once
copy_from_JSBsim(); //update the bus
needTrim=true;
}
//Flight Path
void FGJSBsim::set_Climb_Rate( double roc) {
FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Climb_Rate: " << roc );
fgic->SetClimbRateFpsIC(roc);
fdmex->RunIC(fgic); //loop JSBSim once
copy_from_JSBsim(); //update the bus
needTrim=true;
}
void FGJSBsim::set_Gamma_vert_rad( double gamma) {
FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Gamma_vert_rad: " << gamma );
fgic->SetFlightPathAngleRadIC(gamma);
fdmex->RunIC(fgic); //loop JSBSim once
copy_from_JSBsim(); //update the bus
needTrim=true;
}
//Earth
void FGJSBsim::set_Sea_level_radius(double slr) {
FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Sea_level_radius: " << slr );
fgic->SetSeaLevelRadiusFtIC(slr);
fdmex->RunIC(fgic); //loop JSBSim once
copy_from_JSBsim(); //update the bus
needTrim=true;
}
void FGJSBsim::set_Runway_altitude(double ralt) {
FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Runway_altitude: " << ralt );
_set_Runway_altitude( ralt );
fdmex->RunIC(fgic); //loop JSBSim once
copy_from_JSBsim(); //update the bus
needTrim=true;
}
void FGJSBsim::set_Static_pressure(double p) {
FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Static_pressure: " << p );
fdmex->GetAtmosphere()->SetExPressure(p);
if(fdmex->GetAtmosphere()->External() == true)
needTrim=true;
}
void FGJSBsim::set_Static_temperature(double T) {
FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Static_temperature: " << T );
fdmex->GetAtmosphere()->SetExTemperature(T);
if(fdmex->GetAtmosphere()->External() == true)
needTrim=true;
}
void FGJSBsim::set_Density(double rho) {
FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Density: " << rho );
fdmex->GetAtmosphere()->SetExDensity(rho);
if(fdmex->GetAtmosphere()->External() == true)
needTrim=true;
}
void FGJSBsim::set_Velocities_Local_Airmass (double wnorth,
double weast,
double wdown ) {
FG_LOG(FG_FLIGHT,FG_INFO, "FGJSBsim::set_Velocities_Local_Airmass: "
<< wnorth << ", " << weast << ", " << wdown );
fdmex->GetAtmosphere()->SetWindNED(wnorth, weast, wdown );
if(fdmex->GetAtmosphere()->External() == true)
needTrim=true;
}

View file

@ -25,6 +25,7 @@
#define _JSBSIM_HXX
#include <FDM/JSBSim/FGFDMExec.h>
#include <FDM/JSBSim/FGInitialCondition.h>
#undef MAX_ENGINES
#include <Aircraft/aircraft.hxx>
@ -34,13 +35,19 @@
class FGJSBsim: public FGInterface {
// The aircraft for this instance
FGFDMExec FDMExec;
FGFDMExec *fdmex;
FGInitialCondition *fgic;
bool needTrim;
bool trimmed;
float trim_elev;
float trim_throttle;
public:
FGJSBsim::FGJSBsim(void);
FGJSBsim::~FGJSBsim();
// copy FDM state to LaRCsim structures
bool copy_to_JSBsim();
@ -49,6 +56,37 @@ public:
// reset flight params to a specific position
bool init( double dt );
// Positions
void set_Latitude(double lat); // geocentric
void set_Longitude(double lon);
void set_Altitude(double alt); // triggers re-calc of AGL altitude
//void set_AltitudeAGL(double altagl); // and vice-versa
// Speeds -- setting any of these will trigger a re-calc of the rest
void set_V_calibrated_kts(double vc);
void set_Mach_number(double mach);
void set_Velocities_Local( double north, double east, double down );
void set_Velocities_Wind_Body( double u, double v, double w);
// Euler angles
void set_Euler_Angles( double phi, double theta, double psi );
// Flight Path
void set_Climb_Rate( double roc);
void set_Gamma_vert_rad( double gamma);
// Earth
void set_Sea_level_radius(double slr);
void set_Runway_altitude(double ralt);
// Atmosphere
void set_Static_pressure(double p);
void set_Static_temperature(double T);
void set_Density(double rho);
void set_Velocities_Local_Airmass (double wnorth,
double weast,
double wdown );
// update position based on inputs, positions, velocities, etc.
bool update( int multiloop );

View file

@ -82,6 +82,7 @@ public:
inline void UseExternal(void) { useExternal=true; }
inline void UseInternal(void) { useExternal=false; } //this is the default
bool External(void) { return useExternal; }
inline void SetExTemperature(float t) { exTemperature=t; }
inline void SetExDensity(float d) { exDensity=d; }

View file

@ -46,7 +46,6 @@ SENTRY
#define ECCENTSQRD 0.99330561
#define INVECCENTSQRD 1.0067395
#define INVECCENTSQRDM1 0.0067395
#define EPS 0.081819221
#define Reng 1716 //Specific Gas Constant,ft^2/(sec^2*R)
#define SHRATIO 1.4 //Specific Heat Ratio
#define RADTODEG 57.29578

View file

@ -58,6 +58,7 @@ INCLUDES
static const char *IdSrc = "$Header$";
static const char *IdHdr = ID_INITIALCONDITION;
FGInitialCondition::FGInitialCondition(FGFDMExec *FDMExec) {
vt=vc=ve=0;
mach=0;
@ -68,6 +69,9 @@ FGInitialCondition::FGInitialCondition(FGFDMExec *FDMExec) {
u=v=w=0;
vnorth=veast=vdown=0;
lastSpeedSet=setvt;
sea_level_radius = EARTHRAD;
radius_to_vehicle = EARTHRAD;
terrain_altitude = 0;
if(FDMExec != NULL ) {
fdmex=FDMExec;
fdmex->GetPosition()->Seth(altitude);
@ -84,13 +88,13 @@ FGInitialCondition::~FGInitialCondition(void) {}
void FGInitialCondition::SetVcalibratedKtsIC(float tt) {
if(getMachFromVcas(&mach,tt*KTSTOFPS)) {
if(getMachFromVcas(&mach,tt*jsbKTSTOFPS)) {
//cout << "Mach: " << mach << endl;
lastSpeedSet=setvc;
vc=tt*KTSTOFPS;
vc=tt*jsbKTSTOFPS;
vt=mach*fdmex->GetAtmosphere()->GetSoundSpeed();
ve=vt*sqrt(fdmex->GetAtmosphere()->GetDensityRatio());
//cout << "Vt: " << vt*FPSTOKTS << " Vc: " << vc*FPSTOKTS << endl;
//cout << "Vt: " << vt*jsbFPSTOKTS << " Vc: " << vc*jsbFPSTOKTS << endl;
}
else {
cout << "Failed to get Mach number for given Vc and altitude, Vc unchanged." << endl;
@ -99,7 +103,7 @@ void FGInitialCondition::SetVcalibratedKtsIC(float tt) {
}
void FGInitialCondition::SetVequivalentKtsIC(float tt) {
ve=tt*KTSTOFPS;
ve=tt*jsbKTSTOFPS;
lastSpeedSet=setve;
vt=ve*1/sqrt(fdmex->GetAtmosphere()->GetDensityRatio());
mach=vt/fdmex->GetAtmosphere()->GetSoundSpeed();
@ -107,7 +111,7 @@ void FGInitialCondition::SetVequivalentKtsIC(float tt) {
}
void FGInitialCondition::SetVtrueKtsIC(float tt) {
vt=tt*KTSTOFPS;
vt=tt*jsbKTSTOFPS;
lastSpeedSet=setvt;
mach=vt/fdmex->GetAtmosphere()->GetSoundSpeed();
vc=calcVcas(mach);
@ -120,7 +124,7 @@ void FGInitialCondition::SetMachIC(float tt) {
vt=mach*fdmex->GetAtmosphere()->GetSoundSpeed();
vc=calcVcas(mach);
ve=vt*sqrt(fdmex->GetAtmosphere()->GetDensityRatio());
//cout << "Vt: " << vt*FPSTOKTS << " Vc: " << vc*FPSTOKTS << endl;
//cout << "Vt: " << vt*jsbFPSTOKTS << " Vc: " << vc*jsbFPSTOKTS << endl;
}
void FGInitialCondition::SetClimbRateFpmIC(float tt) {
@ -145,20 +149,20 @@ void FGInitialCondition::SetFlightPathAngleRadIC(float tt) {
void FGInitialCondition::SetUBodyFpsIC(float tt) {
u=tt;
vt=sqrt(u*u+v*v+w*w);
lastSpeedSet=setvt;
lastSpeedSet=setuvw;
}
void FGInitialCondition::SetVBodyFpsIC(float tt) {
v=tt;
vt=sqrt(u*u+v*v+w*w);
lastSpeedSet=setvt;
lastSpeedSet=setuvw;
}
void FGInitialCondition::SetWBodyFpsIC(float tt) {
w=tt;
vt=sqrt(u*u+v*v+w*w);
lastSpeedSet=setvt;
lastSpeedSet=setuvw;
}
@ -170,14 +174,16 @@ void FGInitialCondition::SetAltitudeFtIC(float tt) {
//lets try to make sure the user gets what they intended
switch(lastSpeedSet) {
case setned:
case setuvw:
case setvt:
SetVtrueKtsIC(vt*FPSTOKTS);
SetVtrueKtsIC(vt*jsbFPSTOKTS);
break;
case setvc:
SetVcalibratedKtsIC(vc*FPSTOKTS);
SetVcalibratedKtsIC(vc*jsbFPSTOKTS);
break;
case setve:
SetVequivalentKtsIC(ve*FPSTOKTS);
SetVequivalentKtsIC(ve*jsbFPSTOKTS);
break;
case setmach:
SetMachIC(mach);
@ -190,6 +196,15 @@ void FGInitialCondition::SetAltitudeAGLFtIC(float tt) {
altitude=fdmex->GetPosition()->Geth();
SetAltitudeFtIC(altitude);
}
void FGInitialCondition::SetSeaLevelRadiusFtIC(double tt) {
sea_level_radius = tt;
}
void FGInitialCondition::SetTerrainAltitudeFtIC(double tt) {
terrain_altitude=tt;
fdmex->GetPosition()->SetDistanceAGL(altitude-terrain_altitude);
fdmex->GetPosition()->SetRunwayRadius(sea_level_radius + terrain_altitude);
}
void FGInitialCondition::calcUVWfromNED(void) {
u=vnorth*cos(theta)*cos(psi) +
@ -207,14 +222,14 @@ void FGInitialCondition::SetVnorthFpsIC(float tt) {
vnorth=tt;
calcUVWfromNED();
vt=sqrt(u*u + v*v + w*w);
lastSpeedSet=setvt;
lastSpeedSet=setned;
}
void FGInitialCondition::SetVeastFpsIC(float tt) {
veast=tt;
calcUVWfromNED();
vt=sqrt(u*u + v*v + w*w);
lastSpeedSet=setvt;
lastSpeedSet=setned;
}
void FGInitialCondition::SetVdownFpsIC(float tt) {
@ -222,7 +237,7 @@ void FGInitialCondition::SetVdownFpsIC(float tt) {
calcUVWfromNED();
vt=sqrt(u*u + v*v + w*w);
SetClimbRateFpsIC(-1*vdown);
lastSpeedSet=setvt;
lastSpeedSet=setned;
}
bool FGInitialCondition::getMachFromVcas(float *Mach,float vcas) {
@ -324,7 +339,7 @@ float FGInitialCondition::calcVcas(float Mach) {
A = pow(((pt-p)/psl+1),0.28571);
vcas = sqrt(7*psl/rhosl*(A-1));
//cout << "calcVcas: vcas= " << vcas*FPSTOKTS << " mach= " << Mach << " pressure: " << pt << endl;
//cout << "calcVcas: vcas= " << vcas*jsbFPSTOKTS << " mach= " << Mach << " pressure: " << pt << endl;
return vcas;
}
@ -412,6 +427,6 @@ bool FGInitialCondition::solve(float *y,float x) {
*y=x2;
}
//cout << "Success= " << success << " Vcas: " << vcas*FPSTOKTS << " Mach: " << x2 << endl;
//cout << "Success= " << success << " Vcas: " << vcas*jsbFPSTOKTS << " Mach: " << x2 << endl;
return success;
}

View file

@ -59,7 +59,10 @@ INCLUDES
CLASS DECLARATION
*******************************************************************************/
typedef enum { setvt, setvc, setve, setmach } speedset;
typedef enum { setvt, setvc, setve, setmach, setuvw, setned } speedset;
#define jsbFPSTOKTS 0.5924838
#define jsbKTSTOFPS 1.6878099
/* USAGE NOTES
@ -105,12 +108,13 @@ typedef enum { setvt, setvc, setve, setmach } speedset;
considered equivalent to setting gamma.
*/
class FGInitialCondition {
public:
FGInitialCondition(FGFDMExec *fdmex);
~FGInitialCondition(void);
inline speedset GetSpeedSet(void) { return lastSpeedSet; }
void SetVcalibratedKtsIC(float tt);
void SetVequivalentKtsIC(float tt);
@ -127,7 +131,10 @@ public:
void SetAltitudeFtIC(float tt);
void SetAltitudeAGLFtIC(float tt);
void SetSeaLevelRadiusFtIC(double tt);
void SetTerrainAltitudeFtIC(double tt);
//"vertical" flight path, recalculate theta
inline void SetFlightPathAngleDegIC(float tt) { SetFlightPathAngleRadIC(tt*DEGTORAD); }
void SetFlightPathAngleRadIC(float tt);
@ -147,8 +154,8 @@ public:
inline void SetRollAngleDegIC(float tt) { phi=tt*DEGTORAD; getTheta(); }
inline void SetRollAngleRadIC(float tt) { phi=tt; getTheta(); }
inline void SetHeadingDegIC(float tt) { psi=tt*DEGTORAD; }
inline void SetHeadingRadIC(float tt) { psi=tt; }
inline void SetTrueHeadingDegIC(float tt) { psi=tt*DEGTORAD; }
inline void SetTrueHeadingRadIC(float tt) { psi=tt; }
inline void SetLatitudeDegIC(float tt) { latitude=tt*DEGTORAD; }
inline void SetLatitudeRadIC(float tt) { latitude=tt; }
@ -156,9 +163,9 @@ public:
inline void SetLongitudeDegIC(float tt) { longitude=tt*DEGTORAD; }
inline void SetLongitudeRadIC(float tt) { longitude=tt; }
inline float GetVcalibratedKtsIC(void) { return vc*FPSTOKTS; }
inline float GetVequivalentKtsIC(void) { return ve*FPSTOKTS; }
inline float GetVtrueKtsIC(void) { return vt*FPSTOKTS; }
inline float GetVcalibratedKtsIC(void) { return vc*jsbFPSTOKTS; }
inline float GetVequivalentKtsIC(void) { return ve*jsbFPSTOKTS; }
inline float GetVtrueKtsIC(void) { return vt*jsbFPSTOKTS; }
inline float GetVtrueFpsIC(void) { return vt; }
inline float GetMachIC(void) { return mach; }
@ -210,6 +217,9 @@ private:
float latitude,longitude;
float u,v,w;
float vnorth,veast,vdown;
double sea_level_radius;
double terrain_altitude;
double radius_to_vehicle;
float xlo, xhi,xmin,xmax;

View file

@ -101,6 +101,7 @@ USEUNIT("FGAerodynamics.cpp");
#include "FGPosition.h"
#include "FGAuxiliary.h"
#include "FGOutput.h"
#include "FGInitialCondition.h"
#ifdef FGFS
#include <simgear/compiler.h>
@ -131,17 +132,38 @@ int main(int argc, char** argv)
FDMExec = new FGFDMExec();
result = FDMExec->LoadModel("aircraft", "engine", string(argv[1]));
result = FDMExec->LoadModel("/home/tony/FlightGear/Aircraft",
"/home/tony/FlightGear/Engine",
string(argv[1]));
if (!result) {
cerr << "Aircraft file " << argv[1] << " was not found" << endl;
exit(-1);
}
if ( ! FDMExec->GetState()->Reset("aircraft", string(argv[1]), string(argv[2])))
if ( ! FDMExec->GetState()->Reset("/home/tony/FlightGear/Aircraft",
string(argv[1]), string(argv[2])))
FDMExec->GetState()->Initialize(2000,0,0,0,0,0,0.5,0.5,40000);
float cmd = 0.0;
FGInitialCondition *fgic= new FGInitialCondition(FDMExec);
fgic->SetUBodyFpsIC(170);
fgic->SetTrueHeadingDegIC(275);
FDMExec->RunIC(fgic);
cout << "FDMExec->GetTranslation()->GetVt(): " << FDMExec->GetTranslation()->GetVt() << endl;
cout << "FDMExec->GetPosition()->GetVn(): " << FDMExec->GetPosition()->GetVn() << endl;
cout << "FDMExec->GetPosition()->GetVe(): " << FDMExec->GetPosition()->GetVe() << endl;
cout << "FDMExec->GetAuxiliary()->GetVcalibratedKTS(): " << FDMExec->GetAuxiliary()->GetVcalibratedKTS() << endl;
fgic->SetVnorthFpsIC(170);
cout << "fgic->GetUBodyFpsIC(): " << fgic->GetUBodyFpsIC() << endl;
cout << "fgic->GetVBodyFpsIC(): " << fgic->GetVBodyFpsIC() << endl;
cout << "fgic->GetWBodyFpsIC(): " << fgic->GetWBodyFpsIC() << endl;
FDMExec->RunIC(fgic);
cout << "FDMExec->GetTranslation()->GetVt(): " << FDMExec->GetTranslation()->GetVt() << endl;
cout << "FDMExec->GetPosition()->GetVn(): " << FDMExec->GetPosition()->GetVn() << endl;
cout << "FDMExec->GetPosition()->GetVe(): " << FDMExec->GetPosition()->GetVe() << endl;
cout << "FDMExec->GetAuxiliary()->GetVcalibratedKTS(): " << FDMExec->GetAuxiliary()->GetVcalibratedKTS() << endl;
/* float cmd = 0.0;
while (FDMExec->GetState()->Getsim_time() <= 10.0)
{
@ -166,6 +188,7 @@ int main(int argc, char** argv)
FDMExec->Run();
}
*/
delete FDMExec;

View file

@ -24,33 +24,56 @@
#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx>
#include <Scenery/scenery.hxx>
#include <Aircraft/aircraft.hxx>
#include <Controls/controls.hxx>
#include <FDM/flight.hxx>
#include <FDM/LaRCsim/ls_cockpit.h>
#include <FDM/LaRCsim/ls_generic.h>
#include <FDM/LaRCsim/ls_interface.h>
#include <FDM/LaRCsimIC.hxx>
#include "IO360.hxx"
#include "LaRCsim.hxx"
FGLaRCsim::FGLaRCsim(void) {
ls_toplevel_init( 0.0, (char *)globals->get_options()->get_aircraft().c_str() );
lsic=new LaRCsimIC; //this needs to be brought up after LaRCsim is
copy_to_LaRCsim(); // initialize all of LaRCsim's vars
//this should go away someday -- formerly done in fg_init.cxx
Mass = 8.547270E+01;
I_xx = 1.048000E+03;
I_yy = 3.000000E+03;
I_zz = 3.530000E+03;
I_xz = 0.000000E+00;
}
FGLaRCsim::~FGLaRCsim(void) {
if(lsic != NULL) {
delete lsic;
}
}
// Initialize the LaRCsim flight model, dt is the time increment for
// each subsequent iteration through the EOM
bool FGLaRCsim::init( double dt ) {
ls_set_model_dt(dt);
// Initialize our little engine that hopefully might
eng.init(dt);
// dcl - in passing dt to init rather than update I am assuming
// that the LaRCsim dt is fixed at one value (yes it is 120hz CLO)
if ( globals->get_options()->get_aircraft() == "c172" ) {
// Initialize our little engine that hopefully might
eng.init(dt);
// dcl - in passing dt to init rather than update I am assuming
// that the LaRCsim dt is fixed at one value (yes it is 120hz CLO)
// update the engines interface
FGEngInterface e;
add_engine( e );
// update the engines interface
FGEngInterface e;
add_engine( e );
}
// cout << "FGLaRCsim::init()" << endl;
// FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::init()" );
double save_alt = 0.0;
@ -63,7 +86,8 @@ bool FGLaRCsim::init( double dt ) {
copy_to_LaRCsim();
// actual LaRCsim top level init
ls_toplevel_init( dt, (char *)globals->get_options()->get_aircraft().c_str() );
// ls_toplevel_init( dt, (char *)globals->get_options()->get_aircraft().c_str() );
FG_LOG( FG_FLIGHT, FG_INFO, "FG pos = " <<
get_Latitude() );
@ -85,7 +109,6 @@ bool FGLaRCsim::init( double dt ) {
// Run an iteration of the EOM (equations of motion)
bool FGLaRCsim::update( int multiloop ) {
// cout << "FGLaRCsim::update()" << endl;
if ( globals->get_options()->get_aircraft() == "c172" ) {
// set control inputs
@ -114,24 +137,20 @@ bool FGLaRCsim::update( int multiloop ) {
e->set_prop_thrust( eng.get_prop_thrust_SI() );
#if 0
cout << "Throttle = " << controls.get_throttle( 0 ) * 100.0;
cout << " Mixture = " << controls.get_mixture( 0 ) * 100.0;
cout << " RPM = " << eng.get_RPM();
cout << " MP = " << eng.get_Manifold_Pressure();
cout << " HP = " << ( eng.get_MaxHP() * eng.get_Percentage_Power()
/ 100.0 );
cout << " EGT = " << eng.get_EGT();
cout << " Thrust (N) " << eng.get_prop_thrust_SI(); // Thrust in Newtons
cout << '\n';
FG_LOG( FG_FLIGHT, FG_INFO, "Throttle = " << controls.get_throttle( 0 ) * 100.0);
FG_LOG( FG_FLIGHT, FG_INFO, " Mixture = " << 80);
FG_LOG( FG_FLIGHT, FG_INFO, " RPM = " << eng.get_RPM());
FG_LOG( FG_FLIGHT, FG_INFO, " MP = " << eng.get_Manifold_Pressure());
FG_LOG( FG_FLIGHT, FG_INFO, " HP = " << ( eng.get_MaxHP() * eng.get_Percentage_Power()/ 100.0) );
FG_LOG( FG_FLIGHT, FG_INFO, " EGT = " << eng.get_EGT());
FG_LOG( FG_FLIGHT, FG_INFO, " Thrust (N) " << eng.get_prop_thrust_SI()); // Thrust in Newtons
FG_LOG( FG_FLIGHT, FG_INFO, '\n');
#endif
// Hmm .. Newtons to lbs is 0.2248 ...
F_X_engine = eng.get_prop_thrust_SI() * 0.07;
}
double save_alt = 0.0;
double time_step = (1.0 / globals->get_options()->get_model_hz())
* multiloop;
double start_elev = get_Altitude();
// lets try to avoid really screwing up the LaRCsim model
if ( get_Altitude() < -9000.0 ) {
@ -155,16 +174,19 @@ bool FGLaRCsim::update( int multiloop ) {
}
Throttle_pct = controls.get_throttle( 0 ) * 1.0;
Brake_pct[0] = controls.get_brake( 1 );
Brake_pct[1] = controls.get_brake( 0 );
// Inform LaRCsim of the local terrain altitude
Runway_altitude = get_Runway_altitude();
// Runway_altitude = get_Runway_altitude();
Runway_altitude = scenery.cur_elev * METER_TO_FEET;
// Weather
V_north_airmass = get_V_north_airmass();
/* V_north_airmass = get_V_north_airmass();
V_east_airmass = get_V_east_airmass();
V_down_airmass = get_V_down_airmass();
V_down_airmass = get_V_down_airmass(); */
// old -- FGInterface_2_LaRCsim() not needed except for Init()
// translate FG to LaRCsim structure
@ -175,6 +197,11 @@ bool FGLaRCsim::update( int multiloop ) {
ls_update(multiloop);
if(isnan(Phi)) {
busdump();
exit(1);
}
// printf("%d FG_Altitude = %.2f\n", i, FG_Altitude * 0.3048);
// printf("%d Altitude = %.2f\n", i, Altitude * 0.3048);
@ -188,12 +215,6 @@ bool FGLaRCsim::update( int multiloop ) {
set_Altitude( save_alt );
}
double end_elev = get_Altitude();
if ( time_step > 0.0 ) {
// feet per second
set_Climb_Rate( (end_elev - start_elev) / time_step );
}
return true;
}
@ -262,9 +283,9 @@ bool FGLaRCsim::copy_to_LaRCsim () {
// P_dot_body = get_P_dot_body();
// Q_dot_body = get_Q_dot_body();
// R_dot_body = get_R_dot_body();
V_north = get_V_north();
V_east = get_V_east();
V_down = get_V_down();
// V_north = get_V_north();
// V_east = get_V_east();
// V_down = get_V_down();
// V_north_rel_ground = get_V_north_rel_ground();
// V_east_rel_ground = get_V_east_rel_ground();
// V_down_rel_ground = get_V_down_rel_ground();
@ -289,9 +310,9 @@ bool FGLaRCsim::copy_to_LaRCsim () {
// V_equiv_kts = get_V_equiv_kts();
// V_calibrated = get_V_calibrated();
// V_calibrated_kts = get_V_calibrated_kts();
P_body = get_P_body();
Q_body = get_Q_body();
R_body = get_R_body();
// P_body = get_P_body();
// Q_body = get_Q_body();
// R_body = get_R_body();
// P_local = get_P_local();
// Q_local = get_Q_local();
// R_local = get_R_local();
@ -304,15 +325,15 @@ bool FGLaRCsim::copy_to_LaRCsim () {
// Latitude_dot = get_Latitude_dot();
// Longitude_dot = get_Longitude_dot();
// Radius_dot = get_Radius_dot();
Lat_geocentric = get_Lat_geocentric();
Lon_geocentric = get_Lon_geocentric();
Radius_to_vehicle = get_Radius_to_vehicle();
Latitude = get_Latitude();
Longitude = get_Longitude();
Altitude = get_Altitude();
Phi = get_Phi();
Theta = get_Theta();
Psi = get_Psi();
// Lat_geocentric = get_Lat_geocentric();
// Lon_geocentric = get_Lon_geocentric();
// Radius_to_vehicle = get_Radius_to_vehicle();
// Latitude = get_Latitude();
// Longitude = get_Longitude();
// Altitude = get_Altitude();
// Phi = get_Phi();
// Theta = get_Theta();
// Psi = get_Psi();
// T_local_to_body_11 = get_T_local_to_body_11();
// T_local_to_body_12 = get_T_local_to_body_12();
// T_local_to_body_13 = get_T_local_to_body_13();
@ -350,9 +371,9 @@ bool FGLaRCsim::copy_to_LaRCsim () {
// Dynamic_pressure = get_Dynamic_pressure();
// Static_temperature = get_Static_temperature();
// Total_temperature = get_Total_temperature();
Sea_level_radius = get_Sea_level_radius();
Earth_position_angle = get_Earth_position_angle();
Runway_altitude = get_Runway_altitude();
// Sea_level_radius = get_Sea_level_radius();
// Earth_position_angle = get_Earth_position_angle();
// Runway_altitude = get_Runway_altitude();
// Runway_latitude = get_Runway_latitude();
// Runway_longitude = get_Runway_longitude();
// Runway_heading = get_Runway_heading();
@ -378,9 +399,9 @@ bool FGLaRCsim::copy_to_LaRCsim () {
bool FGLaRCsim::copy_from_LaRCsim() {
// Mass properties and geometry values
set_Inertias( Mass, I_xx, I_yy, I_zz, I_xz );
_set_Inertias( Mass, I_xx, I_yy, I_zz, I_xz );
// set_Pilot_Location( Dx_pilot, Dy_pilot, Dz_pilot );
set_CG_Position( Dx_cg, Dy_cg, Dz_cg );
_set_CG_Position( Dx_cg, Dy_cg, Dz_cg );
// Forces
// set_Forces_Body_Total( F_X, F_Y, F_Z );
@ -397,16 +418,16 @@ bool FGLaRCsim::copy_from_LaRCsim() {
// set_Moments_Gear( M_l_gear, M_m_gear, M_n_gear );
// Accelerations
set_Accels_Local( V_dot_north, V_dot_east, V_dot_down );
set_Accels_Body( U_dot_body, V_dot_body, W_dot_body );
set_Accels_CG_Body( A_X_cg, A_Y_cg, A_Z_cg );
set_Accels_Pilot_Body( A_X_pilot, A_Y_pilot, A_Z_pilot );
_set_Accels_Local( V_dot_north, V_dot_east, V_dot_down );
_set_Accels_Body( U_dot_body, V_dot_body, W_dot_body );
_set_Accels_CG_Body( A_X_cg, A_Y_cg, A_Z_cg );
_set_Accels_Pilot_Body( A_X_pilot, A_Y_pilot, A_Z_pilot );
// set_Accels_CG_Body_N( N_X_cg, N_Y_cg, N_Z_cg );
// set_Accels_Pilot_Body_N( N_X_pilot, N_Y_pilot, N_Z_pilot );
// set_Accels_Omega( P_dot_body, Q_dot_body, R_dot_body );
// Velocities
set_Velocities_Local( V_north, V_east, V_down );
_set_Velocities_Local( V_north, V_east, V_down );
// set_Velocities_Ground( V_north_rel_ground, V_east_rel_ground,
// V_down_rel_ground );
// set_Velocities_Local_Airmass( V_north_airmass, V_east_airmass,
@ -414,26 +435,26 @@ bool FGLaRCsim::copy_from_LaRCsim() {
// set_Velocities_Local_Rel_Airmass( V_north_rel_airmass,
// V_east_rel_airmass, V_down_rel_airmass );
// set_Velocities_Gust( U_gust, V_gust, W_gust );
set_Velocities_Wind_Body( U_body, V_body, W_body );
_set_Velocities_Wind_Body( U_body, V_body, W_body );
// set_V_rel_wind( V_rel_wind );
// set_V_true_kts( V_true_kts );
// set_V_rel_ground( V_rel_ground );
// set_V_inertial( V_inertial );
set_V_ground_speed( V_ground_speed );
_set_V_ground_speed( V_ground_speed );
// set_V_equiv( V_equiv );
set_V_equiv_kts( V_equiv_kts );
_set_V_equiv_kts( V_equiv_kts );
// set_V_calibrated( V_calibrated );
set_V_calibrated_kts( V_calibrated_kts );
_set_V_calibrated_kts( V_calibrated_kts );
set_Omega_Body( P_body, Q_body, R_body );
_set_Omega_Body( P_body, Q_body, R_body );
// set_Omega_Local( P_local, Q_local, R_local );
// set_Omega_Total( P_total, Q_total, R_total );
set_Euler_Rates( Phi_dot, Theta_dot, Psi_dot );
set_Geocentric_Rates( Latitude_dot, Longitude_dot, Radius_dot );
_set_Euler_Rates( Phi_dot, Theta_dot, Psi_dot );
_set_Geocentric_Rates( Latitude_dot, Longitude_dot, Radius_dot );
set_Mach_number( Mach_number );
_set_Mach_number( Mach_number );
FG_LOG( FG_FLIGHT, FG_DEBUG, "lon = " << Longitude
<< " lat_geoc = " << Lat_geocentric << " lat_geod = " << Latitude
@ -449,18 +470,20 @@ bool FGLaRCsim::copy_from_LaRCsim() {
while ( tmp_lon > FG_PI ) { tmp_lon -= FG_2PI; }
// Positions
set_Geocentric_Position( Lat_geocentric, tmp_lon_geoc,
_set_Geocentric_Position( Lat_geocentric, tmp_lon_geoc,
Radius_to_vehicle );
set_Geodetic_Position( Latitude, tmp_lon, Altitude );
set_Euler_Angles( Phi, Theta, Psi );
_set_Geodetic_Position( Latitude, tmp_lon, Altitude );
_set_Euler_Angles( Phi, Theta, Psi );
_set_Altitude_AGL( Altitude-Runway_altitude );
// Miscellaneous quantities
set_T_Local_to_Body(T_local_to_body_m);
_set_T_Local_to_Body(T_local_to_body_m);
// set_Gravity( Gravity );
// set_Centrifugal_relief( Centrifugal_relief );
set_Alpha( Alpha );
set_Beta( Beta );
_set_Alpha( Alpha );
_set_Beta( Beta );
// set_Alpha_dot( Alpha_dot );
// set_Beta_dot( Beta_dot );
@ -469,33 +492,33 @@ bool FGLaRCsim::copy_from_LaRCsim() {
// set_Cos_beta( Cos_beta );
// set_Sin_beta( Sin_beta );
set_Cos_phi( Cos_phi );
_set_Cos_phi( Cos_phi );
// set_Sin_phi( Sin_phi );
set_Cos_theta( Cos_theta );
_set_Cos_theta( Cos_theta );
// set_Sin_theta( Sin_theta );
// set_Cos_psi( Cos_psi );
// set_Sin_psi( Sin_psi );
set_Gamma_vert_rad( Gamma_vert_rad );
_set_Gamma_vert_rad( Gamma_vert_rad );
// set_Gamma_horiz_rad( Gamma_horiz_rad );
// set_Sigma( Sigma );
set_Density( Density );
_set_Density( Density );
// set_V_sound( V_sound );
// set_Mach_number( Mach_number );
set_Static_pressure( Static_pressure );
_set_Static_pressure( Static_pressure );
// set_Total_pressure( Total_pressure );
// set_Impact_pressure( Impact_pressure );
// set_Dynamic_pressure( Dynamic_pressure );
set_Static_temperature( Static_temperature );
_set_Static_temperature( Static_temperature );
// set_Total_temperature( Total_temperature );
set_Sea_level_radius( Sea_level_radius );
set_Earth_position_angle( Earth_position_angle );
_set_Sea_level_radius( Sea_level_radius );
_set_Earth_position_angle( Earth_position_angle );
set_Runway_altitude( Runway_altitude );
_set_Runway_altitude( Runway_altitude );
// set_Runway_latitude( Runway_latitude );
// set_Runway_longitude( Runway_longitude );
// set_Runway_heading( Runway_heading );
@ -507,10 +530,10 @@ bool FGLaRCsim::copy_from_LaRCsim() {
// D_pilot_above_rwy );
// set_Pilot_Rwy_Rwy( X_pilot_rwy, Y_pilot_rwy, H_pilot_rwy );
set_sin_lat_geocentric(Lat_geocentric);
set_cos_lat_geocentric(Lat_geocentric);
set_sin_cos_longitude(Longitude);
set_sin_cos_latitude(Latitude);
_set_sin_lat_geocentric(Lat_geocentric);
_set_cos_lat_geocentric(Lat_geocentric);
_set_sin_cos_longitude(Longitude);
_set_sin_cos_latitude(Latitude);
// printf("sin_lat_geo %f cos_lat_geo %f\n", sin_Lat_geoc, cos_Lat_geoc);
// printf("sin_lat %f cos_lat %f\n",
@ -518,5 +541,166 @@ bool FGLaRCsim::copy_from_LaRCsim() {
// printf("sin_lon %f cos_lon %f\n",
// get_sin_longitude(), get_cos_longitude());
_set_Climb_Rate( -1 * V_down );
return true;
}
void FGLaRCsim::set_ls(void) {
Phi=lsic->GetRollAngleRadIC();
Theta=lsic->GetPitchAngleRadIC();
Psi=lsic->GetHeadingRadIC();
V_north=lsic->GetVnorthFpsIC();
V_east=lsic->GetVeastFpsIC();
V_down=lsic->GetVdownFpsIC();
Altitude=lsic->GetAltitudeFtIC();
Latitude=lsic->GetLatitudeGDRadIC();
Longitude=lsic->GetLongitudeRadIC();
Runway_altitude=lsic->GetRunwayAltitudeFtIC();
V_north_airmass = lsic->GetVnorthAirmassFpsIC();
V_east_airmass = lsic->GetVeastAirmassFpsIC();
V_down_airmass = lsic->GetVdownAirmassFpsIC();
ls_loop(0.0,-1);
copy_from_LaRCsim();
FG_LOG( FG_FLIGHT, FG_INFO, " FGLaRCsim::set_ls(): " );
FG_LOG( FG_FLIGHT, FG_INFO, " Phi: " << Phi );
FG_LOG( FG_FLIGHT, FG_INFO, " Theta: " << Theta );
FG_LOG( FG_FLIGHT, FG_INFO, " Psi: " << Psi );
FG_LOG( FG_FLIGHT, FG_INFO, " V_north: " << V_north );
FG_LOG( FG_FLIGHT, FG_INFO, " V_east: " << V_east );
FG_LOG( FG_FLIGHT, FG_INFO, " V_down: " << V_down );
FG_LOG( FG_FLIGHT, FG_INFO, " Altitude: " << Altitude );
FG_LOG( FG_FLIGHT, FG_INFO, " Latitude: " << Latitude );
FG_LOG( FG_FLIGHT, FG_INFO, " Longitude: " << Longitude );
FG_LOG( FG_FLIGHT, FG_INFO, " Runway_altitude: " << Runway_altitude );
FG_LOG( FG_FLIGHT, FG_INFO, " V_north_airmass: " << V_north_airmass );
FG_LOG( FG_FLIGHT, FG_INFO, " V_east_airmass: " << V_east_airmass );
FG_LOG( FG_FLIGHT, FG_INFO, " V_down_airmass: " << V_down_airmass );
}
//Positions
void FGLaRCsim::set_Latitude(double lat) {
FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Latitude: " << lat );
lsic->SetLatitudeGDRadIC(lat);
set_ls();
copy_from_LaRCsim(); //update the bus
}
void FGLaRCsim::set_Longitude(double lon) {
FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Longitude: " << lon );
lsic->SetLongitudeRadIC(lon);
set_ls();
copy_from_LaRCsim(); //update the bus
}
void FGLaRCsim::set_Altitude(double alt) {
FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Altitude: " << alt );
lsic->SetAltitudeFtIC(alt);
set_ls();
copy_from_LaRCsim(); //update the bus
}
void FGLaRCsim::set_V_calibrated_kts(double vc) {
FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_V_calibrated_kts: " << vc );
lsic->SetVcalibratedKtsIC(vc);
set_ls();
copy_from_LaRCsim(); //update the bus
}
void FGLaRCsim::set_Mach_number(double mach) {
FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Mach_number: " << mach );
lsic->SetMachIC(mach);
set_ls();
copy_from_LaRCsim(); //update the bus
}
void FGLaRCsim::set_Velocities_Local( double north, double east, double down ){
FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Velocities_local: "
<< north << " " << east << " " << down );
lsic->SetVnorthFpsIC(north);
lsic->SetVeastFpsIC(east);
lsic->SetVdownFpsIC(down);
set_ls();
copy_from_LaRCsim(); //update the bus
}
void FGLaRCsim::set_Velocities_Wind_Body( double u, double v, double w){
FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Velocities_Wind_Body: "
<< u << " " << v << " " << w );
lsic->SetUBodyFpsIC(u);
lsic->SetVBodyFpsIC(v);
lsic->SetWBodyFpsIC(w);
set_ls();
copy_from_LaRCsim(); //update the bus
}
//Euler angles
void FGLaRCsim::set_Euler_Angles( double phi, double theta, double psi ) {
FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Euler_angles: "
<< phi << " " << theta << " " << psi );
lsic->SetPitchAngleRadIC(theta);
lsic->SetRollAngleRadIC(phi);
lsic->SetHeadingRadIC(psi);
set_ls();
copy_from_LaRCsim(); //update the bus
}
//Flight Path
void FGLaRCsim::set_Climb_Rate( double roc) {
FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Climb_rate: " << roc );
lsic->SetClimbRateFpsIC(roc);
set_ls();
copy_from_LaRCsim(); //update the bus
}
void FGLaRCsim::set_Gamma_vert_rad( double gamma) {
FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Gamma_vert_rad: " << gamma );
lsic->SetFlightPathAngleRadIC(gamma);
set_ls();
copy_from_LaRCsim(); //update the bus
}
void FGLaRCsim::set_Runway_altitude(double ralt) {
FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Runway_altitude: " << ralt );
lsic->SetRunwayAltitudeFtIC(ralt);
set_ls();
copy_from_LaRCsim(); //update the bus
}
void FGLaRCsim::set_AltitudeAGL(double altagl) {
FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_AltitudeAGL: " << altagl );
lsic->SetAltitudeAGLFtIC(altagl);
set_ls();
copy_from_LaRCsim();
}
void FGLaRCsim::set_Velocities_Local_Airmass (double wnorth,
double weast,
double wdown ) {
FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Velocities_Local_Airmass: "
<< wnorth << " " << weast << " " << wdown );
_set_Velocities_Local_Airmass( wnorth, weast, wdown );
set_ls();
copy_from_LaRCsim();
}
void FGLaRCsim::set_Static_pressure(double p) {
FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Static_pressure: " << p );
FG_LOG( FG_FLIGHT, FG_INFO, "LaRCsim does not support externally supplied atmospheric data" );
}
void FGLaRCsim::set_Static_temperature(double T) {
FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Static_temperature: " << T );
FG_LOG( FG_FLIGHT, FG_INFO, "LaRCsim does not support externally supplied atmospheric data" );
}
void FGLaRCsim::set_Density(double rho) {
FG_LOG( FG_FLIGHT, FG_INFO, "FGLaRCsim::set_Density: " << rho );
FG_LOG( FG_FLIGHT, FG_INFO, "LaRCsim does not support externally supplied atmospheric data" );
}

View file

@ -29,14 +29,19 @@
#include "IO360.hxx"
#include "flight.hxx"
#include <FDM/LaRCsimIC.hxx>
class FGLaRCsim: public FGInterface {
FGNewEngine eng;
LaRCsimIC* lsic;
void set_ls(void);
double time_step;
public:
FGLaRCsim(void);
~FGLaRCsim(void);
// copy FDM state to LaRCsim structures
bool copy_to_LaRCsim();
@ -48,6 +53,35 @@ public:
// update position based on inputs, positions, velocities, etc.
bool update( int multiloop );
// Positions
void set_Latitude(double lat); //geocentric
void set_Longitude(double lon);
void set_Altitude(double alt); // triggers re-calc of AGL altitude
void set_AltitudeAGL(double altagl); // and vice-versa
// Speeds -- setting any of these will trigger a re-calc of the rest
void set_V_calibrated_kts(double vc);
void set_Mach_number(double mach);
void set_Velocities_Local( double north, double east, double down );
void set_Velocities_Wind_Body( double u, double v, double w);
// Euler angles
void set_Euler_Angles( double phi, double theta, double psi );
// Flight Path
void set_Climb_Rate( double roc);
void set_Gamma_vert_rad( double gamma);
// Earth
void set_Runway_altitude(double ralt);
void set_Static_pressure(double p);
void set_Static_temperature(double T);
void set_Density(double rho);
void set_Velocities_Local_Airmass (double wnorth,
double weast,
double wdown );
};

View file

@ -4,9 +4,16 @@
#ifndef _ATMOS_62_H
#define _ATMOS_62_H
#ifdef __cplusplus
extern "C" {
#endif
void ls_atmos( SCALAR altitude, SCALAR * sigma, SCALAR * v_sound,
SCALAR * t_amb, SCALAR * p_amb );
#ifdef __cplusplus
}
#endif
#endif /* _ATMOS_62_H */

View file

@ -262,7 +262,7 @@ int wave_stats(float *var,float *var_rate,int N,FILE *out)
if(Nmaxima > 2)
{
ld=log(varmaxima[1]/varmaxima[2]); //logarithmic decrement
zeta=ld/sqrt(4*PI*PI +ld*ld); //damping ratio
zeta=ld/sqrt(4*LS_PI*LS_PI +ld*ld); //damping ratio
omegad=1/(vm_times[2]-vm_times[1]); //damped natural frequency Hz
if(zeta < 1)
{

View file

@ -141,7 +141,7 @@ void cherokee_aero()
Cz = Cz0 + Cza*Alpha + Czat*(Alpha_dot*c/2.0/V) + Czq*(q*c/2.0/V) + Czde * elevator;
Cm = Cm0 + Cma*Alpha + Cmat*(Alpha_dot*c/2.0/V) + Cmq*(q*c/2.0/V) + Cmde * elevator;
Cx = Cx0 - (Cza*Alpha)*(Cza*Alpha)/(PI*5.71*0.6);
Cx = Cx0 - (Cza*Alpha)*(Cza*Alpha)/(LS_PI*5.71*0.6);
Cl = Clb*Beta + Clp*(p*b/2.0/V) + Clr*(r*b/2.0/V) + Clda * aileron;
Cy = Cyb*Beta + Cyr*(r*b/2.0/V);

View file

@ -47,8 +47,156 @@
$Header$
$Log$
Revision 1.1 1999/06/17 18:07:33 curt
Initial revision
Revision 1.2 2000/10/23 22:34:54 curt
I tested:
LaRCsim c172 on-ground and in-air starts, reset: all work
UIUC Cessna172 on-ground and in-air starts work as expected, reset
results in an aircraft that is upside down but does not crash FG. I
don't know what it was like before, so it may well be no change.
JSBSim c172 and X15 in-air starts work fine, resets now work (and are
trimmed), on-ground starts do not -- the c172 ends up on its back. I
suspect this is no worse than before.
I did not test:
Balloon (the weather code returns nan's for the atmosphere data --this
is in the weather module and apparently is a linux only bug)
ADA (don't know how)
MagicCarpet (needs work yet)
External (don't know how)
known to be broken:
LaRCsim c172 on-ground starts with a negative terrain altitude (this
happens at KPAO when the scenery is not present). The FDM inits to
about 50 feet AGL and the model falls to the ground. It does stay
upright, however, and seems to be fine once it settles out, FWIW.
To do:
--implement set_Model on the bus
--bring Christian's weather data into JSBSim
-- add default method to bus for updating things like the sin and cos of
latitude (for Balloon, MagicCarpet)
-- lots of cleanup
The files:
src/FDM/flight.cxx
src/FDM/flight.hxx
-- all data members now declared protected instead of private.
-- eliminated all but a small set of 'setters', no change to getters.
-- that small set is declared virtual, the default implementation
provided preserves the old behavior
-- all of the vector data members are now initialized.
-- added busdump() method -- FG_LOG's all the bus data when called,
useful for diagnostics.
src/FDM/ADA.cxx
-- bus data members now directly assigned to
src/FDM/Balloon.cxx
-- bus data members now directly assigned to
-- changed V_equiv_kts to V_calibrated_kts
src/FDM/JSBSim.cxx
src/FDM/JSBSim.hxx
-- bus data members now directly assigned to
-- implemented the FGInterface virtual setters with JSBSim specific
logic
-- changed the static FDMExec to a dynamic fdmex (needed so that the
JSBSim object can be deleted when a model change is called for)
-- implemented constructor and destructor, moved some of the logic
formerly in init() to constructor
-- added logic to bring up FGEngInterface objects and set the RPM and
throttle values.
src/FDM/LaRCsim.cxx
src/FDM/LaRCsim.hxx
-- bus data members now directly assigned to
-- implemented the FGInterface virtual setters with LaRCsim specific
logic, uses LaRCsimIC
-- implemented constructor and destructor, moved some of the logic
formerly in init() to constructor
-- moved default inertias to here from fg_init.cxx
-- eliminated the climb rate calculation. The equivalent, climb_rate =
-1*vdown, is now in copy_from_LaRCsim().
src/FDM/LaRCsimIC.cxx
src/FDM/LaRCsimIC.hxx
-- similar to FGInitialCondition, this class has all the logic needed to
turn data like Vc and Mach into the more fundamental quantities LaRCsim
needs to initialize.
-- put it in src/FDM since it is a class
src/FDM/MagicCarpet.cxx
-- bus data members now directly assigned to
src/FDM/Makefile.am
-- adds LaRCsimIC.hxx and cxx
src/FDM/JSBSim/FGAtmosphere.h
src/FDM/JSBSim/FGDefs.h
src/FDM/JSBSim/FGInitialCondition.cpp
src/FDM/JSBSim/FGInitialCondition.h
src/FDM/JSBSim/JSBSim.cpp
-- changes to accomodate the new bus
src/FDM/LaRCsim/atmos_62.h
src/FDM/LaRCsim/ls_geodesy.h
-- surrounded prototypes with #ifdef __cplusplus ... #endif , functions
here are needed in LaRCsimIC
src/FDM/LaRCsim/c172_main.c
src/FDM/LaRCsim/cherokee_aero.c
src/FDM/LaRCsim/ls_aux.c
src/FDM/LaRCsim/ls_constants.h
src/FDM/LaRCsim/ls_geodesy.c
src/FDM/LaRCsim/ls_geodesy.h
src/FDM/LaRCsim/ls_step.c
src/FDM/UIUCModel/uiuc_betaprobe.cpp
-- changed PI to LS_PI, eliminates preprocessor naming conflict with
weather module
src/FDM/LaRCsim/ls_interface.c
src/FDM/LaRCsim/ls_interface.h
-- added function ls_set_model_dt()
src/Main/bfi.cxx
-- eliminated calls that set the NED speeds to body components. They
are no longer needed and confuse the new bus.
src/Main/fg_init.cxx
-- eliminated calls that just brought the bus data up-to-date (e.g.
set_sin_cos_latitude). or set default values. The bus now handles the
defaults and updates itself when the setters are called (for LaRCsim and
JSBSim). A default method for doing this needs to be added to the bus.
-- added fgVelocityInit() to set the speed the user asked for. Both
JSBSim and LaRCsim can now be initialized using any of:
vc,mach, NED components, UVW components.
src/Main/main.cxx
--eliminated call to fgFDMSetGroundElevation, this data is now 'pulled'
onto the bus every update()
src/Main/options.cxx
src/Main/options.hxx
-- added enum to keep track of the speed requested by the user
-- eliminated calls to set NED velocity properties to body speeds, they
are no longer needed.
-- added options for the NED components.
src/Network/garmin.cxx
src/Network/nmea.cxx
--eliminated calls that just brought the bus data up-to-date (e.g.
set_sin_cos_latitude). The bus now updates itself when the setters are
called (for LaRCsim and JSBSim). A default method for doing this needs
to be added to the bus.
-- changed set_V_equiv_kts to set_V_calibrated_kts. set_V_equiv_kts no
longer exists ( get_V_equiv_kts still does, though)
src/WeatherCM/FGLocalWeatherDatabase.cpp
-- commented out the code to put the weather data on the bus, a
different scheme for this is needed.
Revision 1.1.1.1 1999/06/17 18:07:33 curt
Start of 0.7.x branch
Revision 1.1.1.1 1999/04/05 21:32:45 curt
Start of 0.6.x branch.
@ -247,7 +395,7 @@ void ls_aux( void ) {
Gamma_horiz_rad = atan2( V_east_rel_ground, V_north_rel_ground );
if (Gamma_horiz_rad < 0)
Gamma_horiz_rad = Gamma_horiz_rad + 2*PI;
Gamma_horiz_rad = Gamma_horiz_rad + 2*LS_PI;
/* Calculate local gravity */

View file

@ -84,10 +84,7 @@
systems of measure) */
/* Value of Pi from ref [3] */
#ifdef PI
# undef PI /* avoid a harmless compiler warning */
#endif
#define PI 3.14159265358979323846264338327950288419716939967511
#define LS_PI 3.14159265358979323846264338327950288419716939967511
/* Value of earth radius from [8], ft */
#define EQUATORIAL_RADIUS 20925650.

View file

@ -40,8 +40,156 @@
$Header$
$Log$
Revision 1.1 1999/06/17 18:07:34 curt
Initial revision
Revision 1.2 2000/10/23 22:34:54 curt
I tested:
LaRCsim c172 on-ground and in-air starts, reset: all work
UIUC Cessna172 on-ground and in-air starts work as expected, reset
results in an aircraft that is upside down but does not crash FG. I
don't know what it was like before, so it may well be no change.
JSBSim c172 and X15 in-air starts work fine, resets now work (and are
trimmed), on-ground starts do not -- the c172 ends up on its back. I
suspect this is no worse than before.
I did not test:
Balloon (the weather code returns nan's for the atmosphere data --this
is in the weather module and apparently is a linux only bug)
ADA (don't know how)
MagicCarpet (needs work yet)
External (don't know how)
known to be broken:
LaRCsim c172 on-ground starts with a negative terrain altitude (this
happens at KPAO when the scenery is not present). The FDM inits to
about 50 feet AGL and the model falls to the ground. It does stay
upright, however, and seems to be fine once it settles out, FWIW.
To do:
--implement set_Model on the bus
--bring Christian's weather data into JSBSim
-- add default method to bus for updating things like the sin and cos of
latitude (for Balloon, MagicCarpet)
-- lots of cleanup
The files:
src/FDM/flight.cxx
src/FDM/flight.hxx
-- all data members now declared protected instead of private.
-- eliminated all but a small set of 'setters', no change to getters.
-- that small set is declared virtual, the default implementation
provided preserves the old behavior
-- all of the vector data members are now initialized.
-- added busdump() method -- FG_LOG's all the bus data when called,
useful for diagnostics.
src/FDM/ADA.cxx
-- bus data members now directly assigned to
src/FDM/Balloon.cxx
-- bus data members now directly assigned to
-- changed V_equiv_kts to V_calibrated_kts
src/FDM/JSBSim.cxx
src/FDM/JSBSim.hxx
-- bus data members now directly assigned to
-- implemented the FGInterface virtual setters with JSBSim specific
logic
-- changed the static FDMExec to a dynamic fdmex (needed so that the
JSBSim object can be deleted when a model change is called for)
-- implemented constructor and destructor, moved some of the logic
formerly in init() to constructor
-- added logic to bring up FGEngInterface objects and set the RPM and
throttle values.
src/FDM/LaRCsim.cxx
src/FDM/LaRCsim.hxx
-- bus data members now directly assigned to
-- implemented the FGInterface virtual setters with LaRCsim specific
logic, uses LaRCsimIC
-- implemented constructor and destructor, moved some of the logic
formerly in init() to constructor
-- moved default inertias to here from fg_init.cxx
-- eliminated the climb rate calculation. The equivalent, climb_rate =
-1*vdown, is now in copy_from_LaRCsim().
src/FDM/LaRCsimIC.cxx
src/FDM/LaRCsimIC.hxx
-- similar to FGInitialCondition, this class has all the logic needed to
turn data like Vc and Mach into the more fundamental quantities LaRCsim
needs to initialize.
-- put it in src/FDM since it is a class
src/FDM/MagicCarpet.cxx
-- bus data members now directly assigned to
src/FDM/Makefile.am
-- adds LaRCsimIC.hxx and cxx
src/FDM/JSBSim/FGAtmosphere.h
src/FDM/JSBSim/FGDefs.h
src/FDM/JSBSim/FGInitialCondition.cpp
src/FDM/JSBSim/FGInitialCondition.h
src/FDM/JSBSim/JSBSim.cpp
-- changes to accomodate the new bus
src/FDM/LaRCsim/atmos_62.h
src/FDM/LaRCsim/ls_geodesy.h
-- surrounded prototypes with #ifdef __cplusplus ... #endif , functions
here are needed in LaRCsimIC
src/FDM/LaRCsim/c172_main.c
src/FDM/LaRCsim/cherokee_aero.c
src/FDM/LaRCsim/ls_aux.c
src/FDM/LaRCsim/ls_constants.h
src/FDM/LaRCsim/ls_geodesy.c
src/FDM/LaRCsim/ls_geodesy.h
src/FDM/LaRCsim/ls_step.c
src/FDM/UIUCModel/uiuc_betaprobe.cpp
-- changed PI to LS_PI, eliminates preprocessor naming conflict with
weather module
src/FDM/LaRCsim/ls_interface.c
src/FDM/LaRCsim/ls_interface.h
-- added function ls_set_model_dt()
src/Main/bfi.cxx
-- eliminated calls that set the NED speeds to body components. They
are no longer needed and confuse the new bus.
src/Main/fg_init.cxx
-- eliminated calls that just brought the bus data up-to-date (e.g.
set_sin_cos_latitude). or set default values. The bus now handles the
defaults and updates itself when the setters are called (for LaRCsim and
JSBSim). A default method for doing this needs to be added to the bus.
-- added fgVelocityInit() to set the speed the user asked for. Both
JSBSim and LaRCsim can now be initialized using any of:
vc,mach, NED components, UVW components.
src/Main/main.cxx
--eliminated call to fgFDMSetGroundElevation, this data is now 'pulled'
onto the bus every update()
src/Main/options.cxx
src/Main/options.hxx
-- added enum to keep track of the speed requested by the user
-- eliminated calls to set NED velocity properties to body speeds, they
are no longer needed.
-- added options for the NED components.
src/Network/garmin.cxx
src/Network/nmea.cxx
--eliminated calls that just brought the bus data up-to-date (e.g.
set_sin_cos_latitude). The bus now updates itself when the setters are
called (for LaRCsim and JSBSim). A default method for doing this needs
to be added to the bus.
-- changed set_V_equiv_kts to set_V_calibrated_kts. set_V_equiv_kts no
longer exists ( get_V_equiv_kts still does, though)
src/WeatherCM/FGLocalWeatherDatabase.cpp
-- commented out the code to put the weather data on the bus, a
different scheme for this is needed.
Revision 1.1.1.1 1999/06/17 18:07:34 curt
Start of 0.7.x branch
Revision 1.1.1.1 1999/04/05 21:32:45 curt
Start of 0.6.x branch.
@ -108,7 +256,7 @@ Initial Flight Gear revision.
/* ONE_SECOND is pi/180/60/60, or about 100 feet at earths' equator */
#define ONE_SECOND 4.848136811E-6
#define HALF_PI 0.5*PI
#define HALF_PI 0.5*LS_PI
void ls_geoc_to_geod( SCALAR lat_geoc, SCALAR radius, SCALAR *lat_geod,

View file

@ -4,6 +4,9 @@
#ifndef _LS_GEODESY_H
#define _LS_GEODESY_H
#ifdef __cplusplus
extern "C" {
#endif
void ls_geoc_to_geod( SCALAR lat_geoc, SCALAR radius,
SCALAR *lat_geod, SCALAR *alt, SCALAR *sea_level_r );
@ -11,5 +14,8 @@ void ls_geoc_to_geod( SCALAR lat_geoc, SCALAR radius,
void ls_geod_to_geoc( SCALAR lat_geod, SCALAR alt, SCALAR *sl_radius,
SCALAR *lat_geoc );
#ifdef __cplusplus
}
#endif
#endif /* _LS_GEODESY_H */

View file

@ -486,6 +486,9 @@ int ls_checkopts(argc, argv) /* check and set options flags */
}
#endif /* COMPILE_THIS_CODE_THIS_USELESS_CODE */
void ls_set_model_dt(double dt) {
model_dt = dt;
}
void ls_loop( SCALAR dt, int initialize ) {
/* printf (" In ls_loop()\n"); */
@ -575,6 +578,154 @@ int ls_ForceAltitude(double alt_feet) {
/* Flight Gear Modification Log
*
* $Log$
* Revision 1.3 2000/10/23 22:34:54 curt
* I tested:
* LaRCsim c172 on-ground and in-air starts, reset: all work
* UIUC Cessna172 on-ground and in-air starts work as expected, reset
* results in an aircraft that is upside down but does not crash FG. I
* don't know what it was like before, so it may well be no change.
* JSBSim c172 and X15 in-air starts work fine, resets now work (and are
* trimmed), on-ground starts do not -- the c172 ends up on its back. I
* suspect this is no worse than before.
*
* I did not test:
* Balloon (the weather code returns nan's for the atmosphere data --this
* is in the weather module and apparently is a linux only bug)
* ADA (don't know how)
* MagicCarpet (needs work yet)
* External (don't know how)
*
* known to be broken:
* LaRCsim c172 on-ground starts with a negative terrain altitude (this
* happens at KPAO when the scenery is not present). The FDM inits to
* about 50 feet AGL and the model falls to the ground. It does stay
* upright, however, and seems to be fine once it settles out, FWIW.
*
* To do:
* --implement set_Model on the bus
* --bring Christian's weather data into JSBSim
* -- add default method to bus for updating things like the sin and cos of
* latitude (for Balloon, MagicCarpet)
* -- lots of cleanup
*
* The files:
* src/FDM/flight.cxx
* src/FDM/flight.hxx
* -- all data members now declared protected instead of private.
* -- eliminated all but a small set of 'setters', no change to getters.
* -- that small set is declared virtual, the default implementation
* provided preserves the old behavior
* -- all of the vector data members are now initialized.
* -- added busdump() method -- FG_LOG's all the bus data when called,
* useful for diagnostics.
*
* src/FDM/ADA.cxx
* -- bus data members now directly assigned to
*
* src/FDM/Balloon.cxx
* -- bus data members now directly assigned to
* -- changed V_equiv_kts to V_calibrated_kts
*
* src/FDM/JSBSim.cxx
* src/FDM/JSBSim.hxx
* -- bus data members now directly assigned to
* -- implemented the FGInterface virtual setters with JSBSim specific
* logic
* -- changed the static FDMExec to a dynamic fdmex (needed so that the
* JSBSim object can be deleted when a model change is called for)
* -- implemented constructor and destructor, moved some of the logic
* formerly in init() to constructor
* -- added logic to bring up FGEngInterface objects and set the RPM and
* throttle values.
*
* src/FDM/LaRCsim.cxx
* src/FDM/LaRCsim.hxx
* -- bus data members now directly assigned to
* -- implemented the FGInterface virtual setters with LaRCsim specific
* logic, uses LaRCsimIC
* -- implemented constructor and destructor, moved some of the logic
* formerly in init() to constructor
* -- moved default inertias to here from fg_init.cxx
* -- eliminated the climb rate calculation. The equivalent, climb_rate =
* -1*vdown, is now in copy_from_LaRCsim().
*
* src/FDM/LaRCsimIC.cxx
* src/FDM/LaRCsimIC.hxx
* -- similar to FGInitialCondition, this class has all the logic needed to
* turn data like Vc and Mach into the more fundamental quantities LaRCsim
* needs to initialize.
* -- put it in src/FDM since it is a class
*
* src/FDM/MagicCarpet.cxx
* -- bus data members now directly assigned to
*
* src/FDM/Makefile.am
* -- adds LaRCsimIC.hxx and cxx
*
* src/FDM/JSBSim/FGAtmosphere.h
* src/FDM/JSBSim/FGDefs.h
* src/FDM/JSBSim/FGInitialCondition.cpp
* src/FDM/JSBSim/FGInitialCondition.h
* src/FDM/JSBSim/JSBSim.cpp
* -- changes to accomodate the new bus
*
* src/FDM/LaRCsim/atmos_62.h
* src/FDM/LaRCsim/ls_geodesy.h
* -- surrounded prototypes with #ifdef __cplusplus ... #endif , functions
* here are needed in LaRCsimIC
*
* src/FDM/LaRCsim/c172_main.c
* src/FDM/LaRCsim/cherokee_aero.c
* src/FDM/LaRCsim/ls_aux.c
* src/FDM/LaRCsim/ls_constants.h
* src/FDM/LaRCsim/ls_geodesy.c
* src/FDM/LaRCsim/ls_geodesy.h
* src/FDM/LaRCsim/ls_step.c
* src/FDM/UIUCModel/uiuc_betaprobe.cpp
* -- changed PI to LS_PI, eliminates preprocessor naming conflict with
* weather module
*
* src/FDM/LaRCsim/ls_interface.c
* src/FDM/LaRCsim/ls_interface.h
* -- added function ls_set_model_dt()
*
* src/Main/bfi.cxx
* -- eliminated calls that set the NED speeds to body components. They
* are no longer needed and confuse the new bus.
*
* src/Main/fg_init.cxx
* -- eliminated calls that just brought the bus data up-to-date (e.g.
* set_sin_cos_latitude). or set default values. The bus now handles the
* defaults and updates itself when the setters are called (for LaRCsim and
* JSBSim). A default method for doing this needs to be added to the bus.
* -- added fgVelocityInit() to set the speed the user asked for. Both
* JSBSim and LaRCsim can now be initialized using any of:
* vc,mach, NED components, UVW components.
*
* src/Main/main.cxx
* --eliminated call to fgFDMSetGroundElevation, this data is now 'pulled'
* onto the bus every update()
*
* src/Main/options.cxx
* src/Main/options.hxx
* -- added enum to keep track of the speed requested by the user
* -- eliminated calls to set NED velocity properties to body speeds, they
* are no longer needed.
* -- added options for the NED components.
*
* src/Network/garmin.cxx
* src/Network/nmea.cxx
* --eliminated calls that just brought the bus data up-to-date (e.g.
* set_sin_cos_latitude). The bus now updates itself when the setters are
* called (for LaRCsim and JSBSim). A default method for doing this needs
* to be added to the bus.
* -- changed set_V_equiv_kts to set_V_calibrated_kts. set_V_equiv_kts no
* longer exists ( get_V_equiv_kts still does, though)
*
* src/WeatherCM/FGLocalWeatherDatabase.cpp
* -- commented out the code to put the weather data on the bus, a
* different scheme for this is needed.
*
* Revision 1.2 2000/04/10 18:09:41 curt
* David Megginson made a few (mostly minor) mods to the LaRCsim files, and
* it's now possible to choose the LaRCsim model at runtime, as in

View file

@ -42,6 +42,8 @@ int ls_toplevel_init(double dt, char * aircraft);
/* update position based on inputs, positions, velocities, etc. */
int ls_update(int multiloop);
void ls_set_model_dt(double dt);
#if 0
/* Convert from the fgFLIGHT struct to the LaRCsim generic_ struct */
int fgFlight_2_LaRCsim (fgFLIGHT *f);
@ -56,15 +58,162 @@ void ls_loop( SCALAR dt, int initialize );
int ls_ForceAltitude(double alt_feet);
#endif /* _LS_INTERFACE_H */
#ifdef __cplusplus
}
#endif
#endif /* _LS_INTERFACE_H */
// $Log$
// Revision 1.4 2000/10/23 22:34:54 curt
// I tested:
// LaRCsim c172 on-ground and in-air starts, reset: all work
// UIUC Cessna172 on-ground and in-air starts work as expected, reset
// results in an aircraft that is upside down but does not crash FG. I
// don't know what it was like before, so it may well be no change.
// JSBSim c172 and X15 in-air starts work fine, resets now work (and are
// trimmed), on-ground starts do not -- the c172 ends up on its back. I
// suspect this is no worse than before.
//
// I did not test:
// Balloon (the weather code returns nan's for the atmosphere data --this
// is in the weather module and apparently is a linux only bug)
// ADA (don't know how)
// MagicCarpet (needs work yet)
// External (don't know how)
//
// known to be broken:
// LaRCsim c172 on-ground starts with a negative terrain altitude (this
// happens at KPAO when the scenery is not present). The FDM inits to
// about 50 feet AGL and the model falls to the ground. It does stay
// upright, however, and seems to be fine once it settles out, FWIW.
//
// To do:
// --implement set_Model on the bus
// --bring Christian's weather data into JSBSim
// -- add default method to bus for updating things like the sin and cos of
// latitude (for Balloon, MagicCarpet)
// -- lots of cleanup
//
// The files:
// src/FDM/flight.cxx
// src/FDM/flight.hxx
// -- all data members now declared protected instead of private.
// -- eliminated all but a small set of 'setters', no change to getters.
// -- that small set is declared virtual, the default implementation
// provided preserves the old behavior
// -- all of the vector data members are now initialized.
// -- added busdump() method -- FG_LOG's all the bus data when called,
// useful for diagnostics.
//
// src/FDM/ADA.cxx
// -- bus data members now directly assigned to
//
// src/FDM/Balloon.cxx
// -- bus data members now directly assigned to
// -- changed V_equiv_kts to V_calibrated_kts
//
// src/FDM/JSBSim.cxx
// src/FDM/JSBSim.hxx
// -- bus data members now directly assigned to
// -- implemented the FGInterface virtual setters with JSBSim specific
// logic
// -- changed the static FDMExec to a dynamic fdmex (needed so that the
// JSBSim object can be deleted when a model change is called for)
// -- implemented constructor and destructor, moved some of the logic
// formerly in init() to constructor
// -- added logic to bring up FGEngInterface objects and set the RPM and
// throttle values.
//
// src/FDM/LaRCsim.cxx
// src/FDM/LaRCsim.hxx
// -- bus data members now directly assigned to
// -- implemented the FGInterface virtual setters with LaRCsim specific
// logic, uses LaRCsimIC
// -- implemented constructor and destructor, moved some of the logic
// formerly in init() to constructor
// -- moved default inertias to here from fg_init.cxx
// -- eliminated the climb rate calculation. The equivalent, climb_rate =
// -1*vdown, is now in copy_from_LaRCsim().
//
// src/FDM/LaRCsimIC.cxx
// src/FDM/LaRCsimIC.hxx
// -- similar to FGInitialCondition, this class has all the logic needed to
// turn data like Vc and Mach into the more fundamental quantities LaRCsim
// needs to initialize.
// -- put it in src/FDM since it is a class
//
// src/FDM/MagicCarpet.cxx
// -- bus data members now directly assigned to
//
// src/FDM/Makefile.am
// -- adds LaRCsimIC.hxx and cxx
//
// src/FDM/JSBSim/FGAtmosphere.h
// src/FDM/JSBSim/FGDefs.h
// src/FDM/JSBSim/FGInitialCondition.cpp
// src/FDM/JSBSim/FGInitialCondition.h
// src/FDM/JSBSim/JSBSim.cpp
// -- changes to accomodate the new bus
//
// src/FDM/LaRCsim/atmos_62.h
// src/FDM/LaRCsim/ls_geodesy.h
// -- surrounded prototypes with #ifdef __cplusplus ... #endif , functions
// here are needed in LaRCsimIC
//
// src/FDM/LaRCsim/c172_main.c
// src/FDM/LaRCsim/cherokee_aero.c
// src/FDM/LaRCsim/ls_aux.c
// src/FDM/LaRCsim/ls_constants.h
// src/FDM/LaRCsim/ls_geodesy.c
// src/FDM/LaRCsim/ls_geodesy.h
// src/FDM/LaRCsim/ls_step.c
// src/FDM/UIUCModel/uiuc_betaprobe.cpp
// -- changed PI to LS_PI, eliminates preprocessor naming conflict with
// weather module
//
// src/FDM/LaRCsim/ls_interface.c
// src/FDM/LaRCsim/ls_interface.h
// -- added function ls_set_model_dt()
//
// src/Main/bfi.cxx
// -- eliminated calls that set the NED speeds to body components. They
// are no longer needed and confuse the new bus.
//
// src/Main/fg_init.cxx
// -- eliminated calls that just brought the bus data up-to-date (e.g.
// set_sin_cos_latitude). or set default values. The bus now handles the
// defaults and updates itself when the setters are called (for LaRCsim and
// JSBSim). A default method for doing this needs to be added to the bus.
// -- added fgVelocityInit() to set the speed the user asked for. Both
// JSBSim and LaRCsim can now be initialized using any of:
// vc,mach, NED components, UVW components.
//
// src/Main/main.cxx
// --eliminated call to fgFDMSetGroundElevation, this data is now 'pulled'
// onto the bus every update()
//
// src/Main/options.cxx
// src/Main/options.hxx
// -- added enum to keep track of the speed requested by the user
// -- eliminated calls to set NED velocity properties to body speeds, they
// are no longer needed.
// -- added options for the NED components.
//
// src/Network/garmin.cxx
// src/Network/nmea.cxx
// --eliminated calls that just brought the bus data up-to-date (e.g.
// set_sin_cos_latitude). The bus now updates itself when the setters are
// called (for LaRCsim and JSBSim). A default method for doing this needs
// to be added to the bus.
// -- changed set_V_equiv_kts to set_V_calibrated_kts. set_V_equiv_kts no
// longer exists ( get_V_equiv_kts still does, though)
//
// src/WeatherCM/FGLocalWeatherDatabase.cpp
// -- commented out the code to put the weather data on the bus, a
// different scheme for this is needed.
//
// Revision 1.3 2000/04/27 19:57:08 curt
// MacOS build updates.
//

View file

@ -50,6 +50,154 @@
$Header$
$Log$
Revision 1.3 2000/10/23 22:34:55 curt
I tested:
LaRCsim c172 on-ground and in-air starts, reset: all work
UIUC Cessna172 on-ground and in-air starts work as expected, reset
results in an aircraft that is upside down but does not crash FG. I
don't know what it was like before, so it may well be no change.
JSBSim c172 and X15 in-air starts work fine, resets now work (and are
trimmed), on-ground starts do not -- the c172 ends up on its back. I
suspect this is no worse than before.
I did not test:
Balloon (the weather code returns nan's for the atmosphere data --this
is in the weather module and apparently is a linux only bug)
ADA (don't know how)
MagicCarpet (needs work yet)
External (don't know how)
known to be broken:
LaRCsim c172 on-ground starts with a negative terrain altitude (this
happens at KPAO when the scenery is not present). The FDM inits to
about 50 feet AGL and the model falls to the ground. It does stay
upright, however, and seems to be fine once it settles out, FWIW.
To do:
--implement set_Model on the bus
--bring Christian's weather data into JSBSim
-- add default method to bus for updating things like the sin and cos of
latitude (for Balloon, MagicCarpet)
-- lots of cleanup
The files:
src/FDM/flight.cxx
src/FDM/flight.hxx
-- all data members now declared protected instead of private.
-- eliminated all but a small set of 'setters', no change to getters.
-- that small set is declared virtual, the default implementation
provided preserves the old behavior
-- all of the vector data members are now initialized.
-- added busdump() method -- FG_LOG's all the bus data when called,
useful for diagnostics.
src/FDM/ADA.cxx
-- bus data members now directly assigned to
src/FDM/Balloon.cxx
-- bus data members now directly assigned to
-- changed V_equiv_kts to V_calibrated_kts
src/FDM/JSBSim.cxx
src/FDM/JSBSim.hxx
-- bus data members now directly assigned to
-- implemented the FGInterface virtual setters with JSBSim specific
logic
-- changed the static FDMExec to a dynamic fdmex (needed so that the
JSBSim object can be deleted when a model change is called for)
-- implemented constructor and destructor, moved some of the logic
formerly in init() to constructor
-- added logic to bring up FGEngInterface objects and set the RPM and
throttle values.
src/FDM/LaRCsim.cxx
src/FDM/LaRCsim.hxx
-- bus data members now directly assigned to
-- implemented the FGInterface virtual setters with LaRCsim specific
logic, uses LaRCsimIC
-- implemented constructor and destructor, moved some of the logic
formerly in init() to constructor
-- moved default inertias to here from fg_init.cxx
-- eliminated the climb rate calculation. The equivalent, climb_rate =
-1*vdown, is now in copy_from_LaRCsim().
src/FDM/LaRCsimIC.cxx
src/FDM/LaRCsimIC.hxx
-- similar to FGInitialCondition, this class has all the logic needed to
turn data like Vc and Mach into the more fundamental quantities LaRCsim
needs to initialize.
-- put it in src/FDM since it is a class
src/FDM/MagicCarpet.cxx
-- bus data members now directly assigned to
src/FDM/Makefile.am
-- adds LaRCsimIC.hxx and cxx
src/FDM/JSBSim/FGAtmosphere.h
src/FDM/JSBSim/FGDefs.h
src/FDM/JSBSim/FGInitialCondition.cpp
src/FDM/JSBSim/FGInitialCondition.h
src/FDM/JSBSim/JSBSim.cpp
-- changes to accomodate the new bus
src/FDM/LaRCsim/atmos_62.h
src/FDM/LaRCsim/ls_geodesy.h
-- surrounded prototypes with #ifdef __cplusplus ... #endif , functions
here are needed in LaRCsimIC
src/FDM/LaRCsim/c172_main.c
src/FDM/LaRCsim/cherokee_aero.c
src/FDM/LaRCsim/ls_aux.c
src/FDM/LaRCsim/ls_constants.h
src/FDM/LaRCsim/ls_geodesy.c
src/FDM/LaRCsim/ls_geodesy.h
src/FDM/LaRCsim/ls_step.c
src/FDM/UIUCModel/uiuc_betaprobe.cpp
-- changed PI to LS_PI, eliminates preprocessor naming conflict with
weather module
src/FDM/LaRCsim/ls_interface.c
src/FDM/LaRCsim/ls_interface.h
-- added function ls_set_model_dt()
src/Main/bfi.cxx
-- eliminated calls that set the NED speeds to body components. They
are no longer needed and confuse the new bus.
src/Main/fg_init.cxx
-- eliminated calls that just brought the bus data up-to-date (e.g.
set_sin_cos_latitude). or set default values. The bus now handles the
defaults and updates itself when the setters are called (for LaRCsim and
JSBSim). A default method for doing this needs to be added to the bus.
-- added fgVelocityInit() to set the speed the user asked for. Both
JSBSim and LaRCsim can now be initialized using any of:
vc,mach, NED components, UVW components.
src/Main/main.cxx
--eliminated call to fgFDMSetGroundElevation, this data is now 'pulled'
onto the bus every update()
src/Main/options.cxx
src/Main/options.hxx
-- added enum to keep track of the speed requested by the user
-- eliminated calls to set NED velocity properties to body speeds, they
are no longer needed.
-- added options for the NED components.
src/Network/garmin.cxx
src/Network/nmea.cxx
--eliminated calls that just brought the bus data up-to-date (e.g.
set_sin_cos_latitude). The bus now updates itself when the setters are
called (for LaRCsim and JSBSim). A default method for doing this needs
to be added to the bus.
-- changed set_V_equiv_kts to set_V_calibrated_kts. set_V_equiv_kts no
longer exists ( get_V_equiv_kts still does, though)
src/WeatherCM/FGLocalWeatherDatabase.cpp
-- commented out the code to put the weather data on the bus, a
different scheme for this is needed.
Revision 1.2 1999/10/29 16:08:33 curt
Added flaps support to c172 model.
@ -347,7 +495,7 @@ void ls_step( SCALAR dt, int Initialize ) {
/* Resolve Psi to 0 - 359.9999 */
if (Psi < 0 ) Psi = Psi + 2*PI;
if (Psi < 0 ) Psi = Psi + 2*LS_PI;
/* L I N E A R P O S I T I O N S */

411
src/FDM/LaRCsimIC.cxx Normal file
View file

@ -0,0 +1,411 @@
/*******************************************************************************
Header: LaRCsimIC.cxx
Author: Tony Peden
Date started: 10/9/99
------------- Copyright (C) 1999 Anthony K. Peden (apeden@earthlink.net) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA.
Further information about the GNU General Public License can also be found on
the world wide web at http://www.gnu.org.
*/
#include "FDM/LaRCsimIC.hxx"
#include <FDM/LaRCsim/ls_cockpit.h>
#include <FDM/LaRCsim/ls_generic.h>
#include <FDM/LaRCsim/ls_interface.h>
#include <FDM/LaRCsim/atmos_62.h>
#include <FDM/LaRCsim/ls_constants.h>
#include <FDM/LaRCsim/ls_geodesy.h>
#include <math.h>
#include <iostream>
LaRCsimIC::LaRCsimIC(void) {
vt=vtg=vw=vc=ve=0;
mach=0;
alpha=beta=gamma=0;
theta=phi=psi=0;
altitude=runway_altitude=hdot=alt_agl=0;
latitude_gd=latitude_gc=longitude=0;
u=v=w=0;
vnorth=veast=vdown=0;
vnorthwind=veastwind=vdownwind=0;
lastSpeedSet=lssetvt;
lastAltSet=lssetasl;
get_atmosphere();
ls_geod_to_geoc( latitude_gd,altitude,&sea_level_radius,&latitude_gc);
}
LaRCsimIC::~LaRCsimIC(void) {}
void LaRCsimIC::get_atmosphere(void) {
Altitude=altitude; //set LaRCsim variable
ls_atmos(Altitude, &density_ratio, &soundspeed, &T, &p);
rho=density_ratio*SEA_LEVEL_DENSITY;
}
void LaRCsimIC::SetVcalibratedKtsIC( SCALAR tt) {
vc=tt*KTS_TO_FPS;
lastSpeedSet=lssetvc;
vt=sqrt(1/density_ratio*vc*vc);
}
void LaRCsimIC::SetVtrueFpsIC( SCALAR tt) {
vt=tt;
lastSpeedSet=lssetvt;
}
void LaRCsimIC::SetMachIC( SCALAR tt) {
mach=tt;
vt=mach*soundspeed;
lastSpeedSet=lssetmach;
}
void LaRCsimIC::SetVequivalentKtsIC(SCALAR tt) {
ve=tt*KTS_TO_FPS;
lastSpeedSet=lssetve;
vt=sqrt(SEA_LEVEL_DENSITY/rho)*ve;
}
void LaRCsimIC::SetClimbRateFpmIC( SCALAR tt) {
SetClimbRateFpsIC(tt/60.0);
}
void LaRCsimIC::SetClimbRateFpsIC( SCALAR tt) {
vtg=vt+vw;
cout << "vtg: " << vtg << endl;
if(vtg > 0.1) {
hdot = tt - vdownwind;
gamma=asin(hdot/vtg);
getTheta();
vdown=-1*hdot;
cout << "hdot: " << hdot << endl;
cout << "gamma: " << gamma*RAD_TO_DEG << endl;
cout << "vdown: " << vdown << endl;
}
}
void LaRCsimIC::SetFlightPathAngleRadIC( SCALAR tt) {
gamma=tt;
getTheta();
vtg=vt+vw;
hdot=vtg*sin(tt);
cout << "hdot: " << hdot << endl;
vdown=-1*hdot;
}
void LaRCsimIC::SetPitchAngleRadIC(SCALAR tt) {
if(alt_agl < (DEFAULT_AGL_ALT + 0.1) || vt < 10 )
theta=DEFAULT_PITCH_ON_GROUND;
else
theta=tt;
getAlpha();
}
void LaRCsimIC::SetUBodyFpsIC( SCALAR tt) {
u=tt;
vt=sqrt(u*u+v*v+w*w);
lastSpeedSet=lssetuvw;
}
void LaRCsimIC::SetVBodyFpsIC( SCALAR tt) {
v=tt;
vt=sqrt(u*u+v*v+w*w);
lastSpeedSet=lssetuvw;
}
void LaRCsimIC::SetWBodyFpsIC( SCALAR tt) {
w=tt;
vt=sqrt(u*u+v*v+w*w);
lastSpeedSet=lssetuvw;
}
void LaRCsimIC::SetVNorthAirmassFpsIC(SCALAR tt) {
vnorthwind=tt;
vw=sqrt(vnorthwind*vnorthwind + veastwind*veastwind + vdownwind*vdownwind);
}
void LaRCsimIC::SetVEastAirmassFpsIC(SCALAR tt) {
veastwind=tt;
vw=sqrt(vnorthwind*vnorthwind + veastwind*veastwind + vdownwind*vdownwind);
}
void LaRCsimIC::SetVDownAirmassFpsIC(SCALAR tt){
vdownwind=tt;
vw=sqrt(vnorthwind*vnorthwind + veastwind*veastwind + vdownwind*vdownwind);
vtg=vt+vw;
hdot=-vtg*sin(gamma);
}
void LaRCsimIC::SetAltitudeFtIC( SCALAR tt) {
if(tt > (runway_altitude + DEFAULT_AGL_ALT)) {
altitude=tt;
} else {
altitude=runway_altitude + DEFAULT_AGL_ALT;
alt_agl=DEFAULT_AGL_ALT;
theta=DEFAULT_PITCH_ON_GROUND;
}
lastAltSet=lssetasl;
get_atmosphere();
//lets try to make sure the user gets what they intended
switch(lastSpeedSet) {
case lssetned:
calcVtfromNED();
break;
case lssetuvw:
case lssetvt:
SetVtrueFpsIC(vt);
break;
case lssetvc:
SetVcalibratedKtsIC(vc*V_TO_KNOTS);
break;
case lssetve:
SetVequivalentKtsIC(ve*V_TO_KNOTS);
break;
case lssetmach:
SetMachIC(mach);
break;
}
}
void LaRCsimIC::SetAltitudeAGLFtIC( SCALAR tt) {
alt_agl=tt;
lastAltSet=lssetagl;
altitude=runway_altitude + alt_agl;
}
void LaRCsimIC::SetRunwayAltitudeFtIC( SCALAR tt) {
runway_altitude=tt;
if(lastAltSet == lssetagl)
altitude = runway_altitude + alt_agl;
}
void LaRCsimIC::calcVtfromNED(void) {
//take the earth's rotation out of veast first
//float veastner = veast- OMEGA_EARTH*sea_level_radius*cos( latitude_gd );
float veastner=veast;
u = (vnorth - vnorthwind)*cos(theta)*cos(psi) +
(veastner - veastwind)*cos(theta)*sin(psi) -
(vdown - vdownwind)*sin(theta);
v = (vnorth - vnorthwind)*(sin(phi)*sin(theta)*cos(psi) - cos(phi)*sin(psi)) +
(veastner - veastwind)*(sin(phi)*sin(theta)*sin(psi) + cos(phi)*cos(psi)) +
(vdown - vdownwind)*sin(phi)*cos(theta);
w = (vnorth - vnorthwind)*(cos(phi)*sin(theta)*cos(psi) + sin(phi)*sin(psi)) +
(veastner - veastwind)*(cos(phi)*sin(theta)*sin(psi) - sin(phi)*cos(psi)) +
(vdown - vdownwind)*cos(phi)*cos(theta);
vt = sqrt(u*u + v*v + w*w);
}
void LaRCsimIC::calcNEDfromVt(void) {
float veastner;
//get the body components of vt
u = GetUBodyFpsIC();
v = GetVBodyFpsIC();
w = GetWBodyFpsIC();
//transform them to local axes and add on the wind components
vnorth = u*cos(theta)*cos(psi) +
v*(sin(phi)*sin(theta)*cos(psi) - cos(phi)*sin(psi)) +
w*(cos(phi)*sin(theta)*cos(psi) + sin(phi)*sin(psi)) +
vnorthwind;
//need to account for the earth's rotation here
veastner = u*cos(theta)*sin(psi) +
v*(sin(phi)*sin(theta)*sin(psi) + cos(phi)*cos(psi)) +
w*(cos(phi)*sin(theta)*sin(psi) - sin(phi)*cos(psi)) +
veastwind;
veast = veastner;
//veast = veastner + OMEGA_EARTH*sea_level_radius*cos( latitude_gd );
vdown = u*sin(theta) +
v*sin(phi)*cos(theta) +
w*cos(phi)*cos(theta) +
vdownwind;
}
void LaRCsimIC::SetVnorthFpsIC( SCALAR tt) {
vnorth=tt;
lastSpeedSet=lssetned;
calcVtfromNED();
}
void LaRCsimIC::SetVeastFpsIC( SCALAR tt) {
veast=tt;
lastSpeedSet=lssetned;
calcVtfromNED();
}
void LaRCsimIC::SetVdownFpsIC( SCALAR tt) {
vdown=tt;
calcVtfromNED();
SetClimbRateFpsIC(-1*vdown);
lastSpeedSet=lssetned;
}
void LaRCsimIC::SetLatitudeGDRadIC(SCALAR tt) {
latitude_gd=tt;
ls_geod_to_geoc(latitude_gd,altitude,&sea_level_radius, &latitude_gc);
}
bool LaRCsimIC::getAlpha(void) {
bool result=false;
float guess=theta-gamma;
xlo=xhi=0;
xmin=-89;
xmax=89;
sfunc=&LaRCsimIC::GammaEqOfAlpha;
if(findInterval(0,guess)){
if(solve(&alpha,0)){
result=true;
}
}
return result;
}
bool LaRCsimIC::getTheta(void) {
bool result=false;
float guess=alpha+gamma;
xlo=xhi=0;
xmin=-89;xmax=89;
sfunc=&LaRCsimIC::GammaEqOfTheta;
if(findInterval(0,guess)){
if(solve(&theta,0)){
result=true;
}
}
return result;
}
SCALAR LaRCsimIC::GammaEqOfTheta( SCALAR theta_arg) {
SCALAR a,b,c;
a=cos(alpha)*cos(beta)*sin(theta_arg);
b=sin(beta)*sin(phi);
c=sin(alpha)*cos(beta)*cos(phi);
return sin(gamma)-a+(b+c)*cos(theta_arg);
}
SCALAR LaRCsimIC::GammaEqOfAlpha( SCALAR alpha_arg) {
float a,b,c;
a=cos(alpha_arg)*cos(beta)*sin(theta);
b=sin(beta)*sin(phi);
c=sin(alpha_arg)*cos(beta)*cos(phi);
return sin(gamma)-a+(b+c)*cos(theta);
}
bool LaRCsimIC::findInterval( SCALAR x,SCALAR guess) {
//void find_interval(inter_params &ip,eqfunc f,float y,float constant, int &flag){
int i=0;
bool found=false;
float flo,fhi,fguess;
float lo,hi,step;
step=0.1;
fguess=(this->*sfunc)(guess)-x;
lo=hi=guess;
do {
step=2*step;
lo-=step;
hi+=step;
if(lo < xmin) lo=xmin;
if(hi > xmax) hi=xmax;
i++;
flo=(this->*sfunc)(lo)-x;
fhi=(this->*sfunc)(hi)-x;
if(flo*fhi <=0) { //found interval with root
found=true;
if(flo*fguess <= 0) { //narrow interval down a bit
hi=lo+step; //to pass solver interval that is as
//small as possible
}
else if(fhi*fguess <= 0) {
lo=hi-step;
}
}
//cout << "findInterval: i=" << i << " Lo= " << lo << " Hi= " << hi << endl;
}
while((found == 0) && (i <= 100));
xlo=lo;
xhi=hi;
return found;
}
bool LaRCsimIC::solve( SCALAR *y,SCALAR x) {
float x1,x2,x3,f1,f2,f3,d,d0;
float eps=1E-5;
float const relax =0.9;
int i;
bool success=false;
//initializations
d=1;
x1=xlo;x3=xhi;
f1=(this->*sfunc)(x1)-x;
f3=(this->*sfunc)(x3)-x;
d0=fabs(x3-x1);
//iterations
i=0;
while ((fabs(d) > eps) && (i < 100)) {
d=(x3-x1)/d0;
x2=x1-d*d0*f1/(f3-f1);
f2=(this->*sfunc)(x2)-x;
//cout << "solve x1,x2,x3: " << x1 << "," << x2 << "," << x3 << endl;
//cout << " " << f1 << "," << f2 << "," << f3 << endl;
if(fabs(f2) <= 0.001) {
x1=x3=x2;
} else if(f1*f2 <= 0.0) {
x3=x2;
f3=f2;
f1=relax*f1;
} else if(f2*f3 <= 0) {
x1=x2;
f1=f2;
f3=relax*f3;
}
//cout << i << endl;
i++;
}//end while
if(i < 100) {
success=true;
*y=x2;
}
//cout << "Success= " << success << " Vcas: " << vcas*V_TO_KNOTS << " Mach: " << x2 << endl;
return success;
}

203
src/FDM/LaRCsimIC.hxx Normal file
View file

@ -0,0 +1,203 @@
/*******************************************************************************
Header: LaRCsimIC.hxx
Author: Tony Peden
Date started: 10/9/00
------------- Copyright (C) 2000 Anthony K. Peden (apeden@earthlink.net) -------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA.
Further information about the GNU General Public License can also be found on
the world wide web at http://www.gnu.org.
*/
#ifndef _LARCSIMIC_HXX
#define _LARCSIMIC_HXX
/*******************************************************************************
INCLUDES
*******************************************************************************/
#include <FDM/LaRCsim/ls_constants.h>
#include <FDM/LaRCsim/ls_types.h>
/*******************************************************************************
CLASS DECLARATION
*******************************************************************************/
#define KTS_TO_FPS 1.6889
#define M_TO_FT 3.2808399
#define DEFAULT_AGL_ALT 3.758099
#define DEFAULT_PITCH_ON_GROUND 0.0074002
typedef enum lsspeedset { lssetvt, lssetvc, lssetve, lssetmach, lssetuvw, lssetned };
typedef enum lsaltset { lssetasl, lssetagl };
class LaRCsimIC {
public:
LaRCsimIC(void);
~LaRCsimIC(void);
void SetVcalibratedKtsIC(SCALAR tt);
void SetMachIC(SCALAR tt);
void SetVtrueFpsIC(SCALAR tt);
void SetVequivalentKtsIC(SCALAR tt);
void SetUBodyFpsIC(SCALAR tt);
void SetVBodyFpsIC(SCALAR tt);
void SetWBodyFpsIC(SCALAR tt);
void SetVnorthFpsIC(SCALAR tt);
void SetVeastFpsIC(SCALAR tt);
void SetVdownFpsIC(SCALAR tt);
void SetVNorthAirmassFpsIC(SCALAR tt);
void SetVEastAirmassFpsIC(SCALAR tt);
void SetVDownAirmassFpsIC(SCALAR tt);
void SetAltitudeFtIC(SCALAR tt);
void SetAltitudeAGLFtIC(SCALAR tt);
//"vertical" flight path, recalculate theta
inline void SetFlightPathAngleDegIC(SCALAR tt) { SetFlightPathAngleRadIC(tt*DEG_TO_RAD); }
void SetFlightPathAngleRadIC(SCALAR tt);
//set speed first
void SetClimbRateFpmIC(SCALAR tt);
void SetClimbRateFpsIC(SCALAR tt);
//use currently stored gamma, recalcualte theta
inline void SetAlphaDegIC(SCALAR tt) { alpha=tt*DEG_TO_RAD; getTheta(); }
inline void SetAlphaRadIC(SCALAR tt) { alpha=tt; getTheta(); }
//use currently stored gamma, recalcualte alpha
inline void SetPitchAngleDegIC(SCALAR tt) { SetPitchAngleRadIC(tt*DEG_TO_RAD); }
void SetPitchAngleRadIC(SCALAR tt);
inline void SetBetaDegIC(SCALAR tt) { beta=tt*DEG_TO_RAD; getTheta();}
inline void SetBetaRadIC(SCALAR tt) { beta=tt; getTheta(); }
inline void SetRollAngleDegIC(SCALAR tt) { phi=tt*DEG_TO_RAD; getTheta(); }
inline void SetRollAngleRadIC(SCALAR tt) { phi=tt; getTheta(); }
inline void SetHeadingDegIC(SCALAR tt) { psi=tt*DEG_TO_RAD; }
inline void SetHeadingRadIC(SCALAR tt) { psi=tt; }
inline void SetLatitudeGDDegIC(SCALAR tt) { SetLatitudeGDRadIC(tt*DEG_TO_RAD); }
void SetLatitudeGDRadIC(SCALAR tt);
inline void SetLongitudeDegIC(SCALAR tt) { longitude=tt*DEG_TO_RAD; }
inline void SetLongitudeRadIC(SCALAR tt) { longitude=tt; }
void SetRunwayAltitudeFtIC(SCALAR tt);
inline SCALAR GetVcalibratedKtsIC(void) { return sqrt(density_ratio*vt*vt)*V_TO_KNOTS; }
inline SCALAR GetVequivalentKtsIC(void) { return sqrt(density_ratio)*vt*V_TO_KNOTS; }
inline SCALAR GetVtrueKtsIC(void) { return vt*V_TO_KNOTS; }
inline SCALAR GetVtrueFpsIC(void) { return vt; }
inline SCALAR GetMachIC(void) { return vt/soundspeed; }
inline SCALAR GetAltitudeFtIC(void) { return altitude; }
inline SCALAR GetAltitudeAGLFtIC(void) { return alt_agl; }
inline SCALAR GetRunwayAltitudeFtIC(void) { return runway_altitude; }
inline SCALAR GetFlightPathAngleDegIC(void) { return gamma*RAD_TO_DEG; }
inline SCALAR GetFlightPathAngleRadIC(void) { return gamma; }
inline SCALAR GetClimbRateFpmIC(void) { return hdot*60; }
inline SCALAR GetClimbRateFpsIC(void) { return hdot; }
inline SCALAR GetAlphaDegIC(void) { return alpha*RAD_TO_DEG; }
inline SCALAR GetAlphaRadIC(void) { return alpha; }
inline SCALAR GetPitchAngleDegIC(void) { return theta*RAD_TO_DEG; }
inline SCALAR GetPitchAngleRadIC(void) { return theta; }
inline SCALAR GetBetaDegIC(void) { return beta*RAD_TO_DEG; }
inline SCALAR GetBetaRadIC(void) { return beta*RAD_TO_DEG; }
inline SCALAR GetRollAngleDegIC(void) { return phi*RAD_TO_DEG; }
inline SCALAR GetRollAngleRadIC(void) { return phi; }
inline SCALAR GetHeadingDegIC(void) { return psi*RAD_TO_DEG; }
inline SCALAR GetHeadingRadIC(void) { return psi; }
inline SCALAR GetLatitudeGDDegIC(void) { return latitude_gd*RAD_TO_DEG; }
inline SCALAR GetLatitudeGDRadIC(void) { return latitude_gd; }
inline SCALAR GetLongitudeDegIC(void) { return longitude*RAD_TO_DEG; }
inline SCALAR GetLongitudeRadIC(void) { return longitude; }
inline SCALAR GetUBodyFpsIC(void) { return vt*cos(alpha)*cos(beta); }
inline SCALAR GetVBodyFpsIC(void) { return vt*sin(beta); }
inline SCALAR GetWBodyFpsIC(void) { return vt*sin(alpha)*cos(beta); }
inline SCALAR GetVnorthFpsIC(void) { calcNEDfromVt();return vnorth; }
inline SCALAR GetVeastFpsIC(void) { calcNEDfromVt();return veast; }
inline SCALAR GetVdownFpsIC(void) { calcNEDfromVt();return vdown; }
inline SCALAR GetVnorthAirmassFpsIC(void) { return vnorthwind; }
inline SCALAR GetVeastAirmassFpsIC(void) { return veastwind; }
inline SCALAR GetVdownAirmassFpsIC(void) { return vdownwind; }
inline SCALAR GetThetaRadIC(void) { return theta; }
inline SCALAR GetPhiRadIC(void) { return phi; }
inline SCALAR GetPsiRadIC(void) { return psi; }
private:
SCALAR vt,vtg,vw,vc,ve;
SCALAR alpha,beta,gamma,theta,phi,psi;
SCALAR mach;
SCALAR altitude,runway_altitude,hdot,alt_agl,sea_level_radius;
SCALAR latitude_gd,latitude_gc,longitude;
SCALAR u,v,w;
SCALAR vnorth,veast,vdown;
SCALAR vnorthwind, veastwind, vdownwind;
SCALAR p,T,soundspeed,density_ratio,rho;
SCALAR xlo, xhi,xmin,xmax;
typedef SCALAR (LaRCsimIC::*fp)(SCALAR x);
fp sfunc;
lsspeedset lastSpeedSet;
lsaltset lastAltSet;
void calcVtfromNED(void);
void calcNEDfromVt(void);
void calcSpeeds(void);
bool getAlpha(void);
bool getTheta(void);
SCALAR GammaEqOfTheta(SCALAR tt);
SCALAR GammaEqOfAlpha(SCALAR tt);
void get_atmosphere(void);
bool findInterval(SCALAR x,SCALAR guess);
bool solve(SCALAR *y, SCALAR x);
};
#endif

View file

@ -52,28 +52,30 @@ bool FGMagicCarpet::update( int multiloop ) {
double speed = controls.get_throttle( 0 ) * 2000; // meters/sec
double dist = speed * time_step;
double kts = speed * METER_TO_NM * 3600.0;
set_V_equiv_kts( kts );
set_V_calibrated_kts( kts );
set_V_ground_speed( kts );
set_Mach_number(0);
_set_V_equiv_kts( kts );
_set_V_calibrated_kts( kts );
_set_V_ground_speed( kts );
// angle of turn
double turn_rate = controls.get_aileron() * FG_PI_4; // radians/sec
double turn = turn_rate * time_step;
// update euler angles
set_Euler_Angles( get_Phi(), get_Theta(), fmod(get_Psi() + turn, FG_2PI) );
set_Euler_Rates(0,0,0);
_set_Euler_Angles( get_Phi(), get_Theta(), fmod(get_Psi() + turn, FG_2PI) );
_set_Euler_Rates(0,0,0);
// update (lon/lat) position
double lat2, lon2, az2;
geo_direct_wgs_84 ( get_Altitude(),
get_Latitude() * RAD_TO_DEG,
get_Longitude() * RAD_TO_DEG,
get_Psi() * RAD_TO_DEG,
dist, &lat2, &lon2, &az2 );
set_Longitude( lon2 * DEG_TO_RAD );
set_Latitude( lat2 * DEG_TO_RAD );
if ( speed > FG_EPSILON ) {
geo_direct_wgs_84 ( get_Altitude(),
get_Latitude() * RAD_TO_DEG,
get_Longitude() * RAD_TO_DEG,
get_Psi() * RAD_TO_DEG,
dist, &lat2, &lon2, &az2 );
_set_Longitude( lon2 * DEG_TO_RAD );
_set_Latitude( lat2 * DEG_TO_RAD );
}
// cout << "lon error = " << fabs(end.x()*RAD_TO_DEG - lon2)
// << " lat error = " << fabs(end.y()*RAD_TO_DEG - lat2)
@ -84,15 +86,15 @@ bool FGMagicCarpet::update( int multiloop ) {
// update altitude
double real_climb_rate = -controls.get_elevator() * 5000; // feet/sec
set_Climb_Rate( real_climb_rate / 500.0 );
_set_Climb_Rate( real_climb_rate / 500.0 );
double climb = real_climb_rate * time_step;
set_Geocentric_Position( lat_geoc, get_Longitude(),
_set_Geocentric_Position( lat_geoc, get_Longitude(),
sl_radius + get_Altitude() + climb );
// cout << "sea level radius (ft) = " << sl_radius << endl;
// cout << "(setto) sea level radius (ft) = " << get_Sea_level_radius() << endl;
set_Sea_level_radius( sl_radius * METER_TO_FEET);
set_Altitude( get_Altitude() + climb );
_set_Sea_level_radius( sl_radius * METER_TO_FEET);
_set_Altitude( get_Altitude() + climb );
return true;
}

View file

@ -10,6 +10,7 @@ libFlight_a_SOURCES = \
IO360.cxx IO360.hxx \
JSBSim.cxx JSBSim.hxx \
LaRCsim.cxx LaRCsim.hxx \
LaRCsimIC.cxx LaRCsimIC.hxx \
MagicCarpet.cxx MagicCarpet.hxx
bin_PROGRAMS = engine pstest

View file

@ -91,36 +91,36 @@ void uiuc_betaprobe()
Gamma_clean_tail = Lift_clean_tail / (Density * V_rel_wind);
Gamma_iced_tail = Lift_iced_tail / (Density * V_rel_wind);
w_clean_wing = Gamma_clean_wing / (2 * PI * x_probe_wing);
w_iced_wing = Gamma_iced_wing / (2 * PI * x_probe_wing);
w_clean_tail = Gamma_clean_tail / (2 * PI * x_probe_tail);
w_iced_tail = Gamma_iced_tail / (2 * PI * x_probe_tail);
w_clean_wing = Gamma_clean_wing / (2 * LS_PI * x_probe_wing);
w_iced_wing = Gamma_iced_wing / (2 * LS_PI * x_probe_wing);
w_clean_tail = Gamma_clean_tail / (2 * LS_PI * x_probe_tail);
w_iced_tail = Gamma_iced_tail / (2 * LS_PI * x_probe_tail);
V_total_clean_wing = sqrt(w_clean_wing*w_clean_wing +
V_rel_wind*V_rel_wind -
2*w_clean_wing*V_rel_wind *
cos(PI/2 + Alpha));
cos(LS_PI/2 + Alpha));
V_total_iced_wing = sqrt(w_iced_wing*w_iced_wing +
V_rel_wind*V_rel_wind -
2*w_iced_wing*V_rel_wind *
cos(PI/2 + Alpha));
cos(LS_PI/2 + Alpha));
V_total_clean_tail = sqrt(w_clean_tail*w_clean_tail +
V_rel_wind*V_rel_wind -
2*w_clean_tail*V_rel_wind *
cos(PI/2 + Alpha));
cos(LS_PI/2 + Alpha));
V_total_iced_tail = sqrt(w_iced_tail*w_iced_tail +
V_rel_wind*V_rel_wind -
2*w_iced_tail*V_rel_wind *
cos(PI/2 + Alpha));
cos(LS_PI/2 + Alpha));
beta_flow_clean_wing = asin((w_clean_wing / V_total_clean_wing) *
sin (PI/2 + Alpha));
sin (LS_PI/2 + Alpha));
beta_flow_iced_wing = asin((w_iced_wing / V_total_iced_wing) *
sin (PI/2 + Alpha));
sin (LS_PI/2 + Alpha));
beta_flow_clean_tail = asin((w_clean_tail / V_total_clean_tail) *
sin (PI/2 + Alpha));
sin (LS_PI/2 + Alpha));
beta_flow_iced_tail = asin((w_iced_tail / V_total_iced_tail) *
sin (PI/2 + Alpha));
sin (LS_PI/2 + Alpha));
Dbeta_flow_wing = fabs(beta_flow_clean_wing - beta_flow_iced_wing);
Dbeta_flow_tail = fabs(beta_flow_clean_tail - beta_flow_iced_tail);

View file

@ -46,31 +46,99 @@
FGInterface *cur_fdm_state;
FGInterface base_fdm_state;
inline void init_vec(FG_VECTOR_3 vec) {
vec[0] = 0.0; vec[1] = 0.0; vec[2] = 0.0;
}
FGEngInterface::FGEngInterface(void) {
// inputs
Throttle=0;
Mixture=0;
Prop_Advance=0;
// outputs
RPM=0;
Manifold_Pressure=0;
MaxHP=0;
Percentage_Power=0;
EGT=0;
prop_thrust=0;
}
FGEngInterface::~FGEngInterface(void) {
}
// Constructor
FGInterface::FGInterface(void) {
mass=i_xx=i_yy=i_zz=i_xz=0;
nlf=0;
v_rel_wind=v_true_kts=v_rel_ground=v_inertial=0;
v_ground_speed=v_equiv=v_equiv_kts=0;
v_calibrated=v_calibrated_kts=0;
gravity=0;
centrifugal_relief=0;
alpha=beta=alpha_dot=beta_dot=0;
cos_alpha=sin_alpha=cos_beta=sin_beta=0;
cos_phi=sin_phi=cos_theta=sin_theta=cos_psi=sin_psi=0;
gamma_vert_rad=gamma_horiz_rad=0;
sigma=density=v_sound=mach_number=0;
static_pressure=total_pressure=impact_pressure=0;
dynamic_pressure=0;
static_temperature=total_temperature=0;
sea_level_radius=earth_position_angle=0;
runway_altitude=runway_latitude=runway_longitude=0;
runway_heading=0;
radius_to_rwy=0;
climb_rate=0;
sin_lat_geocentric=cos_lat_geocentric=0;
sin_longitude=cos_longitude=0;
init_vec( d_pilot_rp_body_v );
init_vec( d_cg_rp_body_v );
init_vec( f_body_total_v );
init_vec( f_local_total_v );
init_vec( f_aero_v );
init_vec( f_engine_v );
init_vec( f_gear_v );
init_vec( m_total_rp_v );
init_vec( m_total_cg_v );
init_vec( m_aero_v );
init_vec( m_engine_v );
init_vec( m_gear_v );
init_vec( v_dot_local_v );
init_vec( v_dot_body_v );
init_vec( a_cg_body_v );
init_vec( a_pilot_body_v );
init_vec( n_cg_body_v );
init_vec( n_pilot_body_v );
init_vec( omega_dot_body_v );
init_vec( v_local_v );
init_vec( v_local_rel_ground_v );
init_vec( v_local_airmass_v );
init_vec( v_local_rel_airmass_v );
init_vec( v_local_gust_v );
init_vec( v_wind_body_v );
init_vec( omega_body_v );
init_vec( omega_local_v );
init_vec( omega_total_v );
init_vec( euler_rates_v );
init_vec( geocentric_rates_v );
init_vec( geocentric_position_v );
init_vec( geodetic_position_v );
init_vec( euler_angles_v );
init_vec( d_cg_rwy_local_v );
init_vec( d_cg_rwy_rwy_v );
init_vec( d_pilot_rwy_local_v );
init_vec( d_pilot_rwy_rwy_v );
init_vec( t_local_to_body_m[0] );
init_vec( t_local_to_body_m[1] );
init_vec( t_local_to_body_m[2] );
mass=i_xx=i_yy=i_zz=i_xz=0;
nlf=0;
v_rel_wind=v_true_kts=v_rel_ground=v_inertial=0;
v_ground_speed=v_equiv=v_equiv_kts=0;
v_calibrated=v_calibrated_kts=0;
gravity=0;
centrifugal_relief=0;
alpha=beta=alpha_dot=beta_dot=0;
cos_alpha=sin_alpha=cos_beta=sin_beta=0;
cos_phi=sin_phi=cos_theta=sin_theta=cos_psi=sin_psi=0;
gamma_vert_rad=gamma_horiz_rad=0;
sigma=density=v_sound=mach_number=0;
static_pressure=total_pressure=impact_pressure=0;
dynamic_pressure=0;
static_temperature=total_temperature=0;
sea_level_radius=earth_position_angle=0;
runway_altitude=runway_latitude=runway_longitude=0;
runway_heading=0;
radius_to_rwy=0;
climb_rate=0;
sin_lat_geocentric=cos_lat_geocentric=0;
sin_latitude=cos_latitude=0;
sin_longitude=cos_longitude=0;
altitude_agl=0;
resetNeeded=false;
}
@ -131,9 +199,9 @@ void fgFDMForceAltitude(int model, double alt_meters) {
&sea_level_radius_meters, &lat_geoc);
base_fdm_state.set_Altitude( alt_meters * METER_TO_FEET );
base_fdm_state.set_Radius_to_vehicle( base_fdm_state.get_Altitude() +
(sea_level_radius_meters *
METER_TO_FEET) );
base_fdm_state.set_Sea_level_radius( sea_level_radius_meters *
METER_TO_FEET );
// additional work needed for some flight models
if ( model == FGInterface::FG_LARCSIM ) {
@ -144,8 +212,196 @@ void fgFDMForceAltitude(int model, double alt_meters) {
// Set the local ground elevation
void fgFDMSetGroundElevation(int model, double ground_meters) {
FG_LOG( FG_FLIGHT,FG_INFO, "fgFDMSetGroundElevation: "
<< ground_meters*METER_TO_FEET );
base_fdm_state.set_Runway_altitude( ground_meters * METER_TO_FEET );
cur_fdm_state->set_Runway_altitude( ground_meters * METER_TO_FEET );
}
// Positions
void FGInterface::set_Latitude(double lat) {
geodetic_position_v[0] = lat;
}
void FGInterface::set_Longitude(double lon) {
geodetic_position_v[1] = lon;
}
void FGInterface::set_Altitude(double alt) {
geodetic_position_v[2] = alt;
}
void FGInterface::set_AltitudeAGL(double altagl) {
altitude_agl=altagl;
}
// Velocities
void FGInterface::set_V_calibrated_kts(double vc) {
v_calibrated_kts = vc;
}
void FGInterface::set_Mach_number(double mach) {
mach_number = mach;
}
void FGInterface::set_Velocities_Local( double north,
double east,
double down ){
v_local_v[0] = north;
v_local_v[1] = east;
v_local_v[2] = down;
}
void FGInterface::set_Velocities_Wind_Body( double u,
double v,
double w){
v_wind_body_v[0] = u;
v_wind_body_v[1] = v;
v_wind_body_v[2] = w;
}
// Euler angles
void FGInterface::set_Euler_Angles( double phi,
double theta,
double psi ) {
euler_angles_v[0] = phi;
euler_angles_v[1] = theta;
euler_angles_v[2] = psi;
}
// Flight Path
void FGInterface::set_Climb_Rate( double roc) {
climb_rate = roc;
}
void FGInterface::set_Gamma_vert_rad( double gamma) {
gamma_vert_rad = gamma;
}
// Earth
void FGInterface::set_Sea_level_radius(double slr) {
sea_level_radius = slr;
}
void FGInterface::set_Runway_altitude(double ralt) {
runway_altitude = ralt;
}
void FGInterface::set_Static_pressure(double p) { static_pressure = p; }
void FGInterface::set_Static_temperature(double T) { static_temperature = T; }
void FGInterface::set_Density(double rho) { density = rho; }
void FGInterface::set_Velocities_Local_Airmass (double wnorth,
double weast,
double wdown ) {
v_local_airmass_v[0] = wnorth;
v_local_airmass_v[1] = weast;
v_local_airmass_v[2] = wdown;
}
void FGInterface::busdump(void) {
FG_LOG(FG_FLIGHT,FG_INFO,"d_pilot_rp_body_v[3]: " << d_pilot_rp_body_v[0] << ", " << d_pilot_rp_body_v[1] << ", " << d_pilot_rp_body_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"d_cg_rp_body_v[3]: " << d_cg_rp_body_v[0] << ", " << d_cg_rp_body_v[1] << ", " << d_cg_rp_body_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"f_body_total_v[3]: " << f_body_total_v[0] << ", " << f_body_total_v[1] << ", " << f_body_total_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"f_local_total_v[3]: " << f_local_total_v[0] << ", " << f_local_total_v[1] << ", " << f_local_total_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"f_aero_v[3]: " << f_aero_v[0] << ", " << f_aero_v[1] << ", " << f_aero_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"f_engine_v[3]: " << f_engine_v[0] << ", " << f_engine_v[1] << ", " << f_engine_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"f_gear_v[3]: " << f_gear_v[0] << ", " << f_gear_v[1] << ", " << f_gear_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"m_total_rp_v[3]: " << m_total_rp_v[0] << ", " << m_total_rp_v[1] << ", " << m_total_rp_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"m_total_cg_v[3]: " << m_total_cg_v[0] << ", " << m_total_cg_v[1] << ", " << m_total_cg_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"m_aero_v[3]: " << m_aero_v[0] << ", " << m_aero_v[1] << ", " << m_aero_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"m_engine_v[3]: " << m_engine_v[0] << ", " << m_engine_v[1] << ", " << m_engine_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"m_gear_v[3]: " << m_gear_v[0] << ", " << m_gear_v[1] << ", " << m_gear_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"v_dot_local_v[3]: " << v_dot_local_v[0] << ", " << v_dot_local_v[1] << ", " << v_dot_local_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"v_dot_body_v[3]: " << v_dot_body_v[0] << ", " << v_dot_body_v[1] << ", " << v_dot_body_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"a_cg_body_v[3]: " << a_cg_body_v[0] << ", " << a_cg_body_v[1] << ", " << a_cg_body_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"a_pilot_body_v[3]: " << a_pilot_body_v[0] << ", " << a_pilot_body_v[1] << ", " << a_pilot_body_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"n_cg_body_v[3]: " << n_cg_body_v[0] << ", " << n_cg_body_v[1] << ", " << n_cg_body_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"n_pilot_body_v[3]: " << n_pilot_body_v[0] << ", " << n_pilot_body_v[1] << ", " << n_pilot_body_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"omega_dot_body_v[3]: " << omega_dot_body_v[0] << ", " << omega_dot_body_v[1] << ", " << omega_dot_body_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"v_local_v[3]: " << v_local_v[0] << ", " << v_local_v[1] << ", " << v_local_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"v_local_rel_ground_v[3]: " << v_local_rel_ground_v[0] << ", " << v_local_rel_ground_v[1] << ", " << v_local_rel_ground_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"v_local_airmass_v[3]: " << v_local_airmass_v[0] << ", " << v_local_airmass_v[1] << ", " << v_local_airmass_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"v_local_rel_airmass_v[3]: " << v_local_rel_airmass_v[0] << ", " << v_local_rel_airmass_v[1] << ", " << v_local_rel_airmass_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"v_local_gust_v[3]: " << v_local_gust_v[0] << ", " << v_local_gust_v[1] << ", " << v_local_gust_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"v_wind_body_v[3]: " << v_wind_body_v[0] << ", " << v_wind_body_v[1] << ", " << v_wind_body_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"omega_body_v[3]: " << omega_body_v[0] << ", " << omega_body_v[1] << ", " << omega_body_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"omega_local_v[3]: " << omega_local_v[0] << ", " << omega_local_v[1] << ", " << omega_local_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"omega_total_v[3]: " << omega_total_v[0] << ", " << omega_total_v[1] << ", " << omega_total_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"euler_rates_v[3]: " << euler_rates_v[0] << ", " << euler_rates_v[1] << ", " << euler_rates_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"geocentric_rates_v[3]: " << geocentric_rates_v[0] << ", " << geocentric_rates_v[1] << ", " << geocentric_rates_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"geocentric_position_v[3]: " << geocentric_position_v[0] << ", " << geocentric_position_v[1] << ", " << geocentric_position_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"geodetic_position_v[3]: " << geodetic_position_v[0] << ", " << geodetic_position_v[1] << ", " << geodetic_position_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"euler_angles_v[3]: " << euler_angles_v[0] << ", " << euler_angles_v[1] << ", " << euler_angles_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"d_cg_rwy_local_v[3]: " << d_cg_rwy_local_v[0] << ", " << d_cg_rwy_local_v[1] << ", " << d_cg_rwy_local_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"d_cg_rwy_rwy_v[3]: " << d_cg_rwy_rwy_v[0] << ", " << d_cg_rwy_rwy_v[1] << ", " << d_cg_rwy_rwy_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"d_pilot_rwy_local_v[3]: " << d_pilot_rwy_local_v[0] << ", " << d_pilot_rwy_local_v[1] << ", " << d_pilot_rwy_local_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"d_pilot_rwy_rwy_v[3]: " << d_pilot_rwy_rwy_v[0] << ", " << d_pilot_rwy_rwy_v[1] << ", " << d_pilot_rwy_rwy_v[2]);
FG_LOG(FG_FLIGHT,FG_INFO,"t_local_to_body_m[0][3]: " << t_local_to_body_m[0][0] << ", " << t_local_to_body_m[0][1] << ", " << t_local_to_body_m[0][2]);
FG_LOG(FG_FLIGHT,FG_INFO,"t_local_to_body_m[1][3]: " << t_local_to_body_m[1][0] << ", " << t_local_to_body_m[1][1] << ", " << t_local_to_body_m[1][2]);
FG_LOG(FG_FLIGHT,FG_INFO,"t_local_to_body_m[2][3]: " << t_local_to_body_m[2][0] << ", " << t_local_to_body_m[2][1] << ", " << t_local_to_body_m[2][2]);
FG_LOG(FG_FLIGHT,FG_INFO,"mass: " << mass );
FG_LOG(FG_FLIGHT,FG_INFO,"i_xx: " << i_xx );
FG_LOG(FG_FLIGHT,FG_INFO,"i_yy: " << i_yy );
FG_LOG(FG_FLIGHT,FG_INFO,"i_zz: " << i_zz );
FG_LOG(FG_FLIGHT,FG_INFO,"i_xz: " << i_xz );
FG_LOG(FG_FLIGHT,FG_INFO,"nlf: " << nlf );
FG_LOG(FG_FLIGHT,FG_INFO,"v_rel_wind: " << v_rel_wind );
FG_LOG(FG_FLIGHT,FG_INFO,"v_true_kts: " << v_true_kts );
FG_LOG(FG_FLIGHT,FG_INFO,"v_rel_ground: " << v_rel_ground );
FG_LOG(FG_FLIGHT,FG_INFO,"v_inertial: " << v_inertial );
FG_LOG(FG_FLIGHT,FG_INFO,"v_ground_speed: " << v_ground_speed );
FG_LOG(FG_FLIGHT,FG_INFO,"v_equiv: " << v_equiv );
FG_LOG(FG_FLIGHT,FG_INFO,"v_equiv_kts: " << v_equiv_kts );
FG_LOG(FG_FLIGHT,FG_INFO,"v_calibrated: " << v_calibrated );
FG_LOG(FG_FLIGHT,FG_INFO,"v_calibrated_kts: " << v_calibrated_kts );
FG_LOG(FG_FLIGHT,FG_INFO,"gravity: " << gravity );
FG_LOG(FG_FLIGHT,FG_INFO,"centrifugal_relief: " << centrifugal_relief );
FG_LOG(FG_FLIGHT,FG_INFO,"alpha: " << alpha );
FG_LOG(FG_FLIGHT,FG_INFO,"beta: " << beta );
FG_LOG(FG_FLIGHT,FG_INFO,"alpha_dot: " << alpha_dot );
FG_LOG(FG_FLIGHT,FG_INFO,"beta_dot: " << beta_dot );
FG_LOG(FG_FLIGHT,FG_INFO,"cos_alpha: " << cos_alpha );
FG_LOG(FG_FLIGHT,FG_INFO,"sin_alpha: " << sin_alpha );
FG_LOG(FG_FLIGHT,FG_INFO,"cos_beta: " << cos_beta );
FG_LOG(FG_FLIGHT,FG_INFO,"sin_beta: " << sin_beta );
FG_LOG(FG_FLIGHT,FG_INFO,"cos_phi: " << cos_phi );
FG_LOG(FG_FLIGHT,FG_INFO,"sin_phi: " << sin_phi );
FG_LOG(FG_FLIGHT,FG_INFO,"cos_theta: " << cos_theta );
FG_LOG(FG_FLIGHT,FG_INFO,"sin_theta: " << sin_theta );
FG_LOG(FG_FLIGHT,FG_INFO,"cos_psi: " << cos_psi );
FG_LOG(FG_FLIGHT,FG_INFO,"sin_psi: " << sin_psi );
FG_LOG(FG_FLIGHT,FG_INFO,"gamma_vert_rad: " << gamma_vert_rad );
FG_LOG(FG_FLIGHT,FG_INFO,"gamma_horiz_rad: " << gamma_horiz_rad );
FG_LOG(FG_FLIGHT,FG_INFO,"sigma: " << sigma );
FG_LOG(FG_FLIGHT,FG_INFO,"density: " << density );
FG_LOG(FG_FLIGHT,FG_INFO,"v_sound: " << v_sound );
FG_LOG(FG_FLIGHT,FG_INFO,"mach_number: " << mach_number );
FG_LOG(FG_FLIGHT,FG_INFO,"static_pressure: " << static_pressure );
FG_LOG(FG_FLIGHT,FG_INFO,"total_pressure: " << total_pressure );
FG_LOG(FG_FLIGHT,FG_INFO,"impact_pressure: " << impact_pressure );
FG_LOG(FG_FLIGHT,FG_INFO,"dynamic_pressure: " << dynamic_pressure );
FG_LOG(FG_FLIGHT,FG_INFO,"static_temperature: " << static_temperature );
FG_LOG(FG_FLIGHT,FG_INFO,"total_temperature: " << total_temperature );
FG_LOG(FG_FLIGHT,FG_INFO,"sea_level_radius: " << sea_level_radius );
FG_LOG(FG_FLIGHT,FG_INFO,"earth_position_angle: " << earth_position_angle );
FG_LOG(FG_FLIGHT,FG_INFO,"runway_altitude: " << runway_altitude );
FG_LOG(FG_FLIGHT,FG_INFO,"runway_latitude: " << runway_latitude );
FG_LOG(FG_FLIGHT,FG_INFO,"runway_longitude: " << runway_longitude );
FG_LOG(FG_FLIGHT,FG_INFO,"runway_heading: " << runway_heading );
FG_LOG(FG_FLIGHT,FG_INFO,"radius_to_rwy: " << radius_to_rwy );
FG_LOG(FG_FLIGHT,FG_INFO,"climb_rate: " << climb_rate );
FG_LOG(FG_FLIGHT,FG_INFO,"sin_lat_geocentric: " << sin_lat_geocentric );
FG_LOG(FG_FLIGHT,FG_INFO,"cos_lat_geocentric: " << cos_lat_geocentric );
FG_LOG(FG_FLIGHT,FG_INFO,"sin_longitude: " << sin_longitude );
FG_LOG(FG_FLIGHT,FG_INFO,"cos_longitude: " << cos_longitude );
FG_LOG(FG_FLIGHT,FG_INFO,"sin_latitude: " << sin_latitude );
FG_LOG(FG_FLIGHT,FG_INFO,"cos_latitude: " << cos_latitude );
FG_LOG(FG_FLIGHT,FG_INFO,"altitude_agl: " << altitude_agl );
}

View file

@ -113,9 +113,22 @@ private:
double Percentage_Power;
double EGT;
double prop_thrust;
/* others...
double PercentN1,N1; //GE,CFM
double PercentN2,N2;
double EPR; //P&W, RR?
double FuelFlow;
bool AfterBurner;
double InletAngles[3];
double InletPosition[3];
double ThrustVector[3];
*/
public:
FGEngInterface(void);
~FGEngInterface(void);
inline double get_Throttle() const { return Throttle; }
inline double get_Mixture() const { return Mixture; }
inline double get_Prop_Advance() const { return Prop_Advance; }
@ -144,6 +157,10 @@ typedef vector < FGEngInterface > engine_list;
// This is based heavily on LaRCsim/ls_generic.h
class FGInterface {
protected:
void busdump(void);
private:
// Pilot location rel to ref pt
@ -231,6 +248,10 @@ private:
double sin_lat_geocentric, cos_lat_geocentric;
double sin_longitude, cos_longitude;
double sin_latitude, cos_latitude;
double altitude_agl;
//change flag
bool resetNeeded;
// Engine list
engine_list engines;
@ -238,6 +259,157 @@ private:
FGTimeStamp valid_stamp; // time this record is valid
FGTimeStamp next_stamp; // time this record is valid
protected:
inline void _set_Inertias( double m, double xx, double yy,
double zz, double xz)
{
mass = m;
i_xx = xx;
i_yy = yy;
i_zz = zz;
i_xz = xz;
}
inline void _set_CG_Position( double dx, double dy, double dz ) {
d_cg_rp_body_v[0] = dx;
d_cg_rp_body_v[1] = dy;
d_cg_rp_body_v[2] = dz;
}
inline void _set_Accels_Local( double north, double east, double down ) {
v_dot_local_v[0] = north;
v_dot_local_v[1] = east;
v_dot_local_v[2] = down;
}
inline void _set_Accels_Body( double u, double v, double w ) {
v_dot_body_v[0] = u;
v_dot_body_v[1] = v;
v_dot_body_v[2] = w;
}
inline void _set_Accels_CG_Body( double x, double y, double z ) {
a_cg_body_v[0] = x;
a_cg_body_v[1] = y;
a_cg_body_v[2] = z;
}
inline void _set_Accels_Pilot_Body( double x, double y, double z ) {
a_pilot_body_v[0] = x;
a_pilot_body_v[1] = y;
a_pilot_body_v[2] = z;
}
inline void _set_Accels_CG_Body_N( double x, double y, double z ) {
n_cg_body_v[0] = x;
n_cg_body_v[1] = y;
n_cg_body_v[2] = z;
}
void _set_Nlf(double n) { nlf=n; }
inline void _set_Velocities_Local( double north, double east, double down ){
v_local_v[0] = north;
v_local_v[1] = east;
v_local_v[2] = down;
}
inline void _set_Velocities_Ground(double north, double east, double down) {
v_local_rel_ground_v[0] = north;
v_local_rel_ground_v[1] = east;
v_local_rel_ground_v[2] = down;
}
inline void _set_Velocities_Local_Airmass( double north, double east,
double down)
{
v_local_airmass_v[0] = north;
v_local_airmass_v[1] = east;
v_local_airmass_v[2] = down;
}
inline void _set_Velocities_Wind_Body( double u, double v, double w) {
v_wind_body_v[0] = u;
v_wind_body_v[1] = v;
v_wind_body_v[2] = w;
}
inline void _set_V_ground_speed( double v) { v_ground_speed = v; }
inline void _set_V_equiv_kts( double kts ) { v_equiv_kts = kts; }
inline void _set_V_calibrated_kts( double kts ) { v_calibrated_kts = kts; }
inline void _set_Omega_Body( double p, double q, double r ) {
omega_body_v[0] = p;
omega_body_v[1] = q;
omega_body_v[2] = r;
}
inline void _set_Euler_Rates( double phi, double theta, double psi ) {
euler_rates_v[0] = phi;
euler_rates_v[1] = theta;
euler_rates_v[2] = psi;
}
inline void _set_Geocentric_Rates( double lat, double lon, double rad ) {
geocentric_rates_v[0] = lat;
geocentric_rates_v[1] = lon;
geocentric_rates_v[2] = rad;
}
#if 0
inline void _set_Radius_to_vehicle(double radius) {
geocentric_position_v[2] = radius;
}
#endif
inline void _set_Geocentric_Position( double lat, double lon, double rad ) {
geocentric_position_v[0] = lat;
geocentric_position_v[1] = lon;
geocentric_position_v[2] = rad;
}
inline void _set_Latitude(double lat) { geodetic_position_v[0] = lat; }
inline void _set_Longitude(double lon) { geodetic_position_v[1] = lon; }
inline void _set_Altitude(double altitude) {
geodetic_position_v[2] = altitude;
}
inline void _set_Altitude_AGL(double agl) {
altitude_agl = agl;
}
inline void _set_Geodetic_Position( double lat, double lon, double alt ) {
geodetic_position_v[0] = lat;
geodetic_position_v[1] = lon;
geodetic_position_v[2] = alt;
}
inline void _set_Euler_Angles( double phi, double theta, double psi ) {
euler_angles_v[0] = phi;
euler_angles_v[1] = theta;
euler_angles_v[2] = psi;
}
inline void _set_T_Local_to_Body( int i, int j, double value) {
t_local_to_body_m[i-1][j-1] = value;
}
inline void _set_T_Local_to_Body( double m[3][3] ) {
int i, j;
for ( i = 0; i < 3; i++ ) {
for ( j = 0; j < 3; j++ ) {
t_local_to_body_m[i][j] = m[i][j];
}
}
}
inline void _set_Alpha( double a ) { alpha = a; }
inline void _set_Beta( double b ) { beta = b; }
inline void _set_Cos_phi( double cp ) { cos_phi = cp; }
inline void _set_Cos_theta( double ct ) { cos_theta = ct; }
inline void _set_Gamma_vert_rad( double gv ) { gamma_vert_rad = gv; }
inline void _set_Density( double d ) { density = d; }
inline void _set_Mach_number( double m ) { mach_number = m; }
inline void _set_Static_pressure( double sp ) { static_pressure = sp; }
inline void _set_Static_temperature( double t ) { static_temperature = t; }
inline void _set_Sea_level_radius( double r ) { sea_level_radius = r; }
inline void _set_Earth_position_angle(double a) {
earth_position_angle = a;
}
inline void _set_Runway_altitude( double alt ) { runway_altitude = alt; }
inline void _set_Climb_Rate(double rate) { climb_rate = rate; }
inline void _set_sin_lat_geocentric(double parm) {
sin_lat_geocentric = sin(parm);
}
inline void _set_cos_lat_geocentric(double parm) {
cos_lat_geocentric = cos(parm);
}
inline void _set_sin_cos_longitude(double parm) {
sin_longitude = sin(parm);
cos_longitude = cos(parm);
}
inline void _set_sin_cos_latitude(double parm) {
sin_latitude = sin(parm);
cos_latitude = cos(parm);
}
public:
FGInterface(void);
@ -260,7 +432,7 @@ public:
// Christian's hot air balloon simulation
FG_BALLOONSIM = 3,
// AEronautical DEvelopment AGEncy, Bangalore India
// Aeronautical DEvelopment AGEncy, Bangalore India
FG_ADA = 4,
// The following aren't implemented but are here to spark
@ -275,6 +447,38 @@ public:
FG_EXTERNAL = 10
};
// Positions
virtual void set_Latitude(double lat); // geocentric
virtual void set_Longitude(double lon);
virtual void set_Altitude(double alt); // triggers re-calc of AGL altitude
virtual void set_AltitudeAGL(double altagl); // and vice-versa
// Speeds -- setting any of these will trigger a re-calc of the rest
virtual void set_V_calibrated_kts(double vc);
virtual void set_Mach_number(double mach);
virtual void set_Velocities_Local( double north, double east, double down );
virtual void set_Velocities_Wind_Body( double u, double v, double w);
// Euler angles
virtual void set_Euler_Angles( double phi, double theta, double psi );
// Flight Path
virtual void set_Climb_Rate( double roc);
virtual void set_Gamma_vert_rad( double gamma);
// Earth
virtual void set_Sea_level_radius(double slr);
virtual void set_Runway_altitude(double ralt);
virtual void set_Static_pressure(double p);
virtual void set_Static_temperature(double T);
virtual void set_Density(double rho);
virtual void set_Velocities_Local_Airmass (double wnorth,
double weast,
double wdown );
// ========== Mass properties and geometry values ==========
// Inertias
@ -283,15 +487,6 @@ public:
inline double get_I_yy() const { return i_yy; }
inline double get_I_zz() const { return i_zz; }
inline double get_I_xz() const { return i_xz; }
inline void set_Inertias( double m, double xx, double yy,
double zz, double xz)
{
mass = m;
i_xx = xx;
i_yy = yy;
i_zz = zz;
i_xz = xz;
}
// Pilot location rel to ref pt
// inline double * get_D_pilot_rp_body_v() {
@ -311,11 +506,6 @@ public:
inline double get_Dx_cg() const { return d_cg_rp_body_v[0]; }
inline double get_Dy_cg() const { return d_cg_rp_body_v[1]; }
inline double get_Dz_cg() const { return d_cg_rp_body_v[2]; }
inline void set_CG_Position( double dx, double dy, double dz ) {
d_cg_rp_body_v[0] = dx;
d_cg_rp_body_v[1] = dy;
d_cg_rp_body_v[2] = dz;
}
// ========== Forces ==========
@ -427,51 +617,26 @@ public:
inline double get_V_dot_north() const { return v_dot_local_v[0]; }
inline double get_V_dot_east() const { return v_dot_local_v[1]; }
inline double get_V_dot_down() const { return v_dot_local_v[2]; }
inline void set_Accels_Local( double north, double east, double down ) {
v_dot_local_v[0] = north;
v_dot_local_v[1] = east;
v_dot_local_v[2] = down;
}
// inline double * get_V_dot_body_v() { return v_dot_body_v; }
inline double get_U_dot_body() const { return v_dot_body_v[0]; }
inline double get_V_dot_body() const { return v_dot_body_v[1]; }
inline double get_W_dot_body() const { return v_dot_body_v[2]; }
inline void set_Accels_Body( double u, double v, double w ) {
v_dot_body_v[0] = u;
v_dot_body_v[1] = v;
v_dot_body_v[2] = w;
}
// inline double * get_A_cg_body_v() { return a_cg_body_v; }
inline double get_A_X_cg() const { return a_cg_body_v[0]; }
inline double get_A_Y_cg() const { return a_cg_body_v[1]; }
inline double get_A_Z_cg() const { return a_cg_body_v[2]; }
inline void set_Accels_CG_Body( double x, double y, double z ) {
a_cg_body_v[0] = x;
a_cg_body_v[1] = y;
a_cg_body_v[2] = z;
}
// inline double * get_A_pilot_body_v() { return a_pilot_body_v; }
inline double get_A_X_pilot() const { return a_pilot_body_v[0]; }
inline double get_A_Y_pilot() const { return a_pilot_body_v[1]; }
inline double get_A_Z_pilot() const { return a_pilot_body_v[2]; }
inline void set_Accels_Pilot_Body( double x, double y, double z ) {
a_pilot_body_v[0] = x;
a_pilot_body_v[1] = y;
a_pilot_body_v[2] = z;
}
// inline double * get_N_cg_body_v() { return n_cg_body_v; }
inline double get_N_X_cg() const { return n_cg_body_v[0]; }
inline double get_N_Y_cg() const { return n_cg_body_v[1]; }
inline double get_N_Z_cg() const { return n_cg_body_v[2]; }
inline void set_Accels_CG_Body_N( double x, double y, double z ) {
n_cg_body_v[0] = x;
n_cg_body_v[1] = y;
n_cg_body_v[2] = z;
}
// inline double * get_N_pilot_body_v() { return n_pilot_body_v; }
// inline double get_N_X_pilot() const { return n_pilot_body_v[0]; }
@ -483,8 +648,7 @@ public:
// n_pilot_body_v[2] = z;
// }
double get_Nlf(void) { return nlf; }
void set_Nlf(double n) { nlf=n; }
inline double get_Nlf(void) { return nlf; }
// inline double * get_Omega_dot_body_v() { return omega_dot_body_v; }
// inline double get_P_dot_body() const { return omega_dot_body_v[0]; }
@ -503,41 +667,24 @@ public:
inline double get_V_north() const { return v_local_v[0]; }
inline double get_V_east() const { return v_local_v[1]; }
inline double get_V_down() const { return v_local_v[2]; }
inline void set_Velocities_Local( double north, double east, double down ) {
v_local_v[0] = north;
v_local_v[1] = east;
v_local_v[2] = down;
}
// inline double * get_V_local_rel_ground_v() {
// return v_local_rel_ground_v;
// }
inline double get_V_north_rel_ground() const {
return v_local_rel_ground_v[0];
}
inline double get_V_east_rel_ground() const {
return v_local_rel_ground_v[1];
}
inline double get_V_down_rel_ground() const {
return v_local_rel_ground_v[2];
}
inline void set_Velocities_Ground(double north, double east, double down) {
v_local_rel_ground_v[0] = north;
v_local_rel_ground_v[1] = east;
v_local_rel_ground_v[2] = down;
}
// inline double get_V_north_rel_ground() const {
// return v_local_rel_ground_v[0];
// }
// inline double get_V_east_rel_ground() const {
// return v_local_rel_ground_v[1];
// }
// inline double get_V_down_rel_ground() const {
// return v_local_rel_ground_v[2];
// }
// inline double * get_V_local_airmass_v() { return v_local_airmass_v; }
inline double get_V_north_airmass() const { return v_local_airmass_v[0]; }
inline double get_V_east_airmass() const { return v_local_airmass_v[1]; }
inline double get_V_down_airmass() const { return v_local_airmass_v[2]; }
inline void set_Velocities_Local_Airmass( double north, double east,
double down)
{
v_local_airmass_v[0] = north;
v_local_airmass_v[1] = east;
v_local_airmass_v[2] = down;
}
// airmass
// inline double * get_V_local_rel_airmass_v() {
@ -575,11 +722,6 @@ public:
inline double get_U_body() const { return v_wind_body_v[0]; }
inline double get_V_body() const { return v_wind_body_v[1]; }
inline double get_W_body() const { return v_wind_body_v[2]; }
inline void set_Velocities_Wind_Body( double u, double v, double w) {
v_wind_body_v[0] = u;
v_wind_body_v[1] = v;
v_wind_body_v[2] = w;
}
// inline double get_V_rel_wind() const { return v_rel_wind; }
// inline void set_V_rel_wind(double wind) { v_rel_wind = wind; }
@ -594,29 +736,21 @@ public:
// inline void set_V_inertial(double v) { v_inertial = v; }
inline double get_V_ground_speed() const { return v_ground_speed; }
inline void set_V_ground_speed( double v) { v_ground_speed = v; }
// inline double get_V_equiv() const { return v_equiv; }
// inline void set_V_equiv( double v ) { v_equiv = v; }
inline double get_V_equiv_kts() const { return v_equiv_kts; }
inline void set_V_equiv_kts( double kts ) { v_equiv_kts = kts; }
//inline double get_V_calibrated() const { return v_calibrated; }
//inline void set_V_calibrated( double v ) { v_calibrated = v; }
inline double get_V_calibrated_kts() const { return v_calibrated_kts; }
inline void set_V_calibrated_kts( double kts ) { v_calibrated_kts = kts; }
// inline double * get_Omega_body_v() { return omega_body_v; }
inline double get_P_body() const { return omega_body_v[0]; }
inline double get_Q_body() const { return omega_body_v[1]; }
inline double get_R_body() const { return omega_body_v[2]; }
inline void set_Omega_Body( double p, double q, double r ) {
omega_body_v[0] = p;
omega_body_v[1] = q;
omega_body_v[2] = r;
}
// inline double * get_Omega_local_v() { return omega_local_v; }
// inline double get_P_local() const { return omega_local_v[0]; }
@ -642,21 +776,11 @@ public:
inline double get_Phi_dot() const { return euler_rates_v[0]; }
inline double get_Theta_dot() const { return euler_rates_v[1]; }
inline double get_Psi_dot() const { return euler_rates_v[2]; }
inline void set_Euler_Rates( double phi, double theta, double psi ) {
euler_rates_v[0] = phi;
euler_rates_v[1] = theta;
euler_rates_v[2] = psi;
}
// inline double * get_Geocentric_rates_v() { return geocentric_rates_v; }
inline double get_Latitude_dot() const { return geocentric_rates_v[0]; }
inline double get_Longitude_dot() const { return geocentric_rates_v[1]; }
inline double get_Radius_dot() const { return geocentric_rates_v[2]; }
inline void set_Geocentric_Rates( double lat, double lon, double rad ) {
geocentric_rates_v[0] = lat;
geocentric_rates_v[1] = lon;
geocentric_rates_v[2] = rad;
}
// ========== Positions ==========
@ -672,40 +796,17 @@ public:
inline double get_Radius_to_vehicle() const {
return geocentric_position_v[2];
}
inline void set_Radius_to_vehicle(double radius) {
geocentric_position_v[2] = radius;
}
inline void set_Geocentric_Position( double lat, double lon, double rad ) {
geocentric_position_v[0] = lat;
geocentric_position_v[1] = lon;
geocentric_position_v[2] = rad;
}
// inline double * get_Geodetic_position_v() { return geodetic_position_v; }
inline double get_Latitude() const { return geodetic_position_v[0]; }
inline void set_Latitude(double lat) { geodetic_position_v[0] = lat; }
inline double get_Longitude() const { return geodetic_position_v[1]; }
inline void set_Longitude(double lon) { geodetic_position_v[1] = lon; }
inline double get_Altitude() const { return geodetic_position_v[2]; }
inline void set_Altitude(double altitude) {
geodetic_position_v[2] = altitude;
}
inline void set_Geodetic_Position( double lat, double lon, double alt ) {
geodetic_position_v[0] = lat;
geodetic_position_v[1] = lon;
geodetic_position_v[2] = alt;
}
inline double get_Altitude_AGL(void) { return altitude_agl; }
// inline double * get_Euler_angles_v() { return euler_angles_v; }
inline double get_Phi() const { return euler_angles_v[0]; }
inline double get_Theta() const { return euler_angles_v[1]; }
inline double get_Psi() const { return euler_angles_v[2]; }
inline void set_Euler_Angles( double phi, double theta, double psi ) {
euler_angles_v[0] = phi;
euler_angles_v[1] = theta;
euler_angles_v[2] = psi;
}
// ========== Miscellaneous quantities ==========
@ -738,17 +839,6 @@ public:
inline double get_T_local_to_body_33() const {
return t_local_to_body_m[2][2];
}
inline void set_T_Local_to_Body( int i, int j, double value) {
t_local_to_body_m[i-1][j-1] = value;
}
inline void set_T_Local_to_Body( double m[3][3] ) {
int i, j;
for ( i = 0; i < 3; i++ ) {
for ( j = 0; j < 3; j++ ) {
t_local_to_body_m[i][j] = m[i][j];
}
}
}
// inline double get_Gravity() const { return gravity; }
// inline void set_Gravity(double g) { gravity = g; }
@ -761,9 +851,7 @@ public:
// }
inline double get_Alpha() const { return alpha; }
inline void set_Alpha( double a ) { alpha = a; }
inline double get_Beta() const { return beta; }
inline void set_Beta( double b ) { beta = b; }
// inline double get_Alpha_dot() const { return alpha_dot; }
// inline void set_Alpha_dot( double ad ) { alpha_dot = ad; }
// inline double get_Beta_dot() const { return beta_dot; }
@ -779,11 +867,9 @@ public:
// inline void set_Sin_beta( double sb ) { sin_beta = sb; }
inline double get_Cos_phi() const { return cos_phi; }
inline void set_Cos_phi( double cp ) { cos_phi = cp; }
// inline double get_Sin_phi() const { return sin_phi; }
// inline void set_Sin_phi( double sp ) { sin_phi = sp; }
inline double get_Cos_theta() const { return cos_theta; }
inline void set_Cos_theta( double ct ) { cos_theta = ct; }
// inline double get_Sin_theta() const { return sin_theta; }
// inline void set_Sin_theta( double st ) { sin_theta = st; }
// inline double get_Cos_psi() const { return cos_psi; }
@ -792,21 +878,17 @@ public:
// inline void set_Sin_psi( double sp ) { sin_psi = sp; }
inline double get_Gamma_vert_rad() const { return gamma_vert_rad; }
inline void set_Gamma_vert_rad( double gv ) { gamma_vert_rad = gv; }
// inline double get_Gamma_horiz_rad() const { return gamma_horiz_rad; }
// inline void set_Gamma_horiz_rad( double gh ) { gamma_horiz_rad = gh; }
// inline double get_Sigma() const { return sigma; }
// inline void set_Sigma( double s ) { sigma = s; }
inline double get_Density() const { return density; }
inline void set_Density( double d ) { density = d; }
// inline double get_V_sound() const { return v_sound; }
// inline void set_V_sound( double v ) { v_sound = v; }
inline double get_Mach_number() const { return mach_number; }
inline void set_Mach_number( double m ) { mach_number = m; }
inline double get_Static_pressure() const { return static_pressure; }
inline void set_Static_pressure( double sp ) { static_pressure = sp; }
// inline double get_Total_pressure() const { return total_pressure; }
// inline void set_Total_pressure( double tp ) { total_pressure = tp; }
// inline double get_Impact_pressure() const { return impact_pressure; }
@ -815,21 +897,15 @@ public:
// inline void set_Dynamic_pressure( double dp ) { dynamic_pressure = dp; }
inline double get_Static_temperature() const { return static_temperature; }
inline void set_Static_temperature( double t ) { static_temperature = t; }
// inline double get_Total_temperature() const { return total_temperature; }
// inline void set_Total_temperature( double t ) { total_temperature = t; }
inline double get_Sea_level_radius() const { return sea_level_radius; }
inline void set_Sea_level_radius( double r ) { sea_level_radius = r; }
inline double get_Earth_position_angle() const {
return earth_position_angle;
}
inline void set_Earth_position_angle(double a) {
earth_position_angle = a;
}
inline double get_Runway_altitude() const { return runway_altitude; }
inline void set_Runway_altitude( double alt ) { runway_altitude = alt; }
// inline double get_Runway_latitude() const { return runway_latitude; }
// inline void set_Runway_latitude( double lat ) { runway_latitude = lat; }
// inline double get_Runway_longitude() const { return runway_longitude; }
@ -897,7 +973,6 @@ public:
} */
inline double get_Climb_Rate() const { return climb_rate; }
inline void set_Climb_Rate(double rate) { climb_rate = rate; }
inline FGTimeStamp get_time_stamp() const { return valid_stamp; }
inline void stamp_time() { valid_stamp = next_stamp; next_stamp.stamp(); }
@ -906,12 +981,6 @@ public:
void extrapolate( int time_offset );
// sin/cos lat_geocentric
inline void set_sin_lat_geocentric(double parm) {
sin_lat_geocentric = sin(parm);
}
inline void set_cos_lat_geocentric(double parm) {
cos_lat_geocentric = cos(parm);
}
inline double get_sin_lat_geocentric(void) const {
return sin_lat_geocentric;
}
@ -919,10 +988,6 @@ public:
return cos_lat_geocentric;
}
inline void set_sin_cos_longitude(double parm) {
sin_longitude = sin(parm);
cos_longitude = cos(parm);
}
inline double get_sin_longitude(void) const {
return sin_longitude;
}
@ -930,10 +995,6 @@ public:
return cos_longitude;
}
inline void set_sin_cos_latitude(double parm) {
sin_latitude = sin(parm);
cos_latitude = cos(parm);
}
inline double get_sin_latitude(void) const {
return sin_latitude;
}

View file

@ -768,7 +768,6 @@ void
FGBFI::setSpeedNorth (double speed)
{
if (getSpeedNorth() != speed) {
globals->get_options()->set_uBody(speed);
current_aircraft.fdm_state->set_Velocities_Local(speed,
getSpeedEast(),
getSpeedDown());
@ -794,7 +793,6 @@ void
FGBFI::setSpeedEast (double speed)
{
if (getSpeedEast() != speed) {
globals->get_options()->set_vBody(speed);
current_aircraft.fdm_state->set_Velocities_Local(getSpeedNorth(),
speed,
getSpeedDown());
@ -820,7 +818,6 @@ void
FGBFI::setSpeedDown (double speed)
{
if (getSpeedDown() != speed) {
globals->get_options()->set_wBody(speed);
current_aircraft.fdm_state->set_Velocities_Local(getSpeedNorth(),
getSpeedEast(),
speed);

View file

@ -342,8 +342,8 @@ bool fgInitPosition( void ) {
"starting altitude is = " << globals->get_options()->get_altitude() );
f->set_Altitude( globals->get_options()->get_altitude() * METER_TO_FEET );
fgFDMSetGroundElevation( globals->get_options()->get_flight_model(),
f->get_Altitude() * FEET_TO_METER );
// fgFDMSetGroundElevation( globals->get_options()->get_flight_model(),
// f->get_Altitude() * FEET_TO_METER );
#if 0
current_properties.setDoubleValue("/position/longitude",
@ -404,6 +404,36 @@ bool fgInitGeneral( void ) {
}
// set initial aircraft speed
bool fgVelocityInit( void ) {
switch(globals->get_options()->get_speedset()) {
case 1: //FG_VC
current_aircraft.fdm_state->set_V_calibrated_kts(
globals->get_options()->get_vc() );
break;
case 2: //FG_MACH
current_aircraft.fdm_state->set_Mach_number(
globals->get_options()->get_mach() );
break;
case 3: //FG_VTUVW
current_aircraft.fdm_state->set_Velocities_Wind_Body(
globals->get_options()->get_uBody(),
globals->get_options()->get_vBody(),
globals->get_options()->get_wBody() );
break;
case 4: //FG_VTNED
current_aircraft.fdm_state->set_Velocities_Local(
globals->get_options()->get_vNorth(),
globals->get_options()->get_vEast(),
globals->get_options()->get_vDown() );
break;
default:
current_aircraft.fdm_state->set_V_calibrated_kts( 0.0 );
}
return true;
}
// This is the top level init routine which calls all the other
// initialization routines. If you are adding a subsystem to flight
// gear, its initialization call should located in this routine.
@ -469,6 +499,9 @@ bool fgInitSubsystems( void ) {
// model or control parameters are set
fgAircraftInit(); // In the future this might not be the case.
fgFDMSetGroundElevation( globals->get_options()->get_flight_model(),
scenery.cur_elev );
// set the initial position
fgInitPosition();
@ -495,9 +528,6 @@ bool fgInitSubsystems( void ) {
"Altitude after update " << scenery.cur_elev );
*/
fgFDMSetGroundElevation( globals->get_options()->get_flight_model(),
scenery.cur_elev );
// Reset our altitude if we are below ground
FG_LOG( FG_GENERAL, FG_DEBUG, "Current altitude = " << cur_fdm_state->get_Altitude() );
FG_LOG( FG_GENERAL, FG_DEBUG, "Current runway altitude = " <<
@ -522,24 +552,27 @@ bool fgInitSubsystems( void ) {
// Set the FG variables first
sgGeodToGeoc( cur_fdm_state->get_Latitude(), cur_fdm_state->get_Altitude(),
&sea_level_radius_meters, &lat_geoc);
cur_fdm_state->set_Geocentric_Position( lat_geoc, cur_fdm_state->get_Longitude(),
/* cur_fdm_state->set_Geocentric_Position( lat_geoc, cur_fdm_state->get_Longitude(),
cur_fdm_state->get_Altitude() +
(sea_level_radius_meters * METER_TO_FEET) );
*/
cur_fdm_state->set_Sea_level_radius( sea_level_radius_meters * METER_TO_FEET );
cur_fdm_state->set_sin_cos_longitude(cur_fdm_state->get_Longitude());
/* cur_fdm_state->set_sin_cos_longitude(cur_fdm_state->get_Longitude());
cur_fdm_state->set_sin_cos_latitude(cur_fdm_state->get_Latitude());
cur_fdm_state->set_sin_lat_geocentric(sin(lat_geoc));
cur_fdm_state->set_cos_lat_geocentric(cos(lat_geoc));
cur_fdm_state->set_cos_lat_geocentric(cos(lat_geoc)); */
// The following section sets up the flight model EOM parameters
// and should really be read in from one or more files.
// Initial Velocity
cur_fdm_state->set_Velocities_Local( globals->get_options()->get_uBody(),
globals->get_options()->get_vBody(),
globals->get_options()->get_wBody());
//cur_fdm_state->set_Velocities_Local( globals->get_options()->get_uBody(),
// globals->get_options()->get_vBody(),
// globals->get_options()->get_wBody());
fgVelocityInit();
// Initial Orientation
cur_fdm_state->set_Euler_Angles( globals->get_options()->get_roll() * DEG_TO_RAD,
@ -547,16 +580,16 @@ bool fgInitSubsystems( void ) {
globals->get_options()->get_heading() * DEG_TO_RAD );
// Initial Angular Body rates
cur_fdm_state->set_Omega_Body( 7.206685E-05, 0.0, 9.492658E-05 );
//cur_fdm_state->set_Omega_Body( 7.206685E-05, 0.0, 9.492658E-05 );
cur_fdm_state->set_Earth_position_angle( 0.0 );
//cur_fdm_state->set_Earth_position_angle( 0.0 );
// Mass properties and geometry values
cur_fdm_state->set_Inertias( 8.547270E+01,
1.048000E+03, 3.000000E+03, 3.530000E+03, 0.000000E+00 );
//cur_fdm_state->set_Inertias( 8.547270E+01,
// 1.048000E+03, 3.000000E+03, 3.530000E+03, 0.000000E+00 );
// CG position w.r.t. ref. point
cur_fdm_state->set_CG_Position( 0.0, 0.0, 0.0 );
//cur_fdm_state->set_CG_Position( 0.0, 0.0, 0.0 );
// Initialize the event manager
global_events.Init();
@ -805,24 +838,26 @@ void fgReInitSubsystems( void )
// Set the FG variables first
sgGeodToGeoc( cur_fdm_state->get_Latitude(), cur_fdm_state->get_Altitude(),
&sea_level_radius_meters, &lat_geoc);
cur_fdm_state->set_Geocentric_Position( lat_geoc, cur_fdm_state->get_Longitude(),
/* cur_fdm_state->set_Geocentric_Position( lat_geoc, cur_fdm_state->get_Longitude(),
cur_fdm_state->get_Altitude() +
(sea_level_radius_meters * METER_TO_FEET) );
*/
cur_fdm_state->set_Sea_level_radius( sea_level_radius_meters * METER_TO_FEET );
cur_fdm_state->set_sin_cos_longitude(cur_fdm_state->get_Longitude());
cur_fdm_state->set_sin_cos_latitude(cur_fdm_state->get_Latitude());
//cur_fdm_state->set_sin_cos_longitude(cur_fdm_state->get_Longitude());
//cur_fdm_state->set_sin_cos_latitude(cur_fdm_state->get_Latitude());
cur_fdm_state->set_sin_lat_geocentric(sin(lat_geoc));
cur_fdm_state->set_cos_lat_geocentric(cos(lat_geoc));
//cur_fdm_state->set_sin_lat_geocentric(sin(lat_geoc));
//cur_fdm_state->set_cos_lat_geocentric(cos(lat_geoc));
// The following section sets up the flight model EOM parameters
// and should really be read in from one or more files.
// Initial Velocity
cur_fdm_state->set_Velocities_Local( globals->get_options()->get_uBody(),
globals->get_options()->get_vBody(),
globals->get_options()->get_wBody());
//cur_fdm_state->set_Velocities_Local( globals->get_options()->get_uBody(),
// globals->get_options()->get_vBody(),
// globals->get_options()->get_wBody());
fgVelocityInit();
// Initial Orientation
cur_fdm_state->set_Euler_Angles( globals->get_options()->get_roll() * DEG_TO_RAD,
@ -830,16 +865,16 @@ void fgReInitSubsystems( void )
globals->get_options()->get_heading() * DEG_TO_RAD );
// Initial Angular Body rates
cur_fdm_state->set_Omega_Body( 7.206685E-05, 0.0, 9.492658E-05 );
//cur_fdm_state->set_Omega_Body( 7.206685E-05, 0.0, 9.492658E-05 );
cur_fdm_state->set_Earth_position_angle( 0.0 );
//cur_fdm_state->set_Earth_position_angle( 0.0 );
// Mass properties and geometry values
cur_fdm_state->set_Inertias( 8.547270E+01,
1.048000E+03, 3.000000E+03, 3.530000E+03, 0.000000E+00 );
//cur_fdm_state->set_Inertias( 8.547270E+01,
// 1.048000E+03, 3.000000E+03, 3.530000E+03, 0.000000E+00 );
// CG position w.r.t. ref. point
cur_fdm_state->set_CG_Position( 0.0, 0.0, 0.0 );
//cur_fdm_state->set_CG_Position( 0.0, 0.0, 0.0 );
// Initialize view parameters
globals->get_current_view()->set_view_offset( 0.0 );

View file

@ -829,8 +829,8 @@ static void fgMainLoop( void ) {
<< cur_fdm_state->get_Altitude() * FEET_TO_METER
<< " meters" );
}
fgFDMSetGroundElevation( globals->get_options()->get_flight_model(),
scenery.cur_elev ); // meters
//fgFDMSetGroundElevation( globals->get_options()->get_flight_model(),
// scenery.cur_elev ); // meters
}
/* printf("Adjustment - ground = %.2f runway = %.2f alt = %.2f\n",

View file

@ -150,7 +150,10 @@ FGOptions::FGOptions() :
pitch(0.424), // pitch angle in degrees (Theta)
// Initialize current options velocities to 0.0
uBody(0.0), vBody(0.0), wBody(0.0), vkcas(0.0), mach(0.0),
speedset(FG_VC),
uBody(0.0), vBody(0.0), wBody(0.0),
vNorth(0.0),vEast(0.0), vDown(0.0),
vkcas(0.0), mach(0.0),
// Miscellaneous
game_mode(0),
@ -696,35 +699,58 @@ int FGOptions::parse_option( const string& arg ) {
}
current_properties.setDoubleValue("/position/altitude", altitude);
} else if ( arg.find( "--uBody=" ) != string::npos ) {
vkcas=mach=-1;
speedset = FG_VTUVW;
if ( units == FG_UNITS_FEET ) {
uBody = atof( arg.substr(8) );
} else {
uBody = atof( arg.substr(8) ) * FEET_TO_METER;
}
current_properties.setDoubleValue("/velocities/speed-north", uBody);
//current_properties.setDoubleValue("/velocities/speed-north", uBody);
} else if ( arg.find( "--vBody=" ) != string::npos ) {
vkcas=mach=-1;
speedset = FG_VTUVW;
if ( units == FG_UNITS_FEET ) {
vBody = atof( arg.substr(8) );
} else {
vBody = atof( arg.substr(8) ) * FEET_TO_METER;
}
current_properties.setDoubleValue("/velocities/speed-east", vBody);
//current_properties.setDoubleValue("/velocities/speed-east", vBody);
} else if ( arg.find( "--wBody=" ) != string::npos ) {
vkcas=mach=-1;
speedset = FG_VTUVW;
if ( units == FG_UNITS_FEET ) {
wBody = atof( arg.substr(8) );
} else {
wBody = atof( arg.substr(8) ) * FEET_TO_METER;
}
current_properties.setDoubleValue("/velocities/speed-down", wBody);
} else if ( arg.find( "--vNorth=" ) != string::npos ) {
speedset = FG_VTNED;
if ( units == FG_UNITS_FEET ) {
vNorth = atof( arg.substr(9) );
} else {
vNorth = atof( arg.substr(9) ) * FEET_TO_METER;
}
current_properties.setDoubleValue("/velocities/speed-north", vNorth);
} else if ( arg.find( "--vEast=" ) != string::npos ) {
speedset = FG_VTNED;
if ( units == FG_UNITS_FEET ) {
vEast = atof( arg.substr(8) );
} else {
vEast = atof( arg.substr(8) ) * FEET_TO_METER;
}
current_properties.setDoubleValue("/velocities/speed-east", vEast);
} else if ( arg.find( "--vDown=" ) != string::npos ) {
speedset = FG_VTNED;
if ( units == FG_UNITS_FEET ) {
vDown = atof( arg.substr(8) );
} else {
vDown = atof( arg.substr(8) ) * FEET_TO_METER;
}
current_properties.setDoubleValue("/velocities/speed-down", vDown);
} else if ( arg.find( "--vc=" ) != string::npos) {
mach=-1;
speedset = FG_VC;
vkcas=atof( arg.substr(5) );
cout << "Got vc: " << vkcas << endl;
} else if ( arg.find( "--mach=" ) != string::npos) {
vkcas=-1;
speedset = FG_MACH;
mach=atof( arg.substr(7) );
} else if ( arg.find( "--heading=" ) != string::npos ) {
heading = atof( arg.substr(10) );
@ -926,7 +952,6 @@ int FGOptions::parse_option( const string& arg ) {
// just that.
int FGOptions::scan_command_line_for_root( int argc, char **argv ) {
int i = 1;
int result;
FG_LOG(FG_GENERAL, FG_INFO, "Processing command line arguments");

View file

@ -122,6 +122,13 @@ public:
FG_TIME_GMT_ABSOLUTE = 4,
FG_TIME_LAT_ABSOLUTE = 5
};
enum fgSpeedSet {
FG_VC = 1,
FG_MACH = 2,
FG_VTUVW = 3,
FG_VTNED = 4
};
private:
@ -139,9 +146,13 @@ private:
double heading; // heading (yaw) angle in degress (Psi)
double roll; // roll angle in degrees (Phi)
double pitch; // pitch angle in degrees (Theta)
fgSpeedSet speedset; // which speed does the user want
double uBody; // Body axis X velocity (U)
double vBody; // Body axis Y velocity (V)
double wBody; // Body axis Z velocity (W)
double vNorth; // North component of vt
double vEast; // East component of vt
double vDown; // Down component of vt
double vkcas; // Calibrated airspeed, knots
double mach; // Mach number
@ -245,9 +256,13 @@ public:
inline double get_heading() const { return heading; }
inline double get_roll() const { return roll; }
inline double get_pitch() const { return pitch; }
inline fgSpeedSet get_speedset() const { return speedset; }
inline double get_uBody() const {return uBody;}
inline double get_vBody() const {return vBody;}
inline double get_wBody() const {return wBody;}
inline double get_vNorth() const {return vNorth;}
inline double get_vEast() const {return vEast;}
inline double get_vDown() const {return vDown;}
inline double get_vc() const {return vkcas;}
inline double get_mach() const {return mach;}

View file

@ -268,6 +268,7 @@ bool FGGarmin::parse_message() {
cur_fdm_state->set_Longitude( lon * DEG_TO_RAD );
FG_LOG( FG_IO, FG_INFO, " lon = " << lon );
#if 0
double sl_radius, lat_geoc;
sgGeodToGeoc( cur_fdm_state->get_Latitude(),
cur_fdm_state->get_Altitude(),
@ -275,6 +276,7 @@ bool FGGarmin::parse_message() {
cur_fdm_state->set_Geocentric_Position( lat_geoc,
cur_fdm_state->get_Longitude(),
sl_radius + cur_fdm_state->get_Altitude() );
#endif
// speed
end = msg.find(",", begin);
@ -285,8 +287,8 @@ bool FGGarmin::parse_message() {
string speed_str = msg.substr(begin, end - begin);
begin = end + 1;
speed = atof( speed_str.c_str() );
cur_fdm_state->set_V_equiv_kts( speed );
cur_fdm_state->set_V_ground_speed( speed );
cur_fdm_state->set_V_calibrated_kts( speed );
// cur_fdm_state->set_V_ground_speed( speed );
FG_LOG( FG_IO, FG_INFO, " speed = " << speed );
// heading

View file

@ -273,6 +273,7 @@ bool FGNMEA::parse_message() {
cur_fdm_state->set_Longitude( lon * DEG_TO_RAD );
FG_LOG( FG_IO, FG_INFO, " lon = " << lon );
#if 0
double sl_radius, lat_geoc;
sgGeodToGeoc( cur_fdm_state->get_Latitude(),
cur_fdm_state->get_Altitude(),
@ -280,6 +281,7 @@ bool FGNMEA::parse_message() {
cur_fdm_state->set_Geocentric_Position( lat_geoc,
cur_fdm_state->get_Longitude(),
sl_radius + cur_fdm_state->get_Altitude() );
#endif
// speed
end = msg.find(",", begin);
@ -290,8 +292,8 @@ bool FGNMEA::parse_message() {
string speed_str = msg.substr(begin, end - begin);
begin = end + 1;
speed = atof( speed_str.c_str() );
cur_fdm_state->set_V_equiv_kts( speed );
cur_fdm_state->set_V_ground_speed( speed );
cur_fdm_state->set_V_calibrated_kts( speed );
// cur_fdm_state->set_V_ground_speed( speed );
FG_LOG( FG_IO, FG_INFO, " speed = " << speed );
// heading

View file

@ -265,7 +265,7 @@ void fgUpdateWeatherDatabase(void)
// get the data on 'the bus' for the FDM
FGPhysicalProperty porperty = WeatherDatabase->get(position);
/* FGPhysicalProperty porperty = WeatherDatabase->get(position);
current_aircraft.fdm_state->set_Static_temperature( Kelvin2Rankine(porperty.Temperature) );
current_aircraft.fdm_state->set_Static_pressure( Pascal2psf(porperty.AirPressure) );
@ -275,7 +275,8 @@ void fgUpdateWeatherDatabase(void)
#define MSTOFPS 3.2808 //m/s to ft/s
current_aircraft.fdm_state->set_Velocities_Local_Airmass(porperty.Wind[1]*MSTOFPS,
porperty.Wind[0]*MSTOFPS,
porperty.Wind[2]*MSTOFPS);
porperty.Wind[2]*MSTOFPS); */
}