47 #include <px4_platform_common/defines.h>    48 #include <px4_platform_common/module.h>    49 #include <px4_platform_common/module_params.h>    50 #include <px4_platform_common/posix.h>    51 #include <px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp>    52 #include <px4_platform_common/time.h>    84 #define BLEND_MASK_USE_SPD_ACC      1    85 #define BLEND_MASK_USE_HPOS_ACC     2    86 #define BLEND_MASK_USE_VPOS_ACC     4    89 #define GPS_MAX_RECEIVERS 2    90 #define GPS_BLENDED_INSTANCE 2    95 class Ekf2 final : 
public ModuleBase<Ekf2>, 
public ModuleParams, 
public px4::WorkItem
    98     explicit Ekf2(
bool replay_mode = 
false);
   102     static int task_spawn(
int argc, 
char *argv[]);
   105     static int custom_command(
int argc, 
char *argv[]);
   108     static int print_usage(
const char *reason = 
nullptr);
   117     int getRangeSubIndex(); 
   124     void resetPreFlightChecks();
   126     template<
typename Param>
   127     void update_mag_bias(Param &mag_bias_param, 
int axis_index);
   129     template<
typename Param>
   130     bool update_mag_decl(Param &mag_decl_param);
   133     bool publish_wind_estimate(
const hrt_abstime ×tamp);
   143     bool blend_gps_data();
   150     void update_gps_blend_states();
   157     void update_gps_offsets();
   162     void apply_gps_offsets();
   167     void calc_gps_blend_output();
   172     float filter_altitude_ellipsoid(
float amsl_hgt);
   177     uint64_t _integrated_time_us = 0;   
   178     uint64_t _start_time_us = 0;        
   179     int64_t _last_time_slip_us = 0;     
   184     uint8_t _invalid_mag_id_count = 0;  
   187     float _mag_data_sum[3] = {};            
   188     uint64_t _mag_time_sum_ms = 0;      
   189     uint8_t _mag_sample_count = 0;      
   190     int32_t _mag_time_ms_last_used = 0; 
   193     float _balt_data_sum = 0.0f;            
   194     uint64_t _balt_time_sum_ms = 0;     
   195     uint8_t _balt_sample_count = 0;     
   196     uint32_t _balt_time_ms_last_used =
   203     float _last_valid_mag_cal[3] = {};  
   204     bool _valid_cal_available[3] = {};  
   205     float _last_valid_variance[3] = {}; 
   208     bool _mag_decl_saved = 
false;   
   212     static constexpr 
float ep_max_std_dev = 100.0f; 
   213     static constexpr 
float eo_max_std_dev = 100.0f; 
   225     uint8_t _gps_best_index = 0;            
   226     uint8_t _gps_select_index = 0;          
   227     uint8_t _gps_time_ref_index =
   229     uint8_t _gps_oldest_index = 0;          
   230     uint8_t _gps_newest_index = 0;          
   231     uint8_t _gps_slowest_index = 0;         
   233     bool  _gps_new_output_data = 
false;     
   234     bool _had_valid_terrain = 
false;        
   238     float   _wgs84_hgt_offset = 0;  
   240     bool _imu_bias_reset_request{
false};
   243     bool new_ev_data_received = 
false;
   261     int _range_finder_sub_index = -1; 
   288         (ParamExtInt<px4::params::EKF2_MIN_OBS_DT>)
   289         _param_ekf2_min_obs_dt, 
   290         (ParamExtFloat<px4::params::EKF2_MAG_DELAY>)
   291         _param_ekf2_mag_delay,  
   292         (ParamExtFloat<px4::params::EKF2_BARO_DELAY>)
   293         _param_ekf2_baro_delay, 
   294         (ParamExtFloat<px4::params::EKF2_GPS_DELAY>)
   295         _param_ekf2_gps_delay,  
   296         (ParamExtFloat<px4::params::EKF2_OF_DELAY>)
   297         _param_ekf2_of_delay,   
   298         (ParamExtFloat<px4::params::EKF2_RNG_DELAY>)
   299         _param_ekf2_rng_delay,  
   300         (ParamExtFloat<px4::params::EKF2_ASP_DELAY>)
   301         _param_ekf2_asp_delay,  
   302         (ParamExtFloat<px4::params::EKF2_EV_DELAY>)
   303         _param_ekf2_ev_delay,   
   304         (ParamExtFloat<px4::params::EKF2_AVEL_DELAY>)
   305         _param_ekf2_avel_delay, 
   307         (ParamExtFloat<px4::params::EKF2_GYR_NOISE>)
   308         _param_ekf2_gyr_noise,  
   309         (ParamExtFloat<px4::params::EKF2_ACC_NOISE>)
   310         _param_ekf2_acc_noise,  
   313         (ParamExtFloat<px4::params::EKF2_GYR_B_NOISE>)
   314         _param_ekf2_gyr_b_noise,    
   315         (ParamExtFloat<px4::params::EKF2_ACC_B_NOISE>)
   316         _param_ekf2_acc_b_noise,
   317         (ParamExtFloat<px4::params::EKF2_MAG_E_NOISE>)
   318         _param_ekf2_mag_e_noise,    
   319         (ParamExtFloat<px4::params::EKF2_MAG_B_NOISE>)
   320         _param_ekf2_mag_b_noise,    
   321         (ParamExtFloat<px4::params::EKF2_WIND_NOISE>)
   322         _param_ekf2_wind_noise, 
   323         (ParamExtFloat<px4::params::EKF2_TERR_NOISE>) _param_ekf2_terr_noise,   
   324         (ParamExtFloat<px4::params::EKF2_TERR_GRAD>)
   325         _param_ekf2_terr_grad,  
   327         (ParamExtFloat<px4::params::EKF2_GPS_V_NOISE>)
   328         _param_ekf2_gps_v_noise,    
   329         (ParamExtFloat<px4::params::EKF2_GPS_P_NOISE>)
   330         _param_ekf2_gps_p_noise,    
   331         (ParamExtFloat<px4::params::EKF2_NOAID_NOISE>)
   332         _param_ekf2_noaid_noise,    
   333         (ParamExtFloat<px4::params::EKF2_BARO_NOISE>)
   334         _param_ekf2_baro_noise, 
   335         (ParamExtFloat<px4::params::EKF2_BARO_GATE>)
   336         _param_ekf2_baro_gate,  
   337         (ParamExtFloat<px4::params::EKF2_GND_EFF_DZ>)
   338         _param_ekf2_gnd_eff_dz, 
   339         (ParamExtFloat<px4::params::EKF2_GND_MAX_HGT>)
   340         _param_ekf2_gnd_max_hgt,    
   341         (ParamExtFloat<px4::params::EKF2_GPS_P_GATE>)
   342         _param_ekf2_gps_p_gate, 
   343         (ParamExtFloat<px4::params::EKF2_GPS_V_GATE>)
   344         _param_ekf2_gps_v_gate, 
   345         (ParamExtFloat<px4::params::EKF2_TAS_GATE>)
   346         _param_ekf2_tas_gate,   
   349         (ParamExtFloat<px4::params::EKF2_HEAD_NOISE>)
   350         _param_ekf2_head_noise, 
   351         (ParamExtFloat<px4::params::EKF2_MAG_NOISE>)
   352         _param_ekf2_mag_noise,      
   353         (ParamExtFloat<px4::params::EKF2_EAS_NOISE>)
   354         _param_ekf2_eas_noise,      
   355         (ParamExtFloat<px4::params::EKF2_BETA_GATE>)
   356         _param_ekf2_beta_gate, 
   357         (ParamExtFloat<px4::params::EKF2_BETA_NOISE>) _param_ekf2_beta_noise,   
   358         (ParamExtFloat<px4::params::EKF2_MAG_DECL>) _param_ekf2_mag_decl,
   359         (ParamExtFloat<px4::params::EKF2_HDG_GATE>)
   360         _param_ekf2_hdg_gate,
   361         (ParamExtFloat<px4::params::EKF2_MAG_GATE>)
   362         _param_ekf2_mag_gate,   
   363         (ParamExtInt<px4::params::EKF2_DECL_TYPE>)
   364         _param_ekf2_decl_type,  
   365         (ParamExtInt<px4::params::EKF2_MAG_TYPE>)
   366         _param_ekf2_mag_type,   
   367         (ParamExtFloat<px4::params::EKF2_MAG_ACCLIM>)
   368         _param_ekf2_mag_acclim, 
   369         (ParamExtFloat<px4::params::EKF2_MAG_YAWLIM>)
   370         _param_ekf2_mag_yawlim, 
   372         (ParamExtInt<px4::params::EKF2_GPS_CHECK>)
   373         _param_ekf2_gps_check,  
   374         (ParamExtFloat<px4::params::EKF2_REQ_EPH>) _param_ekf2_req_eph, 
   375         (ParamExtFloat<px4::params::EKF2_REQ_EPV>) _param_ekf2_req_epv, 
   376         (ParamExtFloat<px4::params::EKF2_REQ_SACC>) _param_ekf2_req_sacc,   
   377         (ParamExtInt<px4::params::EKF2_REQ_NSATS>) _param_ekf2_req_nsats,   
   378         (ParamExtFloat<px4::params::EKF2_REQ_PDOP>)
   379         _param_ekf2_req_pdop,   
   380         (ParamExtFloat<px4::params::EKF2_REQ_HDRIFT>)
   381         _param_ekf2_req_hdrift, 
   382         (ParamExtFloat<px4::params::EKF2_REQ_VDRIFT>) _param_ekf2_req_vdrift,   
   385         (ParamExtInt<px4::params::EKF2_AID_MASK>)
   386         _param_ekf2_aid_mask,       
   387         (ParamExtInt<px4::params::EKF2_HGT_MODE>) _param_ekf2_hgt_mode, 
   388         (ParamExtInt<px4::params::EKF2_NOAID_TOUT>)
   389         _param_ekf2_noaid_tout, 
   392         (ParamExtFloat<px4::params::EKF2_RNG_NOISE>)
   393         _param_ekf2_rng_noise,  
   394         (ParamExtFloat<px4::params::EKF2_RNG_SFE>) _param_ekf2_rng_sfe, 
   395         (ParamExtFloat<px4::params::EKF2_RNG_GATE>)
   396         _param_ekf2_rng_gate,   
   397         (ParamExtFloat<px4::params::EKF2_MIN_RNG>) _param_ekf2_min_rng, 
   398         (ParamExtFloat<px4::params::EKF2_RNG_PITCH>) _param_ekf2_rng_pitch, 
   399         (ParamExtInt<px4::params::EKF2_RNG_AID>)
   401         (ParamExtFloat<px4::params::EKF2_RNG_A_VMAX>)
   402         _param_ekf2_rng_a_vmax, 
   403         (ParamExtFloat<px4::params::EKF2_RNG_A_HMAX>)
   404         _param_ekf2_rng_a_hmax, 
   405         (ParamExtFloat<px4::params::EKF2_RNG_A_IGATE>)
   406         _param_ekf2_rng_a_igate,    
   409         (ParamInt<px4::params::EKF2_EV_NOISE_MD>)
   410         _param_ekf2_ev_noise_md,    
   411         (ParamFloat<px4::params::EKF2_EVP_NOISE>)
   412         _param_ekf2_evp_noise,  
   413         (ParamFloat<px4::params::EKF2_EVV_NOISE>)
   414         _param_ekf2_evv_noise,  
   415         (ParamFloat<px4::params::EKF2_EVA_NOISE>)
   416         _param_ekf2_eva_noise,  
   417         (ParamExtFloat<px4::params::EKF2_EVV_GATE>)
   418         _param_ekf2_evv_gate,   
   419         (ParamExtFloat<px4::params::EKF2_EVP_GATE>)
   420         _param_ekf2_evp_gate,   
   423         (ParamExtFloat<px4::params::EKF2_OF_N_MIN>)
   424         _param_ekf2_of_n_min,   
   425         (ParamExtFloat<px4::params::EKF2_OF_N_MAX>)
   426         _param_ekf2_of_n_max,   
   427         (ParamExtInt<px4::params::EKF2_OF_QMIN>)
   429         (ParamExtFloat<px4::params::EKF2_OF_GATE>)
   433         (ParamExtFloat<px4::params::EKF2_IMU_POS_X>) _param_ekf2_imu_pos_x,     
   434         (ParamExtFloat<px4::params::EKF2_IMU_POS_Y>) _param_ekf2_imu_pos_y,     
   435         (ParamExtFloat<px4::params::EKF2_IMU_POS_Z>) _param_ekf2_imu_pos_z,     
   436         (ParamExtFloat<px4::params::EKF2_GPS_POS_X>) _param_ekf2_gps_pos_x,     
   437         (ParamExtFloat<px4::params::EKF2_GPS_POS_Y>) _param_ekf2_gps_pos_y,     
   438         (ParamExtFloat<px4::params::EKF2_GPS_POS_Z>) _param_ekf2_gps_pos_z,     
   439         (ParamExtFloat<px4::params::EKF2_RNG_POS_X>) _param_ekf2_rng_pos_x,     
   440         (ParamExtFloat<px4::params::EKF2_RNG_POS_Y>) _param_ekf2_rng_pos_y,     
   441         (ParamExtFloat<px4::params::EKF2_RNG_POS_Z>) _param_ekf2_rng_pos_z,     
   442         (ParamExtFloat<px4::params::EKF2_OF_POS_X>)
   443         _param_ekf2_of_pos_x,   
   444         (ParamExtFloat<px4::params::EKF2_OF_POS_Y>)
   445         _param_ekf2_of_pos_y,   
   446         (ParamExtFloat<px4::params::EKF2_OF_POS_Z>)
   447         _param_ekf2_of_pos_z,   
   448         (ParamExtFloat<px4::params::EKF2_EV_POS_X>)
   449         _param_ekf2_ev_pos_x,       
   450         (ParamExtFloat<px4::params::EKF2_EV_POS_Y>)
   451         _param_ekf2_ev_pos_y,       
   452         (ParamExtFloat<px4::params::EKF2_EV_POS_Z>)
   453         _param_ekf2_ev_pos_z,       
   456         (ParamFloat<px4::params::EKF2_ARSP_THR>)
   457         _param_ekf2_arsp_thr,   
   458         (ParamInt<px4::params::EKF2_FUSE_BETA>)
   459         _param_ekf2_fuse_beta,      
   462         (ParamExtFloat<px4::params::EKF2_TAU_VEL>)
   464         (ParamExtFloat<px4::params::EKF2_TAU_POS>)
   468         (ParamExtFloat<px4::params::EKF2_GBIAS_INIT>)
   469         _param_ekf2_gbias_init, 
   470         (ParamExtFloat<px4::params::EKF2_ABIAS_INIT>)
   471         _param_ekf2_abias_init, 
   472         (ParamExtFloat<px4::params::EKF2_ANGERR_INIT>)
   473         _param_ekf2_angerr_init,    
   476         (ParamFloat<px4::params::EKF2_MAGBIAS_X>) _param_ekf2_magbias_x,        
   477         (ParamFloat<px4::params::EKF2_MAGBIAS_Y>) _param_ekf2_magbias_y,        
   478         (ParamFloat<px4::params::EKF2_MAGBIAS_Z>) _param_ekf2_magbias_z,        
   479         (ParamInt<px4::params::EKF2_MAGBIAS_ID>)
   480         _param_ekf2_magbias_id,     
   481         (ParamFloat<px4::params::EKF2_MAGB_VREF>)
   482         _param_ekf2_magb_vref, 
   483         (ParamFloat<px4::params::EKF2_MAGB_K>)
   487         (ParamExtFloat<px4::params::EKF2_ABL_LIM>) _param_ekf2_abl_lim, 
   488         (ParamExtFloat<px4::params::EKF2_ABL_ACCLIM>)
   489         _param_ekf2_abl_acclim, 
   490         (ParamExtFloat<px4::params::EKF2_ABL_GYRLIM>)
   491         _param_ekf2_abl_gyrlim, 
   492         (ParamExtFloat<px4::params::EKF2_ABL_TAU>)
   496         (ParamExtFloat<px4::params::EKF2_DRAG_NOISE>)
   497         _param_ekf2_drag_noise, 
   498         (ParamExtFloat<px4::params::EKF2_BCOEF_X>) _param_ekf2_bcoef_x,     
   499         (ParamExtFloat<px4::params::EKF2_BCOEF_Y>) _param_ekf2_bcoef_y,     
   503         (ParamFloat<px4::params::EKF2_ASPD_MAX>)
   504         _param_ekf2_aspd_max,       
   505         (ParamFloat<px4::params::EKF2_PCOEF_XP>)
   506         _param_ekf2_pcoef_xp,   
   507         (ParamFloat<px4::params::EKF2_PCOEF_XN>)
   508         _param_ekf2_pcoef_xn,   
   509         (ParamFloat<px4::params::EKF2_PCOEF_YP>)
   510         _param_ekf2_pcoef_yp,   
   511         (ParamFloat<px4::params::EKF2_PCOEF_YN>)
   512         _param_ekf2_pcoef_yn,   
   513         (ParamFloat<px4::params::EKF2_PCOEF_Z>)
   517         (ParamInt<px4::params::EKF2_GPS_MASK>)
   518         _param_ekf2_gps_mask,   
   519         (ParamFloat<px4::params::EKF2_GPS_TAU>)
   523         (ParamExtFloat<px4::params::EKF2_MOVE_TEST>)
   524         _param_ekf2_move_test,  
   526         (ParamFloat<px4::params::EKF2_REQ_GPS_H>) _param_ekf2_req_gps_h, 
   527         (ParamExtInt<px4::params::EKF2_MAG_CHECK>) _param_ekf2_mag_check 
   534     ModuleParams(nullptr),
   535     WorkItem(MODULE_NAME, 
px4::wq_configurations::att_pos_ctrl),
   536     _replay_mode(replay_mode),
   538     _params(_ekf.getParamHandle()),
   539     _param_ekf2_min_obs_dt(_params->sensor_interval_min_ms),
   540     _param_ekf2_mag_delay(_params->mag_delay_ms),
   541     _param_ekf2_baro_delay(_params->baro_delay_ms),
   542     _param_ekf2_gps_delay(_params->gps_delay_ms),
   543     _param_ekf2_of_delay(_params->flow_delay_ms),
   544     _param_ekf2_rng_delay(_params->range_delay_ms),
   545     _param_ekf2_asp_delay(_params->airspeed_delay_ms),
   546     _param_ekf2_ev_delay(_params->ev_delay_ms),
   547     _param_ekf2_avel_delay(_params->auxvel_delay_ms),
   548     _param_ekf2_gyr_noise(_params->gyro_noise),
   549     _param_ekf2_acc_noise(_params->accel_noise),
   550     _param_ekf2_gyr_b_noise(_params->gyro_bias_p_noise),
   551     _param_ekf2_acc_b_noise(_params->accel_bias_p_noise),
   552     _param_ekf2_mag_e_noise(_params->mage_p_noise),
   553     _param_ekf2_mag_b_noise(_params->magb_p_noise),
   554     _param_ekf2_wind_noise(_params->wind_vel_p_noise),
   555     _param_ekf2_terr_noise(_params->terrain_p_noise),
   556     _param_ekf2_terr_grad(_params->terrain_gradient),
   557     _param_ekf2_gps_v_noise(_params->gps_vel_noise),
   558     _param_ekf2_gps_p_noise(_params->gps_pos_noise),
   559     _param_ekf2_noaid_noise(_params->pos_noaid_noise),
   560     _param_ekf2_baro_noise(_params->baro_noise),
   561     _param_ekf2_baro_gate(_params->baro_innov_gate),
   562     _param_ekf2_gnd_eff_dz(_params->gnd_effect_deadzone),
   563     _param_ekf2_gnd_max_hgt(_params->gnd_effect_max_hgt),
   564     _param_ekf2_gps_p_gate(_params->gps_pos_innov_gate),
   565     _param_ekf2_gps_v_gate(_params->gps_vel_innov_gate),
   566     _param_ekf2_tas_gate(_params->tas_innov_gate),
   567     _param_ekf2_head_noise(_params->mag_heading_noise),
   568     _param_ekf2_mag_noise(_params->mag_noise),
   569     _param_ekf2_eas_noise(_params->eas_noise),
   570     _param_ekf2_beta_gate(_params->beta_innov_gate),
   571     _param_ekf2_beta_noise(_params->beta_noise),
   572     _param_ekf2_mag_decl(_params->mag_declination_deg),
   573     _param_ekf2_hdg_gate(_params->heading_innov_gate),
   574     _param_ekf2_mag_gate(_params->mag_innov_gate),
   575     _param_ekf2_decl_type(_params->mag_declination_source),
   576     _param_ekf2_mag_type(_params->mag_fusion_type),
   577     _param_ekf2_mag_acclim(_params->mag_acc_gate),
   578     _param_ekf2_mag_yawlim(_params->mag_yaw_rate_gate),
   579     _param_ekf2_gps_check(_params->gps_check_mask),
   580     _param_ekf2_req_eph(_params->req_hacc),
   581     _param_ekf2_req_epv(_params->req_vacc),
   582     _param_ekf2_req_sacc(_params->req_sacc),
   583     _param_ekf2_req_nsats(_params->req_nsats),
   584     _param_ekf2_req_pdop(_params->req_pdop),
   585     _param_ekf2_req_hdrift(_params->req_hdrift),
   586     _param_ekf2_req_vdrift(_params->req_vdrift),
   587     _param_ekf2_aid_mask(_params->fusion_mode),
   588     _param_ekf2_hgt_mode(_params->vdist_sensor_type),
   589     _param_ekf2_noaid_tout(_params->valid_timeout_max),
   590     _param_ekf2_rng_noise(_params->range_noise),
   591     _param_ekf2_rng_sfe(_params->range_noise_scaler),
   592     _param_ekf2_rng_gate(_params->range_innov_gate),
   593     _param_ekf2_min_rng(_params->rng_gnd_clearance),
   594     _param_ekf2_rng_pitch(_params->rng_sens_pitch),
   595     _param_ekf2_rng_aid(_params->range_aid),
   596     _param_ekf2_rng_a_vmax(_params->max_vel_for_range_aid),
   597     _param_ekf2_rng_a_hmax(_params->max_hagl_for_range_aid),
   598     _param_ekf2_rng_a_igate(_params->range_aid_innov_gate),
   599     _param_ekf2_evv_gate(_params->ev_vel_innov_gate),
   600     _param_ekf2_evp_gate(_params->ev_pos_innov_gate),
   601     _param_ekf2_of_n_min(_params->flow_noise),
   602     _param_ekf2_of_n_max(_params->flow_noise_qual_min),
   603     _param_ekf2_of_qmin(_params->flow_qual_min),
   604     _param_ekf2_of_gate(_params->flow_innov_gate),
   605     _param_ekf2_imu_pos_x(_params->imu_pos_body(0)),
   606     _param_ekf2_imu_pos_y(_params->imu_pos_body(1)),
   607     _param_ekf2_imu_pos_z(_params->imu_pos_body(2)),
   608     _param_ekf2_gps_pos_x(_params->gps_pos_body(0)),
   609     _param_ekf2_gps_pos_y(_params->gps_pos_body(1)),
   610     _param_ekf2_gps_pos_z(_params->gps_pos_body(2)),
   611     _param_ekf2_rng_pos_x(_params->rng_pos_body(0)),
   612     _param_ekf2_rng_pos_y(_params->rng_pos_body(1)),
   613     _param_ekf2_rng_pos_z(_params->rng_pos_body(2)),
   614     _param_ekf2_of_pos_x(_params->flow_pos_body(0)),
   615     _param_ekf2_of_pos_y(_params->flow_pos_body(1)),
   616     _param_ekf2_of_pos_z(_params->flow_pos_body(2)),
   617     _param_ekf2_ev_pos_x(_params->ev_pos_body(0)),
   618     _param_ekf2_ev_pos_y(_params->ev_pos_body(1)),
   619     _param_ekf2_ev_pos_z(_params->ev_pos_body(2)),
   620     _param_ekf2_tau_vel(_params->vel_Tau),
   621     _param_ekf2_tau_pos(_params->pos_Tau),
   622     _param_ekf2_gbias_init(_params->switch_on_gyro_bias),
   623     _param_ekf2_abias_init(_params->switch_on_accel_bias),
   624     _param_ekf2_angerr_init(_params->initial_tilt_err),
   625     _param_ekf2_abl_lim(_params->acc_bias_lim),
   626     _param_ekf2_abl_acclim(_params->acc_bias_learn_acc_lim),
   627     _param_ekf2_abl_gyrlim(_params->acc_bias_learn_gyr_lim),
   628     _param_ekf2_abl_tau(_params->acc_bias_learn_tc),
   629     _param_ekf2_drag_noise(_params->drag_noise),
   630     _param_ekf2_bcoef_x(_params->bcoef_x),
   631     _param_ekf2_bcoef_y(_params->bcoef_y),
   632     _param_ekf2_move_test(_params->is_moving_scaler),
   633     _param_ekf2_mag_check(_params->check_mag_strength)
   650         PX4_ERR(
"sensor combined callback registration failed!");
   662     PX4_INFO(
"time slip: %" PRId64 
" us", _last_time_slip_us);
   669 template<
typename Param>
   672     if (_valid_cal_available[axis_index]) {
   675         const float weighting = 
constrain(_param_ekf2_magb_vref.get() / (_param_ekf2_magb_vref.get() +
   676                           _last_valid_variance[axis_index]), 0.0
f, _param_ekf2_magb_k.get());
   677         const float mag_bias_saved = mag_bias_param.get();
   679         _last_valid_mag_cal[axis_index] = weighting * _last_valid_mag_cal[axis_index] + mag_bias_saved;
   681         mag_bias_param.set(_last_valid_mag_cal[axis_index]);
   682         mag_bias_param.commit_no_notification();
   684         _valid_cal_available[axis_index] = 
false;
   688 template<
typename Param>
   692     float declination_deg;
   695         mag_decl_param.set(declination_deg);
   696         mag_decl_param.commit_no_notification();
   729         ekf2_timestamps.airspeed_timestamp_rel = ekf2_timestamps_s::RELATIVE_TIMESTAMP_INVALID;
   730         ekf2_timestamps.distance_sensor_timestamp_rel = ekf2_timestamps_s::RELATIVE_TIMESTAMP_INVALID;
   731         ekf2_timestamps.gps_timestamp_rel = ekf2_timestamps_s::RELATIVE_TIMESTAMP_INVALID;
   732         ekf2_timestamps.optical_flow_timestamp_rel = ekf2_timestamps_s::RELATIVE_TIMESTAMP_INVALID;
   733         ekf2_timestamps.vehicle_air_data_timestamp_rel = ekf2_timestamps_s::RELATIVE_TIMESTAMP_INVALID;
   734         ekf2_timestamps.vehicle_magnetometer_timestamp_rel = ekf2_timestamps_s::RELATIVE_TIMESTAMP_INVALID;
   735         ekf2_timestamps.visual_odometry_timestamp_rel = ekf2_timestamps_s::RELATIVE_TIMESTAMP_INVALID;
   756                         PX4_WARN(
"accel id changed, resetting IMU bias");
   761                         PX4_WARN(
"gyro id changed, resetting IMU bias");
   800                     if (_invalid_mag_id_count < 200) {
   801                         _invalid_mag_id_count++;
   805                     if (_invalid_mag_id_count > 0) {
   806                         _invalid_mag_id_count--;
   813                     _param_ekf2_magbias_x.set(0.
f);
   814                     _param_ekf2_magbias_x.commit_no_notification();
   815                     _param_ekf2_magbias_y.set(0.
f);
   816                     _param_ekf2_magbias_y.commit_no_notification();
   817                     _param_ekf2_magbias_z.set(0.
f);
   818                     _param_ekf2_magbias_z.commit_no_notification();
   820                     _param_ekf2_magbias_id.commit();
   822                     _invalid_mag_id_count = 0;
   824                     PX4_INFO(
"Mag sensor ID changed to %i", _param_ekf2_magbias_id.get());
   829                 _mag_time_sum_ms += magnetometer.
timestamp / 1000;
   839                     float mag_data_avg_ga[3] = {_mag_data_sum[0] *mag_sample_count_inv - _param_ekf2_magbias_x.get(),
   840                                     _mag_data_sum[1] *mag_sample_count_inv - _param_ekf2_magbias_y.get(),
   841                                     _mag_data_sum[2] *mag_sample_count_inv - _param_ekf2_magbias_z.get()
   844                     _ekf.
setMagData(1000 * (uint64_t)mag_time_ms, mag_data_avg_ga);
   846                     _mag_time_ms_last_used = mag_time_ms;
   847                     _mag_time_sum_ms = 0;
   848                     _mag_sample_count = 0;
   849                     _mag_data_sum[0] = 0.0f;
   850                     _mag_data_sum[1] = 0.0f;
   851                     _mag_data_sum[2] = 0.0f;
   854                 ekf2_timestamps.vehicle_magnetometer_timestamp_rel = (int16_t)((int64_t)magnetometer.
timestamp / 100 -
   855                         (int64_t)ekf2_timestamps.timestamp / 100);
   866                 _balt_time_sum_ms += airdata.
timestamp / 1000;
   867                 _balt_sample_count++;
   873                     float balt_data_avg = _balt_data_sum / (float)_balt_sample_count;
   882                     float K_pstatic_coef_x;
   884                     if (vel_body_wind(0) >= 0.0
f) {
   885                         K_pstatic_coef_x = _param_ekf2_pcoef_xp.get();
   888                         K_pstatic_coef_x = _param_ekf2_pcoef_xn.get();
   891                     float K_pstatic_coef_y;
   893                     if (vel_body_wind(1) >= 0.0
f) {
   894                         K_pstatic_coef_y = _param_ekf2_pcoef_yp.get();
   897                         K_pstatic_coef_y = _param_ekf2_pcoef_yn.get();
   900                     const float max_airspeed_sq = _param_ekf2_aspd_max.get() * _param_ekf2_aspd_max.get();
   901                     const float x_v2 = fminf(vel_body_wind(0) * vel_body_wind(0), max_airspeed_sq);
   902                     const float y_v2 = fminf(vel_body_wind(1) * vel_body_wind(1), max_airspeed_sq);
   903                     const float z_v2 = fminf(vel_body_wind(2) * vel_body_wind(2), max_airspeed_sq);
   905                     const float pstatic_err = 0.5f * airdata.
rho * (
   906                                       K_pstatic_coef_x * x_v2 + K_pstatic_coef_y * y_v2 + _param_ekf2_pcoef_z.get() * z_v2);
   912                     _ekf.
setBaroData(1000 * (uint64_t)balt_time_ms, balt_data_avg);
   914                     _balt_time_ms_last_used = balt_time_ms;
   915                     _balt_time_sum_ms = 0;
   916                     _balt_sample_count = 0;
   917                     _balt_data_sum = 0.0f;
   920                 ekf2_timestamps.vehicle_air_data_timestamp_rel = (int16_t)((int64_t)airdata.
timestamp / 100 -
   921                         (int64_t)ekf2_timestamps.timestamp / 100);
   935                 ekf2_timestamps.gps_timestamp_rel = (int16_t)((int64_t)gps.
timestamp / 100 - (int64_t)ekf2_timestamps.timestamp / 100);
   951         if ((_param_ekf2_gps_mask.get() == 0) && gps1_updated) {
   955         } 
else if ((_param_ekf2_gps_mask.get() > 0) && (gps1_updated || gps2_updated)) {
   963                     _gps_select_index = 0;
   967                     _gps_select_index = 1;
   969                 } 
else if (_gps_select_index == 2) {
   972                         _gps_select_index = 0;
   974                     } 
else if (gps2_updated) {
   975                         _gps_select_index = 1;
   980                 _gps_new_output_data = (gps1_updated && _gps_select_index == 0) ||
   981                                (gps2_updated && _gps_select_index == 1);
   984             if (_gps_new_output_data) {
   989                 if (_gps_select_index == 2) {
  1020                 _gps_new_output_data = 
false;
  1035                 ekf2_timestamps.airspeed_timestamp_rel = (int16_t)((int64_t)airspeed.
timestamp / 100 -
  1036                         (int64_t)ekf2_timestamps.timestamp / 100);
  1063                 ekf2_timestamps.optical_flow_timestamp_rel = (int16_t)((int64_t)optical_flow.
timestamp / 100 -
  1064                         (int64_t)ekf2_timestamps.timestamp / 100);
  1068         if (_range_finder_sub_index >= 0) {
  1079                     ekf2_timestamps.distance_sensor_timestamp_rel = (int16_t)((int64_t)range_finder.
timestamp / 100 -
  1080                             (int64_t)ekf2_timestamps.timestamp / 100);
  1090         new_ev_data_received = 
false;
  1093             new_ev_data_received = 
true;
  1108                     ev_data.
velErr = fmaxf(_param_ekf2_evv_noise.get(),
  1114                     ev_data.
velErr = _param_ekf2_evv_noise.get();
  1126                     ev_data.
posErr = fmaxf(_param_ekf2_evp_noise.get(),
  1129                     ev_data.
hgtErr = fmaxf(_param_ekf2_evp_noise.get(),
  1133                     ev_data.
posErr = _param_ekf2_evp_noise.get();
  1134                     ev_data.
hgtErr = _param_ekf2_evp_noise.get();
  1143                 if (!_param_ekf2_ev_noise_md.get()
  1145                     ev_data.
angErr = fmaxf(_param_ekf2_eva_noise.get(),
  1149                     ev_data.
angErr = _param_ekf2_eva_noise.get();
  1154             if (ev_data.
posErr < ep_max_std_dev && ev_data.
angErr < eo_max_std_dev) {
  1159             ekf2_timestamps.visual_odometry_timestamp_rel = (int16_t)((int64_t)
_ev_odom.
timestamp / 100 -
  1160                     (int64_t)ekf2_timestamps.timestamp / 100);
  1165         if (vehicle_land_detected_updated) {
  1188         const bool updated = _ekf.
update();
  1192         if (_start_time_us == 0) {
  1193             _start_time_us = now;
  1194             _last_time_slip_us = 0;
  1196         } 
else if (_start_time_us > 0) {
  1198             _last_time_slip_us = (now - 
_start_time_us) - _integrated_time_us;
  1217                 odom.local_frame = odom.LOCAL_FRAME_NED;
  1222                 const float lpos_x_prev = lpos.
x;
  1223                 const float lpos_y_prev = lpos.
y;
  1226                 lpos.
z = position[2];
  1236                 lpos.
vx = velocity[0];
  1237                 lpos.
vy = velocity[1];
  1238                 lpos.
vz = velocity[2];
  1251                 lpos.
ax = vel_deriv[0];
  1252                 lpos.
ay = vel_deriv[1];
  1253                 lpos.
az = vel_deriv[2];
  1263                 uint64_t origin_time;
  1270                 if (ekf_origin_valid && (origin_time > lpos.
ref_timestamp)) {
  1287                 odom.rollspeed = sensors.
gyro_rad[0] - gyro_bias[0];
  1288                 odom.pitchspeed = sensors.
gyro_rad[1] - gyro_bias[1];
  1289                 odom.yawspeed = sensors.
gyro_rad[2] - gyro_bias[2];
  1298                 if (lpos.
dist_bottom < _param_ekf2_min_rng.get()) {
  1302                 if (!_had_valid_terrain) {
  1316                     } 
else if (vehicle_land_detected_updated && !_had_valid_terrain) {
  1340                 if (!PX4_ISFINITE(lpos.
vxy_max)) {
  1344                 if (!PX4_ISFINITE(lpos.
vz_max)) {
  1348                 if (!PX4_ISFINITE(lpos.
hagl_min)) {
  1352                 if (!PX4_ISFINITE(lpos.
hagl_max)) {
  1357                 float covariances[24];
  1361                 const size_t POS_URT_SIZE = 
sizeof(odom.pose_covariance) / 
sizeof(odom.pose_covariance[0]);
  1362                 const size_t VEL_URT_SIZE = 
sizeof(odom.velocity_covariance) / 
sizeof(odom.velocity_covariance[0]);
  1365                 for (
size_t i = 0; i < POS_URT_SIZE; i++) {
  1366                     odom.pose_covariance[i] = 0.0;
  1370                 odom.pose_covariance[odom.COVARIANCE_MATRIX_X_VARIANCE] = covariances[7];
  1371                 odom.pose_covariance[odom.COVARIANCE_MATRIX_Y_VARIANCE] = covariances[8];
  1372                 odom.pose_covariance[odom.COVARIANCE_MATRIX_Z_VARIANCE] = covariances[9];
  1378                 for (
size_t i = 0; i < VEL_URT_SIZE; i++) {
  1379                     odom.velocity_covariance[i] = 0.0;
  1383                 odom.velocity_covariance[odom.COVARIANCE_MATRIX_VX_VARIANCE] = covariances[4];
  1384                 odom.velocity_covariance[odom.COVARIANCE_MATRIX_VY_VARIANCE] = covariances[5];
  1385                 odom.velocity_covariance[odom.COVARIANCE_MATRIX_VZ_VARIANCE] = covariances[6];
  1394                 if (new_ev_data_received) {
  1397                     Quatf quat_ev2ekf(q_ev2ekf);
  1398                     Dcmf ev_rot_mat(quat_ev2ekf);
  1404                     aligned_ev_odom.
x = aligned_pos(0);
  1405                     aligned_ev_odom.
y = aligned_pos(1);
  1406                     aligned_ev_odom.
z = aligned_pos(2);
  1409                     aligned_ev_odom.
vx = aligned_vel(0);
  1410                     aligned_ev_odom.
vy = aligned_vel(1);
  1411                     aligned_ev_odom.
vz = aligned_vel(2);
  1415                     ev_quat_aligned.normalize();
  1417                     ev_quat_aligned.copyTo(aligned_ev_odom.
q);
  1418                     quat_ev2ekf.copyTo(aligned_ev_odom.
q_offset);
  1445                     global_pos.
yaw = lpos.
yaw; 
  1474                 bias.mag_bias[0] = _last_valid_mag_cal[0];
  1475                 bias.mag_bias[1] = _last_valid_mag_cal[1];
  1476                 bias.mag_bias[2] = _last_valid_mag_cal[2];
  1502             status.
time_slip = _last_time_slip_us / 1e6f;
  1522                 drift_data.
hspd = gps_drift[2];
  1537                     if (_last_magcal_us == 0) {
  1538                         _last_magcal_us = now;
  1542                         _last_magcal_us = now;
  1548                     _total_cal_time_us = 0;
  1550                     for (
bool &cal_available : _valid_cal_available) {
  1551                         cal_available = 
false;
  1556                 if (_total_cal_time_us > 120_s) {
  1559                     const float max_var_allowed = 100.0f * _param_ekf2_magb_vref.get();
  1560                     const float min_var_allowed = 0.01f * _param_ekf2_magb_vref.get();
  1563                     bool all_estimates_invalid = 
false;
  1565                     for (uint8_t axis_index = 0; axis_index <= 2; axis_index++) {
  1566                         if (status.
covariances[axis_index + 19] < min_var_allowed
  1567                             || status.
covariances[axis_index + 19] > max_var_allowed) {
  1568                             all_estimates_invalid = 
true;
  1573                     if (!all_estimates_invalid) {
  1574                         for (uint8_t axis_index = 0; axis_index <= 2; axis_index++) {
  1575                             _last_valid_mag_cal[axis_index] = status.
states[axis_index + 19];
  1576                             _valid_cal_available[axis_index] = 
true;
  1577                             _last_valid_variance[axis_index] = status.
covariances[axis_index + 19];
  1592                     _total_cal_time_us = 0;
  1672     const bool can_observe_heading_in_flight = (vehicle_status.
vehicle_type != vehicle_status_s::VEHICLE_TYPE_ROTARY_WING);
  1679     _preflt_checker.
update(dt, innov);
  1684     _preflt_checker.
reset();
  1694             if (report.orientation == distance_sensor_s::ROTATION_DOWNWARD_FACING) {
  1695                 PX4_INFO(
"Found range finder with instance %d", i);
  1720     }  
else if (_replay_mode) {
  1735         float velNE_wind[2];
  1743         wind_estimate.timestamp = timestamp;
  1744         wind_estimate.windspeed_north = velNE_wind[0];
  1745         wind_estimate.windspeed_east = velNE_wind[1];
  1746         wind_estimate.variance_north = wind_var[0];
  1747         wind_estimate.variance_east = wind_var[1];
  1748         wind_estimate.tas_scale = 0.0f; 
  1770     float velNE_wind[2];
  1773     Vector3f v_wind_comp = {velocity[0] - velNE_wind[0], velocity[1] - velNE_wind[1], velocity[2]};
  1775     return R_to_body * v_wind_comp;
  1781     memset(&_blend_weights, 0, 
sizeof(_blend_weights));
  1792     float dt_max = 0.0f;
  1793     float dt_min = 0.3f;
  1796         float raw_dt = 0.001f * (float)(
_gps_state[i].time_usec - _time_prev_us[i]);
  1798         if (raw_dt > 0.0
f && raw_dt < 0.3
f) {
  1799             _gps_dt[i] = 0.1f * raw_dt + 0.9f * _gps_dt[i];
  1802         if (_gps_dt[i] > dt_max) {
  1803             dt_max = _gps_dt[i];
  1804             _gps_slowest_index = i;
  1807         if (_gps_dt[i] < dt_min) {
  1808             dt_min = _gps_dt[i];
  1813     uint64_t max_us = 0; 
  1814     uint64_t min_us = -1; 
  1820             _gps_newest_index = i;
  1825             _gps_oldest_index = i;
  1829     if ((max_us - min_us) > 300000) {
  1843     if ((dt_max - dt_min) < 0.2f * dt_min) {
  1845         if ((max_us - min_us) < (uint64_t)(5e5f * dt_min)) {
  1848             _gps_new_output_data = 
true;
  1855         if (
_gps_state[_gps_time_ref_index].time_usec > _time_prev_us[_gps_time_ref_index]) {
  1857             _gps_new_output_data = 
true;
  1861     if (_gps_new_output_data) {
  1865         float speed_accuracy_sum_sq = 0.0f;
  1874                     speed_accuracy_sum_sq = 0.0f;
  1881         float horizontal_accuracy_sum_sq = 0.0f;
  1890                     horizontal_accuracy_sum_sq = 0.0f;
  1897         float vertical_accuracy_sum_sq = 0.0f;
  1906                     vertical_accuracy_sum_sq = 0.0f;
  1913         bool can_do_blending = (horizontal_accuracy_sum_sq > 0.0f || vertical_accuracy_sum_sq > 0.0f
  1914                     || speed_accuracy_sum_sq > 0.0f);
  1917         if (!can_do_blending) {
  1921         float sum_of_all_weights = 0.0f;
  1928             float sum_of_spd_weights = 0.0f;
  1933                     sum_of_spd_weights += spd_blend_weights[i];
  1938             if (sum_of_spd_weights > 0.0
f) {
  1940                     spd_blend_weights[i] = spd_blend_weights[i] / sum_of_spd_weights;
  1943                 sum_of_all_weights += 1.0f;
  1952             float sum_of_hpos_weights = 0.0f;
  1957                     sum_of_hpos_weights += hpos_blend_weights[i];
  1962             if (sum_of_hpos_weights > 0.0
f) {
  1964                     hpos_blend_weights[i] = hpos_blend_weights[i] / sum_of_hpos_weights;
  1967                 sum_of_all_weights += 1.0f;
  1976             float sum_of_vpos_weights = 0.0f;
  1981                     sum_of_vpos_weights += vpos_blend_weights[i];
  1986             if (sum_of_vpos_weights > 0.0
f) {
  1988                     vpos_blend_weights[i] = vpos_blend_weights[i] / sum_of_vpos_weights;
  1991                 sum_of_all_weights += 1.0f;
  1997             _blend_weights[i] = (hpos_blend_weights[i] + vpos_blend_weights[i] + spd_blend_weights[i]) / sum_of_all_weights;
  2004         _gps_select_index = 2;
  2036     _blended_antenna_offset.zero();
  2056         if (_blend_weights[i] > 0.0
f) {
  2102     float best_weight = 0.0f;
  2105         if (_blend_weights[i] > best_weight) {
  2106             best_weight = _blend_weights[i];
  2107             _gps_best_index = i;
  2116     blended_NE_offset_m.zero();
  2117     float blended_alt_offset_mm = 0.0f;
  2120         if ((_blend_weights[i] > 0.0
f) && (i != _gps_best_index)) {
  2125                             &horiz_offset(0), &horiz_offset(1));
  2128             blended_NE_offset_m += horiz_offset * _blend_weights[i];
  2134             blended_alt_offset_mm += vert_offset * _blend_weights[i];
  2141     double lat_deg_res, lon_deg_res;
  2149     uint8_t gps_best_yaw_index = 0;
  2153         if (PX4_ISFINITE(
_gps_state[i].yaw) && (_blend_weights[i] > best_weight)) {
  2154             best_weight = _blend_weights[i];
  2155             gps_best_yaw_index = i;
  2175     float omega_lpf = 1.0f / fmaxf(_param_ekf2_gps_tau.get(), 1.0f);
  2178         if (
_gps_state[i].time_usec - _time_prev_us[i] > 0) {
  2180             float min_alpha = 
constrain(omega_lpf * 1e-6
f * (
float)(
_gps_state[i].time_usec - _time_prev_us[i]),
  2184             if (_blend_weights[i] > min_alpha) {
  2185                 alpha[i] = min_alpha / _blend_weights[i];
  2200         _NE_pos_offset_m[i] = offset * alpha[i] + _NE_pos_offset_m[i] * (1.0f - alpha[i]);
  2202                     _hgt_offset_mm[i] * (1.0f - alpha[i]);
  2207     float max_alt_offset = 0;
  2215                 max_ne_offset(0) = fmaxf(max_ne_offset(0), fabsf(offset(0)));
  2216                 max_ne_offset(1) = fmaxf(max_ne_offset(1), fabsf(offset(1)));
  2224         _NE_pos_offset_m[i](0) = 
constrain(_NE_pos_offset_m[i](0), -max_ne_offset(0), max_ne_offset(0));
  2225         _NE_pos_offset_m[i](1) = 
constrain(_NE_pos_offset_m[i](1), -max_ne_offset(1), max_ne_offset(1));
  2226         _hgt_offset_mm[i] = 
constrain(_hgt_offset_mm[i], -max_alt_offset, max_alt_offset);
  2240         double lat_deg_now = (double)
_gps_state[i].lat * 1.0e-7;
  2241         double lon_deg_now = (double)
_gps_state[i].lon * 1.0e-7;
  2242         double lat_deg_res, lon_deg_res;
  2276     blended_NE_offset_m.zero();
  2277     float blended_alt_offset_mm = 0.0f;
  2280         if (_blend_weights[i] > 0.0
f) {
  2291             blended_NE_offset_m += horiz_offset * _blend_weights[i];
  2297             blended_alt_offset_mm += vert_offset * _blend_weights[i];
  2304     double lat_deg_res, lon_deg_res;
  2336         _wgs84_hgt_offset = height_diff;
  2358     bool replay_mode = 
false;
  2360     if (argc > 1 && !strcmp(argv[1], 
"-r")) {
  2361         PX4_INFO(
"replay mode enabled");
  2368         _object.store(instance);
  2369         _task_id = task_id_is_work_queue;
  2371         if (instance->
init()) {
  2376         PX4_ERR(
"alloc failed");
  2380     _object.store(
nullptr);
  2389         PX4_WARN(
"%s\n", reason);
  2392     PRINT_MODULE_DESCRIPTION(
  2395 Attitude and position estimator using an Extended Kalman Filter. It is used for Multirotors and Fixed-Wing.  2397 The documentation can be found on the [ECL/EKF Overview & Tuning](https://docs.px4.io/en/advanced_config/tuning_the_ecl_ekf.html) page.  2399 ekf2 can be started in replay mode (`-r`): in this mode it does not access the system time, but only uses the  2400 timestamps from the sensor topics.  2404     PRINT_MODULE_USAGE_NAME("ekf2", 
"estimator");
  2405     PRINT_MODULE_USAGE_COMMAND(
"start");
  2406     PRINT_MODULE_USAGE_PARAM_FLAG(
'r', 
"Enable replay mode", 
true);
  2407     PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
 
#define VEHICLE_TYPE_FIXED_WING
int getRangeSubIndex()
get subscription index of first downward-facing range sensor 
void setIMUData(const imuSample &imu_sample)
constexpr _Tp constrain(_Tp val, _Tp min_val, _Tp max_val)
uORB::Publication< ekf_gps_drift_s > _ekf_gps_drift_pub
void setMagData(uint64_t time_usec, float(&data)[3])
struct estimator::filter_control_status_u::@60 flags
bool hasHeightFailed() const
float eph
GPS horizontal position accuracy in m. 
uORB::Subscription _parameter_update_sub
Vector3f delta_ang
delta angle in body frame (integrated gyro measurements) (rad) 
void setUsingFlowAiding(bool val)
float yaw_offset
Heading/Yaw offset for dual antenna GPS - refer to description for GPS_YAW_OFFSET. 
hrt_abstime _last_magcal_us
last time the EKF was operating a mode that estimates magnetomer biases (uSec) 
uint32_t control_mode_flags
uORB::Publication< sensor_bias_s > _sensor_bias_pub
#define BLEND_MASK_USE_HPOS_ACC
float epv
GPS vertical position accuracy in m. 
uORB::Subscription _airdata_sub
void get_hagl_innov(float *hagl_innov)
static struct vehicle_status_s status
void get_ekf_vel_accuracy(float *ekf_evh, float *ekf_evv) override
void setExtVisionData(uint64_t time_usec, ext_vision_message *evdata)
float gyro_x_rate_integral
uint8_t nsats
number of satellites used 
measure the time elapsed performing an event 
float _wgs84_hgt_offset
height offset between AMSL and WGS84 
void setAuxVelData(uint64_t time_usec, float(&data)[2], float(&variance)[2])
void set_optical_flow_limits(float max_flow_rate, float min_distance, float max_distance)
float vel_m_s
GPS ground speed (m/sec) 
Quatf calculate_quaternion() const
bool update(void *dst)
Copy the struct if updated. 
uORB::PublicationData< vehicle_global_position_s > _vehicle_global_position_pub
uORB::Subscription _landing_target_pose_sub
bool get_ekf_origin(uint64_t *origin_time, map_projection_reference_s *origin_pos, float *origin_alt) override
uORB::Publication< vehicle_odometry_s > _vehicle_odometry_pub
uORB::Subscription _sensor_selection_sub
bool is_fixed_wing(const struct vehicle_status_s *current_status)
void get_state_delayed(float *state) override
void get_heading_innov(float *heading_innov) override
void get_terrain_vert_pos(float *ret)
float pixel_flow_y_integral
void get_vector_to_next_waypoint(double lat_now, double lon_now, double lat_next, double lon_next, float *v_n, float *v_e)
uORB::Subscription _range_finder_subs[ORB_MULTI_MAX_INSTANCES]
bool update_mag_decl(Param &mag_decl_param)
bool pre_flt_fail_innov_vel_horiz
void runPreFlightChecks(float dt, const filter_control_status_u &control_status, const vehicle_status_s &vehicle_status, const ekf2_innovations_s &innov)
void set_is_fixed_wing(bool is_fixed_wing)
int main(int argc, char **argv)
void get_gyro_bias(float bias[3]) override
uORB::Publication< ekf_gps_position_s > _blended_gps_pub
void get_output_tracking_error(float error[3]) override
uint8_t vxy_reset_counter
float sacc
GPS speed accuracy in m/s. 
void get_drag_innov_var(float drag_innov_var[2]) override
void get_mag_innov_var(float mag_innov_var[3]) override
Vector3f gyrodata
Gyro rates about the XYZ body axes (rad/sec) 
void set_fuse_beta_flag(bool fuse_beta)
const bool _replay_mode
true when we use replay data from a log 
void set_gnd_effect_flag(bool gnd_effect)
#define GPS_MAX_RECEIVERS
uint8_t fix_type
0-1: no fix, 2: 2D fix, 3: 3D fix, 4: RTCM code differential, 5: Real-Time Kinematic ...
void calc_gps_blend_output()
uint32_t mag_field_disturbed
16 - true when the mag field does not match the expected strength 
float min_ground_distance
float pixel_flow_x_integral
int print_status() override
uint16_t filter_fault_flags
float accelerometer_m_s2[3]
Ekf2(bool replay_mode=false)
float pdop
position dilution of precision 
static int print_usage(const char *reason=nullptr)
static void print_usage()
void get_imu_vibe_metrics(float vibe[3]) override
void get_velocity(float *vel)
void setGpsData(uint64_t time_usec, const gps_message &gps)
uORB::Publication< ekf2_innovations_s > _estimator_innovations_pub
uORB::SubscriptionCallbackWorkItem _sensors_sub
float vel_ned[3]
GPS ground speed NED. 
void setUsingGpsAiding(bool val)
void get_flow_innov_var(float flow_innov_var[2]) override
void update_mag_bias(Param &mag_bias_param, int axis_index)
uint32_t dt
integration time of flow samples (sec) 
void copyTo(Type dst[M *N]) const
High-resolution timer with callouts and timekeeping. 
void get_wind_velocity(float *wind) override
uint8_t quality
Quality of Flow data. 
static constexpr float CONSTANTS_ONE_G
void get_control_mode(uint32_t *val)
uORB::PublicationData< vehicle_local_position_s > _vehicle_local_position_pub
void update(float dt, const ekf2_innovations_s &innov)
void update_gps_offsets()
#define BLEND_MASK_USE_VPOS_ACC
bool pre_flt_fail_innov_vel_vert
uint8_t _gps_slowest_index
index of the physical receiver with the slowest update rate 
uORB::Subscription _gps_subs[GPS_MAX_RECEIVERS]
static char msg[NUM_MSG][CONFIG_USART1_TXBUFSIZE]
float max_ground_distance
void resetPreFlightChecks()
vehicle_status_s _vehicle_status
uORB::Subscription _ev_odom_sub
gps_message _gps_output[GPS_MAX_RECEIVERS+1]
output state data for the physical and blended GPS 
void get_airspeed_innov_var(float *airspeed_innov_var) override
float velErr
1-Sigma velocity accuracy (m/sec) 
#define ORB_ID(_name)
Generates a pointer to the uORB metadata structure for a given topic. 
void get_accel_bias(float bias[3]) override
bool hasHorizVelFailed() const
bool pre_flt_fail_innov_heading
PreFlightChecker _preflt_checker
float hgtErr
1-Sigma height accuracy (m) 
bool publish(const T &data)
Publish the struct. 
void get_heading_innov_var(float *heading_innov_var) override
__EXPORT int ekf2_main(int argc, char *argv[])
void update_gps_blend_states()
uint64_t _gps_alttitude_ellipsoid_previous_timestamp[GPS_MAX_RECEIVERS]
storage for previous timestamp to compute dt 
void perf_free(perf_counter_t handle)
Free a counter. 
int map_projection_reproject(const struct map_projection_reference_s *ref, float x, float y, double *lat, double *lon)
Transforms a point in the local azimuthal equidistant plane to the geographic coordinate system using...
void init()
Activates/configures the hardware registers. 
bool vel_ned_valid
GPS ground speed is valid. 
bool publish_wind_estimate(const hrt_abstime ×tamp)
void get_velD_reset(float *delta, uint8_t *counter) override
void setBaroData(uint64_t time_usec, float data)
uint8_t _gps_time_ref_index
index of the receiver that is used as the timing reference for the blending update ...
void get_vel_pos_innov_var(float vel_pos_innov_var[6]) override
void get_posNE_reset(float delta[2], uint8_t *counter) override
float vel_pos_innov_var[6]
parameters * _params
pointer to ekf parameter struct (located in _ekf class instance) 
uint16_t solution_status_flags
bool reset_imu_bias() override
uORB::Publication< ekf2_timestamps_s > _ekf2_timestamps_pub
uint64_t time_us
timestamp of the measurement (uSec) 
void get_ekf_gpos_accuracy(float *ekf_eph, float *ekf_epv) override
uORB::Subscription _airspeed_sub
void get_vel_deriv_ned(float *vel_deriv)
#define BLEND_MASK_USE_SPD_ACC
void get_filter_fault_status(uint16_t *val)
perf_counter_t perf_alloc_once(enum perf_counter_type type, const char *name)
Get the reference to an existing counter or create a new one if it does not exist. 
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
bool get_gps_drift_metrics(float drift[3], bool *blocked) override
Vector2< float > Vector2f
void add_vector_to_global_position(double lat_now, double lon_now, float v_n, float v_e, double *lat_res, double *lon_res)
int32_t _gps_alttitude_ellipsoid[GPS_MAX_RECEIVERS]
altitude in 1E-3 meters (millimeters) above ellipsoid 
Vector3f pos
XYZ position in earth frame (m) - Z must be aligned with down axis. 
void get_airspeed_innov(float *airspeed_innov) override
bool hasHorizFailed() const
float indicated_airspeed_m_s
gps_message _gps_state[GPS_MAX_RECEIVERS]
internal state data for the physical GPS 
int32_t lat
Latitude in 1E-7 degrees. 
void get_hagl_innov_var(float *hagl_innov_var)
vehicle_odometry_s _ev_odom
bool pre_flt_fail_mag_field_disturbed
void get_ev2ekf_quaternion(float *quat) override
void get_ekf_ctrl_limits(float *vxy_max, float *vz_max, float *hagl_min, float *hagl_max) override
uORB::PublicationMulti< wind_estimate_s > _wind_pub
void get_ekf_lpos_accuracy(float *ekf_eph, float *ekf_epv) override
void perf_end(perf_counter_t handle)
End a performance event. 
void get_ekf_soln_status(uint16_t *status) override
uORB::Publication< estimator_status_s > _estimator_status_pub
uint32_t gyro_integral_dt
bool updated()
Check if there is a new update. 
void get_posD_reset(float *delta, uint8_t *counter) override
__BEGIN_DECLS typedef uint64_t hrt_abstime
Absolute time, in microsecond units. 
void setAirspeedData(uint64_t time_usec, float true_airspeed, float eas2tas)
gps_message _gps_blended_state
internal state data for the blended GPS 
uint8_t _mag_sample_count
number of magnetometer measurements summed during downsampling 
Vector2f flowdata
Optical flow rates about the X and Y body axes (rad/sec) 
void get_flow_innov(float flow_innov[2]) override
void setVehicleCanObserveHeadingInFlight(bool val)
static int custom_command(int argc, char *argv[])
void get_mag_innov(float mag_innov[3]) override
bool get_mag_decl_deg(float *val)
void get_aux_vel_innov(float aux_vel_innov[2]) override
Vector3f vel
XYZ velocity in earth frame (m/sec) - Z must be aligned with down axis. 
Vector3< float > Vector3f
float yaw
yaw angle. NaN if not set (used for dual antenna GPS), (rad, [-PI, PI]) 
bool local_position_is_valid()
void setRangeData(uint64_t time_usec, float data, int8_t quality)
uint32_t opt_flow
3 - true if optical flow measurements are being fused 
Quaternion inversed() const
Invert quaternion. 
void set_rangefinder_limits(float min_distance, float max_distance)
matrix::Vector< float, 24 > covariances_diagonal() const
void get_velNE_reset(float delta[2], uint8_t *counter) override
static int task_spawn(int argc, char *argv[])
uint8_t quat_reset_counter
bool hasVertFailed() const
uint32_t mag_3D
5 - true if 3-axis magnetometer measurement are being fused 
uORB::Publication< vehicle_attitude_s > _att_pub
Quaternion< float > Quatf
void set_min_required_gps_health_time(uint32_t time_us)
float angErr
1-Sigma angular error (rad) 
vehicle_land_detected_s _vehicle_land_detected
float pose_covariance[21]
void get_vel_pos_innov(float vel_pos_innov[6]) override
void perf_print_counter(perf_counter_t handle)
Print one performance counter to stdout. 
#define ORB_MULTI_MAX_INSTANCES
Maximum number of multi topic instances. 
Class handling the EKF2 innovation pre flight checks. 
int32_t alt
Altitude in 1E-3 meters (millimeters) above MSL. 
#define GPS_BLENDED_INSTANCE
void unregisterCallback()
perf_counter_t _ekf_update_perf
int32_t sensor_interval_min_ms
minimum time of arrival difference between non IMU sensor updates. Sets the size of the observation b...
uint16_t gps_check_fail_flags
uint32_t integration_timespan
const Vector3f get_vel_body_wind()
bool publish_attitude(const sensor_combined_s &sensors, const hrt_abstime &now)
void setUsingEvPosAiding(bool val)
void get_gps_check_status(uint16_t *val) override
Quatf quat
quaternion defining rotation from body to earth frame 
sensor_selection_s _sensor_selection
uint32_t ev_pos
12 - true when local position data from external vision is being fused 
uint8_t lat_lon_reset_counter
uint8_t _gps_newest_index
index of the physical receiver with the newest data 
void get_pos_d_deriv(float *pos_d_deriv)
void fillGpsMsgWithVehicleGpsPosData(gps_message &msg, const vehicle_gps_position_s &data)
uORB::Subscription _vehicle_land_detected_sub
void set_in_air_status(bool in_air)
bool update(void *dst)
Update the struct. 
bool pre_flt_fail_innov_height
uint32_t gps
2 - true if GPS measurements are being fused 
void get_wind_velocity_var(float *wind_var) override
bool inertial_dead_reckoning()
uint32_t tilt_align
0 - true if the filter tilt alignment is complete 
float gyro_z_rate_integral
void get_quat_reset(float delta_quat[4], uint8_t *counter) override
float filter_altitude_ellipsoid(float amsl_hgt)
bool _imu_bias_reset_request
float gyro_y_rate_integral
bool publish(const T &data)
Publish the struct. 
uint8_t _gps_select_index
0 = GPS1, 1 = GPS2, 2 = blended 
void get_beta_innov(float *beta_innov) override
Vector3f delta_vel
delta velocity in body frame (integrated accelerometer measurements) (m/sec) 
void get_innovation_test_status(uint16_t *status, float *mag, float *vel, float *pos, float *hgt, float *tas, float *hagl, float *beta) override
uint16_t innovation_check_flags
bool copy(void *dst)
Copy the struct. 
float delta_ang_dt
delta angle integration period (sec) 
void get_drag_innov(float drag_innov[2]) override
bool hasVertVelFailed() const
Class for core functions for ekf attitude and position estimator. 
bool hasHeadingFailed() const
float output_tracking_error[3]
void set_air_density(float air_density)
void perf_begin(perf_counter_t handle)
Begin a performance event. 
void get_beta_innov_var(float *beta_innov_var) override
uORB::Subscription _optical_flow_sub
uint32_t accelerometer_integral_dt
float delta_vel_dt
delta velocity integration period (sec) 
bool global_position_is_valid() override
int32_t gps_check_mask
bitmask used to control which GPS quality checks are used 
uint64_t _start_time_us
system time at EKF start (uSec) 
const matrix::Quatf & get_quaternion() const
int32_t lon
Longitude in 1E-7 degrees. 
float posErr
1-Sigma horizontal position accuracy (m) 
uORB::Subscription _status_sub
void get_position(float *pos)
uint8_t _balt_sample_count
number of barometric altitude measurements summed 
Performance measuring tools. 
uORB::Subscription _magnetometer_sub
uORB::PublicationData< vehicle_odometry_s > _vehicle_visual_odometry_aligned_pub
void setOpticalFlowData(uint64_t time_usec, flow_message *flow)