PX4 Firmware
PX4 Autopilot Software http://px4.io
BlockLocalPositionEstimator.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <drivers/drv_hrt.h>
4 #include <px4_platform_common/module.h>
5 #include <px4_platform_common/module_params.h>
6 #include <px4_platform_common/posix.h>
8 #include <lib/ecl/geo/geo.h>
9 #include <lib/mathlib/mathlib.h>
10 #include <matrix/Matrix.hpp>
11 
12 // uORB Subscriptions
13 #include <uORB/Subscription.hpp>
31 
32 // uORB Publications
33 #include <uORB/Publication.hpp>
38 
39 using namespace matrix;
40 using namespace control;
41 using namespace time_literals;
42 
43 static const float DELAY_MAX = 0.5f; // seconds
44 static const float HIST_STEP = 0.05f; // 20 hz
45 static const float BIAS_MAX = 1e-1f;
46 static const size_t HIST_LEN = 10; // DELAY_MAX / HIST_STEP;
47 static const size_t N_DIST_SUBS = 4;
48 
49 // for fault detection
50 // chi squared distribution, false alarm probability 0.0001
51 // see fault_table.py
52 // note skip 0 index so we can use degree of freedom as index
53 static const float BETA_TABLE[7] = {0,
54  8.82050518214,
55  12.094592431,
56  13.9876612368,
57  16.0875642296,
58  17.8797700658,
59  19.6465647819,
60  };
61 
62 class BlockLocalPositionEstimator : public ModuleBase<BlockLocalPositionEstimator>, public ModuleParams,
63  public px4::WorkItem, public control::SuperBlock
64 {
65 // dynamics:
66 //
67 // x(+) = A * x(-) + B * u(+)
68 // y_i = C_i*x
69 //
70 // kalman filter
71 //
72 // E[xx'] = P
73 // E[uu'] = W
74 // E[y_iy_i'] = R_i
75 //
76 // prediction
77 // x(+|-) = A*x(-|-) + B*u(+)
78 // P(+|-) = A*P(-|-)*A' + B*W*B'
79 //
80 // correction
81 // x(+|+) = x(+|-) + K_i * (y_i - H_i * x(+|-) )
82 //
83 //
84 // input:
85 // ax, ay, az (acceleration NED)
86 //
87 // states:
88 // px, py, pz , ( position NED, m)
89 // vx, vy, vz ( vel NED, m/s),
90 // bx, by, bz ( accel bias, m/s^2)
91 // tz (terrain altitude, ASL, m)
92 //
93 // measurements:
94 //
95 // sonar: pz (measured d*cos(phi)*cos(theta))
96 //
97 // baro: pz
98 //
99 // flow: vx, vy (flow is in body x, y frame)
100 //
101 // gps: px, py, pz, vx, vy, vz (flow is in body x, y frame)
102 //
103 // lidar: pz (actual measured d*cos(phi)*cos(theta))
104 //
105 // vision: px, py, pz, vx, vy, vz
106 //
107 // mocap: px, py, pz
108 //
109 // land (detects when landed)): pz (always measures agl = 0)
110 //
111 public:
112 
114  ~BlockLocalPositionEstimator() override = default;
115 
116  /** @see ModuleBase */
117  static int task_spawn(int argc, char *argv[]);
118 
119  /** @see ModuleBase */
120  static int custom_command(int argc, char *argv[]);
121 
122  /** @see ModuleBase */
123  static int print_usage(const char *reason = nullptr);
124 
125  bool init();
126 
127 private:
128 
129  // constants
130  enum {X_x = 0, X_y, X_z, X_vx, X_vy, X_vz, X_bx, X_by, X_bz, X_tz, n_x};
131  enum {U_ax = 0, U_ay, U_az, n_u};
132  enum {Y_baro_z = 0, n_y_baro};
133  enum {Y_lidar_z = 0, n_y_lidar};
134  enum {Y_flow_vx = 0, Y_flow_vy, n_y_flow};
135  enum {Y_sonar_z = 0, n_y_sonar};
136  enum {Y_gps_x = 0, Y_gps_y, Y_gps_z, Y_gps_vx, Y_gps_vy, Y_gps_vz, n_y_gps};
137  enum {Y_vision_x = 0, Y_vision_y, Y_vision_z, n_y_vision};
138  enum {Y_mocap_x = 0, Y_mocap_y, Y_mocap_z, n_y_mocap};
139  enum {Y_land_vx = 0, Y_land_vy, Y_land_agl, n_y_land};
140  enum {Y_target_x = 0, Y_target_y, n_y_target};
141  enum {
142  FUSE_GPS = 1 << 0,
143  FUSE_FLOW = 1 << 1,
144  FUSE_VIS_POS = 1 << 2,
145  FUSE_LAND_TARGET = 1 << 3,
146  FUSE_LAND = 1 << 4,
147  FUSE_PUB_AGL_Z = 1 << 5,
148  FUSE_FLOW_GYRO_COMP = 1 << 6,
149  FUSE_BARO = 1 << 7
150  };
151 
152  enum sensor_t {
153  SENSOR_BARO = 1 << 0,
154  SENSOR_GPS = 1 << 1,
155  SENSOR_LIDAR = 1 << 2,
156  SENSOR_FLOW = 1 << 3,
157  SENSOR_SONAR = 1 << 4,
158  SENSOR_VISION = 1 << 5,
159  SENSOR_MOCAP = 1 << 6,
160  SENSOR_LAND = 1 << 7,
161  SENSOR_LAND_TARGET = 1 << 8,
162  };
163 
164  enum estimate_t {
165  EST_XY = 1 << 0,
166  EST_Z = 1 << 1,
167  EST_TZ = 1 << 2,
168  };
169 
170  void Run() override;
171 
172  // methods
173  // ----------------------------
174  //
175  Vector<float, n_x> dynamics(
176  float t,
177  const Vector<float, n_x> &x,
178  const Vector<float, n_u> &u);
179  void initP();
180  void initSS();
181  void updateSSStates();
182  void updateSSParams();
183 
184  // predict the next state
185  void predict(const sensor_combined_s &imu);
186 
187  // lidar
188  int lidarMeasure(Vector<float, n_y_lidar> &y);
189  void lidarCorrect();
190  void lidarInit();
191  void lidarCheckTimeout();
192 
193  // sonar
194  int sonarMeasure(Vector<float, n_y_sonar> &y);
195  void sonarCorrect();
196  void sonarInit();
197  void sonarCheckTimeout();
198 
199  // baro
200  int baroMeasure(Vector<float, n_y_baro> &y);
201  void baroCorrect();
202  void baroInit();
203  void baroCheckTimeout();
204 
205  // gps
206  int gpsMeasure(Vector<double, n_y_gps> &y);
207  void gpsCorrect();
208  void gpsInit();
209  void gpsCheckTimeout();
210 
211  // flow
212  int flowMeasure(Vector<float, n_y_flow> &y);
213  void flowCorrect();
214  void flowInit();
215  void flowCheckTimeout();
216 
217  // vision
218  int visionMeasure(Vector<float, n_y_vision> &y);
219  void visionCorrect();
220  void visionInit();
221  void visionCheckTimeout();
222 
223  // mocap
224  int mocapMeasure(Vector<float, n_y_mocap> &y);
225  void mocapCorrect();
226  void mocapInit();
227  void mocapCheckTimeout();
228 
229  // land
230  int landMeasure(Vector<float, n_y_land> &y);
231  void landCorrect();
232  void landInit();
233  void landCheckTimeout();
234 
235  // landing target
236  int landingTargetMeasure(Vector<float, n_y_target> &y);
237  void landingTargetCorrect();
238  void landingTargetInit();
239  void landingTargetCheckTimeout();
240 
241  // timeouts
242  void checkTimeouts();
243 
244  // misc
245  inline float agl()
246  {
247  return _x(X_tz) - _x(X_z);
248  }
249  bool landed();
250  int getDelayPeriods(float delay, uint8_t *periods);
251 
252  // publications
253  void publishLocalPos();
254  void publishGlobalPos();
255  void publishOdom();
256  void publishEstimatorStatus();
257 
258  // attributes
259  // ----------------------------
260 
261  // subscriptions
262  uORB::SubscriptionCallbackWorkItem _sensors_sub{this, ORB_ID(sensor_combined)};
263 
265  uORB::SubscriptionData<vehicle_land_detected_s> _sub_land{ORB_ID(vehicle_land_detected)};
267  uORB::SubscriptionData<vehicle_angular_velocity_s> _sub_angular_velocity{ORB_ID(vehicle_angular_velocity)};
269  uORB::SubscriptionData<parameter_update_s> _sub_param_update{ORB_ID(parameter_update)};
271  uORB::SubscriptionData<vehicle_odometry_s> _sub_visual_odom{ORB_ID(vehicle_visual_odometry)};
272  uORB::SubscriptionData<vehicle_odometry_s> _sub_mocap_odom{ORB_ID(vehicle_mocap_odometry)};
273  uORB::SubscriptionData<distance_sensor_s> _sub_dist0{ORB_ID(distance_sensor), 0};
274  uORB::SubscriptionData<distance_sensor_s> _sub_dist1{ORB_ID(distance_sensor), 1};
275  uORB::SubscriptionData<distance_sensor_s> _sub_dist2{ORB_ID(distance_sensor), 2};
276  uORB::SubscriptionData<distance_sensor_s> _sub_dist3{ORB_ID(distance_sensor), 3};
280  uORB::SubscriptionData<landing_target_pose_s> _sub_landing_target_pose{ORB_ID(landing_target_pose)};
281  uORB::SubscriptionData<vehicle_air_data_s> _sub_airdata{ORB_ID(vehicle_air_data)};
282 
283  // publications
284  uORB::PublicationData<vehicle_local_position_s> _pub_lpos{ORB_ID(vehicle_local_position)};
285  uORB::PublicationData<vehicle_global_position_s> _pub_gpos{ORB_ID(vehicle_global_position)};
286  uORB::PublicationData<vehicle_odometry_s> _pub_odom{ORB_ID(vehicle_odometry)};
287  uORB::PublicationData<estimator_status_s> _pub_est_status{ORB_ID(estimator_status)};
288  uORB::PublicationData<ekf2_innovations_s> _pub_innov{ORB_ID(ekf2_innovations)};
289 
290  // map projection
291  struct map_projection_reference_s _map_ref;
292 
293  // target mode paramters from landing_target_estimator module
294  enum TargetMode {
295  Target_Moving = 0,
296  Target_Stationary = 1
297  };
298 
299  // flow gyro filter
302 
303  // stats
311  uint16_t _landCount;
312 
313  // low pass
316 
317  // delay blocks
320 
321  // misc
322  uint64_t _timeStamp;
323  uint64_t _time_origin;
325  uint64_t _time_last_hist;
326  uint64_t _time_last_flow;
327  uint64_t _time_last_baro;
328  uint64_t _time_last_gps;
334  uint64_t _time_last_land;
336 
337  // reference altitudes
338  float _altOrigin;
340  bool _altOriginGlobal; // true when the altitude of the origin is defined wrt a global reference frame
343 
344  // status
347 
348  // masks
349  uint16_t _sensorTimeout;
350  uint16_t _sensorFault;
352 
353  // sensor update flags
362 
363  // sensor validation flags
368 
369  // sensor std deviations
370  float _vision_eph;
371  float _vision_epv;
372  float _mocap_eph;
373  float _mocap_epv;
374 
375  // local to global coversion related variables
378  double _ref_lat;
379  double _ref_lon;
380  float _ref_alt;
381 
382  // state space
383  Vector<float, n_x> _x; // state vector
384  Vector<float, n_u> _u; // input vector
385  Matrix<float, n_x, n_x> m_P; // state covariance matrix
386 
388 
389  Matrix<float, n_x, n_x> m_A; // dynamics matrix
390  Matrix<float, n_x, n_u> m_B; // input matrix
391  Matrix<float, n_u, n_u> m_R; // input covariance
392  Matrix<float, n_x, n_x> m_Q; // process noise covariance
393 
394 
395  DEFINE_PARAMETERS(
396  (ParamInt<px4::params::SYS_AUTOSTART>) _param_sys_autostart, /**< example parameter */
397 
398  // general parameters
399  (ParamInt<px4::params::LPE_FUSION>) _param_lpe_fusion,
400  (ParamFloat<px4::params::LPE_VXY_PUB>) _param_lpe_vxy_pub,
401  (ParamFloat<px4::params::LPE_Z_PUB>) _param_lpe_z_pub,
402 
403  // sonar parameters
404  (ParamFloat<px4::params::LPE_SNR_Z>) _param_lpe_snr_z,
405  (ParamFloat<px4::params::LPE_SNR_OFF_Z>) _param_lpe_snr_off_z,
406 
407  // lidar parameters
408  (ParamFloat<px4::params::LPE_LDR_Z>) _param_lpe_ldr_z,
409  (ParamFloat<px4::params::LPE_LDR_OFF_Z>) _param_lpe_ldr_off_z,
410 
411  // accel parameters
412  (ParamFloat<px4::params::LPE_ACC_XY>) _param_lpe_acc_xy,
413  (ParamFloat<px4::params::LPE_ACC_Z>) _param_lpe_acc_z,
414 
415  // baro parameters
416  (ParamFloat<px4::params::LPE_BAR_Z>) _param_lpe_bar_z,
417 
418  // gps parameters
419  (ParamFloat<px4::params::LPE_GPS_DELAY>) _param_lpe_gps_delay,
420  (ParamFloat<px4::params::LPE_GPS_XY>) _param_lpe_gps_xy,
421  (ParamFloat<px4::params::LPE_GPS_Z>) _param_lpe_gps_z,
422  (ParamFloat<px4::params::LPE_GPS_VXY>) _param_lpe_gps_vxy,
423  (ParamFloat<px4::params::LPE_GPS_VZ>) _param_lpe_gps_vz,
424  (ParamFloat<px4::params::LPE_EPH_MAX>) _param_lpe_eph_max,
425  (ParamFloat<px4::params::LPE_EPV_MAX>) _param_lpe_epv_max,
426 
427  // vision parameters
428  (ParamFloat<px4::params::LPE_VIS_XY>) _param_lpe_vis_xy,
429  (ParamFloat<px4::params::LPE_VIS_Z>) _param_lpe_vis_z,
430  (ParamFloat<px4::params::LPE_VIS_DELAY>) _param_lpe_vis_delay,
431 
432  // mocap parameters
433  (ParamFloat<px4::params::LPE_VIC_P>) _param_lpe_vic_p,
434 
435  // flow parameters
436  (ParamFloat<px4::params::LPE_FLW_OFF_Z>) _param_lpe_flw_off_z,
437  (ParamFloat<px4::params::LPE_FLW_SCALE>) _param_lpe_flw_scale,
438  (ParamInt<px4::params::LPE_FLW_QMIN>) _param_lpe_flw_qmin,
439  (ParamFloat<px4::params::LPE_FLW_R>) _param_lpe_flw_r,
440  (ParamFloat<px4::params::LPE_FLW_RR>) _param_lpe_flw_rr,
441 
442  // land parameters
443  (ParamFloat<px4::params::LPE_LAND_Z>) _param_lpe_land_z,
444  (ParamFloat<px4::params::LPE_LAND_VXY>) _param_lpe_land_vxy,
445 
446  // process noise
447  (ParamFloat<px4::params::LPE_PN_P>) _param_lpe_pn_p,
448  (ParamFloat<px4::params::LPE_PN_V>) _param_lpe_pn_v,
449  (ParamFloat<px4::params::LPE_PN_B>) _param_lpe_pn_b,
450  (ParamFloat<px4::params::LPE_PN_T>) _param_lpe_pn_t,
451  (ParamFloat<px4::params::LPE_T_MAX_GRADE>) _param_lpe_t_max_grade,
452 
453  (ParamFloat<px4::params::LPE_LT_COV>) _param_lpe_lt_cov,
454  (ParamInt<px4::params::LTEST_MODE>) _param_ltest_mode,
455 
456  // init origin
457  (ParamInt<px4::params::LPE_FAKE_ORIGIN>) _param_lpe_fake_origin,
458  (ParamFloat<px4::params::LPE_LAT>) _param_lpe_lat,
459  (ParamFloat<px4::params::LPE_LON>) _param_lpe_lon
460  )
461 
462 };
static const float BETA_TABLE[7]
BlockStats< float, n_y_lidar > _lidarStats
BlockStats< float, n_y_sonar > _sonarStats
Definition of geo / math functions to perform geodesic calculations.
BlockStats< float, n_y_baro > _baroStats
static const size_t HIST_LEN
A high pass filter as described here: http://en.wikipedia.org/wiki/High-pass_filter.
BlockStats< double, n_y_gps > _gpsStats
static void print_usage()
High-resolution timer with callouts and timekeeping.
static const size_t N_DIST_SUBS
A low pass filter as described here: http://en.wikipedia.org/wiki/Low-pass_filter.
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic.
Definition: uORB.h:87
static const float DELAY_MAX
void init()
Activates/configures the hardware registers.
BlockStats< float, n_y_mocap > _mocapStats
static const float HIST_STEP
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Definition: integration.cpp:8
static const float BIAS_MAX
BlockLowPassVector< float, n_x > _xLowPass
Controller library code.
BlockDelay< uint64_t, 1, 1, HIST_LEN > _tDelay
A simple matrix template library.
BlockStats< float, n_y_vision > _visionStats
BlockDelay< float, n_x, 1, HIST_LEN > _xDelay