@ -115,7 +115,6 @@ void Ekf::controlFusionModes()
// control use of observations for aiding
// control use of observations for aiding
controlMagFusion ( ) ;
controlMagFusion ( ) ;
controlExternalVisionFusion ( ) ;
controlOpticalFlowFusion ( ) ;
controlOpticalFlowFusion ( ) ;
controlGpsFusion ( ) ;
controlGpsFusion ( ) ;
controlAirDataFusion ( ) ;
controlAirDataFusion ( ) ;
@ -123,10 +122,13 @@ void Ekf::controlFusionModes()
controlDragFusion ( ) ;
controlDragFusion ( ) ;
controlHeightFusion ( ) ;
controlHeightFusion ( ) ;
// f or efficiency, fusion of direct state observations for position and velocity is performed sequentially
// F or efficiency, fusion of direct state observations for position and velocity is performed sequentially
// in a single function using sensor data from multiple sources (GPS, external vision, baro, range finder, etc)
// in a single function using sensor data from multiple sources (GPS, baro, range finder, etc)
controlVelPosFusion ( ) ;
controlVelPosFusion ( ) ;
// Additional data from an external vision sensor can also be fused.
controlExternalVisionFusion ( ) ;
// report dead reckoning if we are no longer fusing measurements that constrain velocity drift
// report dead reckoning if we are no longer fusing measurements that constrain velocity drift
_is_dead_reckoning = ( _time_last_imu - _time_last_pos_fuse > _params . no_aid_timeout_max )
_is_dead_reckoning = ( _time_last_imu - _time_last_pos_fuse > _params . no_aid_timeout_max )
& & ( _time_last_imu - _time_last_vel_fuse > _params . no_aid_timeout_max )
& & ( _time_last_imu - _time_last_vel_fuse > _params . no_aid_timeout_max )
@ -143,20 +145,27 @@ void Ekf::controlExternalVisionFusion()
if ( ( _params . fusion_mode & MASK_USE_EVPOS ) & & ! _control_status . flags . ev_pos & & _control_status . flags . tilt_align & & _control_status . flags . yaw_align ) {
if ( ( _params . fusion_mode & MASK_USE_EVPOS ) & & ! _control_status . flags . ev_pos & & _control_status . flags . tilt_align & & _control_status . flags . yaw_align ) {
// check for a exernal vision measurement that has fallen behind the fusion time horizon
// check for a exernal vision measurement that has fallen behind the fusion time horizon
if ( _time_last_imu - _time_last_ext_vision < 2 * EV_MAX_INTERVAL ) {
if ( _time_last_imu - _time_last_ext_vision < 2 * EV_MAX_INTERVAL ) {
// turn on use of external vision measurements for position and height
// turn on use of external vision measurements for position
setControlEVHeight ( ) ;
_control_status . flags . ev_pos = true ;
ECL_INFO ( " EKF commencing external vision position fusion " ) ;
ECL_INFO ( " EKF commencing external vision position fusion " ) ;
// reset the position, height and velocity
resetPosition ( ) ;
// reset the position if we are not already aiding using GPS, else use a relative position
resetVelocity ( ) ;
// method for fusing the position data
resetHeight ( ) ;
if ( _control_status . flags . gps ) {
_control_status . flags . ev_pos = true ;
_hpos_odometry = true ;
} else {
resetPosition ( ) ;
resetVelocity ( ) ;
_hpos_odometry = false ;
}
}
}
}
}
// external vision yaw aiding selection logic
// external vision yaw aiding selection logic
if ( ( _params . fusion_mode & MASK_USE_EVYAW ) & & ! _control_status . flags . ev_yaw & & _control_status . flags . tilt_align ) {
if ( ( _params . fusion_mode & MASK_USE_EVYAW ) & & ! _control_status . flags . ev_yaw & & _control_status . flags . tilt_align ) {
// check for a exernal vision measurement that has fallen behind the fusion time horizon
// don't start using EV data unless daa is arriving frequently
if ( _time_last_imu - _time_last_ext_vision < 2 * EV_MAX_INTERVAL ) {
if ( _time_last_imu - _time_last_ext_vision < 2 * EV_MAX_INTERVAL ) {
// reset the yaw angle to the value from the observaton quaternion
// reset the yaw angle to the value from the observaton quaternion
// get the roll, pitch, yaw estimates from the quaternion states
// get the roll, pitch, yaw estimates from the quaternion states
@ -207,11 +216,18 @@ void Ekf::controlExternalVisionFusion()
}
}
}
}
// determine if we should use the height observation
// determine if we should start using the height observations
if ( _params . vdist_sensor_type = = VDIST_SENSOR_EV ) {
if ( _params . vdist_sensor_type = = VDIST_SENSOR_EV ) {
setControlEVHeight ( ) ;
// don't start using EV data unless daa is arriving frequently
_fuse_height = true ;
if ( ! _control_status . flags . ev_hgt & & ( _time_last_imu - _time_last_ext_vision < 2 * EV_MAX_INTERVAL ) ) {
setControlEVHeight ( ) ;
resetHeight ( ) ;
}
}
// determine if we should use the vertical position observation
if ( _control_status . flags . ev_hgt ) {
_fuse_height = true ;
}
}
// determine if we should use the horizontal position observations
// determine if we should use the horizontal position observations
@ -224,11 +240,24 @@ void Ekf::controlExternalVisionFusion()
_ev_sample_delayed . posNED ( 0 ) - = pos_offset_earth ( 0 ) ;
_ev_sample_delayed . posNED ( 0 ) - = pos_offset_earth ( 0 ) ;
_ev_sample_delayed . posNED ( 1 ) - = pos_offset_earth ( 1 ) ;
_ev_sample_delayed . posNED ( 1 ) - = pos_offset_earth ( 1 ) ;
_ev_sample_delayed . posNED ( 2 ) - = pos_offset_earth ( 2 ) ;
_ev_sample_delayed . posNED ( 2 ) - = pos_offset_earth ( 2 ) ;
// if GPS data is being used, then use an incremental position fusion method for EV data
if ( _control_status . flags . gps ) {
_hpos_odometry = true ;
}
}
// Fuse available NED position data into the main filter
if ( _fuse_height | | _fuse_pos ) {
fuseVelPosHeight ( ) ;
_fuse_pos = _fuse_height = false ;
}
}
// determine if we should use the yaw observation
// determine if we should use the yaw observation
if ( _control_status . flags . ev_yaw ) {
if ( _control_status . flags . ev_yaw ) {
fuseHeading ( ) ;
fuseHeading ( ) ;
}
}
}
}
@ -245,7 +274,6 @@ void Ekf::controlExternalVisionFusion()
}
}
}
}
}
}
void Ekf : : controlOpticalFlowFusion ( )
void Ekf : : controlOpticalFlowFusion ( )