PX4 Firmware
PX4 Autopilot Software http://px4.io
sonar.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 int REQ_SONAR_INIT_COUNT = 10;
10 static const uint32_t SONAR_TIMEOUT = 5000000; // 2.0 s
11 static const float SONAR_MAX_INIT_STD = 0.3f; // meters
12 
14 {
15  // measure
17 
18  if (_sonarStats.getCount() == 0) {
20  }
21 
22  if (sonarMeasure(y) != OK) {
23  return;
24  }
25 
26  // if finished
29  mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] sonar init std > min");
31 
32  } else if ((_timeStamp - _time_init_sonar) > SONAR_TIMEOUT) {
33  mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] sonar init timeout ");
35 
36  } else {
37  PX4_INFO("[lpe] sonar init "
38  "mean %d cm std %d cm",
39  int(100 * _sonarStats.getMean()(0)),
40  int(100 * _sonarStats.getStdDev()(0)));
43  }
44  }
45 }
46 
48 {
49  // measure
50  float d = _sub_sonar->get().current_distance;
51  float eps = 0.01f; // 1 cm
52  float min_dist = _sub_sonar->get().min_distance + eps;
53  float max_dist = _sub_sonar->get().max_distance - eps;
54 
55  // prevent driver from setting min dist below eps
56  if (min_dist < eps) {
57  min_dist = eps;
58  }
59 
60  // check for bad data
61  if (d > max_dist || d < min_dist) {
62  return -1;
63  }
64 
65  // update stats
68  y.setZero();
70  y(0) = (d + _param_lpe_snr_off_z.get()) *
71  cosf(euler.phi()) *
72  cosf(euler.theta());
73  return OK;
74 }
75 
77 {
78  // measure
80 
81  if (sonarMeasure(y) != OK) { return; }
82 
83  // do not use sonar if lidar is active and not faulty or timed out
84  if (_lidarUpdated
86  && !(_sensorTimeout & SENSOR_LIDAR)) { return; }
87 
88  // calculate covariance
89  float cov = _sub_sonar->get().variance;
90 
91  if (cov < 1.0e-3f) {
92  // use sensor value if reasoanble
93  cov = _param_lpe_snr_z.get() * _param_lpe_snr_z.get();
94  }
95 
96  // sonar measurement matrix and noise matrix
98  C.setZero();
99  // y = -(z - tz)
100  // TODO could add trig to make this an EKF correction
101  C(Y_sonar_z, X_z) = -1; // measured altitude, negative down dir.
102  C(Y_sonar_z, X_tz) = 1; // measured altitude, negative down dir.
103 
104  // covariance matrix
106  R.setZero();
107  R(0, 0) = cov;
108 
109  // residual
110  Vector<float, n_y_sonar> r = y - C * _x;
111  // residual covariance
113 
114  // publish innovations
115  _pub_innov.get().hagl_innov = r(0);
116  _pub_innov.get().hagl_innov_var = S(0, 0);
117 
118  // residual covariance, (inverse)
119  Matrix<float, n_y_sonar, n_y_sonar> S_I = inv<float, n_y_sonar>(S);
120 
121  // fault detection
122  float beta = (r.transpose() * (S_I * r))(0, 0);
123 
124  if (beta > BETA_TABLE[n_y_sonar]) {
125  if (!(_sensorFault & SENSOR_SONAR)) {
127  mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] sonar fault, beta %5.2f", double(beta));
128  }
129 
130  // abort correction
131  return;
132 
133  } else if (_sensorFault & SENSOR_SONAR) {
134  _sensorFault &= ~SENSOR_SONAR;
135  //mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] sonar OK");
136  }
137 
138  // kalman filter correction if no fault
139  if (!(_sensorFault & SENSOR_SONAR)) {
141  m_P * C.transpose() * S_I;
142  Vector<float, n_x> dx = K * r;
143  _x += dx;
144  m_P -= K * C * m_P;
145  }
146 }
147 
149 {
151  if (!(_sensorTimeout & SENSOR_SONAR)) {
153  _sonarStats.reset();
154  mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] sonar timeout ");
155  }
156  }
157 }
uORB::SubscriptionData< distance_sensor_s > * _sub_sonar
static const float BETA_TABLE[7]
Type theta() const
Definition: Euler.hpp:132
matrix::Vector< Type, M > getMean()
Definition: BlockStats.hpp:85
BlockStats< float, n_y_sonar > _sonarStats
Type phi() const
Definition: Euler.hpp:128
Quaternion class.
Definition: Dcm.hpp:24
Matrix< Type, N, M > transpose() const
Definition: Matrix.hpp:353
uORB::SubscriptionData< vehicle_attitude_s > _sub_att
Scalar< float > Scalarf
Definition: Scalar.hpp:53
int sonarMeasure(Vector< float, n_y_sonar > &y)
Definition: sonar.cpp:47
static const int REQ_SONAR_INIT_COUNT
Definition: sonar.cpp:9
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Definition: integration.cpp:8
Euler angles class.
Definition: AxisAngle.hpp:18
__BEGIN_DECLS typedef void * orb_advert_t
ORB topic advertiser handle.
Definition: uORB.h:134
const T & get() const
matrix::Vector< Type, M > getStdDev()
Definition: BlockStats.hpp:90
#define OK
Definition: uavcan_main.cpp:71
static const float SONAR_MAX_INIT_STD
Definition: sonar.cpp:11
static const uint32_t SONAR_TIMEOUT
Definition: sonar.cpp:10
uORB::PublicationData< ekf2_innovations_s > _pub_innov
orb_advert_t mavlink_log_pub
void update(const matrix::Vector< Type, M > &u)
Definition: BlockStats.hpp:71