15 static const float P_MAX = 1.0e6f;
21 ModuleParams(nullptr),
22 WorkItem(MODULE_NAME,
px4::wq_configurations::att_pos_ctrl),
31 _flow_gyro_x_high_pass(this,
"FGYRO_HP"),
32 _flow_gyro_y_high_pass(this,
"FGYRO_HP"),
36 _sonarStats(this,
""),
37 _lidarStats(this,
""),
38 _flowQStats(this,
""),
39 _visionStats(this,
""),
40 _mocapStats(this,
""),
44 _xLowPass(this,
"X_LP"),
47 _aglLowPass(this,
"X_LP"),
64 _time_last_vision_p(0),
71 _altOriginInitialized(false),
72 _altOriginGlobal(false),
78 _lastArmedState(false),
81 _sensorTimeout(UINT16_MAX),
83 _estimatorInitialized(0),
88 _visionUpdated(false),
96 _vision_xy_valid(false),
97 _vision_z_valid(false),
98 _mocap_xy_valid(false),
99 _mocap_z_valid(false),
108 _is_global_cov_init(false),
109 _global_ref_timestamp(0.0),
131 PX4_INFO(
"fuse gps: %d, flow: %d, vis_pos: %d, " 132 "landing_target: %d, land: %d, pub_agl_z: %d, flow_gyro: %d, " 134 (_param_lpe_fusion.get() &
FUSE_GPS) != 0,
135 (_param_lpe_fusion.get() &
FUSE_FLOW) != 0,
138 (_param_lpe_fusion.get() &
FUSE_LAND) != 0,
141 (_param_lpe_fusion.get() &
FUSE_BARO) != 0);
148 PX4_ERR(
"sensor combined callback registration failed!");
198 if (s->get().timestamp == 0) {
continue; }
200 if (s->get().type == distance_sensor_s::MAV_DISTANCE_SENSOR_LASER &&
201 s->get().orientation == distance_sensor_s::ROTATION_DOWNWARD_FACING &&
206 }
else if (s->get().type == distance_sensor_s::MAV_DISTANCE_SENSOR_ULTRASOUND &&
207 s->get().orientation == distance_sensor_s::ROTATION_DOWNWARD_FACING &&
270 SuperBlock::updateParams();
271 ModuleParams::updateParams();
276 bool vxy_stddev_ok =
false;
279 vxy_stddev_ok =
true;
303 bool z_stddev_ok = sqrtf(
m_P(
X_z,
X_z)) < _param_lpe_z_pub.get();
318 bool tz_stddev_ok = sqrtf(
m_P(
X_tz,
X_tz)) < _param_lpe_z_pub.get();
337 (
double)_param_lpe_lat.get(),
338 (double)_param_lpe_lon.get());
344 double(_param_lpe_lat.get()),
double(_param_lpe_lon.get()),
double(
_altOrigin));
348 bool reinit_x =
false;
350 for (
size_t i = 0; i <
n_x; i++) {
354 if (!PX4_ISFINITE(
_x(i))) {
362 for (
size_t i = 0; i <
n_x; i++) {
370 bool reinit_P =
false;
372 for (
size_t i = 0; i <
n_x; i++) {
373 for (
size_t j = 0; j <= i; j++) {
374 if (!PX4_ISFINITE(
m_P(i, j))) {
376 "%sreinit P (%zu, %zu) not finite",
msg_label, i, j);
382 if (
m_P(i, i) <= 0) {
384 "%sreinit P (%zu, %zu) negative",
msg_label, i, j);
394 if (reinit_P) {
break; }
397 if (reinit_P) {
break; }
480 if (targetPositionUpdated) {
530 if (!(_param_lpe_fusion.get() &
FUSE_LAND)) {
551 float eph_thresh = 3.0f;
552 float epv_thresh = 3.0f;
554 if (evh < _param_lpe_vxy_pub.get()) {
555 if (eph > eph_thresh) {
559 if (epv > epv_thresh) {
565 if (PX4_ISFINITE(
_x(
X_x)) && PX4_ISFINITE(
_x(
X_y)) && PX4_ISFINITE(
_x(
X_z)) &&
567 && PX4_ISFINITE(
_x(
X_vz))) {
628 if (PX4_ISFINITE(
_x(
X_x)) && PX4_ISFINITE(
_x(
X_y)) && PX4_ISFINITE(
_x(
X_z)) &&
630 && PX4_ISFINITE(
_x(
X_vz))) {
665 for (
size_t i = 0; i < POS_URT_SIZE; i++) {
681 for (
size_t i = 0; i < VEL_URT_SIZE; i++) {
703 for (
size_t i = 0; i <
n_x; i++) {
731 for (
size_t i = 16; i <= 21; i++) {
762 float eph_thresh = 3.0f;
763 float epv_thresh = 3.0f;
765 if (evh < _param_lpe_vxy_pub.get()) {
766 if (eph > eph_thresh) {
770 if (epv > epv_thresh) {
775 if (PX4_ISFINITE(lat) && PX4_ISFINITE(lon) && PX4_ISFINITE(alt) &&
776 PX4_ISFINITE(xLP(
X_vx)) && PX4_ISFINITE(xLP(
X_vy)) &&
777 PX4_ISFINITE(xLP(
X_vz))) {
802 m_P(
X_vx,
X_vx) = 2 * _param_lpe_vxy_pub.get() * _param_lpe_vxy_pub.get();
803 m_P(
X_vy,
X_vy) = 2 * _param_lpe_vxy_pub.get() * _param_lpe_vxy_pub.get();
805 m_P(
X_vz,
X_vz) = 2 * _param_lpe_vxy_pub.get() * _param_lpe_vxy_pub.get();
856 m_R(
U_ax,
U_ax) = _param_lpe_acc_xy.get() * _param_lpe_acc_xy.get();
857 m_R(
U_ay,
U_ay) = _param_lpe_acc_xy.get() * _param_lpe_acc_xy.get();
858 m_R(
U_az,
U_az) = _param_lpe_acc_z.get() * _param_lpe_acc_z.get();
862 float pn_p_sq = _param_lpe_pn_p.get() * _param_lpe_pn_p.get();
863 float pn_v_sq = _param_lpe_pn_v.get() * _param_lpe_pn_v.get();
874 float pn_b_sq = _param_lpe_pn_b.get() * _param_lpe_pn_b.get();
880 float pn_t_noise_density =
881 _param_lpe_pn_t.get() +
883 m_Q(
X_tz,
X_tz) = pn_t_noise_density * pn_t_noise_density;
954 for (
size_t i = 0; i <
n_x; i++) {
959 for (
size_t j = 0; j <
n_x; j++) {
976 for (i_hist = 1; i_hist <
HIST_LEN; i_hist++) {
979 if (t_delay > delay) {
1006 _object.store(instance);
1007 _task_id = task_id_is_work_queue;
1009 if (instance->
init()) {
1014 PX4_ERR(
"alloc failed");
1018 _object.store(
nullptr);
1028 PX4_WARN(
"%s\n", reason);
1031 PRINT_MODULE_DESCRIPTION(
1034 Attitude and position estimator using an Extended Kalman Filter. 1038 PRINT_MODULE_USAGE_NAME("local_position_estimator",
"estimator");
1039 PRINT_MODULE_USAGE_COMMAND(
"start");
1040 PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
uORB::SubscriptionData< distance_sensor_s > * _sub_sonar
void landingTargetCorrect()
void visionCheckTimeout()
uint8_t _estimatorInitialized
bool update(void *dst)
Copy the struct if updated.
orb_advert_t mavlink_log_pub
int getDelayPeriods(float delay, uint8_t *periods)
uORB::SubscriptionData< optical_flow_s > _sub_flow
int main(int argc, char **argv)
static const size_t HIST_LEN
matrix::Vector< Type, M > update(const matrix::Matrix< Type, M, 1 > &input)
uORB::SubscriptionData< distance_sensor_s > * _sub_lidar
uORB::SubscriptionData< vehicle_angular_velocity_s > _sub_angular_velocity
uORB::SubscriptionCallbackWorkItem _sensors_sub
static const float LAND_RATE
matrix::Dcm< float > _R_att
matrix::Vector< Type, M > getState()
float accelerometer_m_s2[3]
Vector< float, n_x > dynamics(float t, const Vector< float, n_x > &x, const Vector< float, n_u > &u)
void landingTargetCheckTimeout()
void copyTo(Type dst[M *N]) const
static const size_t N_DIST_SUBS
Matrix< Type, N, M > transpose() const
#define mavlink_and_console_log_info(_pub, _text,...)
Send a mavlink emergency message and print to console.
static constexpr float CONSTANTS_ONE_G
uORB::SubscriptionData< vehicle_attitude_s > _sub_att
float velocity_covariance[21]
void set_interval_ms(uint32_t interval)
Set the interval in milliseconds.
uORB::PublicationData< estimator_status_s > _pub_est_status
struct map_projection_reference_s _map_ref
uORB::PublicationData< vehicle_odometry_s > _pub_odom
float update(float input)
static const uint32_t EST_STDDEV_XY_VALID
uORB::SubscriptionData< distance_sensor_s > _sub_dist0
Matrix< float, n_u, n_u > m_R
static const float DELAY_MAX
static int print_usage(const char *reason=nullptr)
uORB::SubscriptionData< vehicle_gps_position_s > _sub_gps
int map_projection_reproject(const struct map_projection_reference_s *ref, float x, float y, double *lat, double *lon)
Transforms a point in the local azimuthal equidistant plane to the geographic coordinate system using...
matrix::Matrix< Type, M, N > update(const matrix::Matrix< Type, M, N > &u)
static int task_spawn(int argc, char *argv[])
static const float HIST_STEP
BlockLocalPositionEstimator()
void setDt(float dt) override
void predict(const sensor_combined_s &imu)
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
uORB::PublicationData< vehicle_global_position_s > _pub_gpos
Simple error/warning functions, heavily inspired by the BSD functions of the same names...
uORB::SubscriptionData< distance_sensor_s > * _dist_subs[N_DIST_SUBS]
Matrix< float, n_x, n_x > m_Q
static const float BIAS_MAX
uORB::PublicationData< vehicle_local_position_s > _pub_lpos
uORB::SubscriptionData< vehicle_air_data_s > _sub_airdata
static const uint32_t EST_STDDEV_Z_VALID
__BEGIN_DECLS typedef void * orb_advert_t
ORB topic advertiser handle.
Matrix< float, n_x, n_x > m_A
__EXPORT int local_position_estimator_main(int argc, char *argv[])
Matrix< float, n_x, n_x > m_P
uORB::SubscriptionData< vehicle_odometry_s > _sub_visual_odom
constexpr _Tp max(_Tp a, _Tp b)
BlockLowPassVector< float, n_x > _xLowPass
static int custom_command(int argc, char *argv[])
Quaternion< float > Quatf
float pose_covariance[21]
Matrix< float, n_x, n_u > m_B
uORB::SubscriptionData< actuator_armed_s > _sub_armed
static const uint32_t EST_STDDEV_TZ_VALID
matrix::Matrix< Type, M, N > get(size_t delay)
void unregisterCallback()
BlockDelay< uint64_t, 1, 1, HIST_LEN > _tDelay
uORB::SubscriptionData< distance_sensor_s > _sub_dist1
uORB::SubscriptionData< landing_target_pose_s > _sub_landing_target_pose
uint64_t _timeStampLastBaro
BlockDelay< float, n_x, 1, HIST_LEN > _xDelay
Dual< Scalar, N > abs(const Dual< Scalar, N > &a)
bool _altOriginInitialized
uORB::SubscriptionData< distance_sensor_s > _sub_dist2
int map_projection_init(struct map_projection_reference_s *ref, double lat_0, double lon_0)
Initializes the map transformation given by the argument and sets the timestamp to now...
void publishEstimatorStatus()
uORB::SubscriptionData< vehicle_odometry_s > _sub_mocap_odom
uORB::SubscriptionData< distance_sensor_s > _sub_dist3
uORB::PublicationData< ekf2_innovations_s > _pub_innov
__EXPORT hrt_abstime hrt_absolute_time(void)
Get absolute time in [us] (does not wrap).
uORB::SubscriptionData< parameter_update_s > _sub_param_update
uORB::SubscriptionData< vehicle_land_detected_s > _sub_land
static const char * msg_label