이충섭

feat : caculate rightinclination and compare current inclination

...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 * 31 *
32 ****************************************************************************/ 32 ****************************************************************************/
33 -
34 #include "EKF2.hpp" 33 #include "EKF2.hpp"
35 #include <iostream> 34 #include <iostream>
36 #include <px4_platform_common/defines.h> 35 #include <px4_platform_common/defines.h>
...@@ -165,7 +164,6 @@ EKF2::EKF2(bool multi_mode, const px4::wq_config_t &config, bool replay_mode): ...@@ -165,7 +164,6 @@ EKF2::EKF2(bool multi_mode, const px4::wq_config_t &config, bool replay_mode):
165 _param_ekf2_gsf_tas_default(_params->EKFGSF_tas_default) 164 _param_ekf2_gsf_tas_default(_params->EKFGSF_tas_default)
166 { 165 {
167 } 166 }
168 -
169 EKF2::~EKF2() 167 EKF2::~EKF2()
170 { 168 {
171 perf_free(_ecl_ekf_update_perf); 169 perf_free(_ecl_ekf_update_perf);
...@@ -173,7 +171,6 @@ EKF2::~EKF2() ...@@ -173,7 +171,6 @@ EKF2::~EKF2()
173 perf_free(_imu_missed_perf); 171 perf_free(_imu_missed_perf);
174 perf_free(_mag_missed_perf); 172 perf_free(_mag_missed_perf);
175 } 173 }
176 -
177 bool EKF2::multi_init(int imu, int mag) 174 bool EKF2::multi_init(int imu, int mag)
178 { 175 {
179 // advertise immediately to ensure consistent uORB instance numbering 176 // advertise immediately to ensure consistent uORB instance numbering
...@@ -182,7 +179,6 @@ bool EKF2::multi_init(int imu, int mag) ...@@ -182,7 +179,6 @@ bool EKF2::multi_init(int imu, int mag)
182 _global_position_pub.advertise(); 179 _global_position_pub.advertise();
183 _odometry_pub.advertise(); 180 _odometry_pub.advertise();
184 _wind_pub.advertise(); 181 _wind_pub.advertise();
185 -
186 _ekf2_timestamps_pub.advertise(); 182 _ekf2_timestamps_pub.advertise();
187 _ekf_gps_drift_pub.advertise(); 183 _ekf_gps_drift_pub.advertise();
188 _estimator_innovation_test_ratios_pub.advertise(); 184 _estimator_innovation_test_ratios_pub.advertise();
...@@ -195,28 +191,20 @@ bool EKF2::multi_init(int imu, int mag) ...@@ -195,28 +191,20 @@ bool EKF2::multi_init(int imu, int mag)
195 _estimator_status_flags_pub.advertise(); 191 _estimator_status_flags_pub.advertise();
196 _estimator_visual_odometry_aligned_pub.advertised(); 192 _estimator_visual_odometry_aligned_pub.advertised();
197 _yaw_est_pub.advertise(); 193 _yaw_est_pub.advertise();
198 -
199 bool changed_instance = _vehicle_imu_sub.ChangeInstance(imu) && _magnetometer_sub.ChangeInstance(mag); 194 bool changed_instance = _vehicle_imu_sub.ChangeInstance(imu) && _magnetometer_sub.ChangeInstance(mag);
200 -
201 const int status_instance = _estimator_states_pub.get_instance(); 195 const int status_instance = _estimator_states_pub.get_instance();
202 -
203 if ((status_instance >= 0) && changed_instance 196 if ((status_instance >= 0) && changed_instance
204 && (_attitude_pub.get_instance() == status_instance) 197 && (_attitude_pub.get_instance() == status_instance)
205 && (_local_position_pub.get_instance() == status_instance) 198 && (_local_position_pub.get_instance() == status_instance)
206 && (_global_position_pub.get_instance() == status_instance)) { 199 && (_global_position_pub.get_instance() == status_instance)) {
207 -
208 _instance = status_instance; 200 _instance = status_instance;
209 -
210 ScheduleNow(); 201 ScheduleNow();
211 return true; 202 return true;
212 } 203 }
213 -
214 PX4_ERR("publication instance problem: %d att: %d lpos: %d gpos: %d", status_instance, 204 PX4_ERR("publication instance problem: %d att: %d lpos: %d gpos: %d", status_instance,
215 _attitude_pub.get_instance(), _local_position_pub.get_instance(), _global_position_pub.get_instance()); 205 _attitude_pub.get_instance(), _local_position_pub.get_instance(), _global_position_pub.get_instance());
216 -
217 return false; 206 return false;
218 } 207 }
219 -
220 int EKF2::print_status() 208 int EKF2::print_status()
221 { 209 {
222 PX4_INFO_RAW("ekf2:%d attitude: %d, local position: %d, global position: %d\n", _instance, _ekf.attitude_valid(), 210 PX4_INFO_RAW("ekf2:%d attitude: %d, local position: %d, global position: %d\n", _instance, _ekf.attitude_valid(),
...@@ -224,71 +212,54 @@ int EKF2::print_status() ...@@ -224,71 +212,54 @@ int EKF2::print_status()
224 perf_print_counter(_ecl_ekf_update_perf); 212 perf_print_counter(_ecl_ekf_update_perf);
225 perf_print_counter(_ecl_ekf_update_full_perf); 213 perf_print_counter(_ecl_ekf_update_full_perf);
226 perf_print_counter(_imu_missed_perf); 214 perf_print_counter(_imu_missed_perf);
227 -
228 if (_device_id_mag != 0) { 215 if (_device_id_mag != 0) {
229 perf_print_counter(_mag_missed_perf); 216 perf_print_counter(_mag_missed_perf);
230 } 217 }
231 -
232 return 0; 218 return 0;
233 } 219 }
234 -
235 void EKF2::Run() 220 void EKF2::Run()
236 { 221 {
237 if (should_exit()) { 222 if (should_exit()) {
238 _sensor_combined_sub.unregisterCallback(); 223 _sensor_combined_sub.unregisterCallback();
239 _vehicle_imu_sub.unregisterCallback(); 224 _vehicle_imu_sub.unregisterCallback();
240 -
241 return; 225 return;
242 } 226 }
243 -
244 // check for parameter updates 227 // check for parameter updates
245 if (_parameter_update_sub.updated() || !_callback_registered) { 228 if (_parameter_update_sub.updated() || !_callback_registered) {
246 // clear update 229 // clear update
247 parameter_update_s pupdate; 230 parameter_update_s pupdate;
248 _parameter_update_sub.copy(&pupdate); 231 _parameter_update_sub.copy(&pupdate);
249 -
250 // update parameters from storage 232 // update parameters from storage
251 updateParams(); 233 updateParams();
252 -
253 _ekf.set_min_required_gps_health_time(_param_ekf2_req_gps_h.get() * 1_s); 234 _ekf.set_min_required_gps_health_time(_param_ekf2_req_gps_h.get() * 1_s);
254 -
255 // The airspeed scale factor correcton is only available via parameter as used by the airspeed module 235 // The airspeed scale factor correcton is only available via parameter as used by the airspeed module
256 param_t param_aspd_scale = param_find("ASPD_SCALE"); 236 param_t param_aspd_scale = param_find("ASPD_SCALE");
257 -
258 if (param_aspd_scale != PARAM_INVALID) { 237 if (param_aspd_scale != PARAM_INVALID) {
259 param_get(param_aspd_scale, &_airspeed_scale_factor); 238 param_get(param_aspd_scale, &_airspeed_scale_factor);
260 } 239 }
261 } 240 }
262 -
263 if (!_callback_registered) { 241 if (!_callback_registered) {
264 if (_multi_mode) { 242 if (_multi_mode) {
265 _callback_registered = _vehicle_imu_sub.registerCallback(); 243 _callback_registered = _vehicle_imu_sub.registerCallback();
266 -
267 } else { 244 } else {
268 _callback_registered = _sensor_combined_sub.registerCallback(); 245 _callback_registered = _sensor_combined_sub.registerCallback();
269 } 246 }
270 -
271 if (!_callback_registered) { 247 if (!_callback_registered) {
272 PX4_WARN("%d - failed to register callback, retrying", _instance); 248 PX4_WARN("%d - failed to register callback, retrying", _instance);
273 ScheduleDelayed(1_s); 249 ScheduleDelayed(1_s);
274 return; 250 return;
275 } 251 }
276 } 252 }
277 -
278 if (_vehicle_command_sub.updated()) { 253 if (_vehicle_command_sub.updated()) {
279 vehicle_command_s vehicle_command; 254 vehicle_command_s vehicle_command;
280 -
281 if (_vehicle_command_sub.update(&vehicle_command)) { 255 if (_vehicle_command_sub.update(&vehicle_command)) {
282 if (vehicle_command.command == vehicle_command_s::VEHICLE_CMD_SET_GPS_GLOBAL_ORIGIN) { 256 if (vehicle_command.command == vehicle_command_s::VEHICLE_CMD_SET_GPS_GLOBAL_ORIGIN) {
283 if (!_ekf.control_status_flags().in_air) { 257 if (!_ekf.control_status_flags().in_air) {
284 -
285 uint64_t origin_time {}; 258 uint64_t origin_time {};
286 double latitude = vehicle_command.param5; 259 double latitude = vehicle_command.param5;
287 double longitude = vehicle_command.param6; 260 double longitude = vehicle_command.param6;
288 float altitude = vehicle_command.param7; 261 float altitude = vehicle_command.param7;
289 -
290 _ekf.setEkfGlobalOrigin(latitude, longitude, altitude); 262 _ekf.setEkfGlobalOrigin(latitude, longitude, altitude);
291 -
292 // Validate the ekf origin status. 263 // Validate the ekf origin status.
293 _ekf.getEkfGlobalOrigin(origin_time, latitude, longitude, altitude); 264 _ekf.getEkfGlobalOrigin(origin_time, latitude, longitude, altitude);
294 PX4_INFO("New NED origin (LLA): %3.10f, %3.10f, %4.3f\n", latitude, longitude, static_cast<double>(altitude)); 265 PX4_INFO("New NED origin (LLA): %3.10f, %3.10f, %4.3f\n", latitude, longitude, static_cast<double>(altitude));
...@@ -296,81 +267,63 @@ void EKF2::Run() ...@@ -296,81 +267,63 @@ void EKF2::Run()
296 } 267 }
297 } 268 }
298 } 269 }
299 -
300 bool imu_updated = false; 270 bool imu_updated = false;
301 imuSample imu_sample_new {}; 271 imuSample imu_sample_new {};
302 -
303 hrt_abstime imu_dt = 0; // for tracking time slip later 272 hrt_abstime imu_dt = 0; // for tracking time slip later
304 -
305 if (_multi_mode) { 273 if (_multi_mode) {
306 const unsigned last_generation = _vehicle_imu_sub.get_last_generation(); 274 const unsigned last_generation = _vehicle_imu_sub.get_last_generation();
307 vehicle_imu_s imu; 275 vehicle_imu_s imu;
308 imu_updated = _vehicle_imu_sub.update(&imu); 276 imu_updated = _vehicle_imu_sub.update(&imu);
309 -
310 if (imu_updated && (_vehicle_imu_sub.get_last_generation() != last_generation + 1)) { 277 if (imu_updated && (_vehicle_imu_sub.get_last_generation() != last_generation + 1)) {
311 perf_count(_imu_missed_perf); 278 perf_count(_imu_missed_perf);
312 PX4_DEBUG("%d - vehicle_imu lost, generation %d -> %d", _instance, last_generation, 279 PX4_DEBUG("%d - vehicle_imu lost, generation %d -> %d", _instance, last_generation,
313 _vehicle_imu_sub.get_last_generation()); 280 _vehicle_imu_sub.get_last_generation());
314 } 281 }
315 -
316 imu_sample_new.time_us = imu.timestamp_sample; 282 imu_sample_new.time_us = imu.timestamp_sample;
317 imu_sample_new.delta_ang_dt = imu.delta_angle_dt * 1.e-6f; 283 imu_sample_new.delta_ang_dt = imu.delta_angle_dt * 1.e-6f;
318 imu_sample_new.delta_ang = Vector3f{imu.delta_angle}; 284 imu_sample_new.delta_ang = Vector3f{imu.delta_angle};
319 imu_sample_new.delta_vel_dt = imu.delta_velocity_dt * 1.e-6f; 285 imu_sample_new.delta_vel_dt = imu.delta_velocity_dt * 1.e-6f;
320 imu_sample_new.delta_vel = Vector3f{imu.delta_velocity}; 286 imu_sample_new.delta_vel = Vector3f{imu.delta_velocity};
321 -
322 if (imu.delta_velocity_clipping > 0) { 287 if (imu.delta_velocity_clipping > 0) {
323 imu_sample_new.delta_vel_clipping[0] = imu.delta_velocity_clipping & vehicle_imu_s::CLIPPING_X; 288 imu_sample_new.delta_vel_clipping[0] = imu.delta_velocity_clipping & vehicle_imu_s::CLIPPING_X;
324 imu_sample_new.delta_vel_clipping[1] = imu.delta_velocity_clipping & vehicle_imu_s::CLIPPING_Y; 289 imu_sample_new.delta_vel_clipping[1] = imu.delta_velocity_clipping & vehicle_imu_s::CLIPPING_Y;
325 imu_sample_new.delta_vel_clipping[2] = imu.delta_velocity_clipping & vehicle_imu_s::CLIPPING_Z; 290 imu_sample_new.delta_vel_clipping[2] = imu.delta_velocity_clipping & vehicle_imu_s::CLIPPING_Z;
326 } 291 }
327 -
328 imu_dt = imu.delta_angle_dt; 292 imu_dt = imu.delta_angle_dt;
329 -
330 if ((_device_id_accel == 0) || (_device_id_gyro == 0)) { 293 if ((_device_id_accel == 0) || (_device_id_gyro == 0)) {
331 _device_id_accel = imu.accel_device_id; 294 _device_id_accel = imu.accel_device_id;
332 _device_id_gyro = imu.gyro_device_id; 295 _device_id_gyro = imu.gyro_device_id;
333 _imu_calibration_count = imu.calibration_count; 296 _imu_calibration_count = imu.calibration_count;
334 -
335 } else if ((imu.calibration_count > _imu_calibration_count) 297 } else if ((imu.calibration_count > _imu_calibration_count)
336 || (imu.accel_device_id != _device_id_accel) 298 || (imu.accel_device_id != _device_id_accel)
337 || (imu.gyro_device_id != _device_id_gyro)) { 299 || (imu.gyro_device_id != _device_id_gyro)) {
338 -
339 PX4_INFO("%d - resetting IMU bias", _instance); 300 PX4_INFO("%d - resetting IMU bias", _instance);
340 _device_id_accel = imu.accel_device_id; 301 _device_id_accel = imu.accel_device_id;
341 _device_id_gyro = imu.gyro_device_id; 302 _device_id_gyro = imu.gyro_device_id;
342 -
343 _ekf.resetImuBias(); 303 _ekf.resetImuBias();
344 _imu_calibration_count = imu.calibration_count; 304 _imu_calibration_count = imu.calibration_count;
345 } 305 }
346 -
347 } else { 306 } else {
348 sensor_combined_s sensor_combined; 307 sensor_combined_s sensor_combined;
349 imu_updated = _sensor_combined_sub.update(&sensor_combined); 308 imu_updated = _sensor_combined_sub.update(&sensor_combined);
350 -
351 imu_sample_new.time_us = sensor_combined.timestamp; 309 imu_sample_new.time_us = sensor_combined.timestamp;
352 imu_sample_new.delta_ang_dt = sensor_combined.gyro_integral_dt * 1.e-6f; 310 imu_sample_new.delta_ang_dt = sensor_combined.gyro_integral_dt * 1.e-6f;
353 imu_sample_new.delta_ang = Vector3f{sensor_combined.gyro_rad} * imu_sample_new.delta_ang_dt; 311 imu_sample_new.delta_ang = Vector3f{sensor_combined.gyro_rad} * imu_sample_new.delta_ang_dt;
354 imu_sample_new.delta_vel_dt = sensor_combined.accelerometer_integral_dt * 1.e-6f; 312 imu_sample_new.delta_vel_dt = sensor_combined.accelerometer_integral_dt * 1.e-6f;
355 imu_sample_new.delta_vel = Vector3f{sensor_combined.accelerometer_m_s2} * imu_sample_new.delta_vel_dt; 313 imu_sample_new.delta_vel = Vector3f{sensor_combined.accelerometer_m_s2} * imu_sample_new.delta_vel_dt;
356 -
357 if (sensor_combined.accelerometer_clipping > 0) { 314 if (sensor_combined.accelerometer_clipping > 0) {
358 imu_sample_new.delta_vel_clipping[0] = sensor_combined.accelerometer_clipping & sensor_combined_s::CLIPPING_X; 315 imu_sample_new.delta_vel_clipping[0] = sensor_combined.accelerometer_clipping & sensor_combined_s::CLIPPING_X;
359 imu_sample_new.delta_vel_clipping[1] = sensor_combined.accelerometer_clipping & sensor_combined_s::CLIPPING_Y; 316 imu_sample_new.delta_vel_clipping[1] = sensor_combined.accelerometer_clipping & sensor_combined_s::CLIPPING_Y;
360 imu_sample_new.delta_vel_clipping[2] = sensor_combined.accelerometer_clipping & sensor_combined_s::CLIPPING_Z; 317 imu_sample_new.delta_vel_clipping[2] = sensor_combined.accelerometer_clipping & sensor_combined_s::CLIPPING_Z;
361 } 318 }
362 -
363 imu_dt = sensor_combined.gyro_integral_dt; 319 imu_dt = sensor_combined.gyro_integral_dt;
364 -
365 if (_sensor_selection_sub.updated() || (_device_id_accel == 0 || _device_id_gyro == 0)) { 320 if (_sensor_selection_sub.updated() || (_device_id_accel == 0 || _device_id_gyro == 0)) {
366 sensor_selection_s sensor_selection; 321 sensor_selection_s sensor_selection;
367 -
368 if (_sensor_selection_sub.copy(&sensor_selection)) { 322 if (_sensor_selection_sub.copy(&sensor_selection)) {
369 if (_device_id_accel != sensor_selection.accel_device_id) { 323 if (_device_id_accel != sensor_selection.accel_device_id) {
370 _ekf.resetAccelBias(); 324 _ekf.resetAccelBias();
371 _device_id_accel = sensor_selection.accel_device_id; 325 _device_id_accel = sensor_selection.accel_device_id;
372 } 326 }
373 -
374 if (_device_id_gyro != sensor_selection.gyro_device_id) { 327 if (_device_id_gyro != sensor_selection.gyro_device_id) {
375 _ekf.resetGyroBias(); 328 _ekf.resetGyroBias();
376 _device_id_gyro = sensor_selection.gyro_device_id; 329 _device_id_gyro = sensor_selection.gyro_device_id;
...@@ -378,72 +331,54 @@ void EKF2::Run() ...@@ -378,72 +331,54 @@ void EKF2::Run()
378 } 331 }
379 } 332 }
380 } 333 }
381 -
382 if (imu_updated) { 334 if (imu_updated) {
383 const hrt_abstime now = imu_sample_new.time_us; 335 const hrt_abstime now = imu_sample_new.time_us;
384 -
385 // push imu data into estimator 336 // push imu data into estimator
386 _ekf.setIMUData(imu_sample_new); 337 _ekf.setIMUData(imu_sample_new);
387 PublishAttitude(now); // publish attitude immediately (uses quaternion from output predictor) 338 PublishAttitude(now); // publish attitude immediately (uses quaternion from output predictor)
388 -
389 // integrate time to monitor time slippage 339 // integrate time to monitor time slippage
390 if (_start_time_us > 0) { 340 if (_start_time_us > 0) {
391 _integrated_time_us += imu_dt; 341 _integrated_time_us += imu_dt;
392 _last_time_slip_us = (imu_sample_new.time_us - _start_time_us) - _integrated_time_us; 342 _last_time_slip_us = (imu_sample_new.time_us - _start_time_us) - _integrated_time_us;
393 -
394 } else { 343 } else {
395 _start_time_us = imu_sample_new.time_us; 344 _start_time_us = imu_sample_new.time_us;
396 _last_time_slip_us = 0; 345 _last_time_slip_us = 0;
397 } 346 }
398 -
399 // update all other topics if they have new data 347 // update all other topics if they have new data
400 if (_status_sub.updated()) { 348 if (_status_sub.updated()) {
401 vehicle_status_s vehicle_status; 349 vehicle_status_s vehicle_status;
402 -
403 if (_status_sub.copy(&vehicle_status)) { 350 if (_status_sub.copy(&vehicle_status)) {
404 const bool is_fixed_wing = (vehicle_status.vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING); 351 const bool is_fixed_wing = (vehicle_status.vehicle_type == vehicle_status_s::VEHICLE_TYPE_FIXED_WING);
405 -
406 // only fuse synthetic sideslip measurements if conditions are met 352 // only fuse synthetic sideslip measurements if conditions are met
407 _ekf.set_fuse_beta_flag(is_fixed_wing && (_param_ekf2_fuse_beta.get() == 1)); 353 _ekf.set_fuse_beta_flag(is_fixed_wing && (_param_ekf2_fuse_beta.get() == 1));
408 -
409 // let the EKF know if the vehicle motion is that of a fixed wing (forward flight only relative to wind) 354 // let the EKF know if the vehicle motion is that of a fixed wing (forward flight only relative to wind)
410 _ekf.set_is_fixed_wing(is_fixed_wing); 355 _ekf.set_is_fixed_wing(is_fixed_wing);
411 -
412 _preflt_checker.setVehicleCanObserveHeadingInFlight(vehicle_status.vehicle_type != 356 _preflt_checker.setVehicleCanObserveHeadingInFlight(vehicle_status.vehicle_type !=
413 vehicle_status_s::VEHICLE_TYPE_ROTARY_WING); 357 vehicle_status_s::VEHICLE_TYPE_ROTARY_WING);
414 -
415 _armed = (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED); 358 _armed = (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_ARMED);
416 -
417 // update standby (arming state) flag 359 // update standby (arming state) flag
418 const bool standby = (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_STANDBY); 360 const bool standby = (vehicle_status.arming_state == vehicle_status_s::ARMING_STATE_STANDBY);
419 -
420 if (_standby != standby) { 361 if (_standby != standby) {
421 _standby = standby; 362 _standby = standby;
422 -
423 // reset preflight checks if transitioning in or out of standby arming state 363 // reset preflight checks if transitioning in or out of standby arming state
424 _preflt_checker.reset(); 364 _preflt_checker.reset();
425 } 365 }
426 } 366 }
427 } 367 }
428 -
429 if (_vehicle_land_detected_sub.updated()) { 368 if (_vehicle_land_detected_sub.updated()) {
430 vehicle_land_detected_s vehicle_land_detected; 369 vehicle_land_detected_s vehicle_land_detected;
431 -
432 if (_vehicle_land_detected_sub.copy(&vehicle_land_detected)) { 370 if (_vehicle_land_detected_sub.copy(&vehicle_land_detected)) {
433 _ekf.set_in_air_status(!vehicle_land_detected.landed); 371 _ekf.set_in_air_status(!vehicle_land_detected.landed);
434 -
435 if (_armed && (_param_ekf2_gnd_eff_dz.get() > 0.f)) { 372 if (_armed && (_param_ekf2_gnd_eff_dz.get() > 0.f)) {
436 if (!_had_valid_terrain) { 373 if (!_had_valid_terrain) {
437 // update ground effect flag based on land detector state if we've never had valid terrain data 374 // update ground effect flag based on land detector state if we've never had valid terrain data
438 _ekf.set_gnd_effect_flag(vehicle_land_detected.in_ground_effect); 375 _ekf.set_gnd_effect_flag(vehicle_land_detected.in_ground_effect);
439 } 376 }
440 -
441 } else { 377 } else {
442 _ekf.set_gnd_effect_flag(false); 378 _ekf.set_gnd_effect_flag(false);
443 } 379 }
444 } 380 }
445 } 381 }
446 -
447 // ekf2_timestamps (using 0.1 ms relative timestamps) 382 // ekf2_timestamps (using 0.1 ms relative timestamps)
448 ekf2_timestamps_s ekf2_timestamps { 383 ekf2_timestamps_s ekf2_timestamps {
449 .timestamp = now, 384 .timestamp = now,
...@@ -454,33 +389,25 @@ void EKF2::Run() ...@@ -454,33 +389,25 @@ void EKF2::Run()
454 .vehicle_magnetometer_timestamp_rel = ekf2_timestamps_s::RELATIVE_TIMESTAMP_INVALID, 389 .vehicle_magnetometer_timestamp_rel = ekf2_timestamps_s::RELATIVE_TIMESTAMP_INVALID,
455 .visual_odometry_timestamp_rel = ekf2_timestamps_s::RELATIVE_TIMESTAMP_INVALID, 390 .visual_odometry_timestamp_rel = ekf2_timestamps_s::RELATIVE_TIMESTAMP_INVALID,
456 }; 391 };
457 -
458 UpdateAirspeedSample(ekf2_timestamps); 392 UpdateAirspeedSample(ekf2_timestamps);
459 UpdateAuxVelSample(ekf2_timestamps); 393 UpdateAuxVelSample(ekf2_timestamps);
460 UpdateBaroSample(ekf2_timestamps); 394 UpdateBaroSample(ekf2_timestamps);
461 UpdateGpsSample(ekf2_timestamps); 395 UpdateGpsSample(ekf2_timestamps);
462 UpdateMagSample(ekf2_timestamps); 396 UpdateMagSample(ekf2_timestamps);
463 UpdateRangeSample(ekf2_timestamps); 397 UpdateRangeSample(ekf2_timestamps);
464 -
465 vehicle_odometry_s ev_odom; 398 vehicle_odometry_s ev_odom;
466 const bool new_ev_odom = UpdateExtVisionSample(ekf2_timestamps, ev_odom); 399 const bool new_ev_odom = UpdateExtVisionSample(ekf2_timestamps, ev_odom);
467 -
468 optical_flow_s optical_flow; 400 optical_flow_s optical_flow;
469 const bool new_optical_flow = UpdateFlowSample(ekf2_timestamps, optical_flow); 401 const bool new_optical_flow = UpdateFlowSample(ekf2_timestamps, optical_flow);
470 -
471 -
472 // run the EKF update and output 402 // run the EKF update and output
473 const hrt_abstime ekf_update_start = hrt_absolute_time(); 403 const hrt_abstime ekf_update_start = hrt_absolute_time();
474 -
475 if (_ekf.update()) { 404 if (_ekf.update()) {
476 perf_set_elapsed(_ecl_ekf_update_full_perf, hrt_elapsed_time(&ekf_update_start)); 405 perf_set_elapsed(_ecl_ekf_update_full_perf, hrt_elapsed_time(&ekf_update_start));
477 -
478 PublishLocalPosition(now); 406 PublishLocalPosition(now);
479 PublishOdometry(now, imu_sample_new); 407 PublishOdometry(now, imu_sample_new);
480 PublishGlobalPosition(now); 408 PublishGlobalPosition(now);
481 PublishSensorBias(now); 409 PublishSensorBias(now);
482 PublishWindEstimate(now); 410 PublishWindEstimate(now);
483 -
484 // publish status/logging messages 411 // publish status/logging messages
485 PublishEkfDriftMetrics(now); 412 PublishEkfDriftMetrics(now);
486 PublishEventFlags(now); 413 PublishEventFlags(now);
...@@ -491,28 +418,22 @@ void EKF2::Run() ...@@ -491,28 +418,22 @@ void EKF2::Run()
491 PublishInnovationTestRatios(now); 418 PublishInnovationTestRatios(now);
492 PublishInnovationVariances(now); 419 PublishInnovationVariances(now);
493 PublishYawEstimatorStatus(now); 420 PublishYawEstimatorStatus(now);
494 -
495 UpdateMagCalibration(now); 421 UpdateMagCalibration(now);
496 -
497 } else { 422 } else {
498 // ekf no update 423 // ekf no update
499 perf_set_elapsed(_ecl_ekf_update_perf, hrt_elapsed_time(&ekf_update_start)); 424 perf_set_elapsed(_ecl_ekf_update_perf, hrt_elapsed_time(&ekf_update_start));
500 } 425 }
501 -
502 // publish external visual odometry after fixed frame alignment if new odometry is received 426 // publish external visual odometry after fixed frame alignment if new odometry is received
503 if (new_ev_odom) { 427 if (new_ev_odom) {
504 PublishOdometryAligned(now, ev_odom); 428 PublishOdometryAligned(now, ev_odom);
505 } 429 }
506 -
507 if (new_optical_flow) { 430 if (new_optical_flow) {
508 PublishOpticalFlowVel(now, optical_flow); 431 PublishOpticalFlowVel(now, optical_flow);
509 } 432 }
510 -
511 // publish ekf2_timestamps 433 // publish ekf2_timestamps
512 _ekf2_timestamps_pub.publish(ekf2_timestamps); 434 _ekf2_timestamps_pub.publish(ekf2_timestamps);
513 } 435 }
514 } 436 }
515 -
516 void EKF2::PublishAttitude(const hrt_abstime &timestamp) 437 void EKF2::PublishAttitude(const hrt_abstime &timestamp)
517 { 438 {
518 if (_ekf.attitude_valid()) { 439 if (_ekf.attitude_valid()) {
...@@ -521,11 +442,9 @@ void EKF2::PublishAttitude(const hrt_abstime &timestamp) ...@@ -521,11 +442,9 @@ void EKF2::PublishAttitude(const hrt_abstime &timestamp)
521 att.timestamp_sample = timestamp; 442 att.timestamp_sample = timestamp;
522 const Quatf q{_ekf.calculate_quaternion()}; 443 const Quatf q{_ekf.calculate_quaternion()};
523 q.copyTo(att.q); 444 q.copyTo(att.q);
524 -
525 _ekf.get_quat_reset(&att.delta_q_reset[0], &att.quat_reset_counter); 445 _ekf.get_quat_reset(&att.delta_q_reset[0], &att.quat_reset_counter);
526 att.timestamp = _replay_mode ? timestamp : hrt_absolute_time(); 446 att.timestamp = _replay_mode ? timestamp : hrt_absolute_time();
527 _attitude_pub.publish(att); 447 _attitude_pub.publish(att);
528 -
529 } else if (_replay_mode) { 448 } else if (_replay_mode) {
530 // in replay mode we have to tell the replay module not to wait for an update 449 // in replay mode we have to tell the replay module not to wait for an update
531 // we do this by publishing an attitude with zero timestamp 450 // we do this by publishing an attitude with zero timestamp
...@@ -533,13 +452,11 @@ void EKF2::PublishAttitude(const hrt_abstime &timestamp) ...@@ -533,13 +452,11 @@ void EKF2::PublishAttitude(const hrt_abstime &timestamp)
533 _attitude_pub.publish(att); 452 _attitude_pub.publish(att);
534 } 453 }
535 } 454 }
536 -
537 void EKF2::PublishEkfDriftMetrics(const hrt_abstime &timestamp) 455 void EKF2::PublishEkfDriftMetrics(const hrt_abstime &timestamp)
538 { 456 {
539 // publish GPS drift data only when updated to minimise overhead 457 // publish GPS drift data only when updated to minimise overhead
540 float gps_drift[3]; 458 float gps_drift[3];
541 bool blocked; 459 bool blocked;
542 -
543 if (_ekf.get_gps_drift_metrics(gps_drift, &blocked)) { 460 if (_ekf.get_gps_drift_metrics(gps_drift, &blocked)) {
544 ekf_gps_drift_s drift_data; 461 ekf_gps_drift_s drift_data;
545 drift_data.hpos_drift_rate = gps_drift[0]; 462 drift_data.hpos_drift_rate = gps_drift[0];
...@@ -547,35 +464,28 @@ void EKF2::PublishEkfDriftMetrics(const hrt_abstime &timestamp) ...@@ -547,35 +464,28 @@ void EKF2::PublishEkfDriftMetrics(const hrt_abstime &timestamp)
547 drift_data.hspd = gps_drift[2]; 464 drift_data.hspd = gps_drift[2];
548 drift_data.blocked = blocked; 465 drift_data.blocked = blocked;
549 drift_data.timestamp = _replay_mode ? timestamp : hrt_absolute_time(); 466 drift_data.timestamp = _replay_mode ? timestamp : hrt_absolute_time();
550 -
551 _ekf_gps_drift_pub.publish(drift_data); 467 _ekf_gps_drift_pub.publish(drift_data);
552 } 468 }
553 } 469 }
554 -
555 void EKF2::PublishEventFlags(const hrt_abstime &timestamp) 470 void EKF2::PublishEventFlags(const hrt_abstime &timestamp)
556 { 471 {
557 // information events 472 // information events
558 uint32_t information_events = _ekf.information_event_status().value; 473 uint32_t information_events = _ekf.information_event_status().value;
559 bool information_event_updated = false; 474 bool information_event_updated = false;
560 -
561 if (information_events != 0) { 475 if (information_events != 0) {
562 information_event_updated = true; 476 information_event_updated = true;
563 _filter_information_event_changes++; 477 _filter_information_event_changes++;
564 } 478 }
565 -
566 // warning events 479 // warning events
567 uint32_t warning_events = _ekf.warning_event_status().value; 480 uint32_t warning_events = _ekf.warning_event_status().value;
568 bool warning_event_updated = false; 481 bool warning_event_updated = false;
569 -
570 if (warning_events != 0) { 482 if (warning_events != 0) {
571 warning_event_updated = true; 483 warning_event_updated = true;
572 _filter_warning_event_changes++; 484 _filter_warning_event_changes++;
573 } 485 }
574 -
575 if (information_event_updated || warning_event_updated) { 486 if (information_event_updated || warning_event_updated) {
576 estimator_event_flags_s event_flags{}; 487 estimator_event_flags_s event_flags{};
577 event_flags.timestamp_sample = timestamp; 488 event_flags.timestamp_sample = timestamp;
578 -
579 event_flags.information_event_changes = _filter_information_event_changes; 489 event_flags.information_event_changes = _filter_information_event_changes;
580 event_flags.gps_checks_passed = _ekf.information_event_flags().gps_checks_passed; 490 event_flags.gps_checks_passed = _ekf.information_event_flags().gps_checks_passed;
581 event_flags.reset_vel_to_gps = _ekf.information_event_flags().reset_vel_to_gps; 491 event_flags.reset_vel_to_gps = _ekf.information_event_flags().reset_vel_to_gps;
...@@ -590,7 +500,6 @@ void EKF2::PublishEventFlags(const hrt_abstime &timestamp) ...@@ -590,7 +500,6 @@ void EKF2::PublishEventFlags(const hrt_abstime &timestamp)
590 event_flags.starting_vision_vel_fusion = _ekf.information_event_flags().starting_vision_vel_fusion; 500 event_flags.starting_vision_vel_fusion = _ekf.information_event_flags().starting_vision_vel_fusion;
591 event_flags.starting_vision_yaw_fusion = _ekf.information_event_flags().starting_vision_yaw_fusion; 501 event_flags.starting_vision_yaw_fusion = _ekf.information_event_flags().starting_vision_yaw_fusion;
592 event_flags.yaw_aligned_to_imu_gps = _ekf.information_event_flags().yaw_aligned_to_imu_gps; 502 event_flags.yaw_aligned_to_imu_gps = _ekf.information_event_flags().yaw_aligned_to_imu_gps;
593 -
594 event_flags.warning_event_changes = _filter_warning_event_changes; 503 event_flags.warning_event_changes = _filter_warning_event_changes;
595 event_flags.gps_quality_poor = _ekf.warning_event_flags().gps_quality_poor; 504 event_flags.gps_quality_poor = _ekf.warning_event_flags().gps_quality_poor;
596 event_flags.gps_fusion_timout = _ekf.warning_event_flags().gps_fusion_timout; 505 event_flags.gps_fusion_timout = _ekf.warning_event_flags().gps_fusion_timout;
...@@ -603,62 +512,48 @@ void EKF2::PublishEventFlags(const hrt_abstime &timestamp) ...@@ -603,62 +512,48 @@ void EKF2::PublishEventFlags(const hrt_abstime &timestamp)
603 event_flags.stopping_mag_use = _ekf.warning_event_flags().stopping_mag_use; 512 event_flags.stopping_mag_use = _ekf.warning_event_flags().stopping_mag_use;
604 event_flags.vision_data_stopped = _ekf.warning_event_flags().vision_data_stopped; 513 event_flags.vision_data_stopped = _ekf.warning_event_flags().vision_data_stopped;
605 event_flags.emergency_yaw_reset_mag_stopped = _ekf.warning_event_flags().emergency_yaw_reset_mag_stopped; 514 event_flags.emergency_yaw_reset_mag_stopped = _ekf.warning_event_flags().emergency_yaw_reset_mag_stopped;
606 -
607 event_flags.timestamp = _replay_mode ? timestamp : hrt_absolute_time(); 515 event_flags.timestamp = _replay_mode ? timestamp : hrt_absolute_time();
608 _estimator_event_flags_pub.publish(event_flags); 516 _estimator_event_flags_pub.publish(event_flags);
609 } 517 }
610 -
611 _ekf.clear_information_events(); 518 _ekf.clear_information_events();
612 _ekf.clear_warning_events(); 519 _ekf.clear_warning_events();
613 } 520 }
614 -
615 void EKF2::PublishGlobalPosition(const hrt_abstime &timestamp) 521 void EKF2::PublishGlobalPosition(const hrt_abstime &timestamp)
616 { 522 {
617 if (_ekf.global_position_is_valid() && !_preflt_checker.hasFailed()) { 523 if (_ekf.global_position_is_valid() && !_preflt_checker.hasFailed()) {
618 // only publish if position has changed by at least 1 mm (map_projection_reproject is relatively expensive) 524 // only publish if position has changed by at least 1 mm (map_projection_reproject is relatively expensive)
619 const Vector3f position{_ekf.getPosition()}; 525 const Vector3f position{_ekf.getPosition()};
620 -
621 if ((_last_local_position_for_gpos - position).longerThan(0.001f)) { 526 if ((_last_local_position_for_gpos - position).longerThan(0.001f)) {
622 // generate and publish global position data 527 // generate and publish global position data
623 vehicle_global_position_s global_pos; 528 vehicle_global_position_s global_pos;
624 global_pos.timestamp_sample = timestamp; 529 global_pos.timestamp_sample = timestamp;
625 -
626 // Position of local NED origin in GPS / WGS84 frame 530 // Position of local NED origin in GPS / WGS84 frame
627 map_projection_reproject(&_ekf.global_origin(), position(0), position(1), &global_pos.lat, &global_pos.lon); 531 map_projection_reproject(&_ekf.global_origin(), position(0), position(1), &global_pos.lat, &global_pos.lon);
628 -
629 float delta_xy[2]; 532 float delta_xy[2];
630 _ekf.get_posNE_reset(delta_xy, &global_pos.lat_lon_reset_counter); 533 _ekf.get_posNE_reset(delta_xy, &global_pos.lat_lon_reset_counter);
631 -
632 global_pos.alt = -position(2) + _ekf.getEkfGlobalOriginAltitude(); // Altitude AMSL in meters 534 global_pos.alt = -position(2) + _ekf.getEkfGlobalOriginAltitude(); // Altitude AMSL in meters
633 global_pos.alt_ellipsoid = filter_altitude_ellipsoid(global_pos.alt); 535 global_pos.alt_ellipsoid = filter_altitude_ellipsoid(global_pos.alt);
634 -
635 // global altitude has opposite sign of local down position 536 // global altitude has opposite sign of local down position
636 float delta_z; 537 float delta_z;
637 uint8_t z_reset_counter; 538 uint8_t z_reset_counter;
638 _ekf.get_posD_reset(&delta_z, &z_reset_counter); 539 _ekf.get_posD_reset(&delta_z, &z_reset_counter);
639 global_pos.delta_alt = -delta_z; 540 global_pos.delta_alt = -delta_z;
640 -
641 _ekf.get_ekf_gpos_accuracy(&global_pos.eph, &global_pos.epv); 541 _ekf.get_ekf_gpos_accuracy(&global_pos.eph, &global_pos.epv);
642 -
643 if (_ekf.isTerrainEstimateValid()) { 542 if (_ekf.isTerrainEstimateValid()) {
644 // Terrain altitude in m, WGS84 543 // Terrain altitude in m, WGS84
645 global_pos.terrain_alt = _ekf.getEkfGlobalOriginAltitude() - _ekf.getTerrainVertPos(); 544 global_pos.terrain_alt = _ekf.getEkfGlobalOriginAltitude() - _ekf.getTerrainVertPos();
646 global_pos.terrain_alt_valid = true; 545 global_pos.terrain_alt_valid = true;
647 -
648 } else { 546 } else {
649 global_pos.terrain_alt = NAN; 547 global_pos.terrain_alt = NAN;
650 global_pos.terrain_alt_valid = false; 548 global_pos.terrain_alt_valid = false;
651 } 549 }
652 -
653 global_pos.dead_reckoning = _ekf.inertial_dead_reckoning(); // True if this position is estimated through dead-reckoning 550 global_pos.dead_reckoning = _ekf.inertial_dead_reckoning(); // True if this position is estimated through dead-reckoning
654 global_pos.timestamp = _replay_mode ? timestamp : hrt_absolute_time(); 551 global_pos.timestamp = _replay_mode ? timestamp : hrt_absolute_time();
655 _global_position_pub.publish(global_pos); 552 _global_position_pub.publish(global_pos);
656 -
657 _last_local_position_for_gpos = position; 553 _last_local_position_for_gpos = position;
658 } 554 }
659 } 555 }
660 } 556 }
661 -
662 void EKF2::PublishInnovations(const hrt_abstime &timestamp, const imuSample &imu) 557 void EKF2::PublishInnovations(const hrt_abstime &timestamp, const imuSample &imu)
663 { 558 {
664 // publish estimator innovation data 559 // publish estimator innovation data
...@@ -678,10 +573,8 @@ void EKF2::PublishInnovations(const hrt_abstime &timestamp, const imuSample &imu ...@@ -678,10 +573,8 @@ void EKF2::PublishInnovations(const hrt_abstime &timestamp, const imuSample &imu
678 _ekf.getHaglInnov(innovations.hagl); 573 _ekf.getHaglInnov(innovations.hagl);
679 // Not yet supported 574 // Not yet supported
680 innovations.aux_vvel = NAN; 575 innovations.aux_vvel = NAN;
681 -
682 innovations.timestamp = _replay_mode ? timestamp : hrt_absolute_time(); 576 innovations.timestamp = _replay_mode ? timestamp : hrt_absolute_time();
683 _estimator_innovations_pub.publish(innovations); 577 _estimator_innovations_pub.publish(innovations);
684 -
685 // calculate noise filtered velocity innovations which are used for pre-flight checking 578 // calculate noise filtered velocity innovations which are used for pre-flight checking
686 if (_standby) { 579 if (_standby) {
687 // TODO: move to run before publications 580 // TODO: move to run before publications
...@@ -689,11 +582,9 @@ void EKF2::PublishInnovations(const hrt_abstime &timestamp, const imuSample &imu ...@@ -689,11 +582,9 @@ void EKF2::PublishInnovations(const hrt_abstime &timestamp, const imuSample &imu
689 _preflt_checker.setUsingFlowAiding(_ekf.control_status_flags().opt_flow); 582 _preflt_checker.setUsingFlowAiding(_ekf.control_status_flags().opt_flow);
690 _preflt_checker.setUsingEvPosAiding(_ekf.control_status_flags().ev_pos); 583 _preflt_checker.setUsingEvPosAiding(_ekf.control_status_flags().ev_pos);
691 _preflt_checker.setUsingEvVelAiding(_ekf.control_status_flags().ev_vel); 584 _preflt_checker.setUsingEvVelAiding(_ekf.control_status_flags().ev_vel);
692 -
693 _preflt_checker.update(imu.delta_ang_dt, innovations); 585 _preflt_checker.update(imu.delta_ang_dt, innovations);
694 } 586 }
695 } 587 }
696 -
697 void EKF2::PublishInnovationTestRatios(const hrt_abstime &timestamp) 588 void EKF2::PublishInnovationTestRatios(const hrt_abstime &timestamp)
698 { 589 {
699 // publish estimator innovation test ratio data 590 // publish estimator innovation test ratio data
...@@ -714,11 +605,9 @@ void EKF2::PublishInnovationTestRatios(const hrt_abstime &timestamp) ...@@ -714,11 +605,9 @@ void EKF2::PublishInnovationTestRatios(const hrt_abstime &timestamp)
714 _ekf.getHaglInnovRatio(test_ratios.hagl); 605 _ekf.getHaglInnovRatio(test_ratios.hagl);
715 // Not yet supported 606 // Not yet supported
716 test_ratios.aux_vvel = NAN; 607 test_ratios.aux_vvel = NAN;
717 -
718 test_ratios.timestamp = _replay_mode ? timestamp : hrt_absolute_time(); 608 test_ratios.timestamp = _replay_mode ? timestamp : hrt_absolute_time();
719 _estimator_innovation_test_ratios_pub.publish(test_ratios); 609 _estimator_innovation_test_ratios_pub.publish(test_ratios);
720 } 610 }
721 -
722 void EKF2::PublishInnovationVariances(const hrt_abstime &timestamp) 611 void EKF2::PublishInnovationVariances(const hrt_abstime &timestamp)
723 { 612 {
724 // publish estimator innovation variance data 613 // publish estimator innovation variance data
...@@ -738,44 +627,36 @@ void EKF2::PublishInnovationVariances(const hrt_abstime &timestamp) ...@@ -738,44 +627,36 @@ void EKF2::PublishInnovationVariances(const hrt_abstime &timestamp)
738 _ekf.getHaglInnovVar(variances.hagl); 627 _ekf.getHaglInnovVar(variances.hagl);
739 // Not yet supported 628 // Not yet supported
740 variances.aux_vvel = NAN; 629 variances.aux_vvel = NAN;
741 -
742 variances.timestamp = _replay_mode ? timestamp : hrt_absolute_time(); 630 variances.timestamp = _replay_mode ? timestamp : hrt_absolute_time();
743 _estimator_innovation_variances_pub.publish(variances); 631 _estimator_innovation_variances_pub.publish(variances);
744 } 632 }
745 -
746 void EKF2::PublishLocalPosition(const hrt_abstime &timestamp) 633 void EKF2::PublishLocalPosition(const hrt_abstime &timestamp)
747 { 634 {
748 vehicle_local_position_s lpos; 635 vehicle_local_position_s lpos;
749 // generate vehicle local position data 636 // generate vehicle local position data
750 lpos.timestamp_sample = timestamp; 637 lpos.timestamp_sample = timestamp;
751 -
752 // Position of body origin in local NED frame 638 // Position of body origin in local NED frame
753 const Vector3f position{_ekf.getPosition()}; 639 const Vector3f position{_ekf.getPosition()};
754 lpos.x = position(0); 640 lpos.x = position(0);
755 lpos.y = position(1); 641 lpos.y = position(1);
756 lpos.z = position(2); 642 lpos.z = position(2);
757 -
758 // Velocity of body origin in local NED frame (m/s) 643 // Velocity of body origin in local NED frame (m/s)
759 const Vector3f velocity{_ekf.getVelocity()}; 644 const Vector3f velocity{_ekf.getVelocity()};
760 lpos.vx = velocity(0); 645 lpos.vx = velocity(0);
761 lpos.vy = velocity(1); 646 lpos.vy = velocity(1);
762 lpos.vz = velocity(2); 647 lpos.vz = velocity(2);
763 -
764 // vertical position time derivative (m/s) 648 // vertical position time derivative (m/s)
765 lpos.z_deriv = _ekf.getVerticalPositionDerivative(); 649 lpos.z_deriv = _ekf.getVerticalPositionDerivative();
766 -
767 // Acceleration of body origin in local frame 650 // Acceleration of body origin in local frame
768 const Vector3f vel_deriv{_ekf.getVelocityDerivative()}; 651 const Vector3f vel_deriv{_ekf.getVelocityDerivative()};
769 lpos.ax = vel_deriv(0); 652 lpos.ax = vel_deriv(0);
770 lpos.ay = vel_deriv(1); 653 lpos.ay = vel_deriv(1);
771 lpos.az = vel_deriv(2); 654 lpos.az = vel_deriv(2);
772 -
773 // TODO: better status reporting 655 // TODO: better status reporting
774 lpos.xy_valid = _ekf.local_position_is_valid() && !_preflt_checker.hasHorizFailed(); 656 lpos.xy_valid = _ekf.local_position_is_valid() && !_preflt_checker.hasHorizFailed();
775 lpos.z_valid = !_preflt_checker.hasVertFailed(); 657 lpos.z_valid = !_preflt_checker.hasVertFailed();
776 lpos.v_xy_valid = _ekf.local_position_is_valid() && !_preflt_checker.hasHorizFailed(); 658 lpos.v_xy_valid = _ekf.local_position_is_valid() && !_preflt_checker.hasHorizFailed();
777 lpos.v_z_valid = !_preflt_checker.hasVertFailed(); 659 lpos.v_z_valid = !_preflt_checker.hasVertFailed();
778 -
779 // Position of local NED origin in GPS / WGS84 frame 660 // Position of local NED origin in GPS / WGS84 frame
780 if (_ekf.global_origin_valid()) { 661 if (_ekf.global_origin_valid()) {
781 lpos.ref_timestamp = _ekf.global_origin().timestamp; 662 lpos.ref_timestamp = _ekf.global_origin().timestamp;
...@@ -784,7 +665,6 @@ void EKF2::PublishLocalPosition(const hrt_abstime &timestamp) ...@@ -784,7 +665,6 @@ void EKF2::PublishLocalPosition(const hrt_abstime &timestamp)
784 lpos.ref_alt = _ekf.getEkfGlobalOriginAltitude(); // Reference point in MSL altitude meters 665 lpos.ref_alt = _ekf.getEkfGlobalOriginAltitude(); // Reference point in MSL altitude meters
785 lpos.xy_global = true; 666 lpos.xy_global = true;
786 lpos.z_global = true; 667 lpos.z_global = true;
787 -
788 } else { 668 } else {
789 lpos.ref_timestamp = 0; 669 lpos.ref_timestamp = 0;
790 lpos.ref_lat = static_cast<double>(NAN); 670 lpos.ref_lat = static_cast<double>(NAN);
...@@ -793,147 +673,115 @@ void EKF2::PublishLocalPosition(const hrt_abstime &timestamp) ...@@ -793,147 +673,115 @@ void EKF2::PublishLocalPosition(const hrt_abstime &timestamp)
793 lpos.xy_global = false; 673 lpos.xy_global = false;
794 lpos.z_global = false; 674 lpos.z_global = false;
795 } 675 }
796 -
797 Quatf delta_q_reset; 676 Quatf delta_q_reset;
798 _ekf.get_quat_reset(&delta_q_reset(0), &lpos.heading_reset_counter); 677 _ekf.get_quat_reset(&delta_q_reset(0), &lpos.heading_reset_counter);
799 -
800 lpos.heading = Eulerf(_ekf.getQuaternion()).psi(); 678 lpos.heading = Eulerf(_ekf.getQuaternion()).psi();
801 lpos.delta_heading = Eulerf(delta_q_reset).psi(); 679 lpos.delta_heading = Eulerf(delta_q_reset).psi();
802 -
803 // Distance to bottom surface (ground) in meters 680 // Distance to bottom surface (ground) in meters
804 // constrain the distance to ground to _rng_gnd_clearance 681 // constrain the distance to ground to _rng_gnd_clearance
805 lpos.dist_bottom = math::max(_ekf.getTerrainVertPos() - lpos.z, _param_ekf2_min_rng.get()); 682 lpos.dist_bottom = math::max(_ekf.getTerrainVertPos() - lpos.z, _param_ekf2_min_rng.get());
806 lpos.dist_bottom_valid = _ekf.isTerrainEstimateValid(); 683 lpos.dist_bottom_valid = _ekf.isTerrainEstimateValid();
807 lpos.dist_bottom_sensor_bitfield = _ekf.getTerrainEstimateSensorBitfield(); 684 lpos.dist_bottom_sensor_bitfield = _ekf.getTerrainEstimateSensorBitfield();
808 -
809 if (!_had_valid_terrain) { 685 if (!_had_valid_terrain) {
810 _had_valid_terrain = lpos.dist_bottom_valid; 686 _had_valid_terrain = lpos.dist_bottom_valid;
811 } 687 }
812 -
813 // only consider ground effect if compensation is configured and the vehicle is armed (props spinning) 688 // only consider ground effect if compensation is configured and the vehicle is armed (props spinning)
814 if ((_param_ekf2_gnd_eff_dz.get() > 0.0f) && _armed && lpos.dist_bottom_valid) { 689 if ((_param_ekf2_gnd_eff_dz.get() > 0.0f) && _armed && lpos.dist_bottom_valid) {
815 // set ground effect flag if vehicle is closer than a specified distance to the ground 690 // set ground effect flag if vehicle is closer than a specified distance to the ground
816 _ekf.set_gnd_effect_flag(lpos.dist_bottom < _param_ekf2_gnd_max_hgt.get()); 691 _ekf.set_gnd_effect_flag(lpos.dist_bottom < _param_ekf2_gnd_max_hgt.get());
817 -
818 // if we have no valid terrain estimate and never had one then use ground effect flag from land detector 692 // if we have no valid terrain estimate and never had one then use ground effect flag from land detector
819 // _had_valid_terrain is used to make sure that we don't fall back to using this option 693 // _had_valid_terrain is used to make sure that we don't fall back to using this option
820 // if we temporarily lose terrain data due to the distance sensor getting out of range 694 // if we temporarily lose terrain data due to the distance sensor getting out of range
821 } 695 }
822 -
823 _ekf.get_ekf_lpos_accuracy(&lpos.eph, &lpos.epv); 696 _ekf.get_ekf_lpos_accuracy(&lpos.eph, &lpos.epv);
824 _ekf.get_ekf_vel_accuracy(&lpos.evh, &lpos.evv); 697 _ekf.get_ekf_vel_accuracy(&lpos.evh, &lpos.evv);
825 -
826 // get state reset information of position and velocity 698 // get state reset information of position and velocity
827 _ekf.get_posD_reset(&lpos.delta_z, &lpos.z_reset_counter); 699 _ekf.get_posD_reset(&lpos.delta_z, &lpos.z_reset_counter);
828 _ekf.get_velD_reset(&lpos.delta_vz, &lpos.vz_reset_counter); 700 _ekf.get_velD_reset(&lpos.delta_vz, &lpos.vz_reset_counter);
829 _ekf.get_posNE_reset(&lpos.delta_xy[0], &lpos.xy_reset_counter); 701 _ekf.get_posNE_reset(&lpos.delta_xy[0], &lpos.xy_reset_counter);
830 _ekf.get_velNE_reset(&lpos.delta_vxy[0], &lpos.vxy_reset_counter); 702 _ekf.get_velNE_reset(&lpos.delta_vxy[0], &lpos.vxy_reset_counter);
831 -
832 // get control limit information 703 // get control limit information
833 _ekf.get_ekf_ctrl_limits(&lpos.vxy_max, &lpos.vz_max, &lpos.hagl_min, &lpos.hagl_max); 704 _ekf.get_ekf_ctrl_limits(&lpos.vxy_max, &lpos.vz_max, &lpos.hagl_min, &lpos.hagl_max);
834 -
835 // convert NaN to INFINITY 705 // convert NaN to INFINITY
836 if (!PX4_ISFINITE(lpos.vxy_max)) { 706 if (!PX4_ISFINITE(lpos.vxy_max)) {
837 lpos.vxy_max = INFINITY; 707 lpos.vxy_max = INFINITY;
838 } 708 }
839 -
840 if (!PX4_ISFINITE(lpos.vz_max)) { 709 if (!PX4_ISFINITE(lpos.vz_max)) {
841 lpos.vz_max = INFINITY; 710 lpos.vz_max = INFINITY;
842 } 711 }
843 -
844 if (!PX4_ISFINITE(lpos.hagl_min)) { 712 if (!PX4_ISFINITE(lpos.hagl_min)) {
845 lpos.hagl_min = INFINITY; 713 lpos.hagl_min = INFINITY;
846 } 714 }
847 -
848 if (!PX4_ISFINITE(lpos.hagl_max)) { 715 if (!PX4_ISFINITE(lpos.hagl_max)) {
849 lpos.hagl_max = INFINITY; 716 lpos.hagl_max = INFINITY;
850 } 717 }
851 -
852 // publish vehicle local position data 718 // publish vehicle local position data
853 lpos.timestamp = _replay_mode ? timestamp : hrt_absolute_time(); 719 lpos.timestamp = _replay_mode ? timestamp : hrt_absolute_time();
854 _local_position_pub.publish(lpos); 720 _local_position_pub.publish(lpos);
855 } 721 }
856 -
857 void EKF2::PublishOdometry(const hrt_abstime &timestamp, const imuSample &imu) 722 void EKF2::PublishOdometry(const hrt_abstime &timestamp, const imuSample &imu)
858 { 723 {
859 // generate vehicle odometry data 724 // generate vehicle odometry data
860 vehicle_odometry_s odom; 725 vehicle_odometry_s odom;
861 odom.timestamp_sample = imu.time_us; 726 odom.timestamp_sample = imu.time_us;
862 -
863 odom.local_frame = vehicle_odometry_s::LOCAL_FRAME_NED; 727 odom.local_frame = vehicle_odometry_s::LOCAL_FRAME_NED;
864 -
865 // Vehicle odometry position 728 // Vehicle odometry position
866 const Vector3f position{_ekf.getPosition()}; 729 const Vector3f position{_ekf.getPosition()};
867 odom.x = position(0); 730 odom.x = position(0);
868 odom.y = position(1); 731 odom.y = position(1);
869 odom.z = position(2); 732 odom.z = position(2);
870 -
871 // Vehicle odometry linear velocity 733 // Vehicle odometry linear velocity
872 odom.velocity_frame = vehicle_odometry_s::LOCAL_FRAME_FRD; 734 odom.velocity_frame = vehicle_odometry_s::LOCAL_FRAME_FRD;
873 const Vector3f velocity{_ekf.getVelocity()}; 735 const Vector3f velocity{_ekf.getVelocity()};
874 odom.vx = velocity(0); 736 odom.vx = velocity(0);
875 odom.vy = velocity(1); 737 odom.vy = velocity(1);
876 odom.vz = velocity(2); 738 odom.vz = velocity(2);
877 -
878 // Vehicle odometry quaternion 739 // Vehicle odometry quaternion
879 _ekf.getQuaternion().copyTo(odom.q); 740 _ekf.getQuaternion().copyTo(odom.q);
880 -
881 // Vehicle odometry angular rates 741 // Vehicle odometry angular rates
882 const Vector3f gyro_bias{_ekf.getGyroBias()}; 742 const Vector3f gyro_bias{_ekf.getGyroBias()};
883 const Vector3f rates{imu.delta_ang / imu.delta_ang_dt}; 743 const Vector3f rates{imu.delta_ang / imu.delta_ang_dt};
884 odom.rollspeed = rates(0) - gyro_bias(0); 744 odom.rollspeed = rates(0) - gyro_bias(0);
885 odom.pitchspeed = rates(1) - gyro_bias(1); 745 odom.pitchspeed = rates(1) - gyro_bias(1);
886 odom.yawspeed = rates(2) - gyro_bias(2); 746 odom.yawspeed = rates(2) - gyro_bias(2);
887 -
888 // get the covariance matrix size 747 // get the covariance matrix size
889 static constexpr size_t POS_URT_SIZE = sizeof(odom.pose_covariance) / sizeof(odom.pose_covariance[0]); 748 static constexpr size_t POS_URT_SIZE = sizeof(odom.pose_covariance) / sizeof(odom.pose_covariance[0]);
890 static constexpr size_t VEL_URT_SIZE = sizeof(odom.velocity_covariance) / sizeof(odom.velocity_covariance[0]); 749 static constexpr size_t VEL_URT_SIZE = sizeof(odom.velocity_covariance) / sizeof(odom.velocity_covariance[0]);
891 -
892 // Get covariances to vehicle odometry 750 // Get covariances to vehicle odometry
893 float covariances[24]; 751 float covariances[24];
894 _ekf.covariances_diagonal().copyTo(covariances); 752 _ekf.covariances_diagonal().copyTo(covariances);
895 -
896 // initially set pose covariances to 0 753 // initially set pose covariances to 0
897 for (size_t i = 0; i < POS_URT_SIZE; i++) { 754 for (size_t i = 0; i < POS_URT_SIZE; i++) {
898 odom.pose_covariance[i] = 0.0; 755 odom.pose_covariance[i] = 0.0;
899 } 756 }
900 -
901 // set the position variances 757 // set the position variances
902 odom.pose_covariance[odom.COVARIANCE_MATRIX_X_VARIANCE] = covariances[7]; 758 odom.pose_covariance[odom.COVARIANCE_MATRIX_X_VARIANCE] = covariances[7];
903 odom.pose_covariance[odom.COVARIANCE_MATRIX_Y_VARIANCE] = covariances[8]; 759 odom.pose_covariance[odom.COVARIANCE_MATRIX_Y_VARIANCE] = covariances[8];
904 odom.pose_covariance[odom.COVARIANCE_MATRIX_Z_VARIANCE] = covariances[9]; 760 odom.pose_covariance[odom.COVARIANCE_MATRIX_Z_VARIANCE] = covariances[9];
905 -
906 // TODO: implement propagation from quaternion covariance to Euler angle covariance 761 // TODO: implement propagation from quaternion covariance to Euler angle covariance
907 // by employing the covariance law 762 // by employing the covariance law
908 -
909 // initially set velocity covariances to 0 763 // initially set velocity covariances to 0
910 for (size_t i = 0; i < VEL_URT_SIZE; i++) { 764 for (size_t i = 0; i < VEL_URT_SIZE; i++) {
911 odom.velocity_covariance[i] = 0.0; 765 odom.velocity_covariance[i] = 0.0;
912 } 766 }
913 -
914 // set the linear velocity variances 767 // set the linear velocity variances
915 odom.velocity_covariance[odom.COVARIANCE_MATRIX_VX_VARIANCE] = covariances[4]; 768 odom.velocity_covariance[odom.COVARIANCE_MATRIX_VX_VARIANCE] = covariances[4];
916 odom.velocity_covariance[odom.COVARIANCE_MATRIX_VY_VARIANCE] = covariances[5]; 769 odom.velocity_covariance[odom.COVARIANCE_MATRIX_VY_VARIANCE] = covariances[5];
917 odom.velocity_covariance[odom.COVARIANCE_MATRIX_VZ_VARIANCE] = covariances[6]; 770 odom.velocity_covariance[odom.COVARIANCE_MATRIX_VZ_VARIANCE] = covariances[6];
918 -
919 // publish vehicle odometry data 771 // publish vehicle odometry data
920 odom.timestamp = _replay_mode ? timestamp : hrt_absolute_time(); 772 odom.timestamp = _replay_mode ? timestamp : hrt_absolute_time();
921 _odometry_pub.publish(odom); 773 _odometry_pub.publish(odom);
922 } 774 }
923 -
924 void EKF2::PublishOdometryAligned(const hrt_abstime &timestamp, const vehicle_odometry_s &ev_odom) 775 void EKF2::PublishOdometryAligned(const hrt_abstime &timestamp, const vehicle_odometry_s &ev_odom)
925 { 776 {
926 const Quatf quat_ev2ekf = _ekf.getVisionAlignmentQuaternion(); // rotates from EV to EKF navigation frame 777 const Quatf quat_ev2ekf = _ekf.getVisionAlignmentQuaternion(); // rotates from EV to EKF navigation frame
927 const Dcmf ev_rot_mat(quat_ev2ekf); 778 const Dcmf ev_rot_mat(quat_ev2ekf);
928 -
929 vehicle_odometry_s aligned_ev_odom{ev_odom}; 779 vehicle_odometry_s aligned_ev_odom{ev_odom};
930 -
931 // Rotate external position and velocity into EKF navigation frame 780 // Rotate external position and velocity into EKF navigation frame
932 const Vector3f aligned_pos = ev_rot_mat * Vector3f(ev_odom.x, ev_odom.y, ev_odom.z); 781 const Vector3f aligned_pos = ev_rot_mat * Vector3f(ev_odom.x, ev_odom.y, ev_odom.z);
933 aligned_ev_odom.x = aligned_pos(0); 782 aligned_ev_odom.x = aligned_pos(0);
934 aligned_ev_odom.y = aligned_pos(1); 783 aligned_ev_odom.y = aligned_pos(1);
935 aligned_ev_odom.z = aligned_pos(2); 784 aligned_ev_odom.z = aligned_pos(2);
936 -
937 switch (ev_odom.velocity_frame) { 785 switch (ev_odom.velocity_frame) {
938 case vehicle_odometry_s::BODY_FRAME_FRD: { 786 case vehicle_odometry_s::BODY_FRAME_FRD: {
939 const Vector3f aligned_vel = Dcmf(_ekf.getQuaternion()) * Vector3f(ev_odom.vx, ev_odom.vy, ev_odom.vz); 787 const Vector3f aligned_vel = Dcmf(_ekf.getQuaternion()) * Vector3f(ev_odom.vx, ev_odom.vy, ev_odom.vz);
...@@ -942,7 +790,6 @@ void EKF2::PublishOdometryAligned(const hrt_abstime &timestamp, const vehicle_od ...@@ -942,7 +790,6 @@ void EKF2::PublishOdometryAligned(const hrt_abstime &timestamp, const vehicle_od
942 aligned_ev_odom.vz = aligned_vel(2); 790 aligned_ev_odom.vz = aligned_vel(2);
943 break; 791 break;
944 } 792 }
945 -
946 case vehicle_odometry_s::LOCAL_FRAME_FRD: { 793 case vehicle_odometry_s::LOCAL_FRAME_FRD: {
947 const Vector3f aligned_vel = ev_rot_mat * Vector3f(ev_odom.vx, ev_odom.vy, ev_odom.vz); 794 const Vector3f aligned_vel = ev_rot_mat * Vector3f(ev_odom.vx, ev_odom.vy, ev_odom.vz);
948 aligned_ev_odom.vx = aligned_vel(0); 795 aligned_ev_odom.vx = aligned_vel(0);
...@@ -951,34 +798,26 @@ void EKF2::PublishOdometryAligned(const hrt_abstime &timestamp, const vehicle_od ...@@ -951,34 +798,26 @@ void EKF2::PublishOdometryAligned(const hrt_abstime &timestamp, const vehicle_od
951 break; 798 break;
952 } 799 }
953 } 800 }
954 -
955 aligned_ev_odom.velocity_frame = vehicle_odometry_s::LOCAL_FRAME_NED; 801 aligned_ev_odom.velocity_frame = vehicle_odometry_s::LOCAL_FRAME_NED;
956 -
957 // Compute orientation in EKF navigation frame 802 // Compute orientation in EKF navigation frame
958 Quatf ev_quat_aligned = quat_ev2ekf * Quatf(ev_odom.q) ; 803 Quatf ev_quat_aligned = quat_ev2ekf * Quatf(ev_odom.q) ;
959 ev_quat_aligned.normalize(); 804 ev_quat_aligned.normalize();
960 -
961 ev_quat_aligned.copyTo(aligned_ev_odom.q); 805 ev_quat_aligned.copyTo(aligned_ev_odom.q);
962 quat_ev2ekf.copyTo(aligned_ev_odom.q_offset); 806 quat_ev2ekf.copyTo(aligned_ev_odom.q_offset);
963 -
964 _estimator_visual_odometry_aligned_pub.publish(aligned_ev_odom); 807 _estimator_visual_odometry_aligned_pub.publish(aligned_ev_odom);
965 } 808 }
966 -
967 void EKF2::PublishSensorBias(const hrt_abstime &timestamp) 809 void EKF2::PublishSensorBias(const hrt_abstime &timestamp)
968 { 810 {
969 // estimator_sensor_bias 811 // estimator_sensor_bias
970 estimator_sensor_bias_s bias{}; 812 estimator_sensor_bias_s bias{};
971 bias.timestamp_sample = timestamp; 813 bias.timestamp_sample = timestamp;
972 -
973 const Vector3f gyro_bias{_ekf.getGyroBias()}; 814 const Vector3f gyro_bias{_ekf.getGyroBias()};
974 const Vector3f accel_bias{_ekf.getAccelBias()}; 815 const Vector3f accel_bias{_ekf.getAccelBias()};
975 const Vector3f mag_bias{_mag_cal_last_bias}; 816 const Vector3f mag_bias{_mag_cal_last_bias};
976 -
977 // only publish on change 817 // only publish on change
978 if ((gyro_bias - _last_gyro_bias_published).longerThan(0.001f) 818 if ((gyro_bias - _last_gyro_bias_published).longerThan(0.001f)
979 || (accel_bias - _last_accel_bias_published).longerThan(0.001f) 819 || (accel_bias - _last_accel_bias_published).longerThan(0.001f)
980 || (mag_bias - _last_mag_bias_published).longerThan(0.001f)) { 820 || (mag_bias - _last_mag_bias_published).longerThan(0.001f)) {
981 -
982 // take device ids from sensor_selection_s if not using specific vehicle_imu_s 821 // take device ids from sensor_selection_s if not using specific vehicle_imu_s
983 if (_device_id_gyro != 0) { 822 if (_device_id_gyro != 0) {
984 bias.gyro_device_id = _device_id_gyro; 823 bias.gyro_device_id = _device_id_gyro;
...@@ -986,35 +825,28 @@ void EKF2::PublishSensorBias(const hrt_abstime &timestamp) ...@@ -986,35 +825,28 @@ void EKF2::PublishSensorBias(const hrt_abstime &timestamp)
986 bias.gyro_bias_limit = math::radians(20.f); // 20 degrees/s see Ekf::constrainStates() 825 bias.gyro_bias_limit = math::radians(20.f); // 20 degrees/s see Ekf::constrainStates()
987 _ekf.getGyroBiasVariance().copyTo(bias.gyro_bias_variance); 826 _ekf.getGyroBiasVariance().copyTo(bias.gyro_bias_variance);
988 bias.gyro_bias_valid = true; 827 bias.gyro_bias_valid = true;
989 -
990 _last_gyro_bias_published = gyro_bias; 828 _last_gyro_bias_published = gyro_bias;
991 } 829 }
992 -
993 if ((_device_id_accel != 0) && !(_param_ekf2_aid_mask.get() & MASK_INHIBIT_ACC_BIAS)) { 830 if ((_device_id_accel != 0) && !(_param_ekf2_aid_mask.get() & MASK_INHIBIT_ACC_BIAS)) {
994 bias.accel_device_id = _device_id_accel; 831 bias.accel_device_id = _device_id_accel;
995 accel_bias.copyTo(bias.accel_bias); 832 accel_bias.copyTo(bias.accel_bias);
996 bias.accel_bias_limit = _params->acc_bias_lim; 833 bias.accel_bias_limit = _params->acc_bias_lim;
997 _ekf.getAccelBiasVariance().copyTo(bias.accel_bias_variance); 834 _ekf.getAccelBiasVariance().copyTo(bias.accel_bias_variance);
998 bias.accel_bias_valid = !_ekf.fault_status_flags().bad_acc_bias; 835 bias.accel_bias_valid = !_ekf.fault_status_flags().bad_acc_bias;
999 -
1000 _last_accel_bias_published = accel_bias; 836 _last_accel_bias_published = accel_bias;
1001 } 837 }
1002 -
1003 if (_device_id_mag != 0) { 838 if (_device_id_mag != 0) {
1004 bias.mag_device_id = _device_id_mag; 839 bias.mag_device_id = _device_id_mag;
1005 mag_bias.copyTo(bias.mag_bias); 840 mag_bias.copyTo(bias.mag_bias);
1006 bias.mag_bias_limit = 0.5f; // 0.5 Gauss see Ekf::constrainStates() 841 bias.mag_bias_limit = 0.5f; // 0.5 Gauss see Ekf::constrainStates()
1007 _mag_cal_last_bias_variance.copyTo(bias.mag_bias_variance); 842 _mag_cal_last_bias_variance.copyTo(bias.mag_bias_variance);
1008 bias.mag_bias_valid = _mag_cal_available; 843 bias.mag_bias_valid = _mag_cal_available;
1009 -
1010 _last_mag_bias_published = mag_bias; 844 _last_mag_bias_published = mag_bias;
1011 } 845 }
1012 -
1013 bias.timestamp = _replay_mode ? timestamp : hrt_absolute_time(); 846 bias.timestamp = _replay_mode ? timestamp : hrt_absolute_time();
1014 _estimator_sensor_bias_pub.publish(bias); 847 _estimator_sensor_bias_pub.publish(bias);
1015 } 848 }
1016 } 849 }
1017 -
1018 void EKF2::PublishStates(const hrt_abstime &timestamp) 850 void EKF2::PublishStates(const hrt_abstime &timestamp)
1019 { 851 {
1020 // publish estimator states 852 // publish estimator states
...@@ -1026,91 +858,72 @@ void EKF2::PublishStates(const hrt_abstime &timestamp) ...@@ -1026,91 +858,72 @@ void EKF2::PublishStates(const hrt_abstime &timestamp)
1026 states.timestamp = _replay_mode ? timestamp : hrt_absolute_time(); 858 states.timestamp = _replay_mode ? timestamp : hrt_absolute_time();
1027 _estimator_states_pub.publish(states); 859 _estimator_states_pub.publish(states);
1028 } 860 }
1029 -
1030 void EKF2::PublishStatus(const hrt_abstime &timestamp) 861 void EKF2::PublishStatus(const hrt_abstime &timestamp)
1031 { 862 {
1032 estimator_status_s status{}; 863 estimator_status_s status{};
1033 status.timestamp_sample = timestamp; 864 status.timestamp_sample = timestamp;
1034 -
1035 _ekf.getOutputTrackingError().copyTo(status.output_tracking_error); 865 _ekf.getOutputTrackingError().copyTo(status.output_tracking_error);
1036 -
1037 _ekf.get_gps_check_status(&status.gps_check_fail_flags); 866 _ekf.get_gps_check_status(&status.gps_check_fail_flags);
1038 -
1039 // only report enabled GPS check failures (the param indexes are shifted by 1 bit, because they don't include 867 // only report enabled GPS check failures (the param indexes are shifted by 1 bit, because they don't include
1040 // the GPS Fix bit, which is always checked) 868 // the GPS Fix bit, which is always checked)
1041 status.gps_check_fail_flags &= ((uint16_t)_params->gps_check_mask << 1) | 1; 869 status.gps_check_fail_flags &= ((uint16_t)_params->gps_check_mask << 1) | 1;
1042 -
1043 status.control_mode_flags = _ekf.control_status().value; 870 status.control_mode_flags = _ekf.control_status().value;
1044 status.filter_fault_flags = _ekf.fault_status().value; 871 status.filter_fault_flags = _ekf.fault_status().value;
1045 -
1046 uint16_t innov_check_flags_temp = 0; 872 uint16_t innov_check_flags_temp = 0;
1047 _ekf.get_innovation_test_status(innov_check_flags_temp, status.mag_test_ratio, 873 _ekf.get_innovation_test_status(innov_check_flags_temp, status.mag_test_ratio,
1048 status.vel_test_ratio, status.pos_test_ratio, 874 status.vel_test_ratio, status.pos_test_ratio,
1049 status.hgt_test_ratio, status.tas_test_ratio, 875 status.hgt_test_ratio, status.tas_test_ratio,
1050 status.hagl_test_ratio, status.beta_test_ratio); 876 status.hagl_test_ratio, status.beta_test_ratio);
1051 -
1052 // Bit mismatch between ecl and Firmware, combine the 2 first bits to preserve msg definition 877 // Bit mismatch between ecl and Firmware, combine the 2 first bits to preserve msg definition
1053 // TODO: legacy use only, those flags are also in estimator_status_flags 878 // TODO: legacy use only, those flags are also in estimator_status_flags
1054 status.innovation_check_flags = (innov_check_flags_temp >> 1) | (innov_check_flags_temp & 0x1); 879 status.innovation_check_flags = (innov_check_flags_temp >> 1) | (innov_check_flags_temp & 0x1);
1055 -
1056 _ekf.get_ekf_lpos_accuracy(&status.pos_horiz_accuracy, &status.pos_vert_accuracy); 880 _ekf.get_ekf_lpos_accuracy(&status.pos_horiz_accuracy, &status.pos_vert_accuracy);
1057 _ekf.get_ekf_soln_status(&status.solution_status_flags); 881 _ekf.get_ekf_soln_status(&status.solution_status_flags);
1058 _ekf.getImuVibrationMetrics().copyTo(status.vibe); 882 _ekf.getImuVibrationMetrics().copyTo(status.vibe);
1059 -
1060 // reset counters 883 // reset counters
1061 status.reset_count_vel_ne = _ekf.state_reset_status().velNE_counter; 884 status.reset_count_vel_ne = _ekf.state_reset_status().velNE_counter;
1062 status.reset_count_vel_d = _ekf.state_reset_status().velD_counter; 885 status.reset_count_vel_d = _ekf.state_reset_status().velD_counter;
1063 status.reset_count_pos_ne = _ekf.state_reset_status().posNE_counter; 886 status.reset_count_pos_ne = _ekf.state_reset_status().posNE_counter;
1064 status.reset_count_pod_d = _ekf.state_reset_status().posD_counter; 887 status.reset_count_pod_d = _ekf.state_reset_status().posD_counter;
1065 status.reset_count_quat = _ekf.state_reset_status().quat_counter; 888 status.reset_count_quat = _ekf.state_reset_status().quat_counter;
1066 -
1067 status.time_slip = _last_time_slip_us * 1e-6f; 889 status.time_slip = _last_time_slip_us * 1e-6f;
1068 -
1069 status.pre_flt_fail_innov_heading = _preflt_checker.hasHeadingFailed(); 890 status.pre_flt_fail_innov_heading = _preflt_checker.hasHeadingFailed();
1070 status.pre_flt_fail_innov_vel_horiz = _preflt_checker.hasHorizVelFailed(); 891 status.pre_flt_fail_innov_vel_horiz = _preflt_checker.hasHorizVelFailed();
1071 status.pre_flt_fail_innov_vel_vert = _preflt_checker.hasVertVelFailed(); 892 status.pre_flt_fail_innov_vel_vert = _preflt_checker.hasVertVelFailed();
1072 status.pre_flt_fail_innov_height = _preflt_checker.hasHeightFailed(); 893 status.pre_flt_fail_innov_height = _preflt_checker.hasHeightFailed();
1073 status.pre_flt_fail_mag_field_disturbed = _ekf.control_status_flags().mag_field_disturbed; 894 status.pre_flt_fail_mag_field_disturbed = _ekf.control_status_flags().mag_field_disturbed;
1074 -
1075 status.accel_device_id = _device_id_accel; 895 status.accel_device_id = _device_id_accel;
1076 status.baro_device_id = _device_id_baro; 896 status.baro_device_id = _device_id_baro;
1077 status.gyro_device_id = _device_id_gyro; 897 status.gyro_device_id = _device_id_gyro;
1078 status.mag_device_id = _device_id_mag; 898 status.mag_device_id = _device_id_mag;
1079 -
1080 status.timestamp = _replay_mode ? timestamp : hrt_absolute_time(); 899 status.timestamp = _replay_mode ? timestamp : hrt_absolute_time();
1081 _estimator_status_pub.publish(status); 900 _estimator_status_pub.publish(status);
1082 } 901 }
1083 -
1084 void EKF2::PublishStatusFlags(const hrt_abstime &timestamp) 902 void EKF2::PublishStatusFlags(const hrt_abstime &timestamp)
1085 { 903 {
1086 // publish at ~ 1 Hz (or immediately if filter control status or fault status changes) 904 // publish at ~ 1 Hz (or immediately if filter control status or fault status changes)
1087 bool update = (hrt_elapsed_time(&_last_status_flag_update) >= 1_s); 905 bool update = (hrt_elapsed_time(&_last_status_flag_update) >= 1_s);
1088 -
1089 // filter control status 906 // filter control status
1090 if (_ekf.control_status().value != _filter_control_status) { 907 if (_ekf.control_status().value != _filter_control_status) {
1091 update = true; 908 update = true;
1092 _filter_control_status = _ekf.control_status().value; 909 _filter_control_status = _ekf.control_status().value;
1093 _filter_control_status_changes++; 910 _filter_control_status_changes++;
1094 } 911 }
1095 -
1096 // filter fault status 912 // filter fault status
1097 if (_ekf.fault_status().value != _filter_fault_status) { 913 if (_ekf.fault_status().value != _filter_fault_status) {
1098 update = true; 914 update = true;
1099 _filter_fault_status = _ekf.fault_status().value; 915 _filter_fault_status = _ekf.fault_status().value;
1100 _filter_fault_status_changes++; 916 _filter_fault_status_changes++;
1101 } 917 }
1102 -
1103 // innovation check fail status 918 // innovation check fail status
1104 if (_ekf.innov_check_fail_status().value != _innov_check_fail_status) { 919 if (_ekf.innov_check_fail_status().value != _innov_check_fail_status) {
1105 update = true; 920 update = true;
1106 _innov_check_fail_status = _ekf.innov_check_fail_status().value; 921 _innov_check_fail_status = _ekf.innov_check_fail_status().value;
1107 _innov_check_fail_status_changes++; 922 _innov_check_fail_status_changes++;
1108 } 923 }
1109 -
1110 if (update) { 924 if (update) {
1111 estimator_status_flags_s status_flags{}; 925 estimator_status_flags_s status_flags{};
1112 status_flags.timestamp_sample = timestamp; 926 status_flags.timestamp_sample = timestamp;
1113 -
1114 status_flags.control_status_changes = _filter_control_status_changes; 927 status_flags.control_status_changes = _filter_control_status_changes;
1115 status_flags.cs_tilt_align = _ekf.control_status_flags().tilt_align; 928 status_flags.cs_tilt_align = _ekf.control_status_flags().tilt_align;
1116 status_flags.cs_yaw_align = _ekf.control_status_flags().yaw_align; 929 status_flags.cs_yaw_align = _ekf.control_status_flags().yaw_align;
...@@ -1139,7 +952,6 @@ void EKF2::PublishStatusFlags(const hrt_abstime &timestamp) ...@@ -1139,7 +952,6 @@ void EKF2::PublishStatusFlags(const hrt_abstime &timestamp)
1139 status_flags.cs_ev_vel = _ekf.control_status_flags().ev_vel; 952 status_flags.cs_ev_vel = _ekf.control_status_flags().ev_vel;
1140 status_flags.cs_synthetic_mag_z = _ekf.control_status_flags().synthetic_mag_z; 953 status_flags.cs_synthetic_mag_z = _ekf.control_status_flags().synthetic_mag_z;
1141 status_flags.cs_vehicle_at_rest = _ekf.control_status_flags().vehicle_at_rest; 954 status_flags.cs_vehicle_at_rest = _ekf.control_status_flags().vehicle_at_rest;
1142 -
1143 status_flags.fault_status_changes = _filter_fault_status_changes; 955 status_flags.fault_status_changes = _filter_fault_status_changes;
1144 status_flags.fs_bad_mag_x = _ekf.fault_status_flags().bad_mag_x; 956 status_flags.fs_bad_mag_x = _ekf.fault_status_flags().bad_mag_x;
1145 status_flags.fs_bad_mag_y = _ekf.fault_status_flags().bad_mag_y; 957 status_flags.fs_bad_mag_y = _ekf.fault_status_flags().bad_mag_y;
...@@ -1159,7 +971,6 @@ void EKF2::PublishStatusFlags(const hrt_abstime &timestamp) ...@@ -1159,7 +971,6 @@ void EKF2::PublishStatusFlags(const hrt_abstime &timestamp)
1159 status_flags.fs_bad_acc_bias = _ekf.fault_status_flags().bad_acc_bias; 971 status_flags.fs_bad_acc_bias = _ekf.fault_status_flags().bad_acc_bias;
1160 status_flags.fs_bad_acc_vertical = _ekf.fault_status_flags().bad_acc_vertical; 972 status_flags.fs_bad_acc_vertical = _ekf.fault_status_flags().bad_acc_vertical;
1161 status_flags.fs_bad_acc_clipping = _ekf.fault_status_flags().bad_acc_clipping; 973 status_flags.fs_bad_acc_clipping = _ekf.fault_status_flags().bad_acc_clipping;
1162 -
1163 status_flags.innovation_fault_status_changes = _innov_check_fail_status_changes; 974 status_flags.innovation_fault_status_changes = _innov_check_fail_status_changes;
1164 status_flags.reject_hor_vel = _ekf.innov_check_fail_status_flags().reject_hor_vel; 975 status_flags.reject_hor_vel = _ekf.innov_check_fail_status_flags().reject_hor_vel;
1165 status_flags.reject_ver_vel = _ekf.innov_check_fail_status_flags().reject_ver_vel; 976 status_flags.reject_ver_vel = _ekf.innov_check_fail_status_flags().reject_ver_vel;
...@@ -1174,98 +985,76 @@ void EKF2::PublishStatusFlags(const hrt_abstime &timestamp) ...@@ -1174,98 +985,76 @@ void EKF2::PublishStatusFlags(const hrt_abstime &timestamp)
1174 status_flags.reject_hagl = _ekf.innov_check_fail_status_flags().reject_hagl; 985 status_flags.reject_hagl = _ekf.innov_check_fail_status_flags().reject_hagl;
1175 status_flags.reject_optflow_x = _ekf.innov_check_fail_status_flags().reject_optflow_X; 986 status_flags.reject_optflow_x = _ekf.innov_check_fail_status_flags().reject_optflow_X;
1176 status_flags.reject_optflow_y = _ekf.innov_check_fail_status_flags().reject_optflow_Y; 987 status_flags.reject_optflow_y = _ekf.innov_check_fail_status_flags().reject_optflow_Y;
1177 -
1178 status_flags.timestamp = _replay_mode ? timestamp : hrt_absolute_time(); 988 status_flags.timestamp = _replay_mode ? timestamp : hrt_absolute_time();
1179 _estimator_status_flags_pub.publish(status_flags); 989 _estimator_status_flags_pub.publish(status_flags);
1180 -
1181 _last_status_flag_update = status_flags.timestamp; 990 _last_status_flag_update = status_flags.timestamp;
1182 } 991 }
1183 } 992 }
1184 -
1185 void EKF2::PublishYawEstimatorStatus(const hrt_abstime &timestamp) 993 void EKF2::PublishYawEstimatorStatus(const hrt_abstime &timestamp)
1186 { 994 {
1187 static_assert(sizeof(yaw_estimator_status_s::yaw) / sizeof(float) == N_MODELS_EKFGSF, 995 static_assert(sizeof(yaw_estimator_status_s::yaw) / sizeof(float) == N_MODELS_EKFGSF,
1188 "yaw_estimator_status_s::yaw wrong size"); 996 "yaw_estimator_status_s::yaw wrong size");
1189 -
1190 yaw_estimator_status_s yaw_est_test_data; 997 yaw_estimator_status_s yaw_est_test_data;
1191 -
1192 if (_ekf.getDataEKFGSF(&yaw_est_test_data.yaw_composite, &yaw_est_test_data.yaw_variance, 998 if (_ekf.getDataEKFGSF(&yaw_est_test_data.yaw_composite, &yaw_est_test_data.yaw_variance,
1193 yaw_est_test_data.yaw, 999 yaw_est_test_data.yaw,
1194 yaw_est_test_data.innov_vn, yaw_est_test_data.innov_ve, 1000 yaw_est_test_data.innov_vn, yaw_est_test_data.innov_ve,
1195 yaw_est_test_data.weight)) { 1001 yaw_est_test_data.weight)) {
1196 -
1197 yaw_est_test_data.timestamp_sample = timestamp; 1002 yaw_est_test_data.timestamp_sample = timestamp;
1198 yaw_est_test_data.timestamp = _replay_mode ? timestamp : hrt_absolute_time(); 1003 yaw_est_test_data.timestamp = _replay_mode ? timestamp : hrt_absolute_time();
1199 -
1200 _yaw_est_pub.publish(yaw_est_test_data); 1004 _yaw_est_pub.publish(yaw_est_test_data);
1201 } 1005 }
1202 } 1006 }
1203 -
1204 void EKF2::PublishWindEstimate(const hrt_abstime &timestamp) 1007 void EKF2::PublishWindEstimate(const hrt_abstime &timestamp)
1205 { 1008 {
1206 if (_ekf.get_wind_status()) { 1009 if (_ekf.get_wind_status()) {
1207 // Publish wind estimate only if ekf declares them valid 1010 // Publish wind estimate only if ekf declares them valid
1208 wind_s wind{}; 1011 wind_s wind{};
1209 wind.timestamp_sample = timestamp; 1012 wind.timestamp_sample = timestamp;
1210 -
1211 const Vector2f wind_vel = _ekf.getWindVelocity(); 1013 const Vector2f wind_vel = _ekf.getWindVelocity();
1212 const Vector2f wind_vel_var = _ekf.getWindVelocityVariance(); 1014 const Vector2f wind_vel_var = _ekf.getWindVelocityVariance();
1213 _ekf.getAirspeedInnov(wind.tas_innov); 1015 _ekf.getAirspeedInnov(wind.tas_innov);
1214 _ekf.getAirspeedInnovVar(wind.tas_innov_var); 1016 _ekf.getAirspeedInnovVar(wind.tas_innov_var);
1215 _ekf.getBetaInnov(wind.beta_innov); 1017 _ekf.getBetaInnov(wind.beta_innov);
1216 _ekf.getBetaInnovVar(wind.beta_innov_var); 1018 _ekf.getBetaInnovVar(wind.beta_innov_var);
1217 -
1218 wind.windspeed_north = wind_vel(0); 1019 wind.windspeed_north = wind_vel(0);
1219 wind.windspeed_east = wind_vel(1); 1020 wind.windspeed_east = wind_vel(1);
1220 wind.variance_north = wind_vel_var(0); 1021 wind.variance_north = wind_vel_var(0);
1221 wind.variance_east = wind_vel_var(1); 1022 wind.variance_east = wind_vel_var(1);
1222 wind.timestamp = _replay_mode ? timestamp : hrt_absolute_time(); 1023 wind.timestamp = _replay_mode ? timestamp : hrt_absolute_time();
1223 -
1224 _wind_pub.publish(wind); 1024 _wind_pub.publish(wind);
1225 } 1025 }
1226 } 1026 }
1227 -
1228 void EKF2::PublishOpticalFlowVel(const hrt_abstime &timestamp, const optical_flow_s &flow_sample) 1027 void EKF2::PublishOpticalFlowVel(const hrt_abstime &timestamp, const optical_flow_s &flow_sample)
1229 { 1028 {
1230 estimator_optical_flow_vel_s flow_vel{}; 1029 estimator_optical_flow_vel_s flow_vel{};
1231 flow_vel.timestamp_sample = flow_sample.timestamp; 1030 flow_vel.timestamp_sample = flow_sample.timestamp;
1232 -
1233 _ekf.getFlowVelBody().copyTo(flow_vel.vel_body); 1031 _ekf.getFlowVelBody().copyTo(flow_vel.vel_body);
1234 _ekf.getFlowVelNE().copyTo(flow_vel.vel_ne); 1032 _ekf.getFlowVelNE().copyTo(flow_vel.vel_ne);
1235 _ekf.getFlowUncompensated().copyTo(flow_vel.flow_uncompensated_integral); 1033 _ekf.getFlowUncompensated().copyTo(flow_vel.flow_uncompensated_integral);
1236 _ekf.getFlowCompensated().copyTo(flow_vel.flow_compensated_integral); 1034 _ekf.getFlowCompensated().copyTo(flow_vel.flow_compensated_integral);
1237 _ekf.getFlowGyro().copyTo(flow_vel.gyro_rate_integral); 1035 _ekf.getFlowGyro().copyTo(flow_vel.gyro_rate_integral);
1238 flow_vel.timestamp = _replay_mode ? timestamp : hrt_absolute_time(); 1036 flow_vel.timestamp = _replay_mode ? timestamp : hrt_absolute_time();
1239 -
1240 _estimator_optical_flow_vel_pub.publish(flow_vel); 1037 _estimator_optical_flow_vel_pub.publish(flow_vel);
1241 } 1038 }
1242 -
1243 float EKF2::filter_altitude_ellipsoid(float amsl_hgt) 1039 float EKF2::filter_altitude_ellipsoid(float amsl_hgt)
1244 { 1040 {
1245 float height_diff = static_cast<float>(_gps_alttitude_ellipsoid) * 1e-3f - amsl_hgt; 1041 float height_diff = static_cast<float>(_gps_alttitude_ellipsoid) * 1e-3f - amsl_hgt;
1246 -
1247 if (_gps_alttitude_ellipsoid_previous_timestamp == 0) { 1042 if (_gps_alttitude_ellipsoid_previous_timestamp == 0) {
1248 -
1249 _wgs84_hgt_offset = height_diff; 1043 _wgs84_hgt_offset = height_diff;
1250 _gps_alttitude_ellipsoid_previous_timestamp = _gps_time_usec; 1044 _gps_alttitude_ellipsoid_previous_timestamp = _gps_time_usec;
1251 -
1252 } else if (_gps_time_usec != _gps_alttitude_ellipsoid_previous_timestamp) { 1045 } else if (_gps_time_usec != _gps_alttitude_ellipsoid_previous_timestamp) {
1253 -
1254 // apply a 10 second first order low pass filter to baro offset 1046 // apply a 10 second first order low pass filter to baro offset
1255 float dt = 1e-6f * (_gps_time_usec - _gps_alttitude_ellipsoid_previous_timestamp); 1047 float dt = 1e-6f * (_gps_time_usec - _gps_alttitude_ellipsoid_previous_timestamp);
1256 _gps_alttitude_ellipsoid_previous_timestamp = _gps_time_usec; 1048 _gps_alttitude_ellipsoid_previous_timestamp = _gps_time_usec;
1257 float offset_rate_correction = 0.1f * (height_diff - _wgs84_hgt_offset); 1049 float offset_rate_correction = 0.1f * (height_diff - _wgs84_hgt_offset);
1258 _wgs84_hgt_offset += dt * constrain(offset_rate_correction, -0.1f, 0.1f); 1050 _wgs84_hgt_offset += dt * constrain(offset_rate_correction, -0.1f, 0.1f);
1259 } 1051 }
1260 -
1261 return amsl_hgt + _wgs84_hgt_offset; 1052 return amsl_hgt + _wgs84_hgt_offset;
1262 } 1053 }
1263 -
1264 void EKF2::UpdateAirspeedSample(ekf2_timestamps_s &ekf2_timestamps) 1054 void EKF2::UpdateAirspeedSample(ekf2_timestamps_s &ekf2_timestamps)
1265 { 1055 {
1266 // EKF airspeed sample 1056 // EKF airspeed sample
1267 airspeed_s airspeed; 1057 airspeed_s airspeed;
1268 -
1269 if (_airspeed_sub.update(&airspeed)) { 1058 if (_airspeed_sub.update(&airspeed)) {
1270 // The airspeed measurement received via the airspeed.msg topic has not been corrected 1059 // The airspeed measurement received via the airspeed.msg topic has not been corrected
1271 // for scale favtor errors and requires the ASPD_SCALE correction to be applied. 1060 // for scale favtor errors and requires the ASPD_SCALE correction to be applied.
...@@ -1273,10 +1062,8 @@ void EKF2::UpdateAirspeedSample(ekf2_timestamps_s &ekf2_timestamps) ...@@ -1273,10 +1062,8 @@ void EKF2::UpdateAirspeedSample(ekf2_timestamps_s &ekf2_timestamps)
1273 // was used instead, however this would introduce a potential circular dependency 1062 // was used instead, however this would introduce a potential circular dependency
1274 // via the wind estimator that uses EKF velocity estimates. 1063 // via the wind estimator that uses EKF velocity estimates.
1275 const float true_airspeed_m_s = airspeed.true_airspeed_m_s * _airspeed_scale_factor; 1064 const float true_airspeed_m_s = airspeed.true_airspeed_m_s * _airspeed_scale_factor;
1276 -
1277 // only set airspeed data if condition for airspeed fusion are met 1065 // only set airspeed data if condition for airspeed fusion are met
1278 if ((_param_ekf2_arsp_thr.get() > FLT_EPSILON) && (true_airspeed_m_s > _param_ekf2_arsp_thr.get())) { 1066 if ((_param_ekf2_arsp_thr.get() > FLT_EPSILON) && (true_airspeed_m_s > _param_ekf2_arsp_thr.get())) {
1279 -
1280 airspeedSample airspeed_sample { 1067 airspeedSample airspeed_sample {
1281 .time_us = airspeed.timestamp, 1068 .time_us = airspeed.timestamp,
1282 .true_airspeed = true_airspeed_m_s, 1069 .true_airspeed = true_airspeed_m_s,
...@@ -1284,26 +1071,21 @@ void EKF2::UpdateAirspeedSample(ekf2_timestamps_s &ekf2_timestamps) ...@@ -1284,26 +1071,21 @@ void EKF2::UpdateAirspeedSample(ekf2_timestamps_s &ekf2_timestamps)
1284 }; 1071 };
1285 _ekf.setAirspeedData(airspeed_sample); 1072 _ekf.setAirspeedData(airspeed_sample);
1286 } 1073 }
1287 -
1288 ekf2_timestamps.airspeed_timestamp_rel = (int16_t)((int64_t)airspeed.timestamp / 100 - 1074 ekf2_timestamps.airspeed_timestamp_rel = (int16_t)((int64_t)airspeed.timestamp / 100 -
1289 (int64_t)ekf2_timestamps.timestamp / 100); 1075 (int64_t)ekf2_timestamps.timestamp / 100);
1290 } 1076 }
1291 } 1077 }
1292 -
1293 void EKF2::UpdateAuxVelSample(ekf2_timestamps_s &ekf2_timestamps) 1078 void EKF2::UpdateAuxVelSample(ekf2_timestamps_s &ekf2_timestamps)
1294 { 1079 {
1295 // EKF auxillary velocity sample 1080 // EKF auxillary velocity sample
1296 // - use the landing target pose estimate as another source of velocity data 1081 // - use the landing target pose estimate as another source of velocity data
1297 const unsigned last_generation = _landing_target_pose_sub.get_last_generation(); 1082 const unsigned last_generation = _landing_target_pose_sub.get_last_generation();
1298 landing_target_pose_s landing_target_pose; 1083 landing_target_pose_s landing_target_pose;
1299 -
1300 if (_landing_target_pose_sub.update(&landing_target_pose)) { 1084 if (_landing_target_pose_sub.update(&landing_target_pose)) {
1301 -
1302 if (_landing_target_pose_sub.get_last_generation() != last_generation + 1) { 1085 if (_landing_target_pose_sub.get_last_generation() != last_generation + 1) {
1303 PX4_ERR("%d - landing_target_pose lost, generation %d -> %d", _instance, last_generation, 1086 PX4_ERR("%d - landing_target_pose lost, generation %d -> %d", _instance, last_generation,
1304 _landing_target_pose_sub.get_last_generation()); 1087 _landing_target_pose_sub.get_last_generation());
1305 } 1088 }
1306 -
1307 // we can only use the landing target if it has a fixed position and a valid velocity estimate 1089 // we can only use the landing target if it has a fixed position and a valid velocity estimate
1308 if (landing_target_pose.is_static && landing_target_pose.rel_vel_valid) { 1090 if (landing_target_pose.is_static && landing_target_pose.rel_vel_valid) {
1309 // velocity of vehicle relative to target has opposite sign to target relative to vehicle 1091 // velocity of vehicle relative to target has opposite sign to target relative to vehicle
...@@ -1316,59 +1098,43 @@ void EKF2::UpdateAuxVelSample(ekf2_timestamps_s &ekf2_timestamps) ...@@ -1316,59 +1098,43 @@ void EKF2::UpdateAuxVelSample(ekf2_timestamps_s &ekf2_timestamps)
1316 } 1098 }
1317 } 1099 }
1318 } 1100 }
1319 -
1320 void EKF2::UpdateBaroSample(ekf2_timestamps_s &ekf2_timestamps) 1101 void EKF2::UpdateBaroSample(ekf2_timestamps_s &ekf2_timestamps)
1321 { 1102 {
1322 // EKF baro sample 1103 // EKF baro sample
1323 vehicle_air_data_s airdata; 1104 vehicle_air_data_s airdata;
1324 -
1325 if (_airdata_sub.update(&airdata)) { 1105 if (_airdata_sub.update(&airdata)) {
1326 _ekf.set_air_density(airdata.rho); 1106 _ekf.set_air_density(airdata.rho);
1327 -
1328 _ekf.setBaroData(baroSample{airdata.timestamp_sample, airdata.baro_alt_meter}); 1107 _ekf.setBaroData(baroSample{airdata.timestamp_sample, airdata.baro_alt_meter});
1329 -
1330 _device_id_baro = airdata.baro_device_id; 1108 _device_id_baro = airdata.baro_device_id;
1331 -
1332 ekf2_timestamps.vehicle_air_data_timestamp_rel = (int16_t)((int64_t)airdata.timestamp / 100 - 1109 ekf2_timestamps.vehicle_air_data_timestamp_rel = (int16_t)((int64_t)airdata.timestamp / 100 -
1333 (int64_t)ekf2_timestamps.timestamp / 100); 1110 (int64_t)ekf2_timestamps.timestamp / 100);
1334 } 1111 }
1335 } 1112 }
1336 -
1337 bool EKF2::UpdateExtVisionSample(ekf2_timestamps_s &ekf2_timestamps, vehicle_odometry_s &ev_odom) 1113 bool EKF2::UpdateExtVisionSample(ekf2_timestamps_s &ekf2_timestamps, vehicle_odometry_s &ev_odom)
1338 { 1114 {
1339 bool new_ev_odom = false; 1115 bool new_ev_odom = false;
1340 const unsigned last_generation = _ev_odom_sub.get_last_generation(); 1116 const unsigned last_generation = _ev_odom_sub.get_last_generation();
1341 -
1342 // EKF external vision sample 1117 // EKF external vision sample
1343 if (_ev_odom_sub.update(&ev_odom)) { 1118 if (_ev_odom_sub.update(&ev_odom)) {
1344 -
1345 if (_ev_odom_sub.get_last_generation() != last_generation + 1) { 1119 if (_ev_odom_sub.get_last_generation() != last_generation + 1) {
1346 PX4_ERR("%d - vehicle_visual_odometry lost, generation %d -> %d", _instance, last_generation, 1120 PX4_ERR("%d - vehicle_visual_odometry lost, generation %d -> %d", _instance, last_generation,
1347 _ev_odom_sub.get_last_generation()); 1121 _ev_odom_sub.get_last_generation());
1348 } 1122 }
1349 -
1350 if (_param_ekf2_aid_mask.get() & (MASK_USE_EVPOS | MASK_USE_EVYAW | MASK_USE_EVVEL)) { 1123 if (_param_ekf2_aid_mask.get() & (MASK_USE_EVPOS | MASK_USE_EVYAW | MASK_USE_EVVEL)) {
1351 -
1352 extVisionSample ev_data{}; 1124 extVisionSample ev_data{};
1353 -
1354 // if error estimates are unavailable, use parameter defined defaults 1125 // if error estimates are unavailable, use parameter defined defaults
1355 -
1356 // check for valid velocity data 1126 // check for valid velocity data
1357 if (PX4_ISFINITE(ev_odom.vx) && PX4_ISFINITE(ev_odom.vy) && PX4_ISFINITE(ev_odom.vz)) { 1127 if (PX4_ISFINITE(ev_odom.vx) && PX4_ISFINITE(ev_odom.vy) && PX4_ISFINITE(ev_odom.vz)) {
1358 ev_data.vel(0) = ev_odom.vx; 1128 ev_data.vel(0) = ev_odom.vx;
1359 ev_data.vel(1) = ev_odom.vy; 1129 ev_data.vel(1) = ev_odom.vy;
1360 ev_data.vel(2) = ev_odom.vz; 1130 ev_data.vel(2) = ev_odom.vz;
1361 -
1362 if (ev_odom.velocity_frame == vehicle_odometry_s::BODY_FRAME_FRD) { 1131 if (ev_odom.velocity_frame == vehicle_odometry_s::BODY_FRAME_FRD) {
1363 ev_data.vel_frame = velocity_frame_t::BODY_FRAME_FRD; 1132 ev_data.vel_frame = velocity_frame_t::BODY_FRAME_FRD;
1364 -
1365 } else { 1133 } else {
1366 ev_data.vel_frame = velocity_frame_t::LOCAL_FRAME_FRD; 1134 ev_data.vel_frame = velocity_frame_t::LOCAL_FRAME_FRD;
1367 } 1135 }
1368 -
1369 // velocity measurement error from ev_data or parameters 1136 // velocity measurement error from ev_data or parameters
1370 float param_evv_noise_var = sq(_param_ekf2_evv_noise.get()); 1137 float param_evv_noise_var = sq(_param_ekf2_evv_noise.get());
1371 -
1372 if (!_param_ekf2_ev_noise_md.get() && PX4_ISFINITE(ev_odom.velocity_covariance[ev_odom.COVARIANCE_MATRIX_VX_VARIANCE]) 1138 if (!_param_ekf2_ev_noise_md.get() && PX4_ISFINITE(ev_odom.velocity_covariance[ev_odom.COVARIANCE_MATRIX_VX_VARIANCE])
1373 && PX4_ISFINITE(ev_odom.velocity_covariance[ev_odom.COVARIANCE_MATRIX_VY_VARIANCE]) 1139 && PX4_ISFINITE(ev_odom.velocity_covariance[ev_odom.COVARIANCE_MATRIX_VY_VARIANCE])
1374 && PX4_ISFINITE(ev_odom.velocity_covariance[ev_odom.COVARIANCE_MATRIX_VZ_VARIANCE])) { 1140 && PX4_ISFINITE(ev_odom.velocity_covariance[ev_odom.COVARIANCE_MATRIX_VZ_VARIANCE])) {
...@@ -1378,20 +1144,16 @@ bool EKF2::UpdateExtVisionSample(ekf2_timestamps_s &ekf2_timestamps, vehicle_odo ...@@ -1378,20 +1144,16 @@ bool EKF2::UpdateExtVisionSample(ekf2_timestamps_s &ekf2_timestamps, vehicle_odo
1378 ev_data.velCov(1, 1) = ev_odom.velocity_covariance[ev_odom.COVARIANCE_MATRIX_VY_VARIANCE]; 1144 ev_data.velCov(1, 1) = ev_odom.velocity_covariance[ev_odom.COVARIANCE_MATRIX_VY_VARIANCE];
1379 ev_data.velCov(1, 2) = ev_data.velCov(2, 1) = ev_odom.velocity_covariance[7]; 1145 ev_data.velCov(1, 2) = ev_data.velCov(2, 1) = ev_odom.velocity_covariance[7];
1380 ev_data.velCov(2, 2) = ev_odom.velocity_covariance[ev_odom.COVARIANCE_MATRIX_VZ_VARIANCE]; 1146 ev_data.velCov(2, 2) = ev_odom.velocity_covariance[ev_odom.COVARIANCE_MATRIX_VZ_VARIANCE];
1381 -
1382 } else { 1147 } else {
1383 ev_data.velCov = matrix::eye<float, 3>() * param_evv_noise_var; 1148 ev_data.velCov = matrix::eye<float, 3>() * param_evv_noise_var;
1384 } 1149 }
1385 } 1150 }
1386 -
1387 // check for valid position data 1151 // check for valid position data
1388 if (PX4_ISFINITE(ev_odom.x) && PX4_ISFINITE(ev_odom.y) && PX4_ISFINITE(ev_odom.z)) { 1152 if (PX4_ISFINITE(ev_odom.x) && PX4_ISFINITE(ev_odom.y) && PX4_ISFINITE(ev_odom.z)) {
1389 ev_data.pos(0) = ev_odom.x; 1153 ev_data.pos(0) = ev_odom.x;
1390 ev_data.pos(1) = ev_odom.y; 1154 ev_data.pos(1) = ev_odom.y;
1391 ev_data.pos(2) = ev_odom.z; 1155 ev_data.pos(2) = ev_odom.z;
1392 -
1393 float param_evp_noise_var = sq(_param_ekf2_evp_noise.get()); 1156 float param_evp_noise_var = sq(_param_ekf2_evp_noise.get());
1394 -
1395 // position measurement error from ev_data or parameters 1157 // position measurement error from ev_data or parameters
1396 if (!_param_ekf2_ev_noise_md.get() && PX4_ISFINITE(ev_odom.pose_covariance[ev_odom.COVARIANCE_MATRIX_X_VARIANCE]) 1158 if (!_param_ekf2_ev_noise_md.get() && PX4_ISFINITE(ev_odom.pose_covariance[ev_odom.COVARIANCE_MATRIX_X_VARIANCE])
1397 && PX4_ISFINITE(ev_odom.pose_covariance[ev_odom.COVARIANCE_MATRIX_Y_VARIANCE]) 1159 && PX4_ISFINITE(ev_odom.pose_covariance[ev_odom.COVARIANCE_MATRIX_Y_VARIANCE])
...@@ -1399,55 +1161,41 @@ bool EKF2::UpdateExtVisionSample(ekf2_timestamps_s &ekf2_timestamps, vehicle_odo ...@@ -1399,55 +1161,41 @@ bool EKF2::UpdateExtVisionSample(ekf2_timestamps_s &ekf2_timestamps, vehicle_odo
1399 ev_data.posVar(0) = fmaxf(param_evp_noise_var, ev_odom.pose_covariance[ev_odom.COVARIANCE_MATRIX_X_VARIANCE]); 1161 ev_data.posVar(0) = fmaxf(param_evp_noise_var, ev_odom.pose_covariance[ev_odom.COVARIANCE_MATRIX_X_VARIANCE]);
1400 ev_data.posVar(1) = fmaxf(param_evp_noise_var, ev_odom.pose_covariance[ev_odom.COVARIANCE_MATRIX_Y_VARIANCE]); 1162 ev_data.posVar(1) = fmaxf(param_evp_noise_var, ev_odom.pose_covariance[ev_odom.COVARIANCE_MATRIX_Y_VARIANCE]);
1401 ev_data.posVar(2) = fmaxf(param_evp_noise_var, ev_odom.pose_covariance[ev_odom.COVARIANCE_MATRIX_Z_VARIANCE]); 1163 ev_data.posVar(2) = fmaxf(param_evp_noise_var, ev_odom.pose_covariance[ev_odom.COVARIANCE_MATRIX_Z_VARIANCE]);
1402 -
1403 } else { 1164 } else {
1404 ev_data.posVar.setAll(param_evp_noise_var); 1165 ev_data.posVar.setAll(param_evp_noise_var);
1405 } 1166 }
1406 } 1167 }
1407 -
1408 // check for valid orientation data 1168 // check for valid orientation data
1409 if (PX4_ISFINITE(ev_odom.q[0])) { 1169 if (PX4_ISFINITE(ev_odom.q[0])) {
1410 ev_data.quat = Quatf(ev_odom.q); 1170 ev_data.quat = Quatf(ev_odom.q);
1411 -
1412 // orientation measurement error from ev_data or parameters 1171 // orientation measurement error from ev_data or parameters
1413 float param_eva_noise_var = sq(_param_ekf2_eva_noise.get()); 1172 float param_eva_noise_var = sq(_param_ekf2_eva_noise.get());
1414 -
1415 if (!_param_ekf2_ev_noise_md.get() && PX4_ISFINITE(ev_odom.pose_covariance[ev_odom.COVARIANCE_MATRIX_YAW_VARIANCE])) { 1173 if (!_param_ekf2_ev_noise_md.get() && PX4_ISFINITE(ev_odom.pose_covariance[ev_odom.COVARIANCE_MATRIX_YAW_VARIANCE])) {
1416 ev_data.angVar = fmaxf(param_eva_noise_var, ev_odom.pose_covariance[ev_odom.COVARIANCE_MATRIX_YAW_VARIANCE]); 1174 ev_data.angVar = fmaxf(param_eva_noise_var, ev_odom.pose_covariance[ev_odom.COVARIANCE_MATRIX_YAW_VARIANCE]);
1417 -
1418 } else { 1175 } else {
1419 ev_data.angVar = param_eva_noise_var; 1176 ev_data.angVar = param_eva_noise_var;
1420 } 1177 }
1421 } 1178 }
1422 -
1423 // use timestamp from external computer, clocks are synchronized when using MAVROS 1179 // use timestamp from external computer, clocks are synchronized when using MAVROS
1424 ev_data.time_us = ev_odom.timestamp_sample; 1180 ev_data.time_us = ev_odom.timestamp_sample;
1425 _ekf.setExtVisionData(ev_data); 1181 _ekf.setExtVisionData(ev_data);
1426 -
1427 new_ev_odom = true; 1182 new_ev_odom = true;
1428 } 1183 }
1429 -
1430 ekf2_timestamps.visual_odometry_timestamp_rel = (int16_t)((int64_t)ev_odom.timestamp / 100 - 1184 ekf2_timestamps.visual_odometry_timestamp_rel = (int16_t)((int64_t)ev_odom.timestamp / 100 -
1431 (int64_t)ekf2_timestamps.timestamp / 100); 1185 (int64_t)ekf2_timestamps.timestamp / 100);
1432 } 1186 }
1433 -
1434 return new_ev_odom; 1187 return new_ev_odom;
1435 } 1188 }
1436 -
1437 bool EKF2::UpdateFlowSample(ekf2_timestamps_s &ekf2_timestamps, optical_flow_s &optical_flow) 1189 bool EKF2::UpdateFlowSample(ekf2_timestamps_s &ekf2_timestamps, optical_flow_s &optical_flow)
1438 { 1190 {
1439 bool new_optical_flow = false; 1191 bool new_optical_flow = false;
1440 const unsigned last_generation = _optical_flow_sub.get_last_generation(); 1192 const unsigned last_generation = _optical_flow_sub.get_last_generation();
1441 -
1442 if (_optical_flow_sub.update(&optical_flow)) { 1193 if (_optical_flow_sub.update(&optical_flow)) {
1443 -
1444 if (_optical_flow_sub.get_last_generation() != last_generation + 1) { 1194 if (_optical_flow_sub.get_last_generation() != last_generation + 1) {
1445 PX4_ERR("%d - optical_flow lost, generation %d -> %d", _instance, last_generation, 1195 PX4_ERR("%d - optical_flow lost, generation %d -> %d", _instance, last_generation,
1446 _optical_flow_sub.get_last_generation()); 1196 _optical_flow_sub.get_last_generation());
1447 } 1197 }
1448 -
1449 if (_param_ekf2_aid_mask.get() & MASK_USE_OF) { 1198 if (_param_ekf2_aid_mask.get() & MASK_USE_OF) {
1450 -
1451 flowSample flow { 1199 flowSample flow {
1452 .time_us = optical_flow.timestamp, 1200 .time_us = optical_flow.timestamp,
1453 // NOTE: the EKF uses the reverse sign convention to the flow sensor. EKF assumes positive LOS rate 1201 // NOTE: the EKF uses the reverse sign convention to the flow sensor. EKF assumes positive LOS rate
...@@ -1457,34 +1205,26 @@ bool EKF2::UpdateFlowSample(ekf2_timestamps_s &ekf2_timestamps, optical_flow_s & ...@@ -1457,34 +1205,26 @@ bool EKF2::UpdateFlowSample(ekf2_timestamps_s &ekf2_timestamps, optical_flow_s &
1457 .dt = 1e-6f * (float)optical_flow.integration_timespan, 1205 .dt = 1e-6f * (float)optical_flow.integration_timespan,
1458 .quality = optical_flow.quality, 1206 .quality = optical_flow.quality,
1459 }; 1207 };
1460 -
1461 if (PX4_ISFINITE(optical_flow.pixel_flow_y_integral) && 1208 if (PX4_ISFINITE(optical_flow.pixel_flow_y_integral) &&
1462 PX4_ISFINITE(optical_flow.pixel_flow_x_integral) && 1209 PX4_ISFINITE(optical_flow.pixel_flow_x_integral) &&
1463 flow.dt < 1) { 1210 flow.dt < 1) {
1464 -
1465 // Save sensor limits reported by the optical flow sensor 1211 // Save sensor limits reported by the optical flow sensor
1466 _ekf.set_optical_flow_limits(optical_flow.max_flow_rate, optical_flow.min_ground_distance, 1212 _ekf.set_optical_flow_limits(optical_flow.max_flow_rate, optical_flow.min_ground_distance,
1467 optical_flow.max_ground_distance); 1213 optical_flow.max_ground_distance);
1468 -
1469 _ekf.setOpticalFlowData(flow); 1214 _ekf.setOpticalFlowData(flow);
1470 -
1471 new_optical_flow = true; 1215 new_optical_flow = true;
1472 } 1216 }
1473 } 1217 }
1474 -
1475 ekf2_timestamps.optical_flow_timestamp_rel = (int16_t)((int64_t)optical_flow.timestamp / 100 - 1218 ekf2_timestamps.optical_flow_timestamp_rel = (int16_t)((int64_t)optical_flow.timestamp / 100 -
1476 (int64_t)ekf2_timestamps.timestamp / 100); 1219 (int64_t)ekf2_timestamps.timestamp / 100);
1477 } 1220 }
1478 -
1479 return new_optical_flow; 1221 return new_optical_flow;
1480 } 1222 }
1481 -
1482 void EKF2::UpdateGpsSample(ekf2_timestamps_s &ekf2_timestamps) 1223 void EKF2::UpdateGpsSample(ekf2_timestamps_s &ekf2_timestamps)
1483 { 1224 {
1484 // EKF GPS message 1225 // EKF GPS message
1485 if (_param_ekf2_aid_mask.get() & MASK_USE_GPS) { 1226 if (_param_ekf2_aid_mask.get() & MASK_USE_GPS) {
1486 vehicle_gps_position_s vehicle_gps_position; 1227 vehicle_gps_position_s vehicle_gps_position;
1487 -
1488 if (_vehicle_gps_position_sub.update(&vehicle_gps_position)) { 1228 if (_vehicle_gps_position_sub.update(&vehicle_gps_position)) {
1489 gps_message gps_msg{ 1229 gps_message gps_msg{
1490 .time_usec = vehicle_gps_position.timestamp, 1230 .time_usec = vehicle_gps_position.timestamp,
...@@ -1518,7 +1258,7 @@ void EKF2::UpdateGpsSample(ekf2_timestamps_s &ekf2_timestamps) ...@@ -1518,7 +1258,7 @@ void EKF2::UpdateGpsSample(ekf2_timestamps_s &ekf2_timestamps)
1518 calculate_inclination_target(); 1258 calculate_inclination_target();
1519 print_target_gps(); 1259 print_target_gps();
1520 //print_current_gps(gps_msg); 1260 //print_current_gps(gps_msg);
1521 - calculate_inclination_current(gps_msg); 1261 + check_inclination(calculate_inclination_current(gps_msg));
1522 } 1262 }
1523 } 1263 }
1524 _gps_time_usec = gps_msg.time_usec; 1264 _gps_time_usec = gps_msg.time_usec;
...@@ -1526,6 +1266,19 @@ void EKF2::UpdateGpsSample(ekf2_timestamps_s &ekf2_timestamps) ...@@ -1526,6 +1266,19 @@ void EKF2::UpdateGpsSample(ekf2_timestamps_s &ekf2_timestamps)
1526 } 1266 }
1527 } 1267 }
1528 } 1268 }
1269 +void EKF2::check_inclination(double check)
1270 +{
1271 + double origin=inclination[int(mission.current_seq)-1];
1272 + std:: cout << "origin : "<<origin<<"\tcheck : "<<check<<std::endl;
1273 + if(origin-1<=check && check <= origin+1)
1274 + {
1275 + std::cout<<"*----Good moving----*"<<std::endl;
1276 + }
1277 + else
1278 + {
1279 + std::cout<<"*----Bad moving----*"<<std::endl;
1280 + }
1281 +}
1529 void EKF2::print_current_gps(gps_message gps_msg) 1282 void EKF2::print_current_gps(gps_message gps_msg)
1530 { 1283 {
1531 std::cout<<"curre\t#"<<mission.current_seq<<"(lat/lon/alt)\t" << gps_msg.lat << "\t"<<gps_msg.lon<<"\t"<<gps_msg.alt<<std::endl; 1284 std::cout<<"curre\t#"<<mission.current_seq<<"(lat/lon/alt)\t" << gps_msg.lat << "\t"<<gps_msg.lon<<"\t"<<gps_msg.alt<<std::endl;
...@@ -1534,7 +1287,7 @@ void EKF2::calculate_inclination_target() ...@@ -1534,7 +1287,7 @@ void EKF2::calculate_inclination_target()
1534 { 1287 {
1535 double x,y; 1288 double x,y;
1536 inclination=new double[int(mission.count)]; 1289 inclination=new double[int(mission.count)];
1537 - for (size_t i = 0; i < mission.count-1; i++) { 1290 + for (int i = 0; i < int(mission.count)-1; i++) {
1538 struct mission_item_s mission_item {}; 1291 struct mission_item_s mission_item {};
1539 struct mission_item_s next_mission_item {}; 1292 struct mission_item_s next_mission_item {};
1540 dm_read((dm_item_t)mission.dataman_id, i, &mission_item, sizeof(mission_item_s)); 1293 dm_read((dm_item_t)mission.dataman_id, i, &mission_item, sizeof(mission_item_s));
...@@ -1557,7 +1310,7 @@ void EKF2::calculate_inclination_target() ...@@ -1557,7 +1310,7 @@ void EKF2::calculate_inclination_target()
1557 }*/ 1310 }*/
1558 } 1311 }
1559 } 1312 }
1560 -void EKF2::calculate_inclination_current(gps_message gps_msg) 1313 +double EKF2::calculate_inclination_current(gps_message gps_msg)
1561 { 1314 {
1562 double x,y; 1315 double x,y;
1563 double check_inclination=0; 1316 double check_inclination=0;
...@@ -1568,13 +1321,12 @@ void EKF2::calculate_inclination_current(gps_message gps_msg) ...@@ -1568,13 +1321,12 @@ void EKF2::calculate_inclination_current(gps_message gps_msg)
1568 } 1321 }
1569 std::cout.setf(std::ios::fixed); 1322 std::cout.setf(std::ios::fixed);
1570 std::cout.precision(7); 1323 std::cout.precision(7);
1571 - std::cout << "[Mission] #"<<mission.current_seq<<"\t"<<check_inclination<<std::endl; 1324 + //std::cout << "[Mission] #"<<mission.current_seq<<"\t"<<check_inclination<<std::endl;
1572 - 1325 + return check_inclination;
1573 } 1326 }
1574 void EKF2::print_target_gps() 1327 void EKF2::print_target_gps()
1575 { 1328 {
1576 std::cout.unsetf(std::ios::fixed); 1329 std::cout.unsetf(std::ios::fixed);
1577 -
1578 for (size_t i = 0; i < mission.count; i++) { 1330 for (size_t i = 0; i < mission.count; i++) {
1579 struct mission_item_s mission_item {}; 1331 struct mission_item_s mission_item {};
1580 if(int(mission.current_seq)==int(i)){ 1332 if(int(mission.current_seq)==int(i)){
...@@ -1590,63 +1342,49 @@ void EKF2::UpdateMagSample(ekf2_timestamps_s &ekf2_timestamps) ...@@ -1590,63 +1342,49 @@ void EKF2::UpdateMagSample(ekf2_timestamps_s &ekf2_timestamps)
1590 { 1342 {
1591 const unsigned last_generation = _magnetometer_sub.get_last_generation(); 1343 const unsigned last_generation = _magnetometer_sub.get_last_generation();
1592 vehicle_magnetometer_s magnetometer; 1344 vehicle_magnetometer_s magnetometer;
1593 -
1594 if (_magnetometer_sub.update(&magnetometer)) { 1345 if (_magnetometer_sub.update(&magnetometer)) {
1595 -
1596 if (_magnetometer_sub.get_last_generation() != last_generation + 1) { 1346 if (_magnetometer_sub.get_last_generation() != last_generation + 1) {
1597 perf_count(_mag_missed_perf); 1347 perf_count(_mag_missed_perf);
1598 PX4_DEBUG("%d - vehicle_magnetometer lost, generation %d -> %d", _instance, last_generation, 1348 PX4_DEBUG("%d - vehicle_magnetometer lost, generation %d -> %d", _instance, last_generation,
1599 _magnetometer_sub.get_last_generation()); 1349 _magnetometer_sub.get_last_generation());
1600 } 1350 }
1601 -
1602 bool reset = false; 1351 bool reset = false;
1603 -
1604 // check if magnetometer has changed 1352 // check if magnetometer has changed
1605 if (magnetometer.device_id != _device_id_mag) { 1353 if (magnetometer.device_id != _device_id_mag) {
1606 if (_device_id_mag != 0) { 1354 if (_device_id_mag != 0) {
1607 PX4_WARN("%d - mag sensor ID changed %d -> %d", _instance, _device_id_mag, magnetometer.device_id); 1355 PX4_WARN("%d - mag sensor ID changed %d -> %d", _instance, _device_id_mag, magnetometer.device_id);
1608 } 1356 }
1609 -
1610 reset = true; 1357 reset = true;
1611 -
1612 } else if (magnetometer.calibration_count > _mag_calibration_count) { 1358 } else if (magnetometer.calibration_count > _mag_calibration_count) {
1613 // existing calibration has changed, reset saved mag bias 1359 // existing calibration has changed, reset saved mag bias
1614 PX4_DEBUG("%d - mag %d calibration updated, resetting bias", _instance, _device_id_mag); 1360 PX4_DEBUG("%d - mag %d calibration updated, resetting bias", _instance, _device_id_mag);
1615 reset = true; 1361 reset = true;
1616 } 1362 }
1617 -
1618 if (reset) { 1363 if (reset) {
1619 _ekf.resetMagBias(); 1364 _ekf.resetMagBias();
1620 _device_id_mag = magnetometer.device_id; 1365 _device_id_mag = magnetometer.device_id;
1621 _mag_calibration_count = magnetometer.calibration_count; 1366 _mag_calibration_count = magnetometer.calibration_count;
1622 -
1623 // reset magnetometer bias learning 1367 // reset magnetometer bias learning
1624 _mag_cal_total_time_us = 0; 1368 _mag_cal_total_time_us = 0;
1625 _mag_cal_last_us = 0; 1369 _mag_cal_last_us = 0;
1626 _mag_cal_available = false; 1370 _mag_cal_available = false;
1627 } 1371 }
1628 -
1629 _ekf.setMagData(magSample{magnetometer.timestamp_sample, Vector3f{magnetometer.magnetometer_ga}}); 1372 _ekf.setMagData(magSample{magnetometer.timestamp_sample, Vector3f{magnetometer.magnetometer_ga}});
1630 -
1631 ekf2_timestamps.vehicle_magnetometer_timestamp_rel = (int16_t)((int64_t)magnetometer.timestamp / 100 - 1373 ekf2_timestamps.vehicle_magnetometer_timestamp_rel = (int16_t)((int64_t)magnetometer.timestamp / 100 -
1632 (int64_t)ekf2_timestamps.timestamp / 100); 1374 (int64_t)ekf2_timestamps.timestamp / 100);
1633 } 1375 }
1634 } 1376 }
1635 -
1636 void EKF2::UpdateRangeSample(ekf2_timestamps_s &ekf2_timestamps) 1377 void EKF2::UpdateRangeSample(ekf2_timestamps_s &ekf2_timestamps)
1637 { 1378 {
1638 if (!_distance_sensor_selected) { 1379 if (!_distance_sensor_selected) {
1639 // get subscription index of first downward-facing range sensor 1380 // get subscription index of first downward-facing range sensor
1640 uORB::SubscriptionMultiArray<distance_sensor_s> distance_sensor_subs{ORB_ID::distance_sensor}; 1381 uORB::SubscriptionMultiArray<distance_sensor_s> distance_sensor_subs{ORB_ID::distance_sensor};
1641 -
1642 for (unsigned i = 0; i < distance_sensor_subs.size(); i++) { 1382 for (unsigned i = 0; i < distance_sensor_subs.size(); i++) {
1643 distance_sensor_s distance_sensor; 1383 distance_sensor_s distance_sensor;
1644 -
1645 if (distance_sensor_subs[i].copy(&distance_sensor)) { 1384 if (distance_sensor_subs[i].copy(&distance_sensor)) {
1646 // only use the first instace which has the correct orientation 1385 // only use the first instace which has the correct orientation
1647 if ((hrt_elapsed_time(&distance_sensor.timestamp) < 100_ms) 1386 if ((hrt_elapsed_time(&distance_sensor.timestamp) < 100_ms)
1648 && (distance_sensor.orientation == distance_sensor_s::ROTATION_DOWNWARD_FACING)) { 1387 && (distance_sensor.orientation == distance_sensor_s::ROTATION_DOWNWARD_FACING)) {
1649 -
1650 if (_distance_sensor_sub.ChangeInstance(i)) { 1388 if (_distance_sensor_sub.ChangeInstance(i)) {
1651 PX4_INFO("%d - selected distance_sensor:%d", _instance, i); 1389 PX4_INFO("%d - selected distance_sensor:%d", _instance, i);
1652 _distance_sensor_selected = true; 1390 _distance_sensor_selected = true;
...@@ -1655,21 +1393,16 @@ void EKF2::UpdateRangeSample(ekf2_timestamps_s &ekf2_timestamps) ...@@ -1655,21 +1393,16 @@ void EKF2::UpdateRangeSample(ekf2_timestamps_s &ekf2_timestamps)
1655 } 1393 }
1656 } 1394 }
1657 } 1395 }
1658 -
1659 // EKF range sample 1396 // EKF range sample
1660 const unsigned last_generation = _distance_sensor_sub.get_last_generation(); 1397 const unsigned last_generation = _distance_sensor_sub.get_last_generation();
1661 distance_sensor_s distance_sensor; 1398 distance_sensor_s distance_sensor;
1662 -
1663 if (_distance_sensor_sub.update(&distance_sensor)) { 1399 if (_distance_sensor_sub.update(&distance_sensor)) {
1664 -
1665 if (_distance_sensor_sub.get_last_generation() != last_generation + 1) { 1400 if (_distance_sensor_sub.get_last_generation() != last_generation + 1) {
1666 PX4_ERR("%d - distance_sensor lost, generation %d -> %d", _instance, last_generation, 1401 PX4_ERR("%d - distance_sensor lost, generation %d -> %d", _instance, last_generation,
1667 _distance_sensor_sub.get_last_generation()); 1402 _distance_sensor_sub.get_last_generation());
1668 } 1403 }
1669 -
1670 ekf2_timestamps.distance_sensor_timestamp_rel = (int16_t)((int64_t)distance_sensor.timestamp / 100 - 1404 ekf2_timestamps.distance_sensor_timestamp_rel = (int16_t)((int64_t)distance_sensor.timestamp / 100 -
1671 (int64_t)ekf2_timestamps.timestamp / 100); 1405 (int64_t)ekf2_timestamps.timestamp / 100);
1672 -
1673 if (distance_sensor.orientation == distance_sensor_s::ROTATION_DOWNWARD_FACING) { 1406 if (distance_sensor.orientation == distance_sensor_s::ROTATION_DOWNWARD_FACING) {
1674 rangeSample range_sample { 1407 rangeSample range_sample {
1675 .time_us = distance_sensor.timestamp, 1408 .time_us = distance_sensor.timestamp,
...@@ -1677,29 +1410,23 @@ void EKF2::UpdateRangeSample(ekf2_timestamps_s &ekf2_timestamps) ...@@ -1677,29 +1410,23 @@ void EKF2::UpdateRangeSample(ekf2_timestamps_s &ekf2_timestamps)
1677 .quality = distance_sensor.signal_quality, 1410 .quality = distance_sensor.signal_quality,
1678 }; 1411 };
1679 _ekf.setRangeData(range_sample); 1412 _ekf.setRangeData(range_sample);
1680 -
1681 // Save sensor limits reported by the rangefinder 1413 // Save sensor limits reported by the rangefinder
1682 _ekf.set_rangefinder_limits(distance_sensor.min_distance, distance_sensor.max_distance); 1414 _ekf.set_rangefinder_limits(distance_sensor.min_distance, distance_sensor.max_distance);
1683 -
1684 _last_range_sensor_update = distance_sensor.timestamp; 1415 _last_range_sensor_update = distance_sensor.timestamp;
1685 return; 1416 return;
1686 } 1417 }
1687 } 1418 }
1688 -
1689 if (hrt_elapsed_time(&_last_range_sensor_update) > 1_s) { 1419 if (hrt_elapsed_time(&_last_range_sensor_update) > 1_s) {
1690 _distance_sensor_selected = false; 1420 _distance_sensor_selected = false;
1691 } 1421 }
1692 } 1422 }
1693 -
1694 void EKF2::UpdateMagCalibration(const hrt_abstime &timestamp) 1423 void EKF2::UpdateMagCalibration(const hrt_abstime &timestamp)
1695 { 1424 {
1696 // Check if conditions are OK for learning of magnetometer bias values 1425 // Check if conditions are OK for learning of magnetometer bias values
1697 // the EKF is operating in the correct mode and there are no filter faults 1426 // the EKF is operating in the correct mode and there are no filter faults
1698 if (_ekf.control_status_flags().in_air && _ekf.control_status_flags().mag_3D && (_ekf.fault_status().value == 0)) { 1427 if (_ekf.control_status_flags().in_air && _ekf.control_status_flags().mag_3D && (_ekf.fault_status().value == 0)) {
1699 -
1700 if (_mag_cal_last_us != 0) { 1428 if (_mag_cal_last_us != 0) {
1701 _mag_cal_total_time_us += timestamp - _mag_cal_last_us; 1429 _mag_cal_total_time_us += timestamp - _mag_cal_last_us;
1702 -
1703 // Start checking mag bias estimates when we have accumulated sufficient calibration time 1430 // Start checking mag bias estimates when we have accumulated sufficient calibration time
1704 if (_mag_cal_total_time_us > 30_s) { 1431 if (_mag_cal_total_time_us > 30_s) {
1705 _mag_cal_last_bias = _ekf.getMagBias(); 1432 _mag_cal_last_bias = _ekf.getMagBias();
...@@ -1707,30 +1434,24 @@ void EKF2::UpdateMagCalibration(const hrt_abstime &timestamp) ...@@ -1707,30 +1434,24 @@ void EKF2::UpdateMagCalibration(const hrt_abstime &timestamp)
1707 _mag_cal_available = true; 1434 _mag_cal_available = true;
1708 } 1435 }
1709 } 1436 }
1710 -
1711 _mag_cal_last_us = timestamp; 1437 _mag_cal_last_us = timestamp;
1712 -
1713 } else { 1438 } else {
1714 // conditions are NOT OK for learning magnetometer bias, reset timestamp 1439 // conditions are NOT OK for learning magnetometer bias, reset timestamp
1715 // but keep the accumulated calibration time 1440 // but keep the accumulated calibration time
1716 _mag_cal_last_us = 0; 1441 _mag_cal_last_us = 0;
1717 -
1718 if (_ekf.fault_status().value != 0) { 1442 if (_ekf.fault_status().value != 0) {
1719 // if a filter fault has occurred, assume previous learning was invalid and do not 1443 // if a filter fault has occurred, assume previous learning was invalid and do not
1720 // count it towards total learning time. 1444 // count it towards total learning time.
1721 _mag_cal_total_time_us = 0; 1445 _mag_cal_total_time_us = 0;
1722 } 1446 }
1723 } 1447 }
1724 -
1725 if (!_armed) { 1448 if (!_armed) {
1726 // update stored declination value 1449 // update stored declination value
1727 if (!_mag_decl_saved) { 1450 if (!_mag_decl_saved) {
1728 float declination_deg; 1451 float declination_deg;
1729 -
1730 if (_ekf.get_mag_decl_deg(&declination_deg)) { 1452 if (_ekf.get_mag_decl_deg(&declination_deg)) {
1731 _param_ekf2_mag_decl.set(declination_deg); 1453 _param_ekf2_mag_decl.set(declination_deg);
1732 _mag_decl_saved = true; 1454 _mag_decl_saved = true;
1733 -
1734 if (!_multi_mode) { 1455 if (!_multi_mode) {
1735 _param_ekf2_mag_decl.commit_no_notification(); 1456 _param_ekf2_mag_decl.commit_no_notification();
1736 } 1457 }
...@@ -1738,50 +1459,39 @@ void EKF2::UpdateMagCalibration(const hrt_abstime &timestamp) ...@@ -1738,50 +1459,39 @@ void EKF2::UpdateMagCalibration(const hrt_abstime &timestamp)
1738 } 1459 }
1739 } 1460 }
1740 } 1461 }
1741 -
1742 int EKF2::custom_command(int argc, char *argv[]) 1462 int EKF2::custom_command(int argc, char *argv[])
1743 { 1463 {
1744 return print_usage("unknown command"); 1464 return print_usage("unknown command");
1745 } 1465 }
1746 -
1747 int EKF2::task_spawn(int argc, char *argv[]) 1466 int EKF2::task_spawn(int argc, char *argv[])
1748 { 1467 {
1749 bool success = false; 1468 bool success = false;
1750 bool replay_mode = false; 1469 bool replay_mode = false;
1751 -
1752 if (argc > 1 && !strcmp(argv[1], "-r")) { 1470 if (argc > 1 && !strcmp(argv[1], "-r")) {
1753 PX4_INFO("replay mode enabled"); 1471 PX4_INFO("replay mode enabled");
1754 replay_mode = true; 1472 replay_mode = true;
1755 } 1473 }
1756 -
1757 #if !defined(CONSTRAINED_FLASH) 1474 #if !defined(CONSTRAINED_FLASH)
1758 bool multi_mode = false; 1475 bool multi_mode = false;
1759 int32_t imu_instances = 0; 1476 int32_t imu_instances = 0;
1760 int32_t mag_instances = 0; 1477 int32_t mag_instances = 0;
1761 -
1762 int32_t sens_imu_mode = 1; 1478 int32_t sens_imu_mode = 1;
1763 param_get(param_find("SENS_IMU_MODE"), &sens_imu_mode); 1479 param_get(param_find("SENS_IMU_MODE"), &sens_imu_mode);
1764 -
1765 if (sens_imu_mode == 0) { 1480 if (sens_imu_mode == 0) {
1766 // ekf selector requires SENS_IMU_MODE = 0 1481 // ekf selector requires SENS_IMU_MODE = 0
1767 multi_mode = true; 1482 multi_mode = true;
1768 -
1769 // IMUs (1 - 4 supported) 1483 // IMUs (1 - 4 supported)
1770 param_get(param_find("EKF2_MULTI_IMU"), &imu_instances); 1484 param_get(param_find("EKF2_MULTI_IMU"), &imu_instances);
1771 -
1772 if (imu_instances < 1 || imu_instances > 4) { 1485 if (imu_instances < 1 || imu_instances > 4) {
1773 const int32_t imu_instances_limited = math::constrain(imu_instances, 1, 4); 1486 const int32_t imu_instances_limited = math::constrain(imu_instances, 1, 4);
1774 PX4_WARN("EKF2_MULTI_IMU limited %d -> %d", imu_instances, imu_instances_limited); 1487 PX4_WARN("EKF2_MULTI_IMU limited %d -> %d", imu_instances, imu_instances_limited);
1775 param_set_no_notification(param_find("EKF2_MULTI_IMU"), &imu_instances_limited); 1488 param_set_no_notification(param_find("EKF2_MULTI_IMU"), &imu_instances_limited);
1776 imu_instances = imu_instances_limited; 1489 imu_instances = imu_instances_limited;
1777 } 1490 }
1778 -
1779 int32_t sens_mag_mode = 1; 1491 int32_t sens_mag_mode = 1;
1780 param_get(param_find("SENS_MAG_MODE"), &sens_mag_mode); 1492 param_get(param_find("SENS_MAG_MODE"), &sens_mag_mode);
1781 -
1782 if (sens_mag_mode == 0) { 1493 if (sens_mag_mode == 0) {
1783 param_get(param_find("EKF2_MULTI_MAG"), &mag_instances); 1494 param_get(param_find("EKF2_MULTI_MAG"), &mag_instances);
1784 -
1785 // Mags (1 - 4 supported) 1495 // Mags (1 - 4 supported)
1786 if (mag_instances < 1 || mag_instances > 4) { 1496 if (mag_instances < 1 || mag_instances > 4) {
1787 const int32_t mag_instances_limited = math::constrain(mag_instances, 1, 4); 1497 const int32_t mag_instances_limited = math::constrain(mag_instances, 1, 4);
...@@ -1789,167 +1499,126 @@ int EKF2::task_spawn(int argc, char *argv[]) ...@@ -1789,167 +1499,126 @@ int EKF2::task_spawn(int argc, char *argv[])
1789 param_set_no_notification(param_find("EKF2_MULTI_MAG"), &mag_instances_limited); 1499 param_set_no_notification(param_find("EKF2_MULTI_MAG"), &mag_instances_limited);
1790 mag_instances = mag_instances_limited; 1500 mag_instances = mag_instances_limited;
1791 } 1501 }
1792 -
1793 } else { 1502 } else {
1794 mag_instances = 1; 1503 mag_instances = 1;
1795 } 1504 }
1796 } 1505 }
1797 -
1798 if (multi_mode) { 1506 if (multi_mode) {
1799 // Start EKF2Selector if it's not already running 1507 // Start EKF2Selector if it's not already running
1800 if (_ekf2_selector.load() == nullptr) { 1508 if (_ekf2_selector.load() == nullptr) {
1801 EKF2Selector *inst = new EKF2Selector(); 1509 EKF2Selector *inst = new EKF2Selector();
1802 -
1803 if (inst) { 1510 if (inst) {
1804 _ekf2_selector.store(inst); 1511 _ekf2_selector.store(inst);
1805 -
1806 } else { 1512 } else {
1807 PX4_ERR("Failed to create EKF2 selector"); 1513 PX4_ERR("Failed to create EKF2 selector");
1808 return PX4_ERROR; 1514 return PX4_ERROR;
1809 } 1515 }
1810 } 1516 }
1811 -
1812 const hrt_abstime time_started = hrt_absolute_time(); 1517 const hrt_abstime time_started = hrt_absolute_time();
1813 const int multi_instances = math::min(imu_instances * mag_instances, (int)EKF2_MAX_INSTANCES); 1518 const int multi_instances = math::min(imu_instances * mag_instances, (int)EKF2_MAX_INSTANCES);
1814 int multi_instances_allocated = 0; 1519 int multi_instances_allocated = 0;
1815 -
1816 // allocate EKF2 instances until all found or arming 1520 // allocate EKF2 instances until all found or arming
1817 uORB::SubscriptionData<vehicle_status_s> vehicle_status_sub{ORB_ID(vehicle_status)}; 1521 uORB::SubscriptionData<vehicle_status_s> vehicle_status_sub{ORB_ID(vehicle_status)};
1818 -
1819 bool ekf2_instance_created[4][4] {}; // IMUs * mags 1522 bool ekf2_instance_created[4][4] {}; // IMUs * mags
1820 -
1821 while ((multi_instances_allocated < multi_instances) 1523 while ((multi_instances_allocated < multi_instances)
1822 && (vehicle_status_sub.get().arming_state != vehicle_status_s::ARMING_STATE_ARMED) 1524 && (vehicle_status_sub.get().arming_state != vehicle_status_s::ARMING_STATE_ARMED)
1823 && ((hrt_elapsed_time(&time_started) < 30_s) 1525 && ((hrt_elapsed_time(&time_started) < 30_s)
1824 || (vehicle_status_sub.get().hil_state == vehicle_status_s::HIL_STATE_ON))) { 1526 || (vehicle_status_sub.get().hil_state == vehicle_status_s::HIL_STATE_ON))) {
1825 -
1826 vehicle_status_sub.update(); 1527 vehicle_status_sub.update();
1827 -
1828 for (uint8_t mag = 0; mag < mag_instances; mag++) { 1528 for (uint8_t mag = 0; mag < mag_instances; mag++) {
1829 uORB::SubscriptionData<vehicle_magnetometer_s> vehicle_mag_sub{ORB_ID(vehicle_magnetometer), mag}; 1529 uORB::SubscriptionData<vehicle_magnetometer_s> vehicle_mag_sub{ORB_ID(vehicle_magnetometer), mag};
1830 -
1831 for (uint8_t imu = 0; imu < imu_instances; imu++) { 1530 for (uint8_t imu = 0; imu < imu_instances; imu++) {
1832 -
1833 uORB::SubscriptionData<vehicle_imu_s> vehicle_imu_sub{ORB_ID(vehicle_imu), imu}; 1531 uORB::SubscriptionData<vehicle_imu_s> vehicle_imu_sub{ORB_ID(vehicle_imu), imu};
1834 vehicle_mag_sub.update(); 1532 vehicle_mag_sub.update();
1835 -
1836 // Mag & IMU data must be valid, first mag can be ignored initially 1533 // Mag & IMU data must be valid, first mag can be ignored initially
1837 if ((vehicle_mag_sub.get().device_id != 0 || mag == 0) 1534 if ((vehicle_mag_sub.get().device_id != 0 || mag == 0)
1838 && (vehicle_imu_sub.get().accel_device_id != 0) 1535 && (vehicle_imu_sub.get().accel_device_id != 0)
1839 && (vehicle_imu_sub.get().gyro_device_id != 0)) { 1536 && (vehicle_imu_sub.get().gyro_device_id != 0)) {
1840 -
1841 if (!ekf2_instance_created[imu][mag]) { 1537 if (!ekf2_instance_created[imu][mag]) {
1842 EKF2 *ekf2_inst = new EKF2(true, px4::ins_instance_to_wq(imu), false); 1538 EKF2 *ekf2_inst = new EKF2(true, px4::ins_instance_to_wq(imu), false);
1843 -
1844 if (ekf2_inst && ekf2_inst->multi_init(imu, mag)) { 1539 if (ekf2_inst && ekf2_inst->multi_init(imu, mag)) {
1845 int actual_instance = ekf2_inst->instance(); // match uORB instance numbering 1540 int actual_instance = ekf2_inst->instance(); // match uORB instance numbering
1846 -
1847 if ((actual_instance >= 0) && (_objects[actual_instance].load() == nullptr)) { 1541 if ((actual_instance >= 0) && (_objects[actual_instance].load() == nullptr)) {
1848 _objects[actual_instance].store(ekf2_inst); 1542 _objects[actual_instance].store(ekf2_inst);
1849 success = true; 1543 success = true;
1850 multi_instances_allocated++; 1544 multi_instances_allocated++;
1851 ekf2_instance_created[imu][mag] = true; 1545 ekf2_instance_created[imu][mag] = true;
1852 -
1853 if (actual_instance == 0) { 1546 if (actual_instance == 0) {
1854 // force selector to run immediately if first instance started 1547 // force selector to run immediately if first instance started
1855 _ekf2_selector.load()->ScheduleNow(); 1548 _ekf2_selector.load()->ScheduleNow();
1856 } 1549 }
1857 -
1858 PX4_INFO("starting instance %d, IMU:%d (%d), MAG:%d (%d)", actual_instance, 1550 PX4_INFO("starting instance %d, IMU:%d (%d), MAG:%d (%d)", actual_instance,
1859 imu, vehicle_imu_sub.get().accel_device_id, 1551 imu, vehicle_imu_sub.get().accel_device_id,
1860 mag, vehicle_mag_sub.get().device_id); 1552 mag, vehicle_mag_sub.get().device_id);
1861 -
1862 // sleep briefly before starting more instances 1553 // sleep briefly before starting more instances
1863 px4_usleep(10000); 1554 px4_usleep(10000);
1864 -
1865 } else { 1555 } else {
1866 PX4_ERR("instance numbering problem instance: %d", actual_instance); 1556 PX4_ERR("instance numbering problem instance: %d", actual_instance);
1867 delete ekf2_inst; 1557 delete ekf2_inst;
1868 break; 1558 break;
1869 } 1559 }
1870 -
1871 } else { 1560 } else {
1872 PX4_ERR("alloc and init failed imu: %d mag:%d", imu, mag); 1561 PX4_ERR("alloc and init failed imu: %d mag:%d", imu, mag);
1873 px4_usleep(1000000); 1562 px4_usleep(1000000);
1874 break; 1563 break;
1875 } 1564 }
1876 } 1565 }
1877 -
1878 } else { 1566 } else {
1879 px4_usleep(50000); // give the sensors extra time to start 1567 px4_usleep(50000); // give the sensors extra time to start
1880 continue; 1568 continue;
1881 } 1569 }
1882 } 1570 }
1883 } 1571 }
1884 -
1885 if (multi_instances_allocated < multi_instances) { 1572 if (multi_instances_allocated < multi_instances) {
1886 px4_usleep(100000); 1573 px4_usleep(100000);
1887 } 1574 }
1888 } 1575 }
1889 -
1890 } 1576 }
1891 -
1892 #endif // !CONSTRAINED_FLASH 1577 #endif // !CONSTRAINED_FLASH
1893 -
1894 else { 1578 else {
1895 // otherwise launch regular 1579 // otherwise launch regular
1896 EKF2 *ekf2_inst = new EKF2(false, px4::wq_configurations::INS0, replay_mode); 1580 EKF2 *ekf2_inst = new EKF2(false, px4::wq_configurations::INS0, replay_mode);
1897 -
1898 if (ekf2_inst) { 1581 if (ekf2_inst) {
1899 _objects[0].store(ekf2_inst); 1582 _objects[0].store(ekf2_inst);
1900 ekf2_inst->ScheduleNow(); 1583 ekf2_inst->ScheduleNow();
1901 success = true; 1584 success = true;
1902 } 1585 }
1903 } 1586 }
1904 -
1905 return success ? PX4_OK : PX4_ERROR; 1587 return success ? PX4_OK : PX4_ERROR;
1906 } 1588 }
1907 -
1908 int EKF2::print_usage(const char *reason) 1589 int EKF2::print_usage(const char *reason)
1909 { 1590 {
1910 if (reason) { 1591 if (reason) {
1911 PX4_WARN("%s\n", reason); 1592 PX4_WARN("%s\n", reason);
1912 } 1593 }
1913 -
1914 PRINT_MODULE_DESCRIPTION( 1594 PRINT_MODULE_DESCRIPTION(
1915 R"DESCR_STR( 1595 R"DESCR_STR(
1916 ### Description 1596 ### Description
1917 Attitude and position estimator using an Extended Kalman Filter. It is used for Multirotors and Fixed-Wing. 1597 Attitude and position estimator using an Extended Kalman Filter. It is used for Multirotors and Fixed-Wing.
1918 -
1919 The documentation can be found on the [ECL/EKF Overview & Tuning](https://docs.px4.io/master/en/advanced_config/tuning_the_ecl_ekf.html) page. 1598 The documentation can be found on the [ECL/EKF Overview & Tuning](https://docs.px4.io/master/en/advanced_config/tuning_the_ecl_ekf.html) page.
1920 -
1921 ekf2 can be started in replay mode (`-r`): in this mode it does not access the system time, but only uses the 1599 ekf2 can be started in replay mode (`-r`): in this mode it does not access the system time, but only uses the
1922 timestamps from the sensor topics. 1600 timestamps from the sensor topics.
1923 -
1924 )DESCR_STR"); 1601 )DESCR_STR");
1925 -
1926 PRINT_MODULE_USAGE_NAME("ekf2", "estimator"); 1602 PRINT_MODULE_USAGE_NAME("ekf2", "estimator");
1927 PRINT_MODULE_USAGE_COMMAND("start"); 1603 PRINT_MODULE_USAGE_COMMAND("start");
1928 PRINT_MODULE_USAGE_PARAM_FLAG('r', "Enable replay mode", true); 1604 PRINT_MODULE_USAGE_PARAM_FLAG('r', "Enable replay mode", true);
1929 PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); 1605 PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
1930 -
1931 return 0; 1606 return 0;
1932 } 1607 }
1933 -
1934 extern "C" __EXPORT int ekf2_main(int argc, char *argv[]) 1608 extern "C" __EXPORT int ekf2_main(int argc, char *argv[])
1935 { 1609 {
1936 if (argc <= 1 || strcmp(argv[1], "-h") == 0) { 1610 if (argc <= 1 || strcmp(argv[1], "-h") == 0) {
1937 return EKF2::print_usage(); 1611 return EKF2::print_usage();
1938 } 1612 }
1939 -
1940 if (strcmp(argv[1], "start") == 0) { 1613 if (strcmp(argv[1], "start") == 0) {
1941 int ret = 0; 1614 int ret = 0;
1942 EKF2::lock_module(); 1615 EKF2::lock_module();
1943 -
1944 ret = EKF2::task_spawn(argc - 1, argv + 1); 1616 ret = EKF2::task_spawn(argc - 1, argv + 1);
1945 -
1946 if (ret < 0) { 1617 if (ret < 0) {
1947 PX4_ERR("start failed (%i)", ret); 1618 PX4_ERR("start failed (%i)", ret);
1948 } 1619 }
1949 -
1950 EKF2::unlock_module(); 1620 EKF2::unlock_module();
1951 return ret; 1621 return ret;
1952 -
1953 } else if (strcmp(argv[1], "status") == 0) { 1622 } else if (strcmp(argv[1], "status") == 0) {
1954 if (EKF2::trylock_module()) { 1623 if (EKF2::trylock_module()) {
1955 #if !defined(CONSTRAINED_FLASH) 1624 #if !defined(CONSTRAINED_FLASH)
...@@ -1957,32 +1626,24 @@ extern "C" __EXPORT int ekf2_main(int argc, char *argv[]) ...@@ -1957,32 +1626,24 @@ extern "C" __EXPORT int ekf2_main(int argc, char *argv[])
1957 _ekf2_selector.load()->PrintStatus(); 1626 _ekf2_selector.load()->PrintStatus();
1958 } 1627 }
1959 #endif // !CONSTRAINED_FLASH 1628 #endif // !CONSTRAINED_FLASH
1960 -
1961 for (int i = 0; i < EKF2_MAX_INSTANCES; i++) { 1629 for (int i = 0; i < EKF2_MAX_INSTANCES; i++) {
1962 if (_objects[i].load()) { 1630 if (_objects[i].load()) {
1963 PX4_INFO_RAW("\n"); 1631 PX4_INFO_RAW("\n");
1964 _objects[i].load()->print_status(); 1632 _objects[i].load()->print_status();
1965 } 1633 }
1966 } 1634 }
1967 -
1968 EKF2::unlock_module(); 1635 EKF2::unlock_module();
1969 -
1970 } else { 1636 } else {
1971 PX4_WARN("module locked, try again later"); 1637 PX4_WARN("module locked, try again later");
1972 } 1638 }
1973 -
1974 return 0; 1639 return 0;
1975 -
1976 } else if (strcmp(argv[1], "stop") == 0) { 1640 } else if (strcmp(argv[1], "stop") == 0) {
1977 EKF2::lock_module(); 1641 EKF2::lock_module();
1978 -
1979 if (argc > 2) { 1642 if (argc > 2) {
1980 int instance = atoi(argv[2]); 1643 int instance = atoi(argv[2]);
1981 -
1982 if (instance >= 0 && instance < EKF2_MAX_INSTANCES) { 1644 if (instance >= 0 && instance < EKF2_MAX_INSTANCES) {
1983 PX4_INFO("stopping instance %d", instance); 1645 PX4_INFO("stopping instance %d", instance);
1984 EKF2 *inst = _objects[instance].load(); 1646 EKF2 *inst = _objects[instance].load();
1985 -
1986 if (inst) { 1647 if (inst) {
1987 inst->request_stop(); 1648 inst->request_stop();
1988 px4_usleep(20000); // 20 ms 1649 px4_usleep(20000); // 20 ms
...@@ -1992,11 +1653,9 @@ extern "C" __EXPORT int ekf2_main(int argc, char *argv[]) ...@@ -1992,11 +1653,9 @@ extern "C" __EXPORT int ekf2_main(int argc, char *argv[])
1992 } else { 1653 } else {
1993 PX4_ERR("invalid instance %d", instance); 1654 PX4_ERR("invalid instance %d", instance);
1994 } 1655 }
1995 -
1996 } else { 1656 } else {
1997 // otherwise stop everything 1657 // otherwise stop everything
1998 bool was_running = false; 1658 bool was_running = false;
1999 -
2000 #if !defined(CONSTRAINED_FLASH) 1659 #if !defined(CONSTRAINED_FLASH)
2001 if (_ekf2_selector.load()) { 1660 if (_ekf2_selector.load()) {
2002 PX4_INFO("stopping ekf2 selector"); 1661 PX4_INFO("stopping ekf2 selector");
...@@ -2006,10 +1665,8 @@ extern "C" __EXPORT int ekf2_main(int argc, char *argv[]) ...@@ -2006,10 +1665,8 @@ extern "C" __EXPORT int ekf2_main(int argc, char *argv[])
2006 was_running = true; 1665 was_running = true;
2007 } 1666 }
2008 #endif // !CONSTRAINED_FLASH 1667 #endif // !CONSTRAINED_FLASH
2009 -
2010 for (int i = 0; i < EKF2_MAX_INSTANCES; i++) { 1668 for (int i = 0; i < EKF2_MAX_INSTANCES; i++) {
2011 EKF2 *inst = _objects[i].load(); 1669 EKF2 *inst = _objects[i].load();
2012 -
2013 if (inst) { 1670 if (inst) {
2014 PX4_INFO("stopping ekf2 instance %d", i); 1671 PX4_INFO("stopping ekf2 instance %d", i);
2015 was_running = true; 1672 was_running = true;
...@@ -2019,19 +1676,15 @@ extern "C" __EXPORT int ekf2_main(int argc, char *argv[]) ...@@ -2019,19 +1676,15 @@ extern "C" __EXPORT int ekf2_main(int argc, char *argv[])
2019 _objects[i].store(nullptr); 1676 _objects[i].store(nullptr);
2020 } 1677 }
2021 } 1678 }
2022 -
2023 if (!was_running) { 1679 if (!was_running) {
2024 PX4_WARN("not running"); 1680 PX4_WARN("not running");
2025 } 1681 }
2026 } 1682 }
2027 -
2028 EKF2::unlock_module(); 1683 EKF2::unlock_module();
2029 return PX4_OK; 1684 return PX4_OK;
2030 } 1685 }
2031 -
2032 EKF2::lock_module(); // Lock here, as the method could access _object. 1686 EKF2::lock_module(); // Lock here, as the method could access _object.
2033 int ret = EKF2::custom_command(argc - 1, argv + 1); 1687 int ret = EKF2::custom_command(argc - 1, argv + 1);
2034 EKF2::unlock_module(); 1688 EKF2::unlock_module();
2035 -
2036 return ret; 1689 return ret;
2037 } 1690 }
......
...@@ -30,18 +30,14 @@ ...@@ -30,18 +30,14 @@
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 * 31 *
32 ****************************************************************************/ 32 ****************************************************************************/
33 -
34 /** 33 /**
35 * @file EKF2.cpp 34 * @file EKF2.cpp
36 * Implementation of the attitude and position estimator. 35 * Implementation of the attitude and position estimator.
37 * 36 *
38 * @author Roman Bapst 37 * @author Roman Bapst
39 */ 38 */
40 -
41 #pragma once 39 #pragma once
42 -
43 #include "EKF2Selector.hpp" 40 #include "EKF2Selector.hpp"
44 -
45 #include <float.h> 41 #include <float.h>
46 #include <dataman/dataman.h> 42 #include <dataman/dataman.h>
47 #include <containers/LockGuard.hpp> 43 #include <containers/LockGuard.hpp>
...@@ -89,44 +85,30 @@ ...@@ -89,44 +85,30 @@
89 #include <uORB/topics/vehicle_status.h> 85 #include <uORB/topics/vehicle_status.h>
90 #include <uORB/topics/wind.h> 86 #include <uORB/topics/wind.h>
91 #include <uORB/topics/yaw_estimator_status.h> 87 #include <uORB/topics/yaw_estimator_status.h>
92 -
93 #include "Utility/PreFlightChecker.hpp" 88 #include "Utility/PreFlightChecker.hpp"
94 -
95 extern pthread_mutex_t ekf2_module_mutex; 89 extern pthread_mutex_t ekf2_module_mutex;
96 -
97 class EKF2 final : public ModuleParams, public px4::ScheduledWorkItem 90 class EKF2 final : public ModuleParams, public px4::ScheduledWorkItem
98 { 91 {
99 public: 92 public:
100 EKF2() = delete; 93 EKF2() = delete;
101 EKF2(bool multi_mode, const px4::wq_config_t &config, bool replay_mode); 94 EKF2(bool multi_mode, const px4::wq_config_t &config, bool replay_mode);
102 ~EKF2() override; 95 ~EKF2() override;
103 -
104 /** @see ModuleBase */ 96 /** @see ModuleBase */
105 static int task_spawn(int argc, char *argv[]); 97 static int task_spawn(int argc, char *argv[]);
106 -
107 /** @see ModuleBase */ 98 /** @see ModuleBase */
108 static int custom_command(int argc, char *argv[]); 99 static int custom_command(int argc, char *argv[]);
109 -
110 /** @see ModuleBase */ 100 /** @see ModuleBase */
111 static int print_usage(const char *reason = nullptr); 101 static int print_usage(const char *reason = nullptr);
112 -
113 int print_status(); 102 int print_status();
114 -
115 bool should_exit() const { return _task_should_exit.load(); } 103 bool should_exit() const { return _task_should_exit.load(); }
116 -
117 void request_stop() { _task_should_exit.store(true); } 104 void request_stop() { _task_should_exit.store(true); }
118 -
119 static void lock_module() { pthread_mutex_lock(&ekf2_module_mutex); } 105 static void lock_module() { pthread_mutex_lock(&ekf2_module_mutex); }
120 static bool trylock_module() { return (pthread_mutex_trylock(&ekf2_module_mutex) == 0); } 106 static bool trylock_module() { return (pthread_mutex_trylock(&ekf2_module_mutex) == 0); }
121 static void unlock_module() { pthread_mutex_unlock(&ekf2_module_mutex); } 107 static void unlock_module() { pthread_mutex_unlock(&ekf2_module_mutex); }
122 -
123 bool multi_init(int imu, int mag); 108 bool multi_init(int imu, int mag);
124 -
125 int instance() const { return _instance; } 109 int instance() const { return _instance; }
126 -
127 private: 110 private:
128 void Run() override; 111 void Run() override;
129 -
130 void PublishAttitude(const hrt_abstime &timestamp); 112 void PublishAttitude(const hrt_abstime &timestamp);
131 void PublishEkfDriftMetrics(const hrt_abstime &timestamp); 113 void PublishEkfDriftMetrics(const hrt_abstime &timestamp);
132 void PublishEventFlags(const hrt_abstime &timestamp); 114 void PublishEventFlags(const hrt_abstime &timestamp);
...@@ -144,7 +126,6 @@ private: ...@@ -144,7 +126,6 @@ private:
144 void PublishStatusFlags(const hrt_abstime &timestamp); 126 void PublishStatusFlags(const hrt_abstime &timestamp);
145 void PublishWindEstimate(const hrt_abstime &timestamp); 127 void PublishWindEstimate(const hrt_abstime &timestamp);
146 void PublishYawEstimatorStatus(const hrt_abstime &timestamp); 128 void PublishYawEstimatorStatus(const hrt_abstime &timestamp);
147 -
148 void UpdateAirspeedSample(ekf2_timestamps_s &ekf2_timestamps); 129 void UpdateAirspeedSample(ekf2_timestamps_s &ekf2_timestamps);
149 void UpdateAuxVelSample(ekf2_timestamps_s &ekf2_timestamps); 130 void UpdateAuxVelSample(ekf2_timestamps_s &ekf2_timestamps);
150 void UpdateBaroSample(ekf2_timestamps_s &ekf2_timestamps); 131 void UpdateBaroSample(ekf2_timestamps_s &ekf2_timestamps);
...@@ -153,12 +134,12 @@ private: ...@@ -153,12 +134,12 @@ private:
153 void UpdateGpsSample(ekf2_timestamps_s &ekf2_timestamps); 134 void UpdateGpsSample(ekf2_timestamps_s &ekf2_timestamps);
154 void UpdateMagSample(ekf2_timestamps_s &ekf2_timestamps); 135 void UpdateMagSample(ekf2_timestamps_s &ekf2_timestamps);
155 void UpdateRangeSample(ekf2_timestamps_s &ekf2_timestamps); 136 void UpdateRangeSample(ekf2_timestamps_s &ekf2_timestamps);
156 -
157 void UpdateMagCalibration(const hrt_abstime &timestamp); 137 void UpdateMagCalibration(const hrt_abstime &timestamp);
158 void print_target_gps(); 138 void print_target_gps();
159 void print_current_gps(gps_message gps_msg); 139 void print_current_gps(gps_message gps_msg);
160 void calculate_inclination_target(); 140 void calculate_inclination_target();
161 - void calculate_inclination_current(gps_message gps_msg); 141 + double calculate_inclination_current(gps_message gps_msg);
142 + void check_inclination(double check);
162 double* inclination=nullptr; 143 double* inclination=nullptr;
163 int32_t target_lat,target_lon,target_alt; 144 int32_t target_lat,target_lon,target_alt;
164 mission_s mission; 145 mission_s mission;
...@@ -166,60 +147,44 @@ private: ...@@ -166,60 +147,44 @@ private:
166 * Calculate filtered WGS84 height from estimated AMSL height 147 * Calculate filtered WGS84 height from estimated AMSL height
167 */ 148 */
168 float filter_altitude_ellipsoid(float amsl_hgt); 149 float filter_altitude_ellipsoid(float amsl_hgt);
169 -
170 static constexpr float sq(float x) { return x * x; }; 150 static constexpr float sq(float x) { return x * x; };
171 const bool _replay_mode{false}; ///< true when we use replay data from a log 151 const bool _replay_mode{false}; ///< true when we use replay data from a log
172 const bool _multi_mode; 152 const bool _multi_mode;
173 int _instance{0}; 153 int _instance{0};
174 -
175 px4::atomic_bool _task_should_exit{false}; 154 px4::atomic_bool _task_should_exit{false};
176 -
177 // time slip monitoring 155 // time slip monitoring
178 uint64_t _integrated_time_us = 0; ///< integral of gyro delta time from start (uSec) 156 uint64_t _integrated_time_us = 0; ///< integral of gyro delta time from start (uSec)
179 uint64_t _start_time_us = 0; ///< system time at EKF start (uSec) 157 uint64_t _start_time_us = 0; ///< system time at EKF start (uSec)
180 int64_t _last_time_slip_us = 0; ///< Last time slip (uSec) 158 int64_t _last_time_slip_us = 0; ///< Last time slip (uSec)
181 -
182 perf_counter_t _ecl_ekf_update_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": ECL update")}; 159 perf_counter_t _ecl_ekf_update_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": ECL update")};
183 perf_counter_t _ecl_ekf_update_full_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": ECL full update")}; 160 perf_counter_t _ecl_ekf_update_full_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": ECL full update")};
184 perf_counter_t _imu_missed_perf{perf_alloc(PC_COUNT, MODULE_NAME": IMU message missed")}; 161 perf_counter_t _imu_missed_perf{perf_alloc(PC_COUNT, MODULE_NAME": IMU message missed")};
185 perf_counter_t _mag_missed_perf{perf_alloc(PC_COUNT, MODULE_NAME": mag message missed")}; 162 perf_counter_t _mag_missed_perf{perf_alloc(PC_COUNT, MODULE_NAME": mag message missed")};
186 -
187 // Used to check, save and use learned magnetometer biases 163 // Used to check, save and use learned magnetometer biases
188 hrt_abstime _mag_cal_last_us{0}; ///< last time the EKF was operating a mode that estimates magnetomer biases (uSec) 164 hrt_abstime _mag_cal_last_us{0}; ///< last time the EKF was operating a mode that estimates magnetomer biases (uSec)
189 hrt_abstime _mag_cal_total_time_us{0}; ///< accumulated calibration time since the last save 165 hrt_abstime _mag_cal_total_time_us{0}; ///< accumulated calibration time since the last save
190 -
191 Vector3f _mag_cal_last_bias{}; ///< last valid XYZ magnetometer bias estimates (Gauss) 166 Vector3f _mag_cal_last_bias{}; ///< last valid XYZ magnetometer bias estimates (Gauss)
192 Vector3f _mag_cal_last_bias_variance{}; ///< variances for the last valid magnetometer XYZ bias estimates (Gauss**2) 167 Vector3f _mag_cal_last_bias_variance{}; ///< variances for the last valid magnetometer XYZ bias estimates (Gauss**2)
193 bool _mag_cal_available{false}; ///< true when an unsaved valid calibration for the XYZ magnetometer bias is available 168 bool _mag_cal_available{false}; ///< true when an unsaved valid calibration for the XYZ magnetometer bias is available
194 -
195 // Used to control saving of mag declination to be used on next startup 169 // Used to control saving of mag declination to be used on next startup
196 bool _mag_decl_saved = false; ///< true when the magnetic declination has been saved 170 bool _mag_decl_saved = false; ///< true when the magnetic declination has been saved
197 -
198 bool _had_valid_terrain{false}; ///< true if at any time there was a valid terrain estimate 171 bool _had_valid_terrain{false}; ///< true if at any time there was a valid terrain estimate
199 -
200 uint64_t _gps_time_usec{0}; 172 uint64_t _gps_time_usec{0};
201 int32_t _gps_alttitude_ellipsoid{0}; ///< altitude in 1E-3 meters (millimeters) above ellipsoid 173 int32_t _gps_alttitude_ellipsoid{0}; ///< altitude in 1E-3 meters (millimeters) above ellipsoid
202 uint64_t _gps_alttitude_ellipsoid_previous_timestamp{0}; ///< storage for previous timestamp to compute dt 174 uint64_t _gps_alttitude_ellipsoid_previous_timestamp{0}; ///< storage for previous timestamp to compute dt
203 float _wgs84_hgt_offset = 0; ///< height offset between AMSL and WGS84 175 float _wgs84_hgt_offset = 0; ///< height offset between AMSL and WGS84
204 -
205 uint8_t _imu_calibration_count{0}; 176 uint8_t _imu_calibration_count{0};
206 uint8_t _mag_calibration_count{0}; 177 uint8_t _mag_calibration_count{0};
207 -
208 uint32_t _device_id_accel{0}; 178 uint32_t _device_id_accel{0};
209 uint32_t _device_id_baro{0}; 179 uint32_t _device_id_baro{0};
210 uint32_t _device_id_gyro{0}; 180 uint32_t _device_id_gyro{0};
211 uint32_t _device_id_mag{0}; 181 uint32_t _device_id_mag{0};
212 -
213 Vector3f _last_local_position_for_gpos{}; 182 Vector3f _last_local_position_for_gpos{};
214 -
215 Vector3f _last_accel_bias_published{}; 183 Vector3f _last_accel_bias_published{};
216 Vector3f _last_gyro_bias_published{}; 184 Vector3f _last_gyro_bias_published{};
217 Vector3f _last_mag_bias_published{}; 185 Vector3f _last_mag_bias_published{};
218 -
219 float _airspeed_scale_factor{1.0f}; ///< scale factor correction applied to airspeed measurements 186 float _airspeed_scale_factor{1.0f}; ///< scale factor correction applied to airspeed measurements
220 -
221 uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s}; 187 uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s};
222 -
223 uORB::Subscription _airdata_sub{ORB_ID(vehicle_air_data)}; 188 uORB::Subscription _airdata_sub{ORB_ID(vehicle_air_data)};
224 uORB::Subscription _airspeed_sub{ORB_ID(airspeed)}; 189 uORB::Subscription _airspeed_sub{ORB_ID(airspeed)};
225 uORB::Subscription _distance_sensor_sub{ORB_ID(distance_sensor)}; 190 uORB::Subscription _distance_sensor_sub{ORB_ID(distance_sensor)};
...@@ -232,29 +197,22 @@ private: ...@@ -232,29 +197,22 @@ private:
232 uORB::Subscription _vehicle_command_sub{ORB_ID(vehicle_command)}; 197 uORB::Subscription _vehicle_command_sub{ORB_ID(vehicle_command)};
233 uORB::Subscription _vehicle_gps_position_sub{ORB_ID(vehicle_gps_position)}; 198 uORB::Subscription _vehicle_gps_position_sub{ORB_ID(vehicle_gps_position)};
234 uORB::Subscription _vehicle_land_detected_sub{ORB_ID(vehicle_land_detected)}; 199 uORB::Subscription _vehicle_land_detected_sub{ORB_ID(vehicle_land_detected)};
235 -
236 uORB::SubscriptionCallbackWorkItem _sensor_combined_sub{this, ORB_ID(sensor_combined)}; 200 uORB::SubscriptionCallbackWorkItem _sensor_combined_sub{this, ORB_ID(sensor_combined)};
237 uORB::SubscriptionCallbackWorkItem _vehicle_imu_sub{this, ORB_ID(vehicle_imu)}; 201 uORB::SubscriptionCallbackWorkItem _vehicle_imu_sub{this, ORB_ID(vehicle_imu)};
238 -
239 bool _callback_registered{false}; 202 bool _callback_registered{false};
240 -
241 bool _distance_sensor_selected{false}; // because we can have several distance sensor instances with different orientations 203 bool _distance_sensor_selected{false}; // because we can have several distance sensor instances with different orientations
242 bool _armed{false}; 204 bool _armed{false};
243 bool _standby{false}; // standby arming state 205 bool _standby{false}; // standby arming state
244 -
245 hrt_abstime _last_status_flag_update{0}; 206 hrt_abstime _last_status_flag_update{0};
246 hrt_abstime _last_range_sensor_update{0}; 207 hrt_abstime _last_range_sensor_update{0};
247 -
248 uint32_t _filter_control_status{0}; 208 uint32_t _filter_control_status{0};
249 uint32_t _filter_fault_status{0}; 209 uint32_t _filter_fault_status{0};
250 uint32_t _innov_check_fail_status{0}; 210 uint32_t _innov_check_fail_status{0};
251 -
252 uint32_t _filter_control_status_changes{0}; 211 uint32_t _filter_control_status_changes{0};
253 uint32_t _filter_fault_status_changes{0}; 212 uint32_t _filter_fault_status_changes{0};
254 uint32_t _innov_check_fail_status_changes{0}; 213 uint32_t _innov_check_fail_status_changes{0};
255 uint32_t _filter_warning_event_changes{0}; 214 uint32_t _filter_warning_event_changes{0};
256 uint32_t _filter_information_event_changes{0}; 215 uint32_t _filter_information_event_changes{0};
257 -
258 uORB::PublicationMulti<ekf2_timestamps_s> _ekf2_timestamps_pub{ORB_ID(ekf2_timestamps)}; 216 uORB::PublicationMulti<ekf2_timestamps_s> _ekf2_timestamps_pub{ORB_ID(ekf2_timestamps)};
259 uORB::PublicationMulti<ekf_gps_drift_s> _ekf_gps_drift_pub{ORB_ID(ekf_gps_drift)}; 217 uORB::PublicationMulti<ekf_gps_drift_s> _ekf_gps_drift_pub{ORB_ID(ekf_gps_drift)};
260 uORB::PublicationMulti<estimator_innovations_s> _estimator_innovation_test_ratios_pub{ORB_ID(estimator_innovation_test_ratios)}; 218 uORB::PublicationMulti<estimator_innovations_s> _estimator_innovation_test_ratios_pub{ORB_ID(estimator_innovation_test_ratios)};
...@@ -268,21 +226,15 @@ private: ...@@ -268,21 +226,15 @@ private:
268 uORB::PublicationMulti<estimator_event_flags_s> _estimator_event_flags_pub{ORB_ID(estimator_event_flags)}; 226 uORB::PublicationMulti<estimator_event_flags_s> _estimator_event_flags_pub{ORB_ID(estimator_event_flags)};
269 uORB::PublicationMulti<vehicle_odometry_s> _estimator_visual_odometry_aligned_pub{ORB_ID(estimator_visual_odometry_aligned)}; 227 uORB::PublicationMulti<vehicle_odometry_s> _estimator_visual_odometry_aligned_pub{ORB_ID(estimator_visual_odometry_aligned)};
270 uORB::PublicationMulti<yaw_estimator_status_s> _yaw_est_pub{ORB_ID(yaw_estimator_status)}; 228 uORB::PublicationMulti<yaw_estimator_status_s> _yaw_est_pub{ORB_ID(yaw_estimator_status)};
271 -
272 // publications with topic dependent on multi-mode 229 // publications with topic dependent on multi-mode
273 uORB::PublicationMulti<vehicle_attitude_s> _attitude_pub; 230 uORB::PublicationMulti<vehicle_attitude_s> _attitude_pub;
274 uORB::PublicationMulti<vehicle_local_position_s> _local_position_pub; 231 uORB::PublicationMulti<vehicle_local_position_s> _local_position_pub;
275 uORB::PublicationMulti<vehicle_global_position_s> _global_position_pub; 232 uORB::PublicationMulti<vehicle_global_position_s> _global_position_pub;
276 uORB::PublicationMulti<vehicle_odometry_s> _odometry_pub; 233 uORB::PublicationMulti<vehicle_odometry_s> _odometry_pub;
277 uORB::PublicationMulti<wind_s> _wind_pub; 234 uORB::PublicationMulti<wind_s> _wind_pub;
278 -
279 -
280 PreFlightChecker _preflt_checker; 235 PreFlightChecker _preflt_checker;
281 -
282 Ekf _ekf; 236 Ekf _ekf;
283 -
284 parameters *_params; ///< pointer to ekf parameter struct (located in _ekf class instance) 237 parameters *_params; ///< pointer to ekf parameter struct (located in _ekf class instance)
285 -
286 DEFINE_PARAMETERS( 238 DEFINE_PARAMETERS(
287 (ParamExtInt<px4::params::EKF2_MIN_OBS_DT>) 239 (ParamExtInt<px4::params::EKF2_MIN_OBS_DT>)
288 _param_ekf2_min_obs_dt, ///< Maximum time delay of any sensor used to increase buffer length to handle large timing jitter (mSec) 240 _param_ekf2_min_obs_dt, ///< Maximum time delay of any sensor used to increase buffer length to handle large timing jitter (mSec)
...@@ -302,12 +254,10 @@ private: ...@@ -302,12 +254,10 @@ private:
302 _param_ekf2_ev_delay, ///< off-board vision measurement delay relative to the IMU (mSec) 254 _param_ekf2_ev_delay, ///< off-board vision measurement delay relative to the IMU (mSec)
303 (ParamExtFloat<px4::params::EKF2_AVEL_DELAY>) 255 (ParamExtFloat<px4::params::EKF2_AVEL_DELAY>)
304 _param_ekf2_avel_delay, ///< auxillary velocity measurement delay relative to the IMU (mSec) 256 _param_ekf2_avel_delay, ///< auxillary velocity measurement delay relative to the IMU (mSec)
305 -
306 (ParamExtFloat<px4::params::EKF2_GYR_NOISE>) 257 (ParamExtFloat<px4::params::EKF2_GYR_NOISE>)
307 _param_ekf2_gyr_noise, ///< IMU angular rate noise used for covariance prediction (rad/sec) 258 _param_ekf2_gyr_noise, ///< IMU angular rate noise used for covariance prediction (rad/sec)
308 (ParamExtFloat<px4::params::EKF2_ACC_NOISE>) 259 (ParamExtFloat<px4::params::EKF2_ACC_NOISE>)
309 _param_ekf2_acc_noise, ///< IMU acceleration noise use for covariance prediction (m/sec**2) 260 _param_ekf2_acc_noise, ///< IMU acceleration noise use for covariance prediction (m/sec**2)
310 -
311 // process noise 261 // process noise
312 (ParamExtFloat<px4::params::EKF2_GYR_B_NOISE>) 262 (ParamExtFloat<px4::params::EKF2_GYR_B_NOISE>)
313 _param_ekf2_gyr_b_noise, ///< process noise for IMU rate gyro bias prediction (rad/sec**2) 263 _param_ekf2_gyr_b_noise, ///< process noise for IMU rate gyro bias prediction (rad/sec**2)
...@@ -322,7 +272,6 @@ private: ...@@ -322,7 +272,6 @@ private:
322 (ParamExtFloat<px4::params::EKF2_TERR_NOISE>) _param_ekf2_terr_noise, ///< process noise for terrain offset (m/sec) 272 (ParamExtFloat<px4::params::EKF2_TERR_NOISE>) _param_ekf2_terr_noise, ///< process noise for terrain offset (m/sec)
323 (ParamExtFloat<px4::params::EKF2_TERR_GRAD>) 273 (ParamExtFloat<px4::params::EKF2_TERR_GRAD>)
324 _param_ekf2_terr_grad, ///< gradient of terrain used to estimate process noise due to changing position (m/m) 274 _param_ekf2_terr_grad, ///< gradient of terrain used to estimate process noise due to changing position (m/m)
325 -
326 (ParamExtFloat<px4::params::EKF2_GPS_V_NOISE>) 275 (ParamExtFloat<px4::params::EKF2_GPS_V_NOISE>)
327 _param_ekf2_gps_v_noise, ///< minimum allowed observation noise for gps velocity fusion (m/sec) 276 _param_ekf2_gps_v_noise, ///< minimum allowed observation noise for gps velocity fusion (m/sec)
328 (ParamExtFloat<px4::params::EKF2_GPS_P_NOISE>) 277 (ParamExtFloat<px4::params::EKF2_GPS_P_NOISE>)
...@@ -343,7 +292,6 @@ private: ...@@ -343,7 +292,6 @@ private:
343 _param_ekf2_gps_v_gate, ///< GPS velocity innovation consistency gate size (STD) 292 _param_ekf2_gps_v_gate, ///< GPS velocity innovation consistency gate size (STD)
344 (ParamExtFloat<px4::params::EKF2_TAS_GATE>) 293 (ParamExtFloat<px4::params::EKF2_TAS_GATE>)
345 _param_ekf2_tas_gate, ///< True Airspeed innovation consistency gate size (STD) 294 _param_ekf2_tas_gate, ///< True Airspeed innovation consistency gate size (STD)
346 -
347 // control of magnetometer fusion 295 // control of magnetometer fusion
348 (ParamExtFloat<px4::params::EKF2_HEAD_NOISE>) 296 (ParamExtFloat<px4::params::EKF2_HEAD_NOISE>)
349 _param_ekf2_head_noise, ///< measurement noise used for simple heading fusion (rad) 297 _param_ekf2_head_noise, ///< measurement noise used for simple heading fusion (rad)
...@@ -367,7 +315,6 @@ private: ...@@ -367,7 +315,6 @@ private:
367 _param_ekf2_mag_acclim, ///< integer used to specify the type of magnetometer fusion used 315 _param_ekf2_mag_acclim, ///< integer used to specify the type of magnetometer fusion used
368 (ParamExtFloat<px4::params::EKF2_MAG_YAWLIM>) 316 (ParamExtFloat<px4::params::EKF2_MAG_YAWLIM>)
369 _param_ekf2_mag_yawlim, ///< yaw rate threshold used by mode select logic (rad/sec) 317 _param_ekf2_mag_yawlim, ///< yaw rate threshold used by mode select logic (rad/sec)
370 -
371 (ParamExtInt<px4::params::EKF2_GPS_CHECK>) 318 (ParamExtInt<px4::params::EKF2_GPS_CHECK>)
372 _param_ekf2_gps_check, ///< bitmask used to control which GPS quality checks are used 319 _param_ekf2_gps_check, ///< bitmask used to control which GPS quality checks are used
373 (ParamExtFloat<px4::params::EKF2_REQ_EPH>) _param_ekf2_req_eph, ///< maximum acceptable horiz position error (m) 320 (ParamExtFloat<px4::params::EKF2_REQ_EPH>) _param_ekf2_req_eph, ///< maximum acceptable horiz position error (m)
...@@ -379,7 +326,6 @@ private: ...@@ -379,7 +326,6 @@ private:
379 (ParamExtFloat<px4::params::EKF2_REQ_HDRIFT>) 326 (ParamExtFloat<px4::params::EKF2_REQ_HDRIFT>)
380 _param_ekf2_req_hdrift, ///< maximum acceptable horizontal drift speed (m/s) 327 _param_ekf2_req_hdrift, ///< maximum acceptable horizontal drift speed (m/s)
381 (ParamExtFloat<px4::params::EKF2_REQ_VDRIFT>) _param_ekf2_req_vdrift, ///< maximum acceptable vertical drift speed (m/s) 328 (ParamExtFloat<px4::params::EKF2_REQ_VDRIFT>) _param_ekf2_req_vdrift, ///< maximum acceptable vertical drift speed (m/s)
382 -
383 // measurement source control 329 // measurement source control
384 (ParamExtInt<px4::params::EKF2_AID_MASK>) 330 (ParamExtInt<px4::params::EKF2_AID_MASK>)
385 _param_ekf2_aid_mask, ///< bitmasked integer that selects which of the GPS and optical flow aiding sources will be used 331 _param_ekf2_aid_mask, ///< bitmasked integer that selects which of the GPS and optical flow aiding sources will be used
...@@ -388,7 +334,6 @@ private: ...@@ -388,7 +334,6 @@ private:
388 _param_ekf2_terr_mask, ///< bitmasked integer that selects which of range finder and optical flow aiding sources will be used for terrain estimation 334 _param_ekf2_terr_mask, ///< bitmasked integer that selects which of range finder and optical flow aiding sources will be used for terrain estimation
389 (ParamExtInt<px4::params::EKF2_NOAID_TOUT>) 335 (ParamExtInt<px4::params::EKF2_NOAID_TOUT>)
390 _param_ekf2_noaid_tout, ///< maximum lapsed time from last fusion of measurements that constrain drift before the EKF will report the horizontal nav solution invalid (uSec) 336 _param_ekf2_noaid_tout, ///< maximum lapsed time from last fusion of measurements that constrain drift before the EKF will report the horizontal nav solution invalid (uSec)
391 -
392 // range finder fusion 337 // range finder fusion
393 (ParamExtFloat<px4::params::EKF2_RNG_NOISE>) 338 (ParamExtFloat<px4::params::EKF2_RNG_NOISE>)
394 _param_ekf2_rng_noise, ///< observation noise for range finder measurements (m) 339 _param_ekf2_rng_noise, ///< observation noise for range finder measurements (m)
...@@ -407,7 +352,6 @@ private: ...@@ -407,7 +352,6 @@ private:
407 _param_ekf2_rng_a_igate, ///< gate size used for innovation consistency checks for range aid fusion (STD) 352 _param_ekf2_rng_a_igate, ///< gate size used for innovation consistency checks for range aid fusion (STD)
408 (ParamExtFloat<px4::params::EKF2_RNG_QLTY_T>) 353 (ParamExtFloat<px4::params::EKF2_RNG_QLTY_T>)
409 _param_ekf2_rng_qlty_t, ///< Minimum duration during which the reported range finder signal quality needs to be non-zero in order to be declared valid (s) 354 _param_ekf2_rng_qlty_t, ///< Minimum duration during which the reported range finder signal quality needs to be non-zero in order to be declared valid (s)
410 -
411 // vision estimate fusion 355 // vision estimate fusion
412 (ParamInt<px4::params::EKF2_EV_NOISE_MD>) 356 (ParamInt<px4::params::EKF2_EV_NOISE_MD>)
413 _param_ekf2_ev_noise_md, ///< determine source of vision observation noise 357 _param_ekf2_ev_noise_md, ///< determine source of vision observation noise
...@@ -421,7 +365,6 @@ private: ...@@ -421,7 +365,6 @@ private:
421 _param_ekf2_evv_gate, ///< external vision velocity innovation consistency gate size (STD) 365 _param_ekf2_evv_gate, ///< external vision velocity innovation consistency gate size (STD)
422 (ParamExtFloat<px4::params::EKF2_EVP_GATE>) 366 (ParamExtFloat<px4::params::EKF2_EVP_GATE>)
423 _param_ekf2_evp_gate, ///< external vision position innovation consistency gate size (STD) 367 _param_ekf2_evp_gate, ///< external vision position innovation consistency gate size (STD)
424 -
425 // optical flow fusion 368 // optical flow fusion
426 (ParamExtFloat<px4::params::EKF2_OF_N_MIN>) 369 (ParamExtFloat<px4::params::EKF2_OF_N_MIN>)
427 _param_ekf2_of_n_min, ///< best quality observation noise for optical flow LOS rate measurements (rad/sec) 370 _param_ekf2_of_n_min, ///< best quality observation noise for optical flow LOS rate measurements (rad/sec)
...@@ -431,7 +374,6 @@ private: ...@@ -431,7 +374,6 @@ private:
431 _param_ekf2_of_qmin, ///< minimum acceptable quality integer from the flow sensor 374 _param_ekf2_of_qmin, ///< minimum acceptable quality integer from the flow sensor
432 (ParamExtFloat<px4::params::EKF2_OF_GATE>) 375 (ParamExtFloat<px4::params::EKF2_OF_GATE>)
433 _param_ekf2_of_gate, ///< optical flow fusion innovation consistency gate size (STD) 376 _param_ekf2_of_gate, ///< optical flow fusion innovation consistency gate size (STD)
434 -
435 // sensor positions in body frame 377 // sensor positions in body frame
436 (ParamExtFloat<px4::params::EKF2_IMU_POS_X>) _param_ekf2_imu_pos_x, ///< X position of IMU in body frame (m) 378 (ParamExtFloat<px4::params::EKF2_IMU_POS_X>) _param_ekf2_imu_pos_x, ///< X position of IMU in body frame (m)
437 (ParamExtFloat<px4::params::EKF2_IMU_POS_Y>) _param_ekf2_imu_pos_y, ///< Y position of IMU in body frame (m) 379 (ParamExtFloat<px4::params::EKF2_IMU_POS_Y>) _param_ekf2_imu_pos_y, ///< Y position of IMU in body frame (m)
...@@ -454,19 +396,16 @@ private: ...@@ -454,19 +396,16 @@ private:
454 _param_ekf2_ev_pos_y, ///< Y position of VI sensor focal point in body frame (m) 396 _param_ekf2_ev_pos_y, ///< Y position of VI sensor focal point in body frame (m)
455 (ParamExtFloat<px4::params::EKF2_EV_POS_Z>) 397 (ParamExtFloat<px4::params::EKF2_EV_POS_Z>)
456 _param_ekf2_ev_pos_z, ///< Z position of VI sensor focal point in body frame (m) 398 _param_ekf2_ev_pos_z, ///< Z position of VI sensor focal point in body frame (m)
457 -
458 // control of airspeed and sideslip fusion 399 // control of airspeed and sideslip fusion
459 (ParamFloat<px4::params::EKF2_ARSP_THR>) 400 (ParamFloat<px4::params::EKF2_ARSP_THR>)
460 _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) 401 _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)
461 (ParamInt<px4::params::EKF2_FUSE_BETA>) 402 (ParamInt<px4::params::EKF2_FUSE_BETA>)
462 _param_ekf2_fuse_beta, ///< Controls synthetic sideslip fusion, 0 disables, 1 enables 403 _param_ekf2_fuse_beta, ///< Controls synthetic sideslip fusion, 0 disables, 1 enables
463 -
464 // output predictor filter time constants 404 // output predictor filter time constants
465 (ParamExtFloat<px4::params::EKF2_TAU_VEL>) 405 (ParamExtFloat<px4::params::EKF2_TAU_VEL>)
466 _param_ekf2_tau_vel, ///< time constant used by the output velocity complementary filter (sec) 406 _param_ekf2_tau_vel, ///< time constant used by the output velocity complementary filter (sec)
467 (ParamExtFloat<px4::params::EKF2_TAU_POS>) 407 (ParamExtFloat<px4::params::EKF2_TAU_POS>)
468 _param_ekf2_tau_pos, ///< time constant used by the output position complementary filter (sec) 408 _param_ekf2_tau_pos, ///< time constant used by the output position complementary filter (sec)
469 -
470 // IMU switch on bias parameters 409 // IMU switch on bias parameters
471 (ParamExtFloat<px4::params::EKF2_GBIAS_INIT>) 410 (ParamExtFloat<px4::params::EKF2_GBIAS_INIT>)
472 _param_ekf2_gbias_init, ///< 1-sigma gyro bias uncertainty at switch on (rad/sec) 411 _param_ekf2_gbias_init, ///< 1-sigma gyro bias uncertainty at switch on (rad/sec)
...@@ -474,7 +413,6 @@ private: ...@@ -474,7 +413,6 @@ private:
474 _param_ekf2_abias_init, ///< 1-sigma accelerometer bias uncertainty at switch on (m/sec**2) 413 _param_ekf2_abias_init, ///< 1-sigma accelerometer bias uncertainty at switch on (m/sec**2)
475 (ParamExtFloat<px4::params::EKF2_ANGERR_INIT>) 414 (ParamExtFloat<px4::params::EKF2_ANGERR_INIT>)
476 _param_ekf2_angerr_init, ///< 1-sigma tilt error after initial alignment using gravity vector (rad) 415 _param_ekf2_angerr_init, ///< 1-sigma tilt error after initial alignment using gravity vector (rad)
477 -
478 // EKF accel bias learning control 416 // EKF accel bias learning control
479 (ParamExtFloat<px4::params::EKF2_ABL_LIM>) _param_ekf2_abl_lim, ///< Accelerometer bias learning limit (m/s**2) 417 (ParamExtFloat<px4::params::EKF2_ABL_LIM>) _param_ekf2_abl_lim, ///< Accelerometer bias learning limit (m/s**2)
480 (ParamExtFloat<px4::params::EKF2_ABL_ACCLIM>) 418 (ParamExtFloat<px4::params::EKF2_ABL_ACCLIM>)
...@@ -483,13 +421,11 @@ private: ...@@ -483,13 +421,11 @@ private:
483 _param_ekf2_abl_gyrlim, ///< Maximum IMU gyro angular rate magnitude that allows IMU bias learning (m/s**2) 421 _param_ekf2_abl_gyrlim, ///< Maximum IMU gyro angular rate magnitude that allows IMU bias learning (m/s**2)
484 (ParamExtFloat<px4::params::EKF2_ABL_TAU>) 422 (ParamExtFloat<px4::params::EKF2_ABL_TAU>)
485 _param_ekf2_abl_tau, ///< Time constant used to inhibit IMU delta velocity bias learning (sec) 423 _param_ekf2_abl_tau, ///< Time constant used to inhibit IMU delta velocity bias learning (sec)
486 -
487 // Multi-rotor drag specific force fusion 424 // Multi-rotor drag specific force fusion
488 (ParamExtFloat<px4::params::EKF2_DRAG_NOISE>) 425 (ParamExtFloat<px4::params::EKF2_DRAG_NOISE>)
489 _param_ekf2_drag_noise, ///< observation noise variance for drag specific force measurements (m/sec**2)**2 426 _param_ekf2_drag_noise, ///< observation noise variance for drag specific force measurements (m/sec**2)**2
490 (ParamExtFloat<px4::params::EKF2_BCOEF_X>) _param_ekf2_bcoef_x, ///< ballistic coefficient along the X-axis (kg/m**2) 427 (ParamExtFloat<px4::params::EKF2_BCOEF_X>) _param_ekf2_bcoef_x, ///< ballistic coefficient along the X-axis (kg/m**2)
491 (ParamExtFloat<px4::params::EKF2_BCOEF_Y>) _param_ekf2_bcoef_y, ///< ballistic coefficient along the Y-axis (kg/m**2) 428 (ParamExtFloat<px4::params::EKF2_BCOEF_Y>) _param_ekf2_bcoef_y, ///< ballistic coefficient along the Y-axis (kg/m**2)
492 -
493 // Corrections for static pressure position error where Ps_error = Ps_meas - Ps_truth 429 // Corrections for static pressure position error where Ps_error = Ps_meas - Ps_truth
494 // Coef = Ps_error / Pdynamic, where Pdynamic = 1/2 * density * TAS**2 430 // Coef = Ps_error / Pdynamic, where Pdynamic = 1/2 * density * TAS**2
495 (ParamExtFloat<px4::params::EKF2_ASPD_MAX>) 431 (ParamExtFloat<px4::params::EKF2_ASPD_MAX>)
...@@ -504,19 +440,15 @@ private: ...@@ -504,19 +440,15 @@ private:
504 _param_ekf2_pcoef_yn, ///< static pressure position error coefficient along the negative Y body axis 440 _param_ekf2_pcoef_yn, ///< static pressure position error coefficient along the negative Y body axis
505 (ParamExtFloat<px4::params::EKF2_PCOEF_Z>) 441 (ParamExtFloat<px4::params::EKF2_PCOEF_Z>)
506 _param_ekf2_pcoef_z, ///< static pressure position error coefficient along the Z body axis 442 _param_ekf2_pcoef_z, ///< static pressure position error coefficient along the Z body axis
507 -
508 // Test used to determine if the vehicle is static or moving 443 // Test used to determine if the vehicle is static or moving
509 (ParamExtFloat<px4::params::EKF2_MOVE_TEST>) 444 (ParamExtFloat<px4::params::EKF2_MOVE_TEST>)
510 _param_ekf2_move_test, ///< scaling applied to IMU data thresholds used to determine if the vehicle is static or moving. 445 _param_ekf2_move_test, ///< scaling applied to IMU data thresholds used to determine if the vehicle is static or moving.
511 -
512 (ParamFloat<px4::params::EKF2_REQ_GPS_H>) _param_ekf2_req_gps_h, ///< Required GPS health time 446 (ParamFloat<px4::params::EKF2_REQ_GPS_H>) _param_ekf2_req_gps_h, ///< Required GPS health time
513 (ParamExtInt<px4::params::EKF2_MAG_CHECK>) _param_ekf2_mag_check, ///< Mag field strength check 447 (ParamExtInt<px4::params::EKF2_MAG_CHECK>) _param_ekf2_mag_check, ///< Mag field strength check
514 (ParamExtInt<px4::params::EKF2_SYNT_MAG_Z>) 448 (ParamExtInt<px4::params::EKF2_SYNT_MAG_Z>)
515 _param_ekf2_synthetic_mag_z, ///< Enables the use of a synthetic value for the Z axis of the magnetometer calculated from the 3D magnetic field vector at the location of the drone. 449 _param_ekf2_synthetic_mag_z, ///< Enables the use of a synthetic value for the Z axis of the magnetometer calculated from the 3D magnetic field vector at the location of the drone.
516 -
517 // Used by EKF-GSF experimental yaw estimator 450 // Used by EKF-GSF experimental yaw estimator
518 (ParamExtFloat<px4::params::EKF2_GSF_TAS>) 451 (ParamExtFloat<px4::params::EKF2_GSF_TAS>)
519 _param_ekf2_gsf_tas_default ///< default value of true airspeed assumed during fixed wing operation 452 _param_ekf2_gsf_tas_default ///< default value of true airspeed assumed during fixed wing operation
520 -
521 ) 453 )
522 }; 454 };
......