mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-22 15:23:35 +08:00
ekf2: GPS, baro and range finder control parameters
Also remove the legacy "range aid" than can be achieved by setting the height reference to range finder and the range finder control parameter to "conditional". Conditional range aiding cal also be set when the height reference isn't the range finder. This prevents the ratchetting effect due to switching between references.
This commit is contained in:
@@ -113,21 +113,30 @@ enum HeightSensor : uint8_t {
|
||||
UNKNOWN = 4
|
||||
};
|
||||
|
||||
enum GnssCtrl : uint8_t {
|
||||
HPOS = (1<<0),
|
||||
VPOS = (1<<1),
|
||||
VEL = (1<<2),
|
||||
YAW = (1<<3)
|
||||
};
|
||||
|
||||
enum RngCtrl : uint8_t {
|
||||
DISABLED = 0,
|
||||
CONDITIONAL = 1,
|
||||
ENABLED = 2
|
||||
};
|
||||
|
||||
enum SensorFusionMask : uint16_t {
|
||||
// Bit locations for fusion_mode
|
||||
USE_GPS = (1<<0), ///< set to true to use GPS data
|
||||
/* USE_GPS = (1<<0), ///< set to true to use GPS data */
|
||||
USE_OPT_FLOW = (1<<1), ///< set to true to use optical flow data
|
||||
INHIBIT_ACC_BIAS = (1<<2), ///< set to true to inhibit estimation of accelerometer delta velocity bias
|
||||
USE_EXT_VIS_POS = (1<<3), ///< set to true to use external vision position data
|
||||
USE_EXT_VIS_YAW = (1<<4), ///< set to true to use external vision quaternion data for yaw
|
||||
USE_DRAG = (1<<5), ///< set to true to use the multi-rotor drag model to estimate wind
|
||||
ROTATE_EXT_VIS = (1<<6), ///< set to true to if the EV observations are in a non NED reference frame and need to be rotated before being used
|
||||
USE_GPS_YAW = (1<<7), ///< set to true to use GPS yaw data if available
|
||||
/* USE_GPS_YAW = (1<<7), ///< set to true to use GPS yaw data if available */
|
||||
USE_EXT_VIS_VEL = (1<<8), ///< set to true to use external vision velocity data
|
||||
USE_BARO_HGT = (1<<9), ///< set to true to use baro data
|
||||
USE_GPS_HGT = (1<<10), ///< set to true to use GPS height data
|
||||
USE_RNG_HGT = (1<<11), ///< set to true to use range height data
|
||||
USE_EXT_VIS_HGT = (1<<12) ///< set to true to use external vision height data
|
||||
};
|
||||
|
||||
struct gpsMessage {
|
||||
@@ -251,9 +260,11 @@ struct parameters {
|
||||
int32_t filter_update_interval_us{10000}; ///< filter update interval in microseconds
|
||||
|
||||
// measurement source control
|
||||
int32_t fusion_mode{SensorFusionMask::USE_GPS |
|
||||
SensorFusionMask::USE_BARO_HGT}; ///< bitmasked integer that selects which aiding sources will be used
|
||||
int32_t fusion_mode{}; ///< bitmasked integer that selects some aiding sources
|
||||
int32_t height_sensor_ref{HeightSensor::BARO};
|
||||
int32_t baro_ctrl{1};
|
||||
int32_t gnss_ctrl{GnssCtrl::HPOS | GnssCtrl::VEL};
|
||||
int32_t rng_ctrl{RngCtrl::CONDITIONAL};
|
||||
int32_t terrain_fusion_mode{TerrainFusionMask::TerrainFuseRangeFinder |
|
||||
TerrainFusionMask::TerrainFuseOpticalFlow}; ///< aiding source(s) selection bitmask for the terrain estimator
|
||||
|
||||
@@ -335,9 +346,8 @@ struct parameters {
|
||||
float rng_sens_pitch{0.0f}; ///< Pitch offset of the range sensor (rad). Sensor points out along Z axis when offset is zero. Positive rotation is RH about Y axis.
|
||||
float range_noise_scaler{0.0f}; ///< scaling from range measurement to noise (m/m)
|
||||
const float vehicle_variance_scaler{0.0f}; ///< gain applied to vehicle height variance used in calculation of height above ground observation variance
|
||||
float max_hagl_for_range_aid{5.0f}; ///< maximum height above ground for which we allow to use the range finder as height source (if range_aid == 1)
|
||||
float max_vel_for_range_aid{1.0f}; ///< maximum ground velocity for which we allow to use the range finder as height source (if range_aid == 1)
|
||||
int32_t range_aid{0}; ///< allow switching primary height source to range finder if certain conditions are met
|
||||
float max_hagl_for_range_aid{5.0f}; ///< maximum height above ground for which we allow to use the range finder as height source (if rng_control == 1)
|
||||
float max_vel_for_range_aid{1.0f}; ///< maximum ground velocity for which we allow to use the range finder as height source (if rng_control == 1)
|
||||
float range_aid_innov_gate{1.0f}; ///< gate size used for innovation consistency checks for range aid fusion
|
||||
float range_valid_quality_s{1.0f}; ///< minimum duration during which the reported range finder signal quality needs to be non-zero in order to be declared valid (s)
|
||||
float range_cos_max_tilt{0.7071f}; ///< cosine of the maximum tilt angle from the vertical that permits use of range finder and flow data
|
||||
|
||||
@@ -268,7 +268,7 @@ void Ekf::controlExternalVisionFusion()
|
||||
_ev_sample_delayed.pos -= pos_offset_earth;
|
||||
|
||||
// Use an incremental position fusion method for EV position data if GPS is also used
|
||||
if (_params.fusion_mode & SensorFusionMask::USE_GPS) {
|
||||
if (_params.gnss_ctrl & GnssCtrl::HPOS) {
|
||||
_fuse_hpos_as_odom = true;
|
||||
|
||||
} else {
|
||||
@@ -572,7 +572,7 @@ void Ekf::resetOnGroundMotionForOpticalFlowChecks()
|
||||
|
||||
void Ekf::controlGpsYawFusion(bool gps_checks_passing, bool gps_checks_failing)
|
||||
{
|
||||
if (!(_params.fusion_mode & SensorFusionMask::USE_GPS_YAW)
|
||||
if (!(_params.gnss_ctrl & GnssCtrl::YAW)
|
||||
|| _control_status.flags.gps_yaw_fault) {
|
||||
|
||||
stopGpsYawFusion();
|
||||
@@ -731,7 +731,7 @@ void Ekf::checkHeightSensorRefFallback()
|
||||
}
|
||||
}
|
||||
|
||||
bool Ekf::isRangeAidSuitable()
|
||||
bool Ekf::isConditionalRangeAidSuitable()
|
||||
{
|
||||
bool is_range_aid_suitable = false;
|
||||
|
||||
@@ -764,7 +764,7 @@ bool Ekf::isRangeAidSuitable()
|
||||
|
||||
void Ekf::controlBaroHeightFusion()
|
||||
{
|
||||
if (!(_params.fusion_mode & SensorFusionMask::USE_BARO_HGT)) {
|
||||
if (!(_params.baro_ctrl == 1)) {
|
||||
stopBaroHgtFusion();
|
||||
return;
|
||||
}
|
||||
@@ -812,7 +812,7 @@ void Ekf::controlBaroHeightFusion()
|
||||
|
||||
void Ekf::controlGnssHeightFusion()
|
||||
{
|
||||
if (!(_params.fusion_mode & SensorFusionMask::USE_GPS_HGT)) {
|
||||
if (!(_params.gnss_ctrl & GnssCtrl::VPOS)) {
|
||||
stopGpsHgtFusion();
|
||||
return;
|
||||
}
|
||||
@@ -855,7 +855,7 @@ void Ekf::controlGnssHeightFusion()
|
||||
|
||||
void Ekf::controlRangeHeightFusion()
|
||||
{
|
||||
if (!(_params.fusion_mode & SensorFusionMask::USE_RNG_HGT) && (_params.range_aid == 0)) {
|
||||
if (!((_params.rng_ctrl == RngCtrl::CONDITIONAL) || (_params.rng_ctrl == RngCtrl::ENABLED))) {
|
||||
stopRngHgtFusion();
|
||||
return;
|
||||
}
|
||||
@@ -876,18 +876,13 @@ void Ekf::controlRangeHeightFusion()
|
||||
if (_rng_data_ready) {
|
||||
updateRngHgt(_aid_src_rng_hgt);
|
||||
|
||||
const bool do_range_aid = (_params.range_aid == 1) && isRangeAidSuitable();
|
||||
const bool do_conditional_range_aid = (_params.rng_ctrl == RngCtrl::CONDITIONAL) && isConditionalRangeAidSuitable();
|
||||
|
||||
const bool continuing_conditions_passing = _range_sensor.isDataHealthy() && ((_params.range_aid == 0) || do_range_aid);
|
||||
const bool continuing_conditions_passing = _range_sensor.isDataHealthy() && ((_params.rng_ctrl == RngCtrl::ENABLED) || do_conditional_range_aid);
|
||||
const bool starting_conditions_passing = continuing_conditions_passing
|
||||
&& _range_sensor.isRegularlySendingData();
|
||||
|
||||
if (_control_status.flags.rng_hgt) {
|
||||
if (do_range_aid) {
|
||||
// Force to be the height reference
|
||||
_height_sensor_ref = HeightSensorRef::RANGE;
|
||||
}
|
||||
|
||||
if (continuing_conditions_passing) {
|
||||
fuseRngHgt(_aid_src_rng_hgt);
|
||||
|
||||
@@ -922,7 +917,7 @@ void Ekf::controlRangeHeightFusion()
|
||||
|
||||
void Ekf::controlEvHeightFusion()
|
||||
{
|
||||
if (!(_params.fusion_mode & SensorFusionMask::USE_EXT_VIS_HGT)) {
|
||||
if (!(_params.height_sensor_ref == HeightSensor::EV)) { // TODO: replace by EV control parameter
|
||||
stopEvHgtFusion();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -948,8 +948,7 @@ private:
|
||||
void controlRangeHeightFusion();
|
||||
void controlEvHeightFusion();
|
||||
|
||||
// determine if flight condition is suitable to use range finder instead of the primary height sensor
|
||||
bool isRangeAidSuitable();
|
||||
bool isConditionalRangeAidSuitable();
|
||||
|
||||
void stopMagFusion();
|
||||
void stopMag3DFusion();
|
||||
|
||||
@@ -860,7 +860,7 @@ void Ekf::get_ekf_ctrl_limits(float *vxy_max, float *vz_max, float *hagl_min, fl
|
||||
const float rangefinder_hagl_max = 0.75f * _range_sensor.getValidMaxVal();
|
||||
|
||||
// TODO : calculate visual odometry limits
|
||||
const bool relying_on_rangefinder = _control_status.flags.rng_hgt && !_params.range_aid;
|
||||
const bool relying_on_rangefinder = isOnlyActiveSourceOfVerticalPositionAiding(_control_status.flags.rng_hgt);
|
||||
const bool relying_on_optical_flow = isOnlyActiveSourceOfHorizontalAiding(_control_status.flags.opt_flow);
|
||||
|
||||
// Keep within range sensor limit when using rangefinder as primary height source
|
||||
|
||||
@@ -437,7 +437,7 @@ bool EstimatorInterface::initialise_interface(uint64_t timestamp)
|
||||
float max_time_delay_ms = math::max((float)_params.sensor_interval_max_ms, _params.auxvel_delay_ms);
|
||||
|
||||
// using baro
|
||||
if (_params.fusion_mode & SensorFusionMask::USE_BARO_HGT) {
|
||||
if (_params.baro_ctrl > 0) {
|
||||
max_time_delay_ms = math::max(_params.baro_delay_ms, max_time_delay_ms);
|
||||
}
|
||||
|
||||
@@ -451,12 +451,12 @@ bool EstimatorInterface::initialise_interface(uint64_t timestamp)
|
||||
max_time_delay_ms = math::max(_params.mag_delay_ms, max_time_delay_ms);
|
||||
}
|
||||
|
||||
// range aid or range height
|
||||
if (_params.range_aid || (_params.fusion_mode & SensorFusionMask::USE_RNG_HGT)) {
|
||||
// using range finder
|
||||
if ((_params.rng_ctrl != RngCtrl::DISABLED)) {
|
||||
max_time_delay_ms = math::max(_params.range_delay_ms, max_time_delay_ms);
|
||||
}
|
||||
|
||||
if (_params.fusion_mode & SensorFusionMask::USE_GPS) {
|
||||
if (_params.gnss_ctrl > 0) {
|
||||
max_time_delay_ms = math::max(_params.gps_delay_ms, max_time_delay_ms);
|
||||
}
|
||||
|
||||
@@ -539,6 +539,11 @@ bool EstimatorInterface::isVerticalPositionAidingActive() const
|
||||
return getNumberOfActiveVerticalPositionAidingSources() > 0;
|
||||
}
|
||||
|
||||
bool EstimatorInterface::isOnlyActiveSourceOfVerticalPositionAiding(const bool aiding_flag) const
|
||||
{
|
||||
return aiding_flag && !isOtherSourceOfVerticalPositionAidingThan(aiding_flag);
|
||||
}
|
||||
|
||||
int EstimatorInterface::getNumberOfActiveVerticalPositionAidingSources() const
|
||||
{
|
||||
return int(_control_status.flags.gps_hgt)
|
||||
|
||||
@@ -183,6 +183,7 @@ public:
|
||||
|
||||
bool isOtherSourceOfVerticalPositionAidingThan(bool aiding_flag) const;
|
||||
bool isVerticalPositionAidingActive() const;
|
||||
bool isOnlyActiveSourceOfVerticalPositionAiding(const bool aiding_flag) const;
|
||||
int getNumberOfActiveVerticalPositionAidingSources() const;
|
||||
|
||||
bool isVerticalVelocityAidingActive() const;
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
void Ekf::controlGpsFusion()
|
||||
{
|
||||
if (!(_params.fusion_mode & SensorFusionMask::USE_GPS)) {
|
||||
if (!((_params.gnss_ctrl & GnssCtrl::HPOS) || (_params.gnss_ctrl & GnssCtrl::VEL))) {
|
||||
stopGpsFusion();
|
||||
return;
|
||||
}
|
||||
@@ -72,8 +72,13 @@ void Ekf::controlGpsFusion()
|
||||
if (continuing_conditions_passing
|
||||
|| !isOtherSourceOfHorizontalAidingThan(_control_status.flags.gps)) {
|
||||
|
||||
fuseGpsVel();
|
||||
fuseGpsPos();
|
||||
if (_params.gnss_ctrl & GnssCtrl::VEL) {
|
||||
fuseGpsVel();
|
||||
}
|
||||
|
||||
if ((_params.gnss_ctrl & GnssCtrl::HPOS) || (_params.gnss_ctrl & GnssCtrl::VPOS)) {
|
||||
fuseGpsPos();
|
||||
}
|
||||
|
||||
if (shouldResetGpsFusion()) {
|
||||
const bool was_gps_signal_lost = isTimedOut(_time_prev_gps_us, 1000000);
|
||||
|
||||
Reference in New Issue
Block a user