Visual Inertial Odometry
Visual Inertial Odometry (VIO) is the bigger sibling of optical flow. Where optical flow gives you horizontal velocity from a downward camera plus a rangefinder, VIO gives you a full 6-degree-of-freedom pose (position and orientation in three dimensions) from a forward or downward camera fused with the FC’s IMU.VIO ships in the plugin. Two engines (OpenVINS and VINS-Fusion) ride inside the signed plugin archive as vendor binaries. They stay on disk and never run until you select a VIO mode. VIO needs a one-time camera-IMU calibration and a board with an NPU or a strong multicore CPU; on a weak board the estimator cannot keep up. For low-altitude GPS-denied flight on light hardware, the optical-flow modes are the simpler path.
What it adds
Optical flow tells the EKF “the drone is moving north at 2.1 m/s.” VIO tells the EKF “the drone is at (12.3, 4.7, 1.8) meters from the origin, rolled 2 degrees, pitched 5 degrees, yawed 18 degrees, and moving at (1.4, 1.0, 0.0) m/s.” The richer state lets the FC do things optical flow can’t:- Fly at altitudes where the rangefinder can’t see the ground (above 10 m on most sensors).
- Follow corridors and tunnels where the downward camera has nothing to track.
- Maintain heading-relative position over long flights without GPS or compass drift.
- Land on uneven terrain by combining VIO altitude with the IMU’s gravity vector.
Two engines, side by side
The plugin ships two VIO modes:vio_openvinsuses OpenVINS, a filter-based (MSCKF) estimator. Lower CPU cost, strong on fast motion, slightly looser bound on long-flight drift.vio_vins_fusionuses VINS-Fusion, a sliding-window bundle-adjustment estimator. Higher CPU cost, tighter drift bound in feature-rich scenes, stronger in low-feature or texture-poor environments.
Hardware requirements
The plugin’s VIO modes target a monocular forward-facing or downward-facing camera plus the FC IMU. Stereo and full-SLAM (loop-closure) engines are not in this release; the architecture leaves the seam open.
Camera: a forward-facing or downward-facing camera at 30 Hz, 640x480 or
higher. A rolling-shutter camera works but is more sensitive to fast
motion. Global shutter is strongly preferred.
IMU: the FC’s IMU, sampled through MAVLink
RAW_IMU (the universal
path every FC publishes). A higher-rate direct IMU path (a direct-I2C
BMI088 at around 400 Hz) is a planned addition; until it lands the
MAVLink path is the only source.
How it plugs in
The VIO engine runs as a vendor binary inside the plugin’s process sandbox, started by the plugin and watched by a heartbeat watchdog. The Rust agent reads frames from the shared vision frame bus and bridges them into the engine’s shared-memory ring (zero-copy); IMU samples and control messages flow through a Unix-domain socket encoded as length-prefixed msgpack. Pose estimates flow back over the same socket. The plugin then emitsVISION_POSITION_ESTIMATE on MAVLink
component 197 (MAV_COMP_ID_VISUAL_INERTIAL_ODOMETRY) at the camera
frame rate (around 30 Hz). ArduPilot’s EKF3 fuses these messages when
EK3_SRC1_POSXY, EK3_SRC1_VELXY, and EK3_SRC1_YAW are set to
ExternalNav (6). PX4’s EKF2 fuses them when EKF2_EV_CTRL enables
external vision.
The IPC protocol is documented in the
Architecture page. Adding a
third engine (a future home-grown estimator) is a new VIO engine
variant plus a vendor binary that speaks the same protocol.
Calibration
VIO needs calibrated intrinsics and known camera-IMU extrinsics including the static time offset between the two clocks. The plugin accepts Kalibr-compatiblecamchain.yaml files directly, or you can
run the guided in-app wizard. See
Calibration for the full
workflow.
The pre-arm gate refuses to arm a VIO mode without loaded
calibration files. The GCS sensors card surfaces a Calibrate prompt
when intrinsics are not yet loaded.
License compliance
Both OpenVINS and VINS-Fusion are GPL-3.0-licensed. Shipping a pre-compiled binary inside the plugin archive carries the GPL source-offer obligation. The plugin’s manifest declares avendor_attribution block for each engine with the upstream
repository, the license, the upstream version, and a notice. The
install dialog surfaces these blocks during the summary stage so
operators see what they are installing.
When to use VIO vs optical flow
If you fly close to the ground (under 8 m), have a downward camera, and need stable hover and waypoint flight, the optical-flow modes are the simpler path. See Configure optical flow for the setup. If you fly at altitude, in long corridors, or in environments where the downward camera has nothing to track, VIO is the mode you want, on a board with the compute to run it.Stay in the loop
Plugin updates are announced through the standard channels:- The ADOSExtensions GitHub repository’s release feed.
- The Mission Control update notifier (in-app banner when a new plugin version is published).
- Community channels listed in Open source.