claudeDroneteam-docs
documentation · reference
Docs reference

Structured knowledge from collected_doc_media/claudedrone_docs/. Browse the tree on the left; the source of truth is markdown in the repo.

EKF3 multi-sensor fusion — rangefinder + optical flow + IMU (research)

How ArduCopter's EKF3 fuses IMU + downward rangefinder + optical flow for GPS-denied indoor navigation. `EK3_SRC1_*` parameters and typical init issues.

stableresearchbestupdated 2026-05-11T00:00:00.000ZClaudeDroneResearchEKF3FusionArduPilotIndoorNav

What EKF3 is in ArduCopter

EKF3 (Extended Kalman Filter version 3) is ArduCopter’s main state estimator. It takes raw sensor data and produces a fused estimate of position / velocity / attitude.

Without EKF3, no arming → no flight. Indoor (no GPS) — EKF3 must build on rangefinder + optical flow + IMU.

EKF3 sources — EK3_SRC1_* parameters

Parameter What Indoor value
EK3_SRC1_POSXY XY-position source 0 (none — no GPS)
EK3_SRC1_VELXY XY-velocity source 5 (optical flow PMW3901/CXOF)
EK3_SRC1_POSZ Z-position source 2 (rangefinder TF-Luna down)
EK3_SRC1_VELZ Z-velocity source 0 (none, derive from POSZ)
EK3_SRC1_YAW Yaw source 1 (compass) or 0 (gyro-only)

Typical issue — EKF doesn’t initialize

Symptom: AP: EKF3 IMU0 initialised appears, then AP: Arm: Accels inconsistent / Gyros inconsistent for 15-25 seconds (normal for SITL without accel calib) → then either armed succeed, or stuck.

Stuck if:

  1. EK3_SRC1_VELXY=5 (optical flow) but flow data isn’t arriving (sensor offline) → EKF3 has no XY velocity → doesn’t converge.
  2. EK3_SRC1_POSZ=2 (rangefinder) but RNGFND1_TYPE=0 → no data for Z.
  3. EKF3 expects all sources online before init completes. One missing source → infinite wait.

Fix: first verify via param show EK3_SRC1* + param show RNGFND1* + param show FLOW* that all sources are configured. Then param show STAT_BOOTCNT after reboot — if it grows, EKF can’t finish init.

Minimal EKF3 indoor configuration (for SITL)

# From indoor.parm:
GPS1_TYPE       0
ARMING_SKIPCHK  1
EK3_SRC1_POSXY  0
EK3_SRC1_VELXY  5   # optical flow
EK3_SRC1_POSZ   2   # rangefinder
FLOW_TYPE       6   # MAVLink-based optical flow (CXOF/external)
RNGFND1_TYPE    10  # MAVLink-based rangefinder
RNGFND1_ORIENT  25  # downward facing (POSZ source)

Detailed line-by-line breakdown — see arducopter-params-indoor.

EKF3 init timeline (normal)

t=0:    SITL boots
t=2s:   AP: EKF3 IMU0 initialised
t=5s:   AP: GPS unhealthy (expected for indoor)
t=5-25s: AP: Arm: Accels inconsistent (×3-5)
        AP: Arm: Gyros inconsistent (×3-5)        ← EKF3 settling
t=25s:  EKF healthy, ready to ARM

When EKF3 sources don’t match

If EK3_SRC1_POSZ=2 (rangefinder) but the rangefinder isn’t connected — you need either:

  • Change EK3_SRC1_POSZ=0 (fallback to baro) — not accurate indoor
  • Bring up the rangefinder bridge (MAVROS publishes /mavros/rangefinder/rangefinder → ArduPilot consumes via RNGFND1_TYPE=10)

Sensor sources matrix (by type)

EK3_SRC1_* Value Source
*_POSXY=0 None no GPS
*_POSXY=3 GPS outdoor
*_POSXY=5 ExternalNav ROS 2 + SLAM publish via MAVROS
*_VELXY=0 None derive
*_VELXY=5 OpticalFlow PMW3901/CXOF
*_VELXY=3 GPS outdoor
*_POSZ=2 Rangefinder TF-Luna down
*_POSZ=1 Baro default outdoor
*_POSZ=3 GPS outdoor

Sources

  1. ArduPilot wiki — EK3 estimator overview + parameters
  2. ArduPilot wiki — Non-GPS Navigation (indoor)
  3. ArduPilot discourse — EKF3 troubleshooting threads
  4. Source code libraries/AP_NavEKF3/ — implementation reference
© 2026 claudeDrone Team · auto-pipeline · Nuxt 3 SSR