Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/libraries/AP_AHRS/AP_AHRS_SIM.cpp
Views: 1798
#include "AP_AHRS_SIM.h"12#if AP_AHRS_SIM_ENABLED34#include "AP_AHRS.h"56bool AP_AHRS_SIM::get_location(Location &loc) const7{8if (_sitl == nullptr) {9return false;10}1112const struct SITL::sitl_fdm &fdm = _sitl->state;13loc = {};14loc.lat = fdm.latitude * 1e7;15loc.lng = fdm.longitude * 1e7;16loc.alt = fdm.altitude*100;1718return true;19}2021bool AP_AHRS_SIM::get_velocity_NED(Vector3f &vec) const22{23if (_sitl == nullptr) {24return false;25}2627const struct SITL::sitl_fdm &fdm = _sitl->state;28vec = Vector3f(fdm.speedN, fdm.speedE, fdm.speedD);2930return true;31}3233bool AP_AHRS_SIM::wind_estimate(Vector3f &wind) const34{35if (_sitl == nullptr) {36return false;37}3839wind = _sitl->state.wind_ef;40return true;41}4243bool AP_AHRS_SIM::airspeed_EAS(float &airspeed_ret) const44{45if (_sitl == nullptr) {46return false;47}4849airspeed_ret = _sitl->state.airspeed;5051return true;52}5354bool AP_AHRS_SIM::airspeed_EAS(uint8_t index, float &airspeed_ret) const55{56return airspeed_EAS(airspeed_ret);57}5859bool AP_AHRS_SIM::get_quaternion(Quaternion &quat) const60{61if (_sitl == nullptr) {62return false;63}6465const struct SITL::sitl_fdm &fdm = _sitl->state;66quat = fdm.quaternion;6768return true;69}7071Vector2f AP_AHRS_SIM::groundspeed_vector(void)72{73if (_sitl == nullptr) {74return Vector2f{};75}7677const struct SITL::sitl_fdm &fdm = _sitl->state;7879return Vector2f(fdm.speedN, fdm.speedE);80}8182bool AP_AHRS_SIM::get_vert_pos_rate_D(float &velocity) const83{84if (_sitl == nullptr) {85return false;86}8788velocity = _sitl->state.speedD;8990return true;91}9293bool AP_AHRS_SIM::get_hagl(float &height) const94{95if (_sitl == nullptr) {96return false;97}9899height = _sitl->state.altitude - AP::ahrs().get_home().alt*0.01f;100101return true;102}103104bool AP_AHRS_SIM::get_relative_position_NED_origin(Vector3f &vec) const105{106if (_sitl == nullptr) {107return false;108}109110Location loc, orgn;111if (!get_location(loc) ||112!get_origin(orgn)) {113return false;114}115116const Vector2f diff2d = orgn.get_distance_NE(loc);117const struct SITL::sitl_fdm &fdm = _sitl->state;118vec = Vector3f(diff2d.x, diff2d.y,119-(fdm.altitude - orgn.alt*0.01f));120121return true;122}123124bool AP_AHRS_SIM::get_relative_position_NE_origin(Vector2f &posNE) const125{126Location loc, orgn;127if (!get_location(loc) ||128!get_origin(orgn)) {129return false;130}131posNE = orgn.get_distance_NE(loc);132133return true;134}135136bool AP_AHRS_SIM::get_relative_position_D_origin(float &posD) const137{138if (_sitl == nullptr) {139return false;140}141const struct SITL::sitl_fdm &fdm = _sitl->state;142Location orgn;143if (!get_origin(orgn)) {144return false;145}146posD = -(fdm.altitude - orgn.alt*0.01f);147148return true;149}150151bool AP_AHRS_SIM::get_filter_status(nav_filter_status &status) const152{153memset(&status, 0, sizeof(status));154status.flags.attitude = true;155status.flags.horiz_vel = true;156status.flags.vert_vel = true;157status.flags.horiz_pos_rel = true;158status.flags.horiz_pos_abs = true;159status.flags.vert_pos = true;160status.flags.pred_horiz_pos_rel = true;161status.flags.pred_horiz_pos_abs = true;162status.flags.using_gps = true;163164return true;165}166167void AP_AHRS_SIM::get_control_limits(float &ekfGndSpdLimit, float &ekfNavVelGainScaler) const168{169// same as EKF2 for no optical flow170ekfGndSpdLimit = 400.0f;171ekfNavVelGainScaler = 1.0f;172}173174void AP_AHRS_SIM::send_ekf_status_report(GCS_MAVLINK &link) const175{176#if HAL_GCS_ENABLED177// send status report with everything looking good178const uint16_t flags =179EKF_ATTITUDE | /* Set if EKF's attitude estimate is good. | */180EKF_VELOCITY_HORIZ | /* Set if EKF's horizontal velocity estimate is good. | */181EKF_VELOCITY_VERT | /* Set if EKF's vertical velocity estimate is good. | */182EKF_POS_HORIZ_REL | /* Set if EKF's horizontal position (relative) estimate is good. | */183EKF_POS_HORIZ_ABS | /* Set if EKF's horizontal position (absolute) estimate is good. | */184EKF_POS_VERT_ABS | /* Set if EKF's vertical position (absolute) estimate is good. | */185EKF_POS_VERT_AGL | /* Set if EKF's vertical position (above ground) estimate is good. | */186//EKF_CONST_POS_MODE | /* EKF is in constant position mode and does not know it's absolute or relative position. | */187EKF_PRED_POS_HORIZ_REL | /* Set if EKF's predicted horizontal position (relative) estimate is good. | */188EKF_PRED_POS_HORIZ_ABS; /* Set if EKF's predicted horizontal position (absolute) estimate is good. | */189mavlink_msg_ekf_status_report_send(link.get_chan(), flags, 0, 0, 0, 0, 0, 0);190#endif // HAL_GCS_ENABLED191}192193bool AP_AHRS_SIM::get_origin(Location &ret) const194{195if (_sitl == nullptr) {196return false;197}198199ret = _sitl->state.home;200201return true;202}203204// return the innovations for the specified instance205// An out of range instance (eg -1) returns data for the primary instance206bool AP_AHRS_SIM::get_innovations(Vector3f &velInnov, Vector3f &posInnov, Vector3f &magInnov, float &tasInnov, float &yawInnov) const207{208velInnov.zero();209posInnov.zero();210magInnov.zero();211tasInnov = 0.0f;212yawInnov = 0.0f;213214return true;215}216217bool AP_AHRS_SIM::get_variances(float &velVar, float &posVar, float &hgtVar, Vector3f &magVar, float &tasVar) const218{219velVar = 0;220posVar = 0;221hgtVar = 0;222magVar.zero();223tasVar = 0;224225return true;226}227228void AP_AHRS_SIM::get_results(AP_AHRS_Backend::Estimates &results)229{230if (_sitl == nullptr) {231_sitl = AP::sitl();232if (_sitl == nullptr) {233return;234}235}236237const struct SITL::sitl_fdm &fdm = _sitl->state;238const AP_InertialSensor &_ins = AP::ins();239240fdm.quaternion.rotation_matrix(results.dcm_matrix);241results.dcm_matrix = results.dcm_matrix * AP::ahrs().get_rotation_vehicle_body_to_autopilot_body();242results.dcm_matrix.to_euler(&results.roll_rad, &results.pitch_rad, &results.yaw_rad);243244results.gyro_estimate = _ins.get_gyro();245results.gyro_drift.zero();246247const Vector3f &accel = _ins.get_accel();248results.accel_ef = results.dcm_matrix * AP::ahrs().get_rotation_autopilot_body_to_vehicle_body() * accel;249250results.location_valid = get_location(results.location);251252#if HAL_NAVEKF3_AVAILABLE253if (_sitl->odom_enable) {254// use SITL states to write body frame odometry data at 20Hz255uint32_t timeStamp_ms = AP_HAL::millis();256if (timeStamp_ms - _last_body_odm_update_ms > 50) {257const float quality = 100.0f;258const Vector3f posOffset(0.0f, 0.0f, 0.0f);259const float delTime = 0.001f * (timeStamp_ms - _last_body_odm_update_ms);260_last_body_odm_update_ms = timeStamp_ms;261timeStamp_ms -= (timeStamp_ms - _last_body_odm_update_ms)/2; // correct for first order hold average delay262Vector3f delAng = _ins.get_gyro();263264delAng *= delTime;265// rotate earth velocity into body frame and calculate delta position266Matrix3f Tbn;267Tbn.from_euler(radians(fdm.rollDeg),radians(fdm.pitchDeg),radians(fdm.yawDeg));268const Vector3f earth_vel(fdm.speedN,fdm.speedE,fdm.speedD);269const Vector3f delPos = Tbn.transposed() * (earth_vel * delTime);270// write to EKF271EKF3.writeBodyFrameOdom(quality, delPos, delAng, delTime, timeStamp_ms, 0, posOffset);272}273}274#endif // HAL_NAVEKF3_AVAILABLE275}276277#endif // AP_AHRS_SIM_ENABLED278279280