PX4 Firmware
PX4 Autopilot Software http://px4.io
mocap.cpp
Go to the documentation of this file.
1 #include "../BlockLocalPositionEstimator.hpp"
3 #include <matrix/math.hpp>
4 
6 
7 // required number of samples for sensor
8 // to initialize
9 static const uint32_t REQ_MOCAP_INIT_COUNT = 20;
10 static const uint32_t MOCAP_TIMEOUT = 200000; // 0.2 s
11 
12 // set pose/velocity as invalid if standard deviation is bigger than EP_MAX_STD_DEV
13 // TODO: the user should be allowed to set these values by a parameter
14 static constexpr float EP_MAX_STD_DEV = 100.0f;
15 
17 {
18  // measure
20 
21  if (mocapMeasure(y) != OK) {
23  return;
24  }
25 
26  // if finished
28  mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] mocap position init: "
29  "%5.2f, %5.2f, %5.2f m std %5.2f, %5.2f, %5.2f m",
30  double(_mocapStats.getMean()(0)),
31  double(_mocapStats.getMean()(1)),
32  double(_mocapStats.getMean()(2)),
33  double(_mocapStats.getStdDev()(0)),
34  double(_mocapStats.getStdDev()(1)),
35  double(_mocapStats.getStdDev()(2)));
38 
39  // get reference for global position
43 
45  // initialize global origin using the mocap estimator reference (only if the vision estimation is not being fused as well)
46  mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] global origin init (mocap) : lat %6.2f lon %6.2f alt %5.1f m",
47  double(_ref_lat), double(_ref_lon), double(_ref_alt));
49  // set timestamp when origin was set to current time
51  }
52 
53  if (!_altOriginInitialized) {
54  _altOriginInitialized = true;
55  _altOriginGlobal = true;
57  }
58  }
59 }
60 
62 {
63  uint8_t x_variance = _sub_mocap_odom.get().COVARIANCE_MATRIX_X_VARIANCE;
64  uint8_t y_variance = _sub_mocap_odom.get().COVARIANCE_MATRIX_Y_VARIANCE;
65  uint8_t z_variance = _sub_mocap_odom.get().COVARIANCE_MATRIX_Z_VARIANCE;
66 
67  if (PX4_ISFINITE(_sub_mocap_odom.get().pose_covariance[x_variance])) {
68  // check if the mocap data is valid based on the covariances
69  _mocap_eph = sqrtf(fmaxf(_sub_mocap_odom.get().pose_covariance[x_variance],
70  _sub_mocap_odom.get().pose_covariance[y_variance]));
71  _mocap_epv = sqrtf(_sub_mocap_odom.get().pose_covariance[z_variance]);
74 
75  } else {
76  // if we don't have covariances, assume every reading
77  _mocap_xy_valid = true;
78  _mocap_z_valid = true;
79  }
80 
83  return -1;
84 
85  } else {
87 
88  if (PX4_ISFINITE(_sub_mocap_odom.get().x)) {
89  y.setZero();
94 
95  return OK;
96 
97  } else {
98  return -1;
99  }
100  }
101 }
102 
104 {
105  // measure
107 
108  if (mocapMeasure(y) != OK) {
109  mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] mocap data invalid. eph: %f epv: %f", (double)_mocap_eph,
110  (double)_mocap_epv);
111  return;
112  }
113 
114  // mocap measurement matrix, measures position
116  C.setZero();
117  C(Y_mocap_x, X_x) = 1;
118  C(Y_mocap_y, X_y) = 1;
119  C(Y_mocap_z, X_z) = 1;
120 
121  // noise matrix
123  R.setZero();
124 
125  // use std dev from mocap data if available
126  if (_mocap_eph > _param_lpe_vic_p.get()) {
128  R(Y_mocap_y, Y_mocap_y) = _mocap_eph * _mocap_eph;
129 
130  } else {
131  R(Y_mocap_x, Y_mocap_x) = _param_lpe_vic_p.get() * _param_lpe_vic_p.get();
132  R(Y_mocap_y, Y_mocap_y) = _param_lpe_vic_p.get() * _param_lpe_vic_p.get();
133  }
134 
135  if (_mocap_epv > _param_lpe_vic_p.get()) {
137 
138  } else {
139  R(Y_mocap_z, Y_mocap_z) = _param_lpe_vic_p.get() * _param_lpe_vic_p.get();
140  }
141 
142  // residual
143  Vector<float, n_y_mocap> r = y - C * _x;
144  // residual covariance
146 
147  // publish innovations
148  for (size_t i = 0; i < 3; i++) {
149  _pub_innov.get().vel_pos_innov[i] = r(i);
150  _pub_innov.get().vel_pos_innov_var[i] = S(i, i);
151  }
152 
153  for (size_t i = 3; i < 6; i++) {
154  _pub_innov.get().vel_pos_innov[i] = 0;
156  }
157 
158  // residual covariance, (inverse)
159  Matrix<float, n_y_mocap, n_y_mocap> S_I = inv<float, n_y_mocap>(S);
160 
161  // fault detection
162  float beta = (r.transpose() * (S_I * r))(0, 0);
163 
164  if (beta > BETA_TABLE[n_y_mocap]) {
165  if (!(_sensorFault & SENSOR_MOCAP)) {
166  //mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] mocap fault, beta %5.2f", double(beta));
168  }
169 
170  } else if (_sensorFault & SENSOR_MOCAP) {
171  _sensorFault &= ~SENSOR_MOCAP;
172  //mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] mocap OK");
173  }
174 
175  // kalman filter correction always
177  Vector<float, n_x> dx = K * r;
178  _x += dx;
179  m_P -= K * C * m_P;
180 }
181 
183 {
185  if (!(_sensorTimeout & SENSOR_MOCAP)) {
187  _mocapStats.reset();
188  mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] mocap timeout ");
189  }
190  }
191 }
static const float BETA_TABLE[7]
matrix::Vector< Type, M > getMean()
Definition: BlockStats.hpp:85
int globallocalconverter_getref(double *lat_0, double *lon_0, float *alt_0)
Get reference position of the global to local converter.
Definition: geo.cpp:253
Matrix< Type, N, M > transpose() const
Definition: Matrix.hpp:353
static const uint32_t REQ_MOCAP_INIT_COUNT
Definition: mocap.cpp:9
struct map_projection_reference_s _map_ref
BlockStats< float, n_y_mocap > _mocapStats
int mocapMeasure(Vector< float, n_y_mocap > &y)
Definition: mocap.cpp:61
__BEGIN_DECLS typedef void * orb_advert_t
ORB topic advertiser handle.
Definition: uORB.h:134
const T & get() const
orb_advert_t mavlink_log_pub
matrix::Vector< Type, M > getStdDev()
Definition: BlockStats.hpp:90
static const uint32_t MOCAP_TIMEOUT
Definition: mocap.cpp:10
bool globallocalconverter_initialized()
Checks if globallocalconverter was initialized.
Definition: geo.cpp:224
#define OK
Definition: uavcan_main.cpp:71
static constexpr float EP_MAX_STD_DEV
Definition: mocap.cpp:14
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...
Definition: geo.cpp:105
uORB::SubscriptionData< vehicle_odometry_s > _sub_mocap_odom
uORB::PublicationData< ekf2_innovations_s > _pub_innov
void update(const matrix::Vector< Type, M > &u)
Definition: BlockStats.hpp:71