Range check cleanup (#782)

* EKF: centralize range finder tilt check

* Ekf-control: do not double check for terrain estimate validity

isRangeAidSuitable can only return true if the terrain estimate is valid
so there is no need for an additional check

* range_finder_checks: restructure the checks to avoid early returns

There is now only one clear path that can lead to the validity being
true.
Furthermore, if the _rng_hgt_valid is true, we can trust it and we don't
need for additional checks such as tilt.

The case where we need to provide fake measurements because the drone is
on the ground and the range finder data is bad is already handled
in "controlHeightFusion" so there is no need to hack the range finder
checks with that.

* Add Sensor and SensorRangeFinder classes

The purpose is to encapsulate the checks for each sensor in a dedicated
class with the same interface

* SensorRangeFinder: encapsulate in estimator::sensor namespace

* EKF: rename _sensor_rng to _range_sensor

* Range checks: include limits in valid range

* RangeChecks: update comment in the continuity checks

* RangeChecks: move more low-level checks in functions

Also move setTilt out of the terrain estimator, this is anyway protected internally
to not compute cos/sin if the parameter did not change.

* Sensor: remove unused virtual functions

Those are not required yet but can still be added later

* SensorRangeFinder: re-organise member variables

Also rename getRangeToEarth to getCosTilt

* SensorRangeFinder: split setSensorTilt and setCosMaxTilt functions

* SensorRangeFinder: Add a few unit tests

- good data
- tilt exceeded
- max range exceeded

* SensorRangeFinder: set hysteresis in us instead of ms

* SensorRangeFinder: Add more tests

* SensorRangeFinder: update continuity, hysteresis and stuck tests

* SensorRangeFinder: rename variables

* SensorRangeFinder: get rid of "delayed" specification

From the SensorRangeFinder class point of view, it's not relevant to
know if the data is delayed or not

* SensorRangeFinder: move time_last_valid out of stuck check

* SensorRangeFinder: rename file names to sensor_range_finder

* SensorRangeFinder: address Kamil's comments

* SensorRangeFinder: Add more tilt tests

* SensorRangeFinder: store current tilt offset

This is to avoid recomputing cos/sin functions at each loop
This commit is contained in:
Mathieu Bresciani
2020-04-03 08:28:07 +02:00
committed by GitHub
parent 544385fd8c
commit 0623b2b02d
15 changed files with 747 additions and 263 deletions
+6 -6
View File
@@ -50,7 +50,7 @@
bool Ekf::resetVelocity()
{
// used to calculate the velocity change due to the reset
Vector3f vel_before_reset = _state.vel;
const Vector3f vel_before_reset = _state.vel;
// reset EKF states
if (_control_status.flags.gps && isTimedOut(_last_gps_fail_us, (uint64_t)_min_gps_health_time_us)) {
@@ -64,10 +64,10 @@ bool Ekf::resetVelocity()
} else if (_control_status.flags.opt_flow) {
ECL_INFO_TIMESTAMPED("reset velocity to flow");
// constrain height above ground to be above minimum possible
float heightAboveGndEst = fmaxf((_terrain_vpos - _state.pos(2)), _params.rng_gnd_clearance);
const float heightAboveGndEst = fmaxf((_terrain_vpos - _state.pos(2)), _params.rng_gnd_clearance);
// calculate absolute distance from focal point to centre of frame assuming a flat earth
float range = heightAboveGndEst / _R_rng_to_earth_2_2;
const float range = heightAboveGndEst / _range_sensor.getCosTilt();
if ((range - _params.rng_gnd_clearance) > 0.3f && _flow_sample_delayed.dt > 0.05f) {
// we should have reliable OF measurements so
@@ -227,7 +227,7 @@ void Ekf::resetHeight()
// reset the vertical position
if (_control_status.flags.rng_hgt) {
float new_pos_down = _hgt_sensor_offset - _range_sample_delayed.rng * _R_rng_to_earth_2_2;
const float new_pos_down = _hgt_sensor_offset - _range_sensor.getRange() * _range_sensor.getCosTilt();
// update the state and associated variance
_state.pos(2) = new_pos_down;
@@ -1052,9 +1052,9 @@ hagl_max : Maximum height above ground (meters). NaN when limiting is not needed
void Ekf::get_ekf_ctrl_limits(float *vxy_max, float *vz_max, float *hagl_min, float *hagl_max)
{
// Calculate range finder limits
const float rangefinder_hagl_min = _rng_valid_min_val;
const float rangefinder_hagl_min = _range_sensor.getValidMinVal();
// Allow use of 75% of rangefinder maximum range to allow for angular motion
const float rangefinder_hagl_max = 0.75f * _rng_valid_max_val;
const float rangefinder_hagl_max = 0.75f * _range_sensor.getValidMaxVal();
// Calculate optical flow limits
// Allow ground relative velocity to use 50% of available flow sensor range to allow for angular motion