29# error This library requires C++
79#include <simgear/compiler.h>
80#include <simgear/constants.h>
81#include <simgear/structure/subsystem_mgr.hxx>
82#include <simgear/props/tiedpropertylist.hxx>
107 inline TrackComputer(
double & track,
double & path,
const SGGeod & position ) :
110 _position( position ),
111 _prevPosition( position ) {
115 if( _prevPosition == _position )
return;
118 double distance = .0;
119 if( SGGeodesy::inverse( _prevPosition, _position, _track, d, distance ) ) {
120 d = _position.getElevationM() - _prevPosition.getElevationM();
121 _path = atan2( d, distance ) * SGD_RADIANS_TO_DEGREES;
128 const SGGeod & _position;
129 const SGGeod _prevPosition;
161 SGVec3d d_cg_rp_body_v;
164 SGVec3d v_dot_local_v;
165 SGVec3d v_dot_body_v;
167 SGVec3d a_pilot_body_v;
169 SGVec3d omega_dot_body_v;
173 SGVec3d v_local_rel_ground_v;
174 SGVec3d v_local_airmass_v;
177 SGVec3d omega_body_v;
178 SGVec3d euler_rates_v;
179 SGVec3d geocentric_rates_v;
182 SGGeod geodetic_position_v;
183 SGVec3d cartesian_position_v;
184 SGGeoc geocentric_position_v;
185 SGVec3d euler_angles_v;
191 double v_rel_wind, v_true_kts;
192 double v_ground_speed, v_equiv_kts;
193 double v_calibrated_kts;
197 double gamma_vert_rad;
198 double density, mach_number;
199 double static_pressure, total_pressure;
200 double dynamic_pressure;
201 double static_temperature, total_temperature;
203 double runway_altitude;
212 simgear::TiedPropertyList _tiedProperties;
220 void set_A_X_pilot(
double x)
223 void set_A_Y_pilot(
double y)
226 void set_A_Z_pilot(
double z)
251 _state.d_cg_rp_body_v[0] = dx;
252 _state.d_cg_rp_body_v[1] = dy;
253 _state.d_cg_rp_body_v[2] = dz;
256 _state.v_dot_local_v[0] = north;
257 _state.v_dot_local_v[1] = east;
258 _state.v_dot_local_v[2] = down;
261 _state.v_dot_body_v[0] = u;
262 _state.v_dot_body_v[1] = v;
263 _state.v_dot_body_v[2] = w;
266 _state.a_cg_body_v[0] = x;
267 _state.a_cg_body_v[1] = y;
268 _state.a_cg_body_v[2] = z;
271 _state.a_pilot_body_v[0] = x;
272 _state.a_pilot_body_v[1] = y;
273 _state.a_pilot_body_v[2] = z;
276 _state.n_cg_body_v[0] = x;
277 _state.n_cg_body_v[1] = y;
278 _state.n_cg_body_v[2] = z;
282 _state.v_local_v[0] = north;
283 _state.v_local_v[1] = east;
284 _state.v_local_v[2] = down;
287 _state.v_local_rel_ground_v[0] = north;
288 _state.v_local_rel_ground_v[1] = east;
289 _state.v_local_rel_ground_v[2] = down;
294 _state.v_local_airmass_v[0] = north;
295 _state.v_local_airmass_v[1] = east;
296 _state.v_local_airmass_v[2] = down;
299 _state.v_body_v[0] = u;
300 _state.v_body_v[1] = v;
301 _state.v_body_v[2] = w;
308 _state.omega_body_v[0] =
p;
309 _state.omega_body_v[1] = q;
310 _state.omega_body_v[2] = r;
313 _state.euler_rates_v[0] = phi;
314 _state.euler_rates_v[1] = theta;
315 _state.euler_rates_v[2] = psi;
320 _state.euler_rates_v[0] = x * SGD_DEGREES_TO_RADIANS;
325 _state.euler_rates_v[1] = x * SGD_DEGREES_TO_RADIANS;
330 _state.euler_rates_v[2] = x * SGD_DEGREES_TO_RADIANS;
334 _state.geocentric_rates_v[0] = lat;
335 _state.geocentric_rates_v[1] = lon;
336 _state.geocentric_rates_v[2] = rad;
339 _state.geocentric_position_v.setLatitudeRad(lat);
340 _state.geocentric_position_v.setLongitudeRad(lon);
341 _state.geocentric_position_v.setRadiusFt(rad);
354 _state.geodetic_position_v.setElevationFt(
altitude);
357 _state.altitude_agl = agl;
363 TrackComputer tracker( _state.track, _state.path, _state.geodetic_position_v );
364 _state.geodetic_position_v.setLatitudeRad(lat);
365 _state.geodetic_position_v.setLongitudeRad(lon);
366 _state.geodetic_position_v.setElevationFt(alt);
369 _state.euler_angles_v[0] = phi;
370 _state.euler_angles_v[1] = theta;
371 _state.euler_angles_v[2] = psi;
378 inline void set_Alpha_deg(
double a ) { _state.alpha = a * SGD_DEGREES_TO_RADIANS; }
397 void bind()
override;
398 void init()
override;
400 void update(
double dt)
override;
450 std::function<
void(
const std::string& from,
const std::string& to)> fn
501 set_Phi(phi * SGD_DEGREES_TO_RADIANS);
504 set_Theta(theta * SGD_DEGREES_TO_RADIANS);
507 set_Psi(psi * SGD_DEGREES_TO_RADIANS);
527 inline double get_Dx_cg()
const {
return _state.d_cg_rp_body_v[0]; }
528 inline double get_Dy_cg()
const {
return _state.d_cg_rp_body_v[1]; }
529 inline double get_Dz_cg()
const {
return _state.d_cg_rp_body_v[2]; }
541 inline double get_A_X_cg()
const {
return _state.a_cg_body_v[0]; }
542 inline double get_A_Y_cg()
const {
return _state.a_cg_body_v[1]; }
543 inline double get_A_Z_cg()
const {
return _state.a_cg_body_v[2]; }
549 inline double get_N_X_cg()
const {
return _state.n_cg_body_v[0]; }
550 inline double get_N_Y_cg()
const {
return _state.n_cg_body_v[1]; }
551 inline double get_N_Z_cg()
const {
return _state.n_cg_body_v[2]; }
553 inline double get_Nlf(
void)
const {
return _state.nlf; }
558 inline double get_V_east()
const {
return _state.v_local_v[1]; }
559 inline double get_V_down()
const {
return _state.v_local_v[2]; }
560 inline double get_uBody ()
const {
return _state.v_body_v[0]; }
561 inline double get_vBody ()
const {
return _state.v_body_v[1]; }
562 inline double get_wBody ()
const {
return _state.v_body_v[2]; }
567 return _state.v_local_rel_ground_v[0];
570 return _state.v_local_rel_ground_v[1];
573 return _state.v_local_rel_ground_v[2];
581 inline double get_U_body()
const {
return _state.v_body_v[0]; }
582 inline double get_V_body()
const {
return _state.v_body_v[1]; }
583 inline double get_W_body()
const {
return _state.v_body_v[2]; }
590 inline double get_V_ground_speed_kt()
const {
return _state.v_ground_speed * SG_FEET_TO_METER * 3600 * SG_METER_TO_NM; }
591 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); }
597 inline double get_P_body()
const {
return _state.omega_body_v[0]; }
598 inline double get_Q_body()
const {
return _state.omega_body_v[1]; }
599 inline double get_R_body()
const {
return _state.omega_body_v[2]; }
601 inline double get_Phi_dot()
const {
return _state.euler_rates_v[0]; }
603 inline double get_Psi_dot()
const {
return _state.euler_rates_v[2]; }
604 inline double get_Phi_dot_degps()
const {
return _state.euler_rates_v[0] * SGD_RADIANS_TO_DEGREES; }
606 inline double get_Psi_dot_degps()
const {
return _state.euler_rates_v[2] * SGD_RADIANS_TO_DEGREES; }
615 return _state.geocentric_position_v.getLatitudeRad();
618 return _state.geocentric_position_v.getLongitudeRad();
621 return _state.geocentric_position_v.getRadiusFt();
624 const SGGeod&
getPosition()
const {
return _state.geodetic_position_v; }
629 return _state.geodetic_position_v.getLatitudeRad();
632 return _state.geodetic_position_v.getLongitudeRad();
635 return _state.geodetic_position_v.getElevationFt();
638 inline double get_Track(
void)
const {
return _state.track; }
639 inline double get_Path(
void)
const {
return _state.path; }
642 return _state.geodetic_position_v.getLatitudeDeg();
645 return _state.geodetic_position_v.getLongitudeDeg();
648 inline double get_Phi()
const {
return _state.euler_angles_v[0]; }
649 inline double get_Theta()
const {
return _state.euler_angles_v[1]; }
650 inline double get_Psi()
const {
return _state.euler_angles_v[2]; }
658 inline double get_Alpha()
const {
return _state.alpha; }
659 inline double get_Alpha_deg()
const {
return _state.alpha * SGD_RADIANS_TO_DEGREES; }
660 inline double get_Beta()
const {
return _state.beta; }
661 inline double get_Beta_deg()
const {
return _state.beta * SGD_RADIANS_TO_DEGREES; }
676 return _state.earth_position_angle;
696 const double pt[3],
double rad);
698 const double pt[3],
double rad);
704 bool is_valid_m(
double *ref_time,
double pt[3],
double *rad);
705 bool is_valid_ft(
double *ref_time,
double pt[3],
double *rad);
709 double get_cat_m(
double t,
const double pt[3],
710 double end[2][3],
double vel[2][3]);
711 double get_cat_ft(
double t,
const double pt[3],
712 double end[2][3],
double vel[2][3]);
718 bool get_body_m(
double t, simgear::BVHNode::Id
id,
double bodyToWorld[16],
719 double linearVel[3],
double angularVel[3]);
726 bool get_agl_m(
double t,
const double pt[3],
double max_altoff,
727 double contact[3],
double normal[3],
double linearVel[3],
728 double angularVel[3], simgear::BVHMaterial
const*& material,
729 simgear::BVHNode::Id&
id);
730 bool get_agl_ft(
double t,
const double pt[3],
double max_altoff,
731 double contact[3],
double normal[3],
double linearVel[3],
732 double angularVel[3], simgear::BVHMaterial
const*& material,
733 simgear::BVHNode::Id&
id);
741 bool get_nearest_m(
double t,
const double pt[3],
double maxDist,
742 double contact[3],
double normal[3],
double linearVel[3],
743 double angularVel[3], simgear::BVHMaterial
const*& material,
744 simgear::BVHNode::Id&
id);
746 double contact[3],
double normal[3],
double linearVel[3],
747 double angularVel[3], simgear::BVHMaterial
const*& material,
748 simgear::BVHNode::Id&
id);
769 return _groundReactions.update(material);
771 inline void setHeading(
float h) { _groundReactions.setHeading(h); }
773 _groundReactions.setPosition(pt);
775 inline float getPressure() {
return _groundReactions.getPressure(); }
776 inline float getBumpiness() {
return _groundReactions.getBumpiness(); }
778 return _groundReactions.getGroundDisplacement();
781 return _groundReactions.getStaticFrictionFactor();
784 return _groundReactions.getRolingFrictionFactor();
786 inline bool getSolid() {
return _groundReactions.getSolid(); }
void _updatePosition(const SGGeod &geod)
void _set_Altitude(double altitude)
void _set_Mach_number(double m)
double get_V_east_airmass() const
void _set_Geodetic_Position(double lat, double lon)
double get_V_north_airmass() const
const SGGeod & getPosition() const
double get_V_dot_east() const
void set_Theta_dot_degps(double x)
void set_V_ground_speed_kt(double ground_speed)
double get_Lat_geocentric() const
double get_U_dot_body() const
double get_Longitude() const
virtual void set_Static_temperature(double T)
const SGVec3d & getCartPosition() const
double get_V_east() const
void _set_Geodetic_Position(double lat, double lon, double alt)
double get_Latitude() const
void _set_Total_temperature(double tat)
void _update_ground_elev_at_pos(void)
void _set_Velocities_Local(double north, double east, double down)
float getStaticFrictionFactor()
bool get_nearest_m(double t, const double pt[3], double maxDist, double contact[3], double normal[3], double linearVel[3], double angularVel[3], simgear::BVHMaterial const *&material, simgear::BVHNode::Id &id)
virtual void set_Psi(double psi)
double get_V_north_rel_ground() const
bool writeState(SGIOChannel *io)
void set_V_east(double east)
void _set_Accels_Pilot_Body(double x, double y, double z)
double get_Phi_dot() const
double get_V_down() const
virtual void set_Latitude_deg(double lat)
virtual void set_Theta_deg(double theta)
virtual void set_Velocities_Body(double u, double v, double w)
bool caught_wire_m(double t, const double pt[4][3])
void _set_Alpha(double a)
bool get_nearest_ft(double t, const double pt[3], double maxDist, double contact[3], double normal[3], double linearVel[3], double angularVel[3], simgear::BVHMaterial const *&material, simgear::BVHNode::Id &id)
virtual void set_Theta(double theta)
void _set_Velocities_Body(double u, double v, double w)
void _set_Accels_Body(double u, double v, double w)
double get_W_dot_body() const
virtual void set_vBody(double vBody)
double get_V_calibrated_kts() const
void unbind() override
Unbind any properties bound to this FDM.
void set_inited(bool value)
double get_Psi_deg() const
bool get_agl_ft(double t, const double pt[3], double max_altoff, double contact[3], double normal[3], double linearVel[3], double angularVel[3], simgear::BVHMaterial const *&material, simgear::BVHNode::Id &id)
virtual void set_wBody(double wBody)
double get_V_equiv_kts() const
bool get_wire_ends_ft(double t, double end[2][3], double vel[2][3])
float getGroundDisplacement()
bool is_valid_ft(double *ref_time, double pt[3], double *rad)
double get_V_dot_body() const
double get_V_body() const
double get_Static_temperature() const
double get_V_down_rel_ground() const
double get_V_ground_speed() const
void _set_Earth_position_angle(double a)
double get_V_true_kts() const
virtual void set_Phi_deg(double phi)
void _set_Climb_Rate(double rate)
void _set_CG_Position(double dx, double dy, double dz)
double get_cat_m(double t, const double pt[3], double end[2][3], double vel[2][3])
virtual void property_associations(std::function< void(const std::string &from, const std::string &to)> fn)
virtual void set_Latitude(double lat)
virtual void set_Climb_Rate(double roc)
double get_P_body() const
bool updateGroundReactions(simgear::BVHMaterial const *&material)
void bind() override
Bind getters and setters to properties.
double get_Gamma_vert_rad() const
void _set_Accels_Local(double north, double east, double down)
double get_A_X_cg() const
void set_Phi_dot_degps(double x)
void common_init()
Initialize the state of the FDM.
bool readState(SGIOChannel *io)
double get_Density() const
virtual bool ToggleDataLogging(bool state)
bool prepare_ground_cache_ft(double startSimTime, double endSimTime, const double pt[3], double rad)
virtual void set_Mach_number(double mach)
void _set_Accels_CG_Body_N(double x, double y, double z)
void _set_Runway_altitude(double alt)
double get_cat_ft(double t, const double pt[3], double end[2][3], double vel[2][3])
double get_Track(void) const
void _set_Static_pressure(double sp)
double get_Dynamic_pressure() const
virtual void set_Gamma_vert_rad(double gamma)
void set_V_down(double down)
void _set_Geocentric_Position(double lat, double lon, double rad)
double get_Beta_deg() const
float getRolingFrictionFactor()
const AIWakeGroup & get_wake_group(void)
double get_Longitude_dot() const
double get_Radius_to_vehicle() const
void _set_Velocities_Ground(double north, double east, double down)
void set_Alpha_deg(double a)
double get_Mach_number() const
double get_A_Z_pilot() const
void _set_Static_temperature(double t)
void _set_Omega_Body(double p, double q, double r)
double get_Total_temperature() const
virtual void set_V_calibrated_kts(double vc)
bool prepare_ground_cache_m(double startSimTime, double endSimTime, const double pt[3], double rad)
virtual void set_Phi(double phi)
virtual bool ToggleDataLogging(void)
double get_ground_elev_ft() const
double get_Runway_altitude_m() const
double get_A_Y_cg() const
double get_Theta_dot() const
virtual void set_Altitude(double alt)
double get_Runway_altitude() const
void _set_Geocentric_Rates(double lat, double lon, double rad)
bool get_agl_m(double t, const double pt[3], double max_altoff, double contact[3], double normal[3], double linearVel[3], double angularVel[3], simgear::BVHMaterial const *&material, simgear::BVHNode::Id &id)
double get_Earth_position_angle() const
double get_V_dot_down() const
void _set_Velocities_Local_Airmass(double north, double east, double down)
double get_V_rel_wind() const
virtual void set_Longitude_deg(double lon)
double get_W_body() const
virtual void set_Density(double rho)
double get_Total_pressure() const
double get_Nlf(void) const
double get_Longitude_deg() const
double get_N_Z_cg() const
double get_Latitude_dot() const
bool is_valid_m(double *ref_time, double pt[3], double *rad)
void _set_Accels_CG_Body(double x, double y, double z)
void _set_V_calibrated_kts(double kts)
double get_Path(void) const
double get_Latitude_deg() const
const SGGeoc & getGeocPosition() const
double get_V_north() const
void _setup()
Set default values for the state of the FDM.
bool get_wire_ends_m(double t, double end[2][3], double vel[2][3])
double get_A_X_pilot() const
void _set_Sea_level_radius(double r)
void _updateGeocentricPosition(double lat_geoc, double lon, double alt)
double get_V_dot_north() const
double get_A_Y_pilot() const
double get_Altitude() const
void _set_V_rel_wind(double vt)
void _updatePositionFt(const SGVec3d &cartPos)
void setPosition(double pt[3])
double get_A_Z_cg() const
void set_V_north(double north)
virtual void set_Static_pressure(double p)
bool caught_wire_ft(double t, const double pt[4][3])
void _set_Altitude_AGL(double agl)
virtual void set_Psi_deg(double psi)
void _set_T_Local_to_Body(int i, int j, double value)
virtual void set_Euler_Angles(double phi, double theta, double psi)
double get_N_X_cg() const
void update(double dt) override
Update the state of the FDM (i.e.
bool get_body_m(double t, simgear::BVHNode::Id id, double bodyToWorld[16], double linearVel[3], double angularVel[3])
void _updateGeodeticPosition(double lat, double lon, double alt)
double get_Psi_dot_degps() const
void _set_Euler_Rates(double phi, double theta, double psi)
double get_V_east_rel_ground() const
double get_N_Y_cg() const
double get_Phi_dot_degps() const
double get_Static_pressure() const
void _set_V_equiv_kts(double kts)
void _updatePositionM(const SGVec3d &cartPos)
int _calc_multiloop(double dt)
void add_ai_wake(FGAIAircraft *ai)
double get_Sea_level_radius() const
void reset_wake_group(void)
double get_Alpha_deg() const
void _set_V_ground_speed(double v)
void _set_Gamma_vert_rad(double gv)
virtual void set_uBody(double uBody)
virtual void set_Longitude(double lon)
double get_groundlevel_m(double lat, double lon, double alt)
double get_V_ground_speed_kt() const
double get_Lon_geocentric() const
double get_Climb_Rate() const
virtual void set_Velocities_Local(double north, double east, double down)
double get_Radius_dot() const
double get_Altitude_AGL(void) const
double get_Q_body() const
virtual void set_Velocities_Local_Airmass(double wnorth, double weast, double wdown)
double get_Theta_dot_degps() const
virtual void set_AltitudeAGL(double altagl)
void _set_Euler_Angles(double phi, double theta, double psi)
double get_Phi_deg() const
double get_Psi_dot() const
void _set_Density(double d)
double get_U_body() const
double get_V_down_airmass() const
double get_R_body() const
void set_Psi_dot_degps(double x)
double get_Theta_deg() const
A little helper class to update the track if the position has changed.
TrackComputer(double &track, double &path, const SGGeod &position)