PX4 Firmware
PX4 Autopilot Software http://px4.io
vision.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 to initialize.
8 // This is a vision based position measurement so we assume
9 // as soon as we get one measurement it is initialized.
10 static const uint32_t REQ_VISION_INIT_COUNT = 1;
11 
12 // We don't want to deinitialize it because
13 // this will throw away a correction before it starts using the data so we
14 // set the timeout to 0.5 seconds
15 static const uint32_t VISION_TIMEOUT = 500000; // 0.5 s
16 
17 // set pose/velocity as invalid if standard deviation is bigger than EP_MAX_STD_DEV
18 // TODO: the user should be allowed to set these values by a parameter
19 static constexpr float EP_MAX_STD_DEV = 100.0f;
20 
22 {
23  // measure
25 
26  if (visionMeasure(y) != OK) {
28  return;
29  }
30 
31  // increament sums for mean
33  mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] vision position init: "
34  "%5.2f %5.2f %5.2f m std %5.2f %5.2f %5.2f m",
35  double(_visionStats.getMean()(0)),
36  double(_visionStats.getMean()(1)),
37  double(_visionStats.getMean()(2)),
38  double(_visionStats.getStdDev()(0)),
39  double(_visionStats.getStdDev()(1)),
40  double(_visionStats.getStdDev()(2)));
43 
44  // get reference for global position
48 
50  // initialize global origin using the visual estimator reference
51  mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] global origin init (vision) : lat %6.2f lon %6.2f alt %5.1f m",
52  double(_ref_lat), double(_ref_lon), double(_ref_alt));
54  // set timestamp when origin was set to current time
56  }
57 
58  if (!_altOriginInitialized) {
59  _altOriginInitialized = true;
60  _altOriginGlobal = true;
62  }
63  }
64 }
65 
67 {
68  uint8_t x_variance = _sub_visual_odom.get().COVARIANCE_MATRIX_X_VARIANCE;
69  uint8_t y_variance = _sub_visual_odom.get().COVARIANCE_MATRIX_Y_VARIANCE;
70  uint8_t z_variance = _sub_visual_odom.get().COVARIANCE_MATRIX_Z_VARIANCE;
71 
72  if (PX4_ISFINITE(_sub_visual_odom.get().pose_covariance[x_variance])) {
73  // check if the vision data is valid based on the covariances
74  _vision_eph = sqrtf(fmaxf(_sub_visual_odom.get().pose_covariance[x_variance],
75  _sub_visual_odom.get().pose_covariance[y_variance]));
76  _vision_epv = sqrtf(_sub_visual_odom.get().pose_covariance[z_variance]);
79 
80  } else {
81  // if we don't have covariances, assume every reading
82  _vision_xy_valid = true;
83  _vision_z_valid = true;
84  }
85 
88  return -1;
89 
90  } else {
92 
93  if (PX4_ISFINITE(_sub_visual_odom.get().x)) {
94  y.setZero();
99 
100  return OK;
101 
102  } else {
103  return -1;
104  }
105  }
106 }
107 
109 {
110  // measure
112 
113  if (visionMeasure(y) != OK) {
114  mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] vision data invalid. eph: %f epv: %f", (double)_vision_eph,
115  (double)_vision_epv);
116  return;
117  }
118 
119  // vision measurement matrix, measures position
121  C.setZero();
122  C(Y_vision_x, X_x) = 1;
123  C(Y_vision_y, X_y) = 1;
124  C(Y_vision_z, X_z) = 1;
125 
126  // noise matrix
128  R.setZero();
129 
130  // use std dev from vision data if available
131  if (_vision_eph > _param_lpe_vis_xy.get()) {
133  R(Y_vision_y, Y_vision_y) = _vision_eph * _vision_eph;
134 
135  } else {
136  R(Y_vision_x, Y_vision_x) = _param_lpe_vis_xy.get() * _param_lpe_vis_xy.get();
137  R(Y_vision_y, Y_vision_y) = _param_lpe_vis_xy.get() * _param_lpe_vis_xy.get();
138  }
139 
140  if (_vision_epv > _param_lpe_vis_z.get()) {
142 
143  } else {
144  R(Y_vision_z, Y_vision_z) = _param_lpe_vis_z.get() * _param_lpe_vis_z.get();
145  }
146 
147  // vision delayed x
148  uint8_t i_hist = 0;
149 
150  float vision_delay = (_timeStamp - _sub_visual_odom.get().timestamp) * 1e-6f; // measurement delay in seconds
151 
152  if (vision_delay < 0.0f) { vision_delay = 0.0f; }
153 
154  // use auto-calculated delay from measurement if parameter is set to zero
155  if (getDelayPeriods(_param_lpe_vis_delay.get() > 0.0f ? _param_lpe_vis_delay.get() : vision_delay, &i_hist) < 0) { return; }
156 
157  Vector<float, n_x> x0 = _xDelay.get(i_hist);
158 
159  // residual
160  Matrix<float, n_y_vision, 1> r = y - C * x0;
161  // residual covariance
163 
164  // publish innovations
165  for (size_t i = 0; i < 3; i++) {
166  _pub_innov.get().vel_pos_innov[i] = r(i, 0);
167  _pub_innov.get().vel_pos_innov_var[i] = S(i, i);
168  }
169 
170  for (size_t i = 3; i < 6; i++) {
171  _pub_innov.get().vel_pos_innov[i] = 0;
173  }
174 
175  // residual covariance, (inverse)
176  Matrix<float, n_y_vision, n_y_vision> S_I = inv<float, n_y_vision>(S);
177 
178  // fault detection
179  float beta = (r.transpose() * (S_I * r))(0, 0);
180 
181  if (beta > BETA_TABLE[n_y_vision]) {
182  if (!(_sensorFault & SENSOR_VISION)) {
183  mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] vision position fault, beta %5.2f", double(beta));
185  }
186 
187  } else if (_sensorFault & SENSOR_VISION) {
188  _sensorFault &= ~SENSOR_VISION;
189  mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] vision position OK");
190  }
191 
192  // kalman filter correction if no fault
193  if (!(_sensorFault & SENSOR_VISION)) {
195  Vector<float, n_x> dx = K * r;
196  _x += dx;
197  m_P -= K * C * m_P;
198  }
199 }
200 
202 {
204  if (!(_sensorTimeout & SENSOR_VISION)) {
207  mavlink_log_critical(&mavlink_log_pub, "[lpe] vision position timeout ");
208  }
209  }
210 }
static const float BETA_TABLE[7]
matrix::Vector< Type, M > getMean()
Definition: BlockStats.hpp:85
int getDelayPeriods(float delay, uint8_t *periods)
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
struct map_projection_reference_s _map_ref
static constexpr float EP_MAX_STD_DEV
Definition: vision.cpp:19
orb_advert_t mavlink_log_pub
static const uint32_t REQ_VISION_INIT_COUNT
Definition: vision.cpp:10
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Definition: integration.cpp:8
__BEGIN_DECLS typedef void * orb_advert_t
ORB topic advertiser handle.
Definition: uORB.h:134
const T & get() const
int visionMeasure(Vector< float, n_y_vision > &y)
Definition: vision.cpp:66
matrix::Vector< Type, M > getStdDev()
Definition: BlockStats.hpp:90
uORB::SubscriptionData< vehicle_odometry_s > _sub_visual_odom
matrix::Matrix< Type, M, N > get(size_t delay)
Definition: BlockDelay.hpp:99
bool globallocalconverter_initialized()
Checks if globallocalconverter was initialized.
Definition: geo.cpp:224
static const uint32_t VISION_TIMEOUT
Definition: vision.cpp:15
BlockStats< float, n_y_vision > _visionStats
#define OK
Definition: uavcan_main.cpp:71
BlockDelay< float, n_x, 1, HIST_LEN > _xDelay
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::PublicationData< ekf2_innovations_s > _pub_innov
void update(const matrix::Vector< Type, M > &u)
Definition: BlockStats.hpp:71