Skip to content

Commit 3d7df89

Browse files
committed
feat(ekf2): add airspeed fusion ctrl, uint8 intended types, prepare dual-GPS msg
- Replace IMU with airspeed (ASPD) in fusion control - Change all intended fields from int32 to uint8 - EKF2_ARSP_THR param changed from float to int32 - Add drag_active, test_ratio NaN init, MagFuseType casts - Prepare EstimatorFusionControl msg and SENS_EN bitmask for dual-GPS (gps_intended[2], gps_active bitmask), OF stays single - ack.result pre-initialized in handleSensorFusionCommand
1 parent 2ae0054 commit 3d7df89

File tree

13 files changed

+113
-109
lines changed

13 files changed

+113
-109
lines changed

msg/EstimatorFusionControl.msg

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
uint64 timestamp # time since system start (microseconds)
22

3-
int32 gps_intended # effective EKF2_GPS_CTRL value (0 = disabled)
4-
int32 of_intended # effective EKF2_OF_CTRL value (0 = disabled)
5-
int32 ev_intended # effective EKF2_EV_CTRL value (0 = disabled)
6-
int32[4] agp_intended # effective EKF2_AGPx_CTRL values (0 = disabled)
7-
int32 baro_intended # effective EKF2_BARO_CTRL value (0 = disabled)
8-
int32 rng_intended # effective EKF2_RNG_CTRL value (0 = disabled)
9-
int32 drag_intended # effective EKF2_DRAG_CTRL value (0 = disabled)
10-
int32 mag_intended # effective EKF2_MAG_TYPE value (5 = disabled/NONE)
11-
int32 imu_intended # effective EKF2_IMU_CTRL value (0 = disabled)
3+
# effective CTRL param values with runtime overrides (0 = disabled)
4+
uint8[2] gps_intended
5+
uint8 of_intended
6+
uint8 ev_intended
7+
uint8[4] agp_intended
8+
uint8 baro_intended
9+
uint8 rng_intended
10+
uint8 drag_intended
11+
uint8 mag_intended
12+
uint8 aspd_intended
1213

13-
uint8 agp_active # bitmask of AGP instances actively fusing (bit i = instance i)
14+
# whether the estimator is actively fusing data from each source
15+
uint8 gps_active
16+
bool of_active
17+
bool ev_active
18+
uint8 agp_active
19+
bool baro_active
20+
bool rng_active
21+
bool drag_active
22+
bool mag_active
23+
bool aspd_active

msg/versioned/VehicleCommand.msg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,15 +111,15 @@ uint16 VEHICLE_CMD_EXTERNAL_POSITION_ESTIMATE = 43003 # External reset of estima
111111
uint16 VEHICLE_CMD_EXTERNAL_WIND_ESTIMATE = 43004
112112
uint16 VEHICLE_CMD_SET_EKF_SENSOR_FUSION = 43005 # Enable/disable EKF sensor fusion. |sensor (FUSION_SOURCE_*)|instance (0-based, for multi-instance types)|action (0=disable, 1=enable)|Unused|Unused|Unused|Unused|
113113
# Sensor fusion source types for VEHICLE_CMD_SET_EKF_SENSOR_FUSION
114-
uint8 FUSION_SOURCE_GPS = 1 # GNSS (EKF2_GPS_CTRL)
114+
uint8 FUSION_SOURCE_GPS = 1 # GNSS (EKF2_GPS{i}_CTRL, use instance param)
115115
uint8 FUSION_SOURCE_OF = 2 # Optical Flow (EKF2_OF_CTRL)
116116
uint8 FUSION_SOURCE_EV = 3 # External Vision (EKF2_EV_CTRL)
117117
uint8 FUSION_SOURCE_AGP = 4 # Auxiliary Global Position (EKF2_AGP{i}_CTRL, use instance param)
118118
uint8 FUSION_SOURCE_BARO = 5 # Barometer (EKF2_BARO_CTRL)
119119
uint8 FUSION_SOURCE_RNG = 6 # Range Finder (EKF2_RNG_CTRL)
120120
uint8 FUSION_SOURCE_DRAG = 7 # Drag (EKF2_DRAG_CTRL)
121121
uint8 FUSION_SOURCE_MAG = 8 # Magnetometer (EKF2_MAG_TYPE)
122-
uint8 FUSION_SOURCE_IMU = 9 # IMU (EKF2_IMU_CTRL)
122+
uint8 FUSION_SOURCE_ASPD = 9 # Airspeed (EKF2_ARSP_THR)
123123

124124
# PX4 vehicle commands (beyond 16 bit MAVLink commands).
125125
uint32 VEHICLE_CMD_PX4_INTERNAL_START = 65537 # Start of PX4 internal only vehicle commands (> UINT16_MAX).

src/modules/ekf2/EKF/aid_sources/airspeed/airspeed_fusion.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ void Ekf::controlAirDataFusion(const imuSample &imu_delayed)
8282

8383
#endif // CONFIG_EKF2_GNSS
8484

85-
if (_params.ekf2_arsp_thr <= 0.f) {
85+
if (_fc.aspd.intended <= 0) {
8686
stopAirspeedFusion();
8787
return;
8888
}
@@ -97,7 +97,7 @@ void Ekf::controlAirDataFusion(const imuSample &imu_delayed)
9797
|| _control_status.flags.in_transition)
9898
&& !_control_status.flags.fake_pos;
9999

100-
const bool is_airspeed_significant = airspeed_sample.true_airspeed > _params.ekf2_arsp_thr;
100+
const bool is_airspeed_significant = airspeed_sample.true_airspeed > _fc.aspd.intended;
101101
const bool is_airspeed_consistent = (_aid_src_airspeed.test_ratio > 0.f && _aid_src_airspeed.test_ratio < 1.f);
102102
const bool starting_conditions_passing = continuing_conditions_passing
103103
&& is_airspeed_significant

src/modules/ekf2/EKF/aid_sources/gravity/gravity_fusion.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ void Ekf::controlGravityFusion(const imuSample &imu)
5959
&& (accel_lpf_norm_sq < sq(upper_accel_limit));
6060

6161
// fuse gravity observation if our overall acceleration isn't too big
62-
_control_status.flags.gravity_vector = (_fc.imu.intended & static_cast<int32_t>(ImuCtrl::GravityVector))
62+
_control_status.flags.gravity_vector = (_params.ekf2_imu_ctrl & static_cast<int32_t>(ImuCtrl::GravityVector))
6363
&& (accel_lpf_norm_good || _control_status.flags.vehicle_at_rest)
6464
&& !isHorizontalAidingActive()
6565
&& _control_status.flags.tilt_align; // Let fake position do the initial alignment (more robust before takeoff)

src/modules/ekf2/EKF/aid_sources/magnetometer/mag_control.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ void Ekf::controlMagFusion(const imuSample &imu_sample)
5454
_control_status.flags.mag_aligned_in_flight = false;
5555
}
5656

57-
if (_fc.mag.intended == MagFuseType::NONE) {
57+
if (_fc.mag.intended == static_cast<int32_t>(MagFuseType::NONE)) {
5858
stopMagFusion();
5959
return;
6060
}
@@ -150,9 +150,9 @@ void Ekf::controlMagFusion(const imuSample &imu_sample)
150150
math::max(_params.ekf2_mag_gate, 1.f)); // innovation gate
151151

152152
// determine if we should use mag fusion
153-
bool continuing_conditions_passing = ((_fc.mag.intended == MagFuseType::INIT)
154-
|| (_fc.mag.intended == MagFuseType::AUTO)
155-
|| (_fc.mag.intended == MagFuseType::HEADING))
153+
bool continuing_conditions_passing = ((_fc.mag.intended == static_cast<int32_t>(MagFuseType::INIT))
154+
|| (_fc.mag.intended == static_cast<int32_t>(MagFuseType::AUTO))
155+
|| (_fc.mag.intended == static_cast<int32_t>(MagFuseType::HEADING)))
156156
&& _control_status.flags.tilt_align
157157
&& (_control_status.flags.yaw_align || (!_control_status.flags.ev_yaw && !_control_status.flags.yaw_align))
158158
&& mag_sample.mag.longerThan(0.f)
@@ -187,12 +187,12 @@ void Ekf::controlMagFusion(const imuSample &imu_sample)
187187
&& (!_control_status.flags.yaw_manual || _control_status.flags.mag_aligned_in_flight);
188188

189189
_control_status.flags.mag_3D = common_conditions_passing
190-
&& (_fc.mag.intended == MagFuseType::AUTO)
190+
&& (_fc.mag.intended == static_cast<int32_t>(MagFuseType::AUTO))
191191
&& _control_status.flags.mag_aligned_in_flight;
192192

193193
_control_status.flags.mag_hdg = common_conditions_passing
194-
&& ((_fc.mag.intended == MagFuseType::HEADING)
195-
|| (_fc.mag.intended == MagFuseType::AUTO && !_control_status.flags.mag_3D));
194+
&& ((_fc.mag.intended == static_cast<int32_t>(MagFuseType::HEADING))
195+
|| (_fc.mag.intended == static_cast<int32_t>(MagFuseType::AUTO) && !_control_status.flags.mag_3D));
196196
}
197197

198198
if (_control_status.flags.mag_3D && !_control_status_prev.flags.mag_3D) {

src/modules/ekf2/EKF/common.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -274,10 +274,9 @@ struct systemFlagUpdate {
274274
// Runtime fusion control. Populated by EKF2 module, read by EKF core.
275275
static constexpr uint8_t MAX_AGP_INSTANCES = 4;
276276

277-
278277
struct FusionSensor {
279278
bool enabled{false};
280-
int32_t intended{0};
279+
uint8_t intended{0};
281280
};
282281

283282
struct FusionControl {
@@ -289,7 +288,7 @@ struct FusionControl {
289288
FusionSensor rng;
290289
FusionSensor drag;
291290
FusionSensor mag{false, 5}; // MagFuseType::NONE
292-
FusionSensor imu;
291+
FusionSensor aspd;
293292
};
294293

295294
struct parameters {
@@ -413,7 +412,7 @@ struct parameters {
413412
float ekf2_asp_delay{100.0f}; ///< airspeed measurement delay relative to the IMU (mSec)
414413
float ekf2_tas_gate{5.0f}; ///< True Airspeed innovation consistency gate size (STD)
415414
float ekf2_eas_noise{1.4f}; ///< EAS measurement noise standard deviation used for airspeed fusion (m/s)
416-
float ekf2_arsp_thr{2.0f}; ///< Airspeed fusion threshold. A value of zero will deactivate airspeed fusion
415+
int32_t ekf2_arsp_thr{2}; ///< Airspeed fusion threshold. A value of zero will deactivate airspeed fusion
417416
#endif // CONFIG_EKF2_AIRSPEED
418417

419418
#if defined(CONFIG_EKF2_SIDESLIP)

src/modules/ekf2/EKF/control.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ void Ekf::controlFusionModes(const imuSample &imu_delayed)
158158

159159
_zero_velocity_update.update(*this, imu_delayed);
160160

161-
if (_fc.imu.intended & static_cast<int32_t>(ImuCtrl::GyroBias)) {
161+
if (_params.ekf2_imu_ctrl & static_cast<int32_t>(ImuCtrl::GyroBias)) {
162162
_zero_gyro_update.update(*this, imu_delayed);
163163
}
164164

src/modules/ekf2/EKF/ekf_helper.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,7 @@ void Ekf::updateHorizontalDeadReckoningstatus()
852852

853853
if (!_control_status.flags.in_air && _control_status.flags.fixed_wing
854854
&& (_params.ekf2_fuse_beta == 1)
855-
&& (_params.ekf2_arsp_thr > 0.f) && isRecent(_aid_src_airspeed.timestamp_sample, _params.no_aid_timeout_max)
855+
&& (_fc.aspd.intended > 0) && isRecent(_aid_src_airspeed.timestamp_sample, _params.no_aid_timeout_max)
856856
) {
857857
// currently landed, but air data aiding should be possible once in air
858858
aiding_expected_in_air = true;
@@ -996,15 +996,15 @@ void Ekf::updateIMUBiasInhibit(const imuSample &imu_delayed)
996996

997997

998998
// gyro bias inhibit
999-
const bool do_inhibit_all_gyro_axes = !(_fc.imu.intended & static_cast<int32_t>(ImuCtrl::GyroBias));
999+
const bool do_inhibit_all_gyro_axes = !(_params.ekf2_imu_ctrl & static_cast<int32_t>(ImuCtrl::GyroBias));
10001000

10011001
for (unsigned index = 0; index < State::gyro_bias.dof; index++) {
10021002
bool is_bias_observable = true; // TODO: gyro bias conditions
10031003
_gyro_bias_inhibit[index] = do_inhibit_all_gyro_axes || !is_bias_observable;
10041004
}
10051005

10061006
// accel bias inhibit
1007-
const bool do_inhibit_all_accel_axes = !(_fc.imu.intended & static_cast<int32_t>(ImuCtrl::AccelBias))
1007+
const bool do_inhibit_all_accel_axes = !(_params.ekf2_imu_ctrl & static_cast<int32_t>(ImuCtrl::AccelBias))
10081008
|| is_manoeuvre_level_high
10091009
|| _fault_status.flags.bad_acc_vertical;
10101010

src/modules/ekf2/EKF2.cpp

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ void EKF2::AdvertiseTopics()
265265

266266
#if defined(CONFIG_EKF2_AIRSPEED)
267267

268-
if (_param_ekf2_arsp_thr.get() > 0.f) {
268+
if (_param_ekf2_arsp_thr.get() > 0) {
269269
_estimator_aid_src_airspeed_pub.advertise();
270270
}
271271

@@ -987,7 +987,7 @@ void EKF2::initFusionControl()
987987
_num_sensor_table = 0;
988988

989989
auto add = [this, sens_en](FusionSensor & sensor, uint8_t sens_en_bit, uint8_t sensor_id,
990-
int8_t instance, param_t param, int32_t disabled_val = 0) {
990+
int8_t instance, param_t param, uint8_t disabled_val = 0) {
991991
if (_num_sensor_table < MAX_SENSOR_TABLE) {
992992
sensor.enabled = sens_en & (1 << sens_en_bit);
993993
int32_t param_val = disabled_val;
@@ -996,20 +996,21 @@ void EKF2::initFusionControl()
996996
param_get(param, &param_val);
997997
}
998998

999-
sensor.intended = sensor.enabled ? param_val : disabled_val;
999+
sensor.intended = sensor.enabled ? static_cast<uint8_t>(param_val) : disabled_val;
10001000
_sensor_table[_num_sensor_table++] = {&sensor, param, sens_en_bit, sensor_id, instance, disabled_val};
10011001
}
10021002
};
10031003

1004-
// bit layout: 0=GPS 1=OF 2=EV 3..6=AGP0..3 7=BARO 8=RNG 9=DRAG 10=MAG 11=IMU
1004+
// bit layout: 0..1=GPS0..1 2=OF 3=EV 4..7=AGP0..3 8=BARO 9=RNG 10=DRAG 11=MAG 12=ASPD
10051005
#if defined(CONFIG_EKF2_GNSS)
1006-
add(_fc.gps, 0, vehicle_command_s::FUSION_SOURCE_GPS, -1, _param_ekf2_gps_ctrl.handle());
1006+
add(_fc.gps, 0, vehicle_command_s::FUSION_SOURCE_GPS, -1, _param_ekf2_gps_ctrl.handle());
1007+
// TODO: gps[1] reserved — no param yet, add second GPS instance here when multi-GPS CTRL is implemented
10071008
#endif
10081009
#if defined(CONFIG_EKF2_OPTICAL_FLOW)
1009-
add(_fc.of, 1, vehicle_command_s::FUSION_SOURCE_OF, -1, _param_ekf2_of_ctrl.handle());
1010+
add(_fc.of, 2, vehicle_command_s::FUSION_SOURCE_OF, -1, _param_ekf2_of_ctrl.handle());
10101011
#endif
10111012
#if defined(CONFIG_EKF2_EXTERNAL_VISION)
1012-
add(_fc.ev, 2, vehicle_command_s::FUSION_SOURCE_EV, -1, _param_ekf2_ev_ctrl.handle());
1013+
add(_fc.ev, 3, vehicle_command_s::FUSION_SOURCE_EV, -1, _param_ekf2_ev_ctrl.handle());
10131014
#endif
10141015
#if defined(CONFIG_EKF2_AUX_GLOBAL_POSITION)
10151016

@@ -1020,24 +1021,26 @@ void EKF2::initFusionControl()
10201021
const param_t param_agp_ctrl = param_find_no_notification(param_name);
10211022

10221023
if (param_used(param_agp_ctrl) > 0) {
1023-
add(_fc.agp[i], 3 + i, vehicle_command_s::FUSION_SOURCE_AGP, static_cast<int8_t>(i), param_agp_ctrl);
1024+
add(_fc.agp[i], 4 + i, vehicle_command_s::FUSION_SOURCE_AGP, static_cast<int8_t>(i), param_agp_ctrl);
10241025
}
10251026
}
10261027

10271028
#endif
10281029
#if defined(CONFIG_EKF2_BAROMETER)
1029-
add(_fc.baro, 7, vehicle_command_s::FUSION_SOURCE_BARO, -1, _param_ekf2_baro_ctrl.handle());
1030+
add(_fc.baro, 8, vehicle_command_s::FUSION_SOURCE_BARO, -1, _param_ekf2_baro_ctrl.handle());
10301031
#endif
10311032
#if defined(CONFIG_EKF2_RANGE_FINDER)
1032-
add(_fc.rng, 8, vehicle_command_s::FUSION_SOURCE_RNG, -1, _param_ekf2_rng_ctrl.handle());
1033+
add(_fc.rng, 9, vehicle_command_s::FUSION_SOURCE_RNG, -1, _param_ekf2_rng_ctrl.handle());
10331034
#endif
10341035
#if defined(CONFIG_EKF2_DRAG_FUSION)
1035-
add(_fc.drag, 9, vehicle_command_s::FUSION_SOURCE_DRAG, -1, _param_ekf2_drag_ctrl.handle());
1036+
add(_fc.drag, 10, vehicle_command_s::FUSION_SOURCE_DRAG, -1, _param_ekf2_drag_ctrl.handle());
10361037
#endif
10371038
#if defined(CONFIG_EKF2_MAGNETOMETER)
1038-
add(_fc.mag, 10, vehicle_command_s::FUSION_SOURCE_MAG, -1, _param_ekf2_mag_type.handle(), 5);
1039+
add(_fc.mag, 11, vehicle_command_s::FUSION_SOURCE_MAG, -1, _param_ekf2_mag_type.handle(), 5);
1040+
#endif
1041+
#if defined(CONFIG_EKF2_AIRSPEED)
1042+
add(_fc.aspd, 12, vehicle_command_s::FUSION_SOURCE_ASPD, -1, _param_ekf2_arsp_thr.handle());
10391043
#endif
1040-
add(_fc.imu, 11, vehicle_command_s::FUSION_SOURCE_IMU, -1, _param_ekf2_imu_ctrl.handle());
10411044
}
10421045

10431046
void EKF2::updateFusionIntended()
@@ -1050,12 +1053,14 @@ void EKF2::updateFusionIntended()
10501053
param_get(e.param, &param_val);
10511054
}
10521055

1053-
e.sensor->intended = e.sensor->enabled ? param_val : e.disabled_val;
1056+
e.sensor->intended = e.sensor->enabled ? static_cast<uint8_t>(param_val) : e.disabled_val;
10541057
}
10551058
}
10561059

10571060
void EKF2::handleSensorFusionCommand(const vehicle_command_s &cmd, vehicle_command_ack_s &ack)
10581061
{
1062+
ack.result = vehicle_command_ack_s::VEHICLE_CMD_RESULT_UNSUPPORTED;
1063+
10591064
const uint8_t sensor = static_cast<uint8_t>(cmd.param1);
10601065
const uint8_t instance = PX4_ISFINITE(cmd.param2) ? static_cast<uint8_t>(cmd.param2) : 0;
10611066
const bool enable = (static_cast<int32_t>(cmd.param3) == 1);
@@ -1071,14 +1076,12 @@ void EKF2::handleSensorFusionCommand(const vehicle_command_s &cmd, vehicle_comma
10711076
param_get(e.param, &param_val);
10721077
}
10731078

1074-
e.sensor->intended = enable ? param_val : e.disabled_val;
1079+
e.sensor->intended = enable ? static_cast<uint8_t>(param_val) : e.disabled_val;
10751080
updateSensEnParam(e.sens_en_bit, enable);
10761081
ack.result = vehicle_command_ack_s::VEHICLE_CMD_RESULT_ACCEPTED;
10771082
return;
10781083
}
10791084
}
1080-
1081-
ack.result = vehicle_command_ack_s::VEHICLE_CMD_RESULT_UNSUPPORTED;
10821085
}
10831086

10841087
void EKF2::updateSensEnParam(uint8_t bit, bool enable)
@@ -2016,7 +2019,7 @@ void EKF2::PublishStatus(const hrt_abstime &timestamp)
20162019
void EKF2::PublishFusionControl(const hrt_abstime &timestamp)
20172020
{
20182021
estimator_fusion_control_s msg{};
2019-
msg.gps_intended = _fc.gps.intended;
2022+
msg.gps_intended[0] = _fc.gps.intended;
20202023
msg.of_intended = _fc.of.intended;
20212024
msg.ev_intended = _fc.ev.intended;
20222025

@@ -2028,10 +2031,20 @@ void EKF2::PublishFusionControl(const hrt_abstime &timestamp)
20282031
msg.rng_intended = _fc.rng.intended;
20292032
msg.drag_intended = _fc.drag.intended;
20302033
msg.mag_intended = _fc.mag.intended;
2031-
msg.imu_intended = _fc.imu.intended;
2034+
msg.aspd_intended = _fc.aspd.intended;
2035+
2036+
const auto &cs = _ekf.control_status_flags();
2037+
msg.gps_active = (cs.gnss_pos || cs.gps_hgt || cs.gnss_vel || cs.gnss_yaw) ? 1u : 0u; // TODO: per-instance active tracking
2038+
msg.of_active = cs.opt_flow;
2039+
msg.ev_active = cs.ev_pos || cs.ev_hgt || cs.ev_vel || cs.ev_yaw;
2040+
msg.baro_active = cs.baro_hgt;
2041+
msg.rng_active = cs.rng_hgt;
2042+
msg.drag_active = (_fc.drag.intended > 0) && cs.wind && cs.in_air && !cs.fake_pos;
2043+
msg.mag_active = cs.mag;
2044+
msg.aspd_active = cs.fuse_aspd;
20322045

20332046
#if defined(CONFIG_EKF2_AUX_GLOBAL_POSITION)
2034-
msg.agp_active = _ekf.getAgpFusingBitmask();
2047+
msg.agp_active = _ekf.getAgpFusingBitmask();
20352048
#endif
20362049

20372050
msg.timestamp = _replay_mode ? timestamp : hrt_absolute_time();

src/modules/ekf2/EKF2.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ class EKF2 final : public ModuleParams, public px4::ScheduledWorkItem
402402
uint8_t sens_en_bit;
403403
uint8_t sensor_id;
404404
int8_t instance; // -1 = any instance
405-
int32_t disabled_val;
405+
uint8_t disabled_val;
406406
};
407407

408408
static constexpr uint8_t MAX_SENSOR_TABLE = 9 + (MAX_AGP_INSTANCES - 1); // 12
@@ -594,7 +594,7 @@ class EKF2 final : public ModuleParams, public px4::ScheduledWorkItem
594594
_param_ekf2_eas_noise, ///< measurement noise used for airspeed fusion (m/sec)
595595

596596
// control of airspeed fusion
597-
(ParamExtFloat<px4::params::EKF2_ARSP_THR>)
597+
(ParamExtInt<px4::params::EKF2_ARSP_THR>)
598598
_param_ekf2_arsp_thr, ///< A value of zero will disabled airspeed fusion. Any positive value sets the minimum airspeed which will be used (m/sec)
599599
#endif // CONFIG_EKF2_AIRSPEED
600600

0 commit comments

Comments
 (0)