using std::vector;
using std::string;
+/**
+ * A little helper class to update the track if
+ * the position has changed. In the constructor,
+ * create a copy of the current position and store
+ * references to the position object and the track
+ * variable to update.
+ * The destructor, called at TrackComputer's end of
+ * life/visibility, computes the track if the
+ * position has changed.
+ */
+class TrackComputer {
+public:
+ inline TrackComputer( double & track, const SGGeod & position ) :
+ _track( track ),
+ _position( position ),
+ _prevPosition( position ) {
+ }
+
+ inline ~TrackComputer() {
+ if( _prevPosition == _position ) return;
+ _track = SGGeodesy::courseDeg( _prevPosition, _position );
+ }
+private:
+ double & _track;
+ const SGGeod & _position;
+ const SGGeod _prevPosition;
+};
+
// This is based heavily on LaRCsim/ls_generic.h
class FGInterface : public SGSubsystem {
// next elapsed time. This yields a small amount of temporal
// jitter ( < dt ) but in practice seems to work well.
- double remainder; // remainder time from last run
-
// CG position w.r.t. ref. point
SGVec3d d_cg_rp_body_v;
double runway_altitude;
double climb_rate; // in feet per second
double altitude_agl;
-
- double daux[16]; // auxilliary doubles
- float faux[16]; // auxilliary floats
- int iaux[16]; // auxilliary ints
+ double track;
// 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]); }
+
+ void set_A_Y_pilot(double y)
+ { _set_Accels_Pilot_Body(a_pilot_body_v[0], y, 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); }
+
protected:
int _calc_multiloop (double dt);
euler_rates_v[1] = theta;
euler_rates_v[2] = psi;
}
+
+ void set_Phi_dot_degps(double x)
+ {
+ 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;
+ }
+
+ void set_Psi_dot_degps(double x)
+ {
+ 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_position_v.setLongitudeRad(lon);
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.
+ *
inline void _set_Latitude(double lat) {
geodetic_position_v.setLatitudeRad(lat);
}
inline void _set_Longitude(double lon) {
geodetic_position_v.setLongitudeRad(lon);
}
+*/
inline void _set_Altitude(double altitude) {
geodetic_position_v.setElevationFt(altitude);
}
inline void _set_Altitude_AGL(double agl) {
altitude_agl = agl;
}
+ inline void _set_Geodetic_Position( double lat, double lon ) {
+ _set_Geodetic_Position( lat, lon, 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);
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_deg( double a ) { 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_Runway_altitude( double alt ) { runway_altitude = alt; }
inline void _set_Climb_Rate(double rate) { climb_rate = rate; }
- inline void _set_daux( int n, double value ) { daux[n] = value; }
- inline void _set_faux( int n, float value ) { faux[n] = value; }
- inline void _set_iaux( int n, int value ) { iaux[n] = value; }
-
public:
FGInterface();
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_equiv_kts() const { return v_equiv_kts; }
return 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_Latitude_deg () const {
return geodetic_position_v.getLatitudeDeg();
inline double get_Climb_Rate() const { return climb_rate; }
- // Auxilliary variables
- inline double get_daux( int n ) const { return daux[n]; }
- inline float get_faux( int n ) const { return faux[n]; }
- inline int get_iaux( int n ) const { return iaux[n]; }
-
// Note that currently this is the "same" value runway altitude...
inline double get_ground_elev_ft() const { return runway_altitude; }
// Ground handling routines
//////////////////////////////////////////////////////////////////////////
- enum GroundType {
- /// I sused at least in YAsim. Deprecate this ad get it from the
- /// Material instead
- Unknown = 0, //??
- Solid, // Whatever we will roll on with infinite load factor.
- Water // For the beaver ...
- };
-
// Prepare the ground cache for the wgs84 position pt_*.
// That is take all vertices in the ball with radius rad around the
// position given by the pt_* and store them in a local scene graph.
- bool prepare_ground_cache_m(double ref_time, const double pt[3],
- double rad);
- bool prepare_ground_cache_ft(double ref_time, const double pt[3],
- double rad);
+ bool prepare_ground_cache_m(double startSimTime, double endSimTime,
+ const double pt[3], double rad);
+ bool prepare_ground_cache_ft(double startSimTime, double endSimTime,
+ const double pt[3], double rad);
// Returns true if the cache is valid.
double end[2][3], double vel[2][3]);
- // Return the altitude above ground below the wgs84 point pt
- // Search for the nearest triangle to pt.
- // Return ground properties like the ground type, the maximum load
- // this kind kind of ground can carry, the friction factor between
- // 0 and 1 which can be used to model lower friction with wet runways
- // and finally the altitude above ground.
- bool get_agl_m(double t, const double pt[3],
- double contact[3], double normal[3], double vel[3],
- int *type, double *loadCapacity,
- double *frictionFactor, double *agl);
- bool get_agl_m(double t, const double pt[3],
- double contact[3], double normal[3], double vel[3],
- int *type, const SGMaterial **material,double *agl);
- bool get_agl_ft(double t, const double pt[3],
- double contact[3], double normal[3], double vel[3],
- int *type, double *loadCapacity,
- double *frictionFactor, double *agl);
+ // Return the orientation and position matrix and the linear and angular
+ // velocity of that local coordinate systems origin for a given time and
+ // body id. The velocities are in the wgs84 frame at the bodys origin.
+ bool get_body_m(double t, simgear::BVHNode::Id id, double bodyToWorld[16],
+ double linearVel[3], double angularVel[3]);
+
// Return the altitude above ground below the wgs84 point pt
- // Search for the nearest triangle to pt.
- // Return ground properties like the ground type, a pointer to the
- // material and finally the altitude above ground.
+ // Search for the nearest triangle to pt in downward direction.
+ // Return ground properties. The velocities are in the wgs84 frame at the
+ // contact point.
bool get_agl_m(double t, const double pt[3], double max_altoff,
- double contact[3], double normal[3], double vel[3],
- int *type, const SGMaterial** material, double *agl);
+ double contact[3], double normal[3], double linearVel[3],
+ double angularVel[3], SGMaterial const*& material,
+ simgear::BVHNode::Id& id);
bool get_agl_ft(double t, const double pt[3], double max_altoff,
- double contact[3], double normal[3], double vel[3],
- int *type, const SGMaterial** material, double *agl);
+ double contact[3], double normal[3], double linearVel[3],
+ double angularVel[3], SGMaterial const*& material,
+ simgear::BVHNode::Id& id);
double get_groundlevel_m(double lat, double lon, double alt);
double get_groundlevel_m(const SGGeod& geod);
+ // Return the nearest point in any direction to the point pt with a maximum
+ // distance maxDist. The velocities are in the wgs84 frame at the query
+ // position pt.
+ bool get_nearest_m(double t, const double pt[3], double maxDist,
+ double contact[3], double normal[3], double linearVel[3],
+ double angularVel[3], SGMaterial const*& material,
+ simgear::BVHNode::Id& id);
+ bool get_nearest_ft(double t, const double pt[3], double maxDist,
+ double contact[3], double normal[3],double linearVel[3],
+ double angularVel[3], SGMaterial const*& material,
+ simgear::BVHNode::Id& id);
+
+
// Return 1 if the hook intersects with a wire.
// That test is done by checking if the quad spanned by the points pt*
// intersects with the line representing the wire.
void release_wire(void);
};
-extern FGInterface * cur_fdm_state;
-
-// Toggle data logging on/off
-void fgToggleFDMdataLogging(void);
-
-
#endif // _FLIGHT_HXX