#pragma once #include #include #include #include #include #include // uORB Subscriptions #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // uORB Publications #include #include #include #include #include using namespace matrix; using namespace control; static const float DELAY_MAX = 0.5f; // seconds static const float HIST_STEP = 0.05f; // 20 hz static const float BIAS_MAX = 1e-1f; static const size_t HIST_LEN = 10; // DELAY_MAX / HIST_STEP; static const size_t N_DIST_SUBS = 4; // for fault detection // chi squared distribution, false alarm probability 0.0001 // see fault_table.py // note skip 0 index so we can use degree of freedom as index static const float BETA_TABLE[7] = {0, 8.82050518214, 12.094592431, 13.9876612368, 16.0875642296, 17.8797700658, 19.6465647819, }; class BlockLocalPositionEstimator : public control::SuperBlock, public ModuleParams { // dynamics: // // x(+) = A * x(-) + B * u(+) // y_i = C_i*x // // kalman filter // // E[xx'] = P // E[uu'] = W // E[y_iy_i'] = R_i // // prediction // x(+|-) = A*x(-|-) + B*u(+) // P(+|-) = A*P(-|-)*A' + B*W*B' // // correction // x(+|+) = x(+|-) + K_i * (y_i - H_i * x(+|-) ) // // // input: // ax, ay, az (acceleration NED) // // states: // px, py, pz , ( position NED, m) // vx, vy, vz ( vel NED, m/s), // bx, by, bz ( accel bias, m/s^2) // tz (terrain altitude, ASL, m) // // measurements: // // sonar: pz (measured d*cos(phi)*cos(theta)) // // baro: pz // // flow: vx, vy (flow is in body x, y frame) // // gps: px, py, pz, vx, vy, vz (flow is in body x, y frame) // // lidar: pz (actual measured d*cos(phi)*cos(theta)) // // vision: px, py, pz, vx, vy, vz // // mocap: px, py, pz // // land (detects when landed)): pz (always measures agl = 0) // public: // constants enum {X_x = 0, X_y, X_z, X_vx, X_vy, X_vz, X_bx, X_by, X_bz, X_tz, n_x}; enum {U_ax = 0, U_ay, U_az, n_u}; enum {Y_baro_z = 0, n_y_baro}; enum {Y_lidar_z = 0, n_y_lidar}; enum {Y_flow_vx = 0, Y_flow_vy, n_y_flow}; enum {Y_sonar_z = 0, n_y_sonar}; enum {Y_gps_x = 0, Y_gps_y, Y_gps_z, Y_gps_vx, Y_gps_vy, Y_gps_vz, n_y_gps}; enum {Y_vision_x = 0, Y_vision_y, Y_vision_z, n_y_vision}; enum {Y_mocap_x = 0, Y_mocap_y, Y_mocap_z, n_y_mocap}; enum {Y_land_vx = 0, Y_land_vy, Y_land_agl, n_y_land}; enum {Y_target_x = 0, Y_target_y, n_y_target}; enum {POLL_FLOW = 0, POLL_SENSORS, POLL_PARAM, n_poll}; enum { FUSE_GPS = 1 << 0, FUSE_FLOW = 1 << 1, FUSE_VIS_POS = 1 << 2, FUSE_LAND_TARGET = 1 << 3, FUSE_LAND = 1 << 4, FUSE_PUB_AGL_Z = 1 << 5, FUSE_FLOW_GYRO_COMP = 1 << 6, FUSE_BARO = 1 << 7 }; enum sensor_t { SENSOR_BARO = 1 << 0, SENSOR_GPS = 1 << 1, SENSOR_LIDAR = 1 << 2, SENSOR_FLOW = 1 << 3, SENSOR_SONAR = 1 << 4, SENSOR_VISION = 1 << 5, SENSOR_MOCAP = 1 << 6, SENSOR_LAND = 1 << 7, SENSOR_LAND_TARGET = 1 << 8, }; enum estimate_t { EST_XY = 1 << 0, EST_Z = 1 << 1, EST_TZ = 1 << 2, }; // public methods BlockLocalPositionEstimator(); void update(); virtual ~BlockLocalPositionEstimator() = default; private: BlockLocalPositionEstimator(const BlockLocalPositionEstimator &) = delete; BlockLocalPositionEstimator operator=(const BlockLocalPositionEstimator &) = delete; // methods // ---------------------------- // Vector dynamics( float t, const Vector &x, const Vector &u); void initP(); void initSS(); void updateSSStates(); void updateSSParams(); // predict the next state void predict(); // lidar int lidarMeasure(Vector &y); void lidarCorrect(); void lidarInit(); void lidarCheckTimeout(); // sonar int sonarMeasure(Vector &y); void sonarCorrect(); void sonarInit(); void sonarCheckTimeout(); // baro int baroMeasure(Vector &y); void baroCorrect(); void baroInit(); void baroCheckTimeout(); // gps int gpsMeasure(Vector &y); void gpsCorrect(); void gpsInit(); void gpsCheckTimeout(); // flow int flowMeasure(Vector &y); void flowCorrect(); void flowInit(); void flowCheckTimeout(); // vision int visionMeasure(Vector &y); void visionCorrect(); void visionInit(); void visionCheckTimeout(); // mocap int mocapMeasure(Vector &y); void mocapCorrect(); void mocapInit(); void mocapCheckTimeout(); // land int landMeasure(Vector &y); void landCorrect(); void landInit(); void landCheckTimeout(); // landing target int landingTargetMeasure(Vector &y); void landingTargetCorrect(); void landingTargetInit(); void landingTargetCheckTimeout(); // timeouts void checkTimeouts(); // misc inline float agl() { return _x(X_tz) - _x(X_z); } bool landed(); int getDelayPeriods(float delay, uint8_t *periods); // publications void publishLocalPos(); void publishGlobalPos(); void publishEstimatorStatus(); // attributes // ---------------------------- // subscriptions uORB::Subscription _sub_armed; uORB::Subscription _sub_land; uORB::Subscription _sub_att; uORB::Subscription _sub_flow; uORB::Subscription _sub_sensor; uORB::Subscription _sub_param_update; uORB::Subscription _sub_gps; uORB::Subscription _sub_vision_pos; uORB::Subscription _sub_mocap; uORB::Subscription _sub_dist0; uORB::Subscription _sub_dist1; uORB::Subscription _sub_dist2; uORB::Subscription _sub_dist3; uORB::Subscription *_dist_subs[N_DIST_SUBS]; uORB::Subscription *_sub_lidar; uORB::Subscription *_sub_sonar; uORB::Subscription _sub_landing_target_pose; uORB::Subscription _sub_airdata; // publications uORB::Publication _pub_lpos; uORB::Publication _pub_gpos; uORB::Publication _pub_est_status; uORB::Publication _pub_innov; // map projection struct map_projection_reference_s _map_ref; DEFINE_PARAMETERS( (ParamInt) _sys_autostart, /**< example parameter */ // general parameters (ParamInt) _fusion, (ParamFloat) _vxy_pub_thresh, (ParamFloat) _z_pub_thresh, // sonar parameters (ParamFloat) _sonar_z_stddev, (ParamFloat) _sonar_z_offset, // lidar parameters (ParamFloat) _lidar_z_stddev, (ParamFloat) _lidar_z_offset, // accel parameters (ParamFloat) _accel_xy_stddev, (ParamFloat) _accel_z_stddev, // baro parameters (ParamFloat) _baro_stddev, // gps parameters (ParamFloat) _gps_delay, (ParamFloat) _gps_xy_stddev, (ParamFloat) _gps_z_stddev, (ParamFloat) _gps_vxy_stddev, (ParamFloat) _gps_vz_stddev, (ParamFloat) _gps_eph_max, (ParamFloat) _gps_epv_max, // vision parameters (ParamFloat) _vision_xy_stddev, (ParamFloat) _vision_z_stddev, (ParamFloat) _vision_delay, // mocap parameters (ParamFloat) _mocap_p_stddev, // flow parameters (ParamFloat) _flow_z_offset, (ParamFloat) _flow_scale, (ParamInt) _flow_min_q, (ParamFloat) _flow_r, (ParamFloat) _flow_rr, // land parameters (ParamFloat) _land_z_stddev, (ParamFloat) _land_vxy_stddev, // process noise (ParamFloat) _pn_p_noise_density, (ParamFloat) _pn_v_noise_density, (ParamFloat) _pn_b_noise_density, (ParamFloat) _pn_t_noise_density, (ParamFloat) _t_max_grade, (ParamFloat) _target_min_cov, (ParamInt) _target_mode, // init origin (ParamInt) _fake_origin, (ParamFloat) _init_origin_lat, (ParamFloat) _init_origin_lon ) // target mode paramters from landing_target_estimator module enum TargetMode { Target_Moving = 0, Target_Stationary = 1 }; // flow gyro filter BlockHighPass _flow_gyro_x_high_pass; BlockHighPass _flow_gyro_y_high_pass; // stats BlockStats _baroStats; BlockStats _sonarStats; BlockStats _lidarStats; BlockStats _flowQStats; BlockStats _visionStats; BlockStats _mocapStats; BlockStats _gpsStats; uint16_t _landCount; // low pass BlockLowPassVector _xLowPass; BlockLowPass _aglLowPass; // delay blocks BlockDelay _xDelay; BlockDelay _tDelay; // misc px4_pollfd_struct_t _polls[3]; uint64_t _timeStamp; uint64_t _time_origin; uint64_t _timeStampLastBaro; uint64_t _time_last_hist; uint64_t _time_last_flow; uint64_t _time_last_baro; uint64_t _time_last_gps; uint64_t _time_last_lidar; uint64_t _time_last_sonar; uint64_t _time_init_sonar; uint64_t _time_last_vision_p; uint64_t _time_last_mocap; uint64_t _time_last_land; uint64_t _time_last_target; // reference altitudes float _altOrigin; bool _altOriginInitialized; bool _altOriginGlobal; // true when the altitude of the origin is defined wrt a global reference frame float _baroAltOrigin; float _gpsAltOrigin; // status bool _receivedGps; bool _lastArmedState; // masks uint16_t _sensorTimeout; uint16_t _sensorFault; uint8_t _estimatorInitialized; // sensor update flags bool _flowUpdated; bool _gpsUpdated; bool _visionUpdated; bool _mocapUpdated; bool _lidarUpdated; bool _sonarUpdated; bool _landUpdated; bool _baroUpdated; // state space Vector _x; // state vector Vector _u; // input vector Matrix _P; // state covariance matrix matrix::Dcm _R_att; Vector3f _eul; Matrix _A; // dynamics matrix Matrix _B; // input matrix Matrix _R; // input covariance Matrix _Q; // process noise covariance };