From 948aa70af78626584042b70fdf3c3babfb5aa804 Mon Sep 17 00:00:00 2001 From: James Turner Date: Thu, 18 Jul 2013 12:01:36 +0100 Subject: [PATCH] Fix native protocol crashes. As part of this, kill off the evil global FDM state, and avoid us copying FGInterfaces (which is bad since it contains TiedProperties and an FGGroundCache, neither of which are especially keen on being copied). Will probably disable copy/assignment on TiedProperties in a future commit. --- src/FDM/fdm_shell.cxx | 13 +- src/FDM/fdm_shell.hxx | 1 + src/FDM/flight.cxx | 257 +++++++++++++---------- src/FDM/flight.hxx | 455 +++++++++++++++++++++-------------------- src/Network/native.cxx | 45 ++-- src/Network/native.hxx | 9 +- 6 files changed, 405 insertions(+), 375 deletions(-) diff --git a/src/FDM/fdm_shell.cxx b/src/FDM/fdm_shell.cxx index ac6466ade..21a3b79df 100644 --- a/src/FDM/fdm_shell.cxx +++ b/src/FDM/fdm_shell.cxx @@ -59,12 +59,6 @@ #include #endif -/* - * Evil global variable required by Network/FGNative, - * see that class for more information - */ -FGInterface* evil_global_fdm_state = NULL; - FDMShell::FDMShell() : _tankProperties( fgGetNode("/consumables/fuel", true) ), _impl(NULL), @@ -99,7 +93,6 @@ void FDMShell::reinit() { if (_impl) { fgSetBool("/sim/fdm-initialized", false); - evil_global_fdm_state = NULL; _impl->unbind(); delete _impl; _impl = NULL; @@ -146,7 +139,6 @@ void FDMShell::update(double dt) } _impl->bind(); - evil_global_fdm_state = _impl; fgSetBool("/sim/fdm-initialized", true); fgSetBool("/sim/signals/fdm-initialized", true); } @@ -196,6 +188,11 @@ void FDMShell::update(double dt) } } +FGInterface* FDMShell::getInterface() const +{ + return _impl; +} + void FDMShell::createImplementation() { assert(!_impl); diff --git a/src/FDM/fdm_shell.hxx b/src/FDM/fdm_shell.hxx index 3979067e1..9beb293e1 100644 --- a/src/FDM/fdm_shell.hxx +++ b/src/FDM/fdm_shell.hxx @@ -51,6 +51,7 @@ public: virtual void update(double dt); + FGInterface* getInterface() const; private: void createImplementation(); diff --git a/src/FDM/flight.cxx b/src/FDM/flight.cxx index c65a009a6..ccef14e0b 100644 --- a/src/FDM/flight.cxx +++ b/src/FDM/flight.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include #include
@@ -88,39 +89,40 @@ FGInterface::_setup () inited = false; bound = false; - d_cg_rp_body_v = SGVec3d::zeros(); - v_dot_local_v = SGVec3d::zeros(); - v_dot_body_v = SGVec3d::zeros(); - a_cg_body_v = SGVec3d::zeros(); - a_pilot_body_v = SGVec3d::zeros(); - n_cg_body_v = SGVec3d::zeros(); - v_local_v = SGVec3d::zeros(); - v_local_rel_ground_v = SGVec3d::zeros(); - v_local_airmass_v = SGVec3d::zeros(); - v_wind_body_v = SGVec3d::zeros(); - omega_body_v = SGVec3d::zeros(); - euler_rates_v = SGVec3d::zeros(); - geocentric_rates_v = SGVec3d::zeros(); - geodetic_position_v = SGGeod::fromRadM(0, 0, 0); - cartesian_position_v = SGVec3d::fromGeod(geodetic_position_v); - geocentric_position_v = SGGeoc::fromCart(cartesian_position_v); - euler_angles_v = SGVec3d::zeros(); + _state.d_cg_rp_body_v = SGVec3d::zeros(); + _state.v_dot_local_v = SGVec3d::zeros(); + _state.v_dot_body_v = SGVec3d::zeros(); + _state.a_cg_body_v = SGVec3d::zeros(); + _state.a_pilot_body_v = SGVec3d::zeros(); + _state.n_cg_body_v = SGVec3d::zeros(); + _state.v_local_v = SGVec3d::zeros(); + _state.v_local_rel_ground_v = SGVec3d::zeros(); + _state.v_local_airmass_v = SGVec3d::zeros(); + _state.v_wind_body_v = SGVec3d::zeros(); + _state.omega_body_v = SGVec3d::zeros(); + _state.euler_rates_v = SGVec3d::zeros(); + _state.geocentric_rates_v = SGVec3d::zeros(); + _state.geodetic_position_v = SGGeod::fromRadM(0, 0, 0); + _state.cartesian_position_v = SGVec3d::fromGeod(_state.geodetic_position_v); + _state.geocentric_position_v = SGGeoc::fromCart(_state.cartesian_position_v); + _state.euler_angles_v = SGVec3d::zeros(); + + _state.nlf=0; + _state.v_rel_wind=_state.v_true_kts=0; + _state.v_ground_speed=_state.v_equiv_kts=0; + _state.v_calibrated_kts=0; + _state.alpha=_state.beta=0; + _state.gamma_vert_rad=0; + _state.density=_state.mach_number=0; + _state.static_pressure=_state.total_pressure=0; + _state.dynamic_pressure=0; + _state.static_temperature=_state.total_temperature=0; + _state.sea_level_radius=_state.earth_position_angle=0; + _state.runway_altitude=0; + _state.climb_rate=0; + _state.altitude_agl=0; + _state.track=0; - nlf=0; - v_rel_wind=v_true_kts=0; - v_ground_speed=v_equiv_kts=0; - v_calibrated_kts=0; - alpha=beta=0; - gamma_vert_rad=0; - density=mach_number=0; - static_pressure=total_pressure=0; - dynamic_pressure=0; - static_temperature=total_temperature=0; - sea_level_radius=earth_position_angle=0; - runway_altitude=0; - climb_rate=0; - altitude_agl=0; - track=0; delta_loops = 0.0; } @@ -181,7 +183,7 @@ FGInterface::common_init () SG_LOG( SG_FLIGHT, SG_INFO, " lat = " << fgGetDouble("/sim/presets/latitude-deg") << " alt = " << get_Altitude() ); - double slr = SGGeodesy::SGGeodToSeaLevelRadius(geodetic_position_v); + double slr = SGGeodesy::SGGeodToSeaLevelRadius(_state.geodetic_position_v); _set_Sea_level_radius( slr * SG_METER_TO_FEET ); // Set initial Euler angles @@ -441,38 +443,73 @@ FGInterface::update (double dt) SG_LOG(SG_FLIGHT, SG_ALERT, "dummy update() ... SHOULDN'T BE CALLED!"); } +bool FGInterface::readState(SGIOChannel* io) +{ + FlightState buf; + int length = sizeof(FlightState); + + if ( io->get_type() == sgFileType ) { + if ( io->read( (char *)(& buf), length ) == length ) { + SG_LOG( SG_IO, SG_DEBUG, "Success reading data." ); + } else { + return false; + } + } else { + while ( io->read( (char *)(& buf), length ) == length ) { + SG_LOG( SG_IO, SG_DEBUG, "Success reading data." ); + } + } + + _state = buf; // copy the read state over + return true; +} + +bool FGInterface::writeState(SGIOChannel* io) +{ + if (!bound || !inited) { + return false; + } + + int length = sizeof(FlightState); + if ( ! io->write( (char *)(& _state), length ) ) { + SG_LOG( SG_IO, SG_ALERT, "Error writing data." ); + return false; + } + + return true; +} void FGInterface::_updatePositionM(const SGVec3d& cartPos) { - TrackComputer tracker( track, geodetic_position_v ); - cartesian_position_v = cartPos; - geodetic_position_v = SGGeod::fromCart(cartesian_position_v); - geocentric_position_v = SGGeoc::fromCart(cartesian_position_v); - _set_Sea_level_radius( SGGeodesy::SGGeodToSeaLevelRadius(geodetic_position_v)*SG_METER_TO_FEET ); + TrackComputer tracker( _state.track, _state.geodetic_position_v ); + _state.cartesian_position_v = cartPos; + _state.geodetic_position_v = SGGeod::fromCart(_state.cartesian_position_v); + _state.geocentric_position_v = SGGeoc::fromCart(_state.cartesian_position_v); + _set_Sea_level_radius( SGGeodesy::SGGeodToSeaLevelRadius(_state.geodetic_position_v)*SG_METER_TO_FEET ); _update_ground_elev_at_pos(); } void FGInterface::_updatePosition(const SGGeod& geod) { - TrackComputer tracker( track, geodetic_position_v ); - geodetic_position_v = geod; - cartesian_position_v = SGVec3d::fromGeod(geodetic_position_v); - geocentric_position_v = SGGeoc::fromCart(cartesian_position_v); + TrackComputer tracker( _state.track, _state.geodetic_position_v ); + _state.geodetic_position_v = geod; + _state.cartesian_position_v = SGVec3d::fromGeod(_state.geodetic_position_v); + _state.geocentric_position_v = SGGeoc::fromCart(_state.cartesian_position_v); - _set_Sea_level_radius( SGGeodesy::SGGeodToSeaLevelRadius(geodetic_position_v)*SG_METER_TO_FEET ); + _set_Sea_level_radius( SGGeodesy::SGGeodToSeaLevelRadius(_state.geodetic_position_v)*SG_METER_TO_FEET ); _update_ground_elev_at_pos(); } void FGInterface::_updatePosition(const SGGeoc& geoc) { - TrackComputer tracker( track, geodetic_position_v ); - geocentric_position_v = geoc; - cartesian_position_v = SGVec3d::fromGeoc(geocentric_position_v); - geodetic_position_v = SGGeod::fromCart(cartesian_position_v); + TrackComputer tracker( _state.track, _state.geodetic_position_v ); + _state.geocentric_position_v = geoc; + _state.cartesian_position_v = SGVec3d::fromGeoc(_state.geocentric_position_v); + _state.geodetic_position_v = SGGeod::fromCart(_state.cartesian_position_v); - _set_Sea_level_radius( SGGeodesy::SGGeodToSeaLevelRadius(geodetic_position_v)*SG_METER_TO_FEET ); + _set_Sea_level_radius( SGGeodesy::SGGeodToSeaLevelRadius(_state.geodetic_position_v)*SG_METER_TO_FEET ); _update_ground_elev_at_pos(); } @@ -490,123 +527,123 @@ void FGInterface::_updateGeocentricPosition( double lat, double lon, } void FGInterface::_update_ground_elev_at_pos( void ) { - double groundlevel_m = get_groundlevel_m(geodetic_position_v); + double groundlevel_m = get_groundlevel_m(_state.geodetic_position_v); _set_Runway_altitude( groundlevel_m * SG_METER_TO_FEET ); } // Positions void FGInterface::set_Latitude(double lat) { - geodetic_position_v.setLatitudeRad(lat); + _state.geodetic_position_v.setLatitudeRad(lat); } void FGInterface::set_Longitude(double lon) { - geodetic_position_v.setLongitudeRad(lon); + _state.geodetic_position_v.setLongitudeRad(lon); } void FGInterface::set_Altitude(double alt) { - geodetic_position_v.setElevationFt(alt); + _state.geodetic_position_v.setElevationFt(alt); } void FGInterface::set_AltitudeAGL(double altagl) { - altitude_agl=altagl; + _state.altitude_agl=altagl; } // Velocities void FGInterface::set_V_calibrated_kts(double vc) { - v_calibrated_kts = vc; + _state.v_calibrated_kts = vc; } void FGInterface::set_Mach_number(double mach) { - mach_number = mach; + _state.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; + _state.v_local_v[0] = north; + _state.v_local_v[1] = east; + _state.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; + _state.v_wind_body_v[0] = u; + _state.v_wind_body_v[1] = v; + _state.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; + _state.euler_angles_v[0] = phi; + _state.euler_angles_v[1] = theta; + _state.euler_angles_v[2] = psi; } // Flight Path void FGInterface::set_Climb_Rate( double roc) { - climb_rate = roc; + _state.climb_rate = roc; } void FGInterface::set_Gamma_vert_rad( double gamma) { - gamma_vert_rad = gamma; + _state.gamma_vert_rad = gamma; } -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_Static_pressure(double p) { _state.static_pressure = p; } +void FGInterface::set_Static_temperature(double T) { _state.static_temperature = T; } +void FGInterface::set_Density(double rho) { _state.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; + _state.v_local_airmass_v[0] = wnorth; + _state.v_local_airmass_v[1] = weast; + _state.v_local_airmass_v[2] = wdown; } void FGInterface::_busdump(void) { - SG_LOG(SG_FLIGHT,SG_INFO,"d_cg_rp_body_v: " << d_cg_rp_body_v); - SG_LOG(SG_FLIGHT,SG_INFO,"v_dot_local_v: " << v_dot_local_v); - SG_LOG(SG_FLIGHT,SG_INFO,"v_dot_body_v: " << v_dot_body_v); - SG_LOG(SG_FLIGHT,SG_INFO,"a_cg_body_v: " << a_cg_body_v); - SG_LOG(SG_FLIGHT,SG_INFO,"a_pilot_body_v: " << a_pilot_body_v); - SG_LOG(SG_FLIGHT,SG_INFO,"n_cg_body_v: " << n_cg_body_v); - SG_LOG(SG_FLIGHT,SG_INFO,"v_local_v: " << v_local_v); - SG_LOG(SG_FLIGHT,SG_INFO,"v_local_rel_ground_v: " << v_local_rel_ground_v); - SG_LOG(SG_FLIGHT,SG_INFO,"v_local_airmass_v: " << v_local_airmass_v); - SG_LOG(SG_FLIGHT,SG_INFO,"v_wind_body_v: " << v_wind_body_v); - SG_LOG(SG_FLIGHT,SG_INFO,"omega_body_v: " << omega_body_v); - SG_LOG(SG_FLIGHT,SG_INFO,"euler_rates_v: " << euler_rates_v); - SG_LOG(SG_FLIGHT,SG_INFO,"geocentric_rates_v: " << geocentric_rates_v); - SG_LOG(SG_FLIGHT,SG_INFO,"geocentric_position_v: " << geocentric_position_v); - SG_LOG(SG_FLIGHT,SG_INFO,"geodetic_position_v: " << geodetic_position_v); - SG_LOG(SG_FLIGHT,SG_INFO,"euler_angles_v: " << euler_angles_v); - - SG_LOG(SG_FLIGHT,SG_INFO,"nlf: " << nlf ); - SG_LOG(SG_FLIGHT,SG_INFO,"v_rel_wind: " << v_rel_wind ); - SG_LOG(SG_FLIGHT,SG_INFO,"v_true_kts: " << v_true_kts ); - SG_LOG(SG_FLIGHT,SG_INFO,"v_ground_speed: " << v_ground_speed ); - SG_LOG(SG_FLIGHT,SG_INFO,"v_equiv_kts: " << v_equiv_kts ); - SG_LOG(SG_FLIGHT,SG_INFO,"v_calibrated_kts: " << v_calibrated_kts ); - SG_LOG(SG_FLIGHT,SG_INFO,"alpha: " << alpha ); - SG_LOG(SG_FLIGHT,SG_INFO,"beta: " << beta ); - SG_LOG(SG_FLIGHT,SG_INFO,"gamma_vert_rad: " << gamma_vert_rad ); - SG_LOG(SG_FLIGHT,SG_INFO,"density: " << density ); - SG_LOG(SG_FLIGHT,SG_INFO,"mach_number: " << mach_number ); - SG_LOG(SG_FLIGHT,SG_INFO,"static_pressure: " << static_pressure ); - SG_LOG(SG_FLIGHT,SG_INFO,"total_pressure: " << total_pressure ); - SG_LOG(SG_FLIGHT,SG_INFO,"dynamic_pressure: " << dynamic_pressure ); - SG_LOG(SG_FLIGHT,SG_INFO,"static_temperature: " << static_temperature ); - SG_LOG(SG_FLIGHT,SG_INFO,"total_temperature: " << total_temperature ); - SG_LOG(SG_FLIGHT,SG_INFO,"sea_level_radius: " << sea_level_radius ); - SG_LOG(SG_FLIGHT,SG_INFO,"earth_position_angle: " << earth_position_angle ); - SG_LOG(SG_FLIGHT,SG_INFO,"runway_altitude: " << runway_altitude ); - SG_LOG(SG_FLIGHT,SG_INFO,"climb_rate: " << climb_rate ); - SG_LOG(SG_FLIGHT,SG_INFO,"altitude_agl: " << altitude_agl ); + SG_LOG(SG_FLIGHT,SG_INFO,"d_cg_rp_body_v: " << _state.d_cg_rp_body_v); + SG_LOG(SG_FLIGHT,SG_INFO,"v_dot_local_v: " << _state.v_dot_local_v); + SG_LOG(SG_FLIGHT,SG_INFO,"v_dot_body_v: " << _state.v_dot_body_v); + SG_LOG(SG_FLIGHT,SG_INFO,"a_cg_body_v: " << _state.a_cg_body_v); + SG_LOG(SG_FLIGHT,SG_INFO,"a_pilot_body_v: " << _state.a_pilot_body_v); + SG_LOG(SG_FLIGHT,SG_INFO,"n_cg_body_v: " << _state.n_cg_body_v); + SG_LOG(SG_FLIGHT,SG_INFO,"v_local_v: " << _state.v_local_v); + SG_LOG(SG_FLIGHT,SG_INFO,"v_local_rel_ground_v: " << _state.v_local_rel_ground_v); + SG_LOG(SG_FLIGHT,SG_INFO,"v_local_airmass_v: " << _state.v_local_airmass_v); + SG_LOG(SG_FLIGHT,SG_INFO,"v_wind_body_v: " << _state.v_wind_body_v); + SG_LOG(SG_FLIGHT,SG_INFO,"omega_body_v: " << _state.omega_body_v); + SG_LOG(SG_FLIGHT,SG_INFO,"euler_rates_v: " << _state.euler_rates_v); + SG_LOG(SG_FLIGHT,SG_INFO,"geocentric_rates_v: " << _state.geocentric_rates_v); + SG_LOG(SG_FLIGHT,SG_INFO,"geocentric_position_v: " << _state.geocentric_position_v); + SG_LOG(SG_FLIGHT,SG_INFO,"geodetic_position_v: " << _state.geodetic_position_v); + SG_LOG(SG_FLIGHT,SG_INFO,"euler_angles_v: " << _state.euler_angles_v); + + SG_LOG(SG_FLIGHT,SG_INFO,"nlf: " << _state.nlf ); + SG_LOG(SG_FLIGHT,SG_INFO,"v_rel_wind: " << _state.v_rel_wind ); + SG_LOG(SG_FLIGHT,SG_INFO,"v_true_kts: " << _state.v_true_kts ); + SG_LOG(SG_FLIGHT,SG_INFO,"v_ground_speed: " << _state.v_ground_speed ); + SG_LOG(SG_FLIGHT,SG_INFO,"v_equiv_kts: " << _state.v_equiv_kts ); + SG_LOG(SG_FLIGHT,SG_INFO,"v_calibrated_kts: " << _state.v_calibrated_kts ); + SG_LOG(SG_FLIGHT,SG_INFO,"alpha: " << _state.alpha ); + SG_LOG(SG_FLIGHT,SG_INFO,"beta: " << _state.beta ); + SG_LOG(SG_FLIGHT,SG_INFO,"gamma_vert_rad: " << _state.gamma_vert_rad ); + SG_LOG(SG_FLIGHT,SG_INFO,"density: " << _state.density ); + SG_LOG(SG_FLIGHT,SG_INFO,"mach_number: " << _state.mach_number ); + SG_LOG(SG_FLIGHT,SG_INFO,"static_pressure: " << _state.static_pressure ); + SG_LOG(SG_FLIGHT,SG_INFO,"total_pressure: " << _state.total_pressure ); + SG_LOG(SG_FLIGHT,SG_INFO,"dynamic_pressure: " << _state.dynamic_pressure ); + SG_LOG(SG_FLIGHT,SG_INFO,"static_temperature: " << _state.static_temperature ); + SG_LOG(SG_FLIGHT,SG_INFO,"total_temperature: " << _state.total_temperature ); + SG_LOG(SG_FLIGHT,SG_INFO,"sea_level_radius: " << _state.sea_level_radius ); + SG_LOG(SG_FLIGHT,SG_INFO,"earth_position_angle: " << _state.earth_position_angle ); + SG_LOG(SG_FLIGHT,SG_INFO,"runway_altitude: " << _state.runway_altitude ); + SG_LOG(SG_FLIGHT,SG_INFO,"climb_rate: " << _state.climb_rate ); + SG_LOG(SG_FLIGHT,SG_INFO,"altitude_agl: " << _state.altitude_agl ); } bool diff --git a/src/FDM/flight.hxx b/src/FDM/flight.hxx index bf1bf28bb..0c3a81ce2 100644 --- a/src/FDM/flight.hxx +++ b/src/FDM/flight.hxx @@ -93,6 +93,8 @@ namespace simgear { class BVHMaterial; } +class SGIOChannel; + /** * A little helper class to update the track if * the position has changed. In the constructor, @@ -134,6 +136,8 @@ private: // Have we bound to the property system bool bound; + double delta_loops; + // periodic update management variable. This is a scheme to run // the fdm with a fixed delta-t. We control how many iteration of // the fdm to run with the fixed dt based on the elapsed time from @@ -144,69 +148,79 @@ private: // next elapsed time. This yields a small amount of temporal // jitter ( < dt ) but in practice seems to work well. - // CG position w.r.t. ref. point - SGVec3d d_cg_rp_body_v; - - // Accelerations - SGVec3d v_dot_local_v; - SGVec3d v_dot_body_v; - SGVec3d a_cg_body_v; - SGVec3d a_pilot_body_v; - SGVec3d n_cg_body_v; - SGVec3d omega_dot_body_v; - - // Velocities - SGVec3d v_local_v; - SGVec3d v_local_rel_ground_v; // V rel w.r.t. earth surface - SGVec3d v_local_airmass_v; // velocity of airmass (steady winds) - SGVec3d v_wind_body_v; // Wind-relative velocities in body axis - - SGVec3d omega_body_v; // Angular B rates - SGVec3d euler_rates_v; - SGVec3d geocentric_rates_v; // Geocentric linear velocities - - // Positions - SGGeod geodetic_position_v; - SGVec3d cartesian_position_v; - SGGeoc geocentric_position_v; - SGVec3d euler_angles_v; - - // Normal Load Factor - double nlf; - - // Velocities - double v_rel_wind, v_true_kts; - double v_ground_speed, v_equiv_kts; - double v_calibrated_kts; - - // Miscellaneious Quantities - double alpha, beta; // in radians - double gamma_vert_rad; // Flight path angles - double density, mach_number; - double static_pressure, total_pressure; - double dynamic_pressure; - double static_temperature, total_temperature; - double sea_level_radius, earth_position_angle; - double runway_altitude; - double climb_rate; // in feet per second - double altitude_agl; - double track; - double delta_loops; - + /** + * encapsulate primary flight state. This is packaged so it can be + * (unfortunately) sent directly over the wire by the 'native' FDM + * protocol. + */ + struct FlightState + { + // CG position w.r.t. ref. point + SGVec3d d_cg_rp_body_v; + + // Accelerations + SGVec3d v_dot_local_v; + SGVec3d v_dot_body_v; + SGVec3d a_cg_body_v; + SGVec3d a_pilot_body_v; + SGVec3d n_cg_body_v; + SGVec3d omega_dot_body_v; + + // Velocities + SGVec3d v_local_v; + SGVec3d v_local_rel_ground_v; // V rel w.r.t. earth surface + SGVec3d v_local_airmass_v; // velocity of airmass (steady winds) + SGVec3d v_wind_body_v; // Wind-relative velocities in body axis + + SGVec3d omega_body_v; // Angular B rates + SGVec3d euler_rates_v; + SGVec3d geocentric_rates_v; // Geocentric linear velocities + + // Positions + SGGeod geodetic_position_v; + SGVec3d cartesian_position_v; + SGGeoc geocentric_position_v; + SGVec3d euler_angles_v; + + // Normal Load Factor + double nlf; + + // Velocities + double v_rel_wind, v_true_kts; + double v_ground_speed, v_equiv_kts; + double v_calibrated_kts; + + // Miscellaneious Quantities + double alpha, beta; // in radians + double gamma_vert_rad; // Flight path angles + double density, mach_number; + double static_pressure, total_pressure; + double dynamic_pressure; + double static_temperature, total_temperature; + double sea_level_radius, earth_position_angle; + double runway_altitude; + double climb_rate; // in feet per second + double altitude_agl; + double track; + }; + + FlightState _state; + simgear::TiedPropertyList _tiedProperties; // the ground cache object itself. FGGroundCache ground_cache; void set_A_X_pilot(double x) - { _set_Accels_Pilot_Body(x, a_pilot_body_v[1], a_pilot_body_v[2]); } + { _set_Accels_Pilot_Body(x, _state.a_pilot_body_v[1], _state.a_pilot_body_v[2]); } void set_A_Y_pilot(double y) - { _set_Accels_Pilot_Body(a_pilot_body_v[0], y, a_pilot_body_v[2]); } + { _set_Accels_Pilot_Body(_state.a_pilot_body_v[0], y, _state.a_pilot_body_v[2]); } void set_A_Z_pilot(double z) - { _set_Accels_Pilot_Body(a_pilot_body_v[0], a_pilot_body_v[1], z); } + { _set_Accels_Pilot_Body(_state.a_pilot_body_v[0], _state.a_pilot_body_v[1], z); } + protected: int _calc_multiloop (double dt); @@ -231,97 +245,97 @@ public: void _update_ground_elev_at_pos( void ); 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; + _state.d_cg_rp_body_v[0] = dx; + _state.d_cg_rp_body_v[1] = dy; + _state.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; + _state.v_dot_local_v[0] = north; + _state.v_dot_local_v[1] = east; + _state.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; + _state.v_dot_body_v[0] = u; + _state.v_dot_body_v[1] = v; + _state.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; + _state.a_cg_body_v[0] = x; + _state.a_cg_body_v[1] = y; + _state.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; + _state.a_pilot_body_v[0] = x; + _state.a_pilot_body_v[1] = y; + _state.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; + _state.n_cg_body_v[0] = x; + _state.n_cg_body_v[1] = y; + _state.n_cg_body_v[2] = z; } - void _set_Nlf(double n) { nlf=n; } + void _set_Nlf(double n) { _state.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; + _state.v_local_v[0] = north; + _state.v_local_v[1] = east; + _state.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; + _state.v_local_rel_ground_v[0] = north; + _state.v_local_rel_ground_v[1] = east; + _state.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; + _state.v_local_airmass_v[0] = north; + _state.v_local_airmass_v[1] = east; + _state.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_rel_wind(double vt) { v_rel_wind = vt; } - 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; } + _state.v_wind_body_v[0] = u; + _state.v_wind_body_v[1] = v; + _state.v_wind_body_v[2] = w; + } + inline void _set_V_rel_wind(double vt) { _state.v_rel_wind = vt; } + inline void _set_V_ground_speed( double v) { _state.v_ground_speed = v; } + inline void _set_V_equiv_kts( double kts ) { _state.v_equiv_kts = kts; } + inline void _set_V_calibrated_kts( double kts ) { _state.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; + _state.omega_body_v[0] = p; + _state.omega_body_v[1] = q; + _state.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; + _state.euler_rates_v[0] = phi; + _state.euler_rates_v[1] = theta; + _state.euler_rates_v[2] = psi; } void set_Phi_dot_degps(double x) { - euler_rates_v[0] = x * SG_DEGREES_TO_RADIANS; + _state.euler_rates_v[0] = x * SG_DEGREES_TO_RADIANS; } void set_Theta_dot_degps(double x) { - euler_rates_v[1] = x * SG_DEGREES_TO_RADIANS; + _state.euler_rates_v[1] = x * SG_DEGREES_TO_RADIANS; } void set_Psi_dot_degps(double x) { - euler_rates_v[2] = x * SG_DEGREES_TO_RADIANS; + _state.euler_rates_v[2] = x * SG_DEGREES_TO_RADIANS; } 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; + _state.geocentric_rates_v[0] = lat; + _state.geocentric_rates_v[1] = lon; + _state.geocentric_rates_v[2] = rad; } inline void _set_Geocentric_Position( double lat, double lon, double rad ) { - geocentric_position_v.setLatitudeRad(lat); - geocentric_position_v.setLongitudeRad(lon); - geocentric_position_v.setRadiusFt(rad); + _state.geocentric_position_v.setLatitudeRad(lat); + _state.geocentric_position_v.setLongitudeRad(lon); + _state.geocentric_position_v.setRadiusFt(rad); } /* Don't call _set_L[at|ong]itude() directly, use _set_Geodetic_Position() instead. These methods can't update the track. @@ -334,42 +348,42 @@ public: } */ inline void _set_Altitude(double altitude) { - geodetic_position_v.setElevationFt(altitude); + _state.geodetic_position_v.setElevationFt(altitude); } inline void _set_Altitude_AGL(double agl) { - altitude_agl = agl; + _state.altitude_agl = agl; } inline void _set_Geodetic_Position( double lat, double lon ) { - _set_Geodetic_Position( lat, lon, geodetic_position_v.getElevationFt()); + _set_Geodetic_Position( lat, lon, _state.geodetic_position_v.getElevationFt()); } inline void _set_Geodetic_Position( double lat, double lon, double alt ) { - TrackComputer tracker( track, geodetic_position_v ); - geodetic_position_v.setLatitudeRad(lat); - geodetic_position_v.setLongitudeRad(lon); - geodetic_position_v.setElevationFt(alt); + TrackComputer tracker( _state.track, _state.geodetic_position_v ); + _state.geodetic_position_v.setLatitudeRad(lat); + _state.geodetic_position_v.setLongitudeRad(lon); + _state.geodetic_position_v.setElevationFt(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; + _state.euler_angles_v[0] = phi; + _state.euler_angles_v[1] = theta; + _state.euler_angles_v[2] = psi; } // FIXME, for compatibility with JSBSim inline void _set_T_Local_to_Body( int i, int j, double value) { } - inline void _set_Alpha( double a ) { alpha = a; } - inline void _set_Beta( double b ) { beta = b; } + inline void _set_Alpha( double a ) { _state.alpha = a; } + inline void _set_Beta( double b ) { _state.beta = b; } - inline void set_Alpha_deg( double a ) { alpha = a * SG_DEGREES_TO_RADIANS; } + inline void set_Alpha_deg( double a ) { _state.alpha = a * SG_DEGREES_TO_RADIANS; } - 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_Total_temperature( double tat ) { total_temperature = tat; } //JW - 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_Gamma_vert_rad( double gv ) { _state.gamma_vert_rad = gv; } + inline void _set_Density( double d ) { _state.density = d; } + inline void _set_Mach_number( double m ) { _state.mach_number = m; } + inline void _set_Static_pressure( double sp ) { _state.static_pressure = sp; } + inline void _set_Static_temperature( double t ) { _state.static_temperature = t; } + inline void _set_Total_temperature( double tat ) { _state.total_temperature = tat; } //JW + inline void _set_Sea_level_radius( double r ) { _state.sea_level_radius = r; } + inline void _set_Earth_position_angle(double a) {_state.earth_position_angle = a; } + inline void _set_Runway_altitude( double alt ) { _state.runway_altitude = alt; } + inline void _set_Climb_Rate(double rate) { _state.climb_rate = rate; } public: @@ -384,6 +398,9 @@ public: virtual bool ToggleDataLogging(bool state) { return false; } virtual bool ToggleDataLogging(void) { return false; } + bool readState(SGIOChannel* io); + bool writeState(SGIOChannel* io); + // Define the various supported flight models (many not yet implemented) enum { // Magic Carpet mode @@ -439,23 +456,23 @@ public: virtual void set_Mach_number(double mach); virtual void set_Velocities_Local( double north, double east, double down ); inline void set_V_north (double north) { - set_Velocities_Local(north, v_local_v[1], v_local_v[2]); + set_Velocities_Local(north, _state.v_local_v[1], _state.v_local_v[2]); } inline void set_V_east (double east) { - set_Velocities_Local(v_local_v[0], east, v_local_v[2]); + set_Velocities_Local(_state.v_local_v[0], east, _state.v_local_v[2]); } inline void set_V_down (double down) { - set_Velocities_Local(v_local_v[0], v_local_v[1], down); + set_Velocities_Local(_state.v_local_v[0], _state.v_local_v[1], down); } virtual void set_Velocities_Wind_Body( double u, double v, double w); virtual void set_uBody (double uBody) { - set_Velocities_Wind_Body(uBody, v_wind_body_v[1], v_wind_body_v[2]); + set_Velocities_Wind_Body(uBody, _state.v_wind_body_v[1], _state.v_wind_body_v[2]); } virtual void set_vBody (double vBody) { - set_Velocities_Wind_Body(v_wind_body_v[0], vBody, v_wind_body_v[2]); + set_Velocities_Wind_Body(_state.v_wind_body_v[0], vBody, _state.v_wind_body_v[2]); } virtual void set_wBody (double wBody) { - set_Velocities_Wind_Body(v_wind_body_v[0], v_wind_body_v[1], wBody); + set_Velocities_Wind_Body(_state.v_wind_body_v[0], _state.v_wind_body_v[1], wBody); } // Euler angles @@ -496,129 +513,129 @@ public: // ========== Mass properties and geometry values ========== // CG position w.r.t. ref. point - 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 double get_Dx_cg() const { return _state.d_cg_rp_body_v[0]; } + inline double get_Dy_cg() const { return _state.d_cg_rp_body_v[1]; } + inline double get_Dz_cg() const { return _state.d_cg_rp_body_v[2]; } // ========== Accelerations ========== - 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 double get_V_dot_north() const { return _state.v_dot_local_v[0]; } + inline double get_V_dot_east() const { return _state.v_dot_local_v[1]; } + inline double get_V_dot_down() const { return _state.v_dot_local_v[2]; } - 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 double get_U_dot_body() const { return _state.v_dot_body_v[0]; } + inline double get_V_dot_body() const { return _state.v_dot_body_v[1]; } + inline double get_W_dot_body() const { return _state.v_dot_body_v[2]; } - 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 double get_A_X_cg() const { return _state.a_cg_body_v[0]; } + inline double get_A_Y_cg() const { return _state.a_cg_body_v[1]; } + inline double get_A_Z_cg() const { return _state.a_cg_body_v[2]; } - 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 double get_A_X_pilot() const { return _state.a_pilot_body_v[0]; } + inline double get_A_Y_pilot() const { return _state.a_pilot_body_v[1]; } + inline double get_A_Z_pilot() const { return _state.a_pilot_body_v[2]; } - 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 double get_N_X_cg() const { return _state.n_cg_body_v[0]; } + inline double get_N_Y_cg() const { return _state.n_cg_body_v[1]; } + inline double get_N_Z_cg() const { return _state.n_cg_body_v[2]; } - inline double get_Nlf(void) const { return nlf; } + inline double get_Nlf(void) const { return _state.nlf; } // ========== Velocities ========== - 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 double get_uBody () const { return v_wind_body_v[0]; } - inline double get_vBody () const { return v_wind_body_v[1]; } - inline double get_wBody () const { return v_wind_body_v[2]; } + inline double get_V_north() const { return _state.v_local_v[0]; } + inline double get_V_east() const { return _state.v_local_v[1]; } + inline double get_V_down() const { return _state.v_local_v[2]; } + inline double get_uBody () const { return _state.v_wind_body_v[0]; } + inline double get_vBody () const { return _state.v_wind_body_v[1]; } + inline double get_wBody () const { return _state.v_wind_body_v[2]; } // Please dont comment these out. fdm=ada uses these (see // cockpit.cxx) ---> inline double get_V_north_rel_ground() const { - return v_local_rel_ground_v[0]; + return _state.v_local_rel_ground_v[0]; } inline double get_V_east_rel_ground() const { - return v_local_rel_ground_v[1]; + return _state.v_local_rel_ground_v[1]; } inline double get_V_down_rel_ground() const { - return v_local_rel_ground_v[2]; + return _state.v_local_rel_ground_v[2]; } // <--- fdm=ada uses these (see cockpit.cxx) - 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 double get_V_north_airmass() const { return _state.v_local_airmass_v[0]; } + inline double get_V_east_airmass() const { return _state.v_local_airmass_v[1]; } + inline double get_V_down_airmass() const { return _state.v_local_airmass_v[2]; } - 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 double get_U_body() const { return _state.v_wind_body_v[0]; } + inline double get_V_body() const { return _state.v_wind_body_v[1]; } + inline double get_W_body() const { return _state.v_wind_body_v[2]; } - inline double get_V_rel_wind() const { return v_rel_wind; } + inline double get_V_rel_wind() const { return _state.v_rel_wind; } - inline double get_V_true_kts() const { return v_true_kts; } + inline double get_V_true_kts() const { return _state.v_true_kts; } - inline double get_V_ground_speed() const { return v_ground_speed; } - inline double get_V_ground_speed_kt() const { return v_ground_speed * SG_FEET_TO_METER * 3600 * SG_METER_TO_NM; } - inline void set_V_ground_speed_kt(double ground_speed) { v_ground_speed = ground_speed / ( SG_FEET_TO_METER * 3600 * SG_METER_TO_NM); } + inline double get_V_ground_speed() const { return _state.v_ground_speed; } + inline double get_V_ground_speed_kt() const { return _state.v_ground_speed * SG_FEET_TO_METER * 3600 * SG_METER_TO_NM; } + inline void set_V_ground_speed_kt(double ground_speed) { _state.v_ground_speed = ground_speed / ( SG_FEET_TO_METER * 3600 * SG_METER_TO_NM); } - inline double get_V_equiv_kts() const { return v_equiv_kts; } + inline double get_V_equiv_kts() const { return _state.v_equiv_kts; } - inline double get_V_calibrated_kts() const { return v_calibrated_kts; } + inline double get_V_calibrated_kts() const { return _state.v_calibrated_kts; } - 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 double get_P_body() const { return _state.omega_body_v[0]; } + inline double get_Q_body() const { return _state.omega_body_v[1]; } + inline double get_R_body() const { return _state.omega_body_v[2]; } - 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 double get_Phi_dot_degps() const { return euler_rates_v[0] * SGD_RADIANS_TO_DEGREES; } - inline double get_Theta_dot_degps() const { return euler_rates_v[1] * SGD_RADIANS_TO_DEGREES; } - inline double get_Psi_dot_degps() const { return euler_rates_v[2] * SGD_RADIANS_TO_DEGREES; } + inline double get_Phi_dot() const { return _state.euler_rates_v[0]; } + inline double get_Theta_dot() const { return _state.euler_rates_v[1]; } + inline double get_Psi_dot() const { return _state.euler_rates_v[2]; } + inline double get_Phi_dot_degps() const { return _state.euler_rates_v[0] * SGD_RADIANS_TO_DEGREES; } + inline double get_Theta_dot_degps() const { return _state.euler_rates_v[1] * SGD_RADIANS_TO_DEGREES; } + inline double get_Psi_dot_degps() const { return _state.euler_rates_v[2] * SGD_RADIANS_TO_DEGREES; } - 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 double get_Latitude_dot() const { return _state.geocentric_rates_v[0]; } + inline double get_Longitude_dot() const { return _state.geocentric_rates_v[1]; } + inline double get_Radius_dot() const { return _state.geocentric_rates_v[2]; } // ========== Positions ========== inline double get_Lat_geocentric() const { - return geocentric_position_v.getLatitudeRad(); + return _state.geocentric_position_v.getLatitudeRad(); } inline double get_Lon_geocentric() const { - return geocentric_position_v.getLongitudeRad(); + return _state.geocentric_position_v.getLongitudeRad(); } inline double get_Radius_to_vehicle() const { - return geocentric_position_v.getRadiusFt(); + return _state.geocentric_position_v.getRadiusFt(); } - const SGGeod& getPosition() const { return geodetic_position_v; } - const SGGeoc& getGeocPosition() const { return geocentric_position_v; } - const SGVec3d& getCartPosition() const { return cartesian_position_v; } + const SGGeod& getPosition() const { return _state.geodetic_position_v; } + const SGGeoc& getGeocPosition() const { return _state.geocentric_position_v; } + const SGVec3d& getCartPosition() const { return _state.cartesian_position_v; } inline double get_Latitude() const { - return geodetic_position_v.getLatitudeRad(); + return _state.geodetic_position_v.getLatitudeRad(); } inline double get_Longitude() const { - return geodetic_position_v.getLongitudeRad(); + return _state.geodetic_position_v.getLongitudeRad(); } inline double get_Altitude() const { - return geodetic_position_v.getElevationFt(); + return _state.geodetic_position_v.getElevationFt(); } - inline double get_Altitude_AGL(void) const { return altitude_agl; } - inline double get_Track(void) const { return track; } + inline double get_Altitude_AGL(void) const { return _state.altitude_agl; } + inline double get_Track(void) const { return _state.track; } inline double get_Latitude_deg () const { - return geodetic_position_v.getLatitudeDeg(); + return _state.geodetic_position_v.getLatitudeDeg(); } inline double get_Longitude_deg () const { - return geodetic_position_v.getLongitudeDeg(); + return _state.geodetic_position_v.getLongitudeDeg(); } - 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 double get_Phi() const { return _state.euler_angles_v[0]; } + inline double get_Theta() const { return _state.euler_angles_v[1]; } + inline double get_Psi() const { return _state.euler_angles_v[2]; } inline double get_Phi_deg () const { return get_Phi() * SGD_RADIANS_TO_DEGREES; } inline double get_Theta_deg () const { return get_Theta() * SGD_RADIANS_TO_DEGREES; } inline double get_Psi_deg () const { return get_Psi() * SGD_RADIANS_TO_DEGREES; } @@ -626,34 +643,34 @@ public: // ========== Miscellaneous quantities ========== - inline double get_Alpha() const { return alpha; } - inline double get_Alpha_deg() const { return alpha * SGD_RADIANS_TO_DEGREES; } - inline double get_Beta() const { return beta; } - inline double get_Beta_deg() const { return beta * SGD_RADIANS_TO_DEGREES; } - inline double get_Gamma_vert_rad() const { return gamma_vert_rad; } + inline double get_Alpha() const { return _state.alpha; } + inline double get_Alpha_deg() const { return _state.alpha * SGD_RADIANS_TO_DEGREES; } + inline double get_Beta() const { return _state.beta; } + inline double get_Beta_deg() const { return _state.beta * SGD_RADIANS_TO_DEGREES; } + inline double get_Gamma_vert_rad() const { return _state.gamma_vert_rad; } - inline double get_Density() const { return density; } - inline double get_Mach_number() const { return mach_number; } + inline double get_Density() const { return _state.density; } + inline double get_Mach_number() const { return _state.mach_number; } - inline double get_Static_pressure() const { return static_pressure; } - inline double get_Total_pressure() const { return total_pressure; } - inline double get_Dynamic_pressure() const { return dynamic_pressure; } + inline double get_Static_pressure() const { return _state.static_pressure; } + inline double get_Total_pressure() const { return _state.total_pressure; } + inline double get_Dynamic_pressure() const { return _state.dynamic_pressure; } - inline double get_Static_temperature() const { return static_temperature; } - inline double get_Total_temperature() const { return total_temperature; } + inline double get_Static_temperature() const { return _state.static_temperature; } + inline double get_Total_temperature() const { return _state.total_temperature; } - inline double get_Sea_level_radius() const { return sea_level_radius; } + inline double get_Sea_level_radius() const { return _state.sea_level_radius; } inline double get_Earth_position_angle() const { - return earth_position_angle; + return _state.earth_position_angle; } - inline double get_Runway_altitude() const { return runway_altitude; } - inline double get_Runway_altitude_m() const { return SG_FEET_TO_METER * runway_altitude; } + inline double get_Runway_altitude() const { return _state.runway_altitude; } + inline double get_Runway_altitude_m() const { return SG_FEET_TO_METER * _state.runway_altitude; } - inline double get_Climb_Rate() const { return climb_rate; } + inline double get_Climb_Rate() const { return _state.climb_rate; } // Note that currently this is the "same" value runway altitude... - inline double get_ground_elev_ft() const { return runway_altitude; } + inline double get_ground_elev_ft() const { return _state.runway_altitude; } ////////////////////////////////////////////////////////////////////////// diff --git a/src/Network/native.cxx b/src/Network/native.cxx index 005704053..48edaf115 100644 --- a/src/Network/native.cxx +++ b/src/Network/native.cxx @@ -25,10 +25,12 @@ #endif #include -#include + #include "native.hxx" +#include
+#include #include FGNative::FGNative() { @@ -58,40 +60,21 @@ bool FGNative::open() { return true; } -/** - * The design of FGNative requires direct, memcpy access to FGInterface, - * unfortunately. Since this is the only remaining place that does, the - * extern lives here, rather than a header file. - * - */ -extern FGInterface* evil_global_fdm_state; - // process work for this port -bool FGNative::process() { +bool FGNative::process() +{ + FDMShell* fdm = static_cast(globals->get_subsystem("flight")); + FGInterface* fdmState = fdm->getInterface(); + if (!fdmState) { + return false; + } + SGIOChannel *io = get_io_channel(); - int length = sizeof(FGInterface); - if ( get_direction() == SG_IO_OUT ) { - buf = *evil_global_fdm_state; - if ( ! io->write( (char *)(& buf), length ) ) { - SG_LOG( SG_IO, SG_ALERT, "Error writing data." ); - return false; - } - } else if ( get_direction() == SG_IO_IN ) { - if ( io->get_type() == sgFileType ) { - if ( io->read( (char *)(& buf), length ) == length ) { - SG_LOG( SG_IO, SG_DEBUG, "Success reading data." ); - *evil_global_fdm_state = buf; - } - } else { - while ( io->read( (char *)(& buf), length ) == length ) { - SG_LOG( SG_IO, SG_DEBUG, "Success reading data." ); - *evil_global_fdm_state = buf; - } - } + return fdmState->writeState(io); + } else { + return fdmState->readState(io); } - - return true; } diff --git a/src/Network/native.hxx b/src/Network/native.hxx index 254ef1391..927dc6990 100644 --- a/src/Network/native.hxx +++ b/src/Network/native.hxx @@ -27,15 +27,10 @@ #include -#include - #include "protocol.hxx" -#include - -class FGNative : public FGProtocol { - - FGInterface buf; +class FGNative : public FGProtocol +{ public: FGNative(); -- 2.39.5