Link Search Menu Expand Document


voxl-qvio-server is a Visual Inertial Odometry service that uses the Qualcomm MV SDK mvVISLAM algorithm. This is the basis for indoor flight and navigation.

Table of contents

  1. Inputs
  2. Outputs
  3. voxl-inspect-qvio
  4. Quality
  5. Resetting VIO
  6. Camera-IMU extrinsic Relation
  7. Camera and IMU Calibration
  8. Output Coordinate Frame
  9. Source


voxl-qvio-server currently only supports the fisheye tracking camera published at the pipe /run/mpa/tracking with support for other cameras planned for the future.

It will consume IMU data from any pipe that publishes the standard libmodal_pipe imu_data_t type defined in modal_pipe_interfaces.h. This is configurable in /etc/modalai/voxl-qvio-server.conf and the server will advertizes the name of the IMU it is using to the info file in both output pipes so that consumers know what coordinate frame the VIO data is with respect to.


voxl-qvio-server publishes two pipes: /run/mpa/qvio and /run/mpa/qvio_extended

The first pipe, /run/mpa/qvio, is the more simple data and publishes the common vio_data_t type from modal_pipe_interfaces.h. This is what is consumed by voxl-vision-px4.

The second pipe, qvio_extended, publishes a larger struct, qvio_data_t, which is a superset of vio_data_t and contains lower level data specific to the QVIO algorithm and is helpful for debugging. The qvio_data_t struct is defined here and is currently only used by voxl-inspect-qvio.


Most voxl-inspect-*** tools are generic and live in the voxl-mpa-tools package. However, voxl-inspect-qvio is specifically for inspecting the qvio_data_t type and so it lives in the voxl-qvio-server project. For more details see the voxl-inspect-qvio page.


Both vio_data_t and qvio_data_t structs contain a quality field which has no strict definition and will vary between VIO algorithms. Quality is be >0 in normal use with a larger number indicating higher quality. A positive quality does not guarantee the algorithm has initialized completely. A value of -1 means the algorithm is still initializing or has failed.

The quality is calculated by inverting the “worst” diagonal entry of the covariance matrix. This results in a higher number when the VIO Kalman Filter is behaving well and a worse number in high noise or low feature conditions. The highest quality numbers will be observed when the camera is extremely close to feature points.

voxl-vision-px4 will automatically send the reset command to voxl-qvio-server if it detects a quality below 0.0005 which is low enough to indicate the kalman filter has diverged.

Resetting VIO

If the drone encounters difficult conditions that cause the kalman filter to diverge we call this a “blow up”. voxl-qvio-server will try to recover from this if the drone is left stationary after a blowup, but it is usually recommended to reset the kalman filter. This can also be done preemptively if the drone has been sitting still for a very long time, or the user wishes to reset VIO to a new local coordinate frame centered at the drone’s new location.

This can be done with the voxl-reset-qvio command

yocto:/$ voxl-reset-qvio
Sending hard reset command to voxl-qvio-server

Camera-IMU extrinsic Relation

One of the most important configuration steps for reliable VIO performance is the extrinsic relation between the camera and IMU. This is set in the /etc/modalai/extrinsics.conf file. voxl-configure-mpa and voxl-configure-extrinsics will configure this file correctly for all ModalAI reference platforms.

For help on this, see the configure extrinsics page and

Camera and IMU Calibration

A well calibrated IMU and tracking camera lens will also help VIO performance significatly. If you are having VIO issues, ensure there is a tracking calibration file at /data/modalai/opencv_tracking_intrinsics.yml and real (e.g. non-zero) data in the /data/modalai/ file.

Output Coordinate Frame

QVIO and most other VIO algorithms output position and velocity with respect to the IMU’s coordinate frame. On the VOXL Flight deck, M500, and Starling, the IMU aligns with NED/FRD frame by design for easy debugging. This means the the output from voxl-inspect-qvio will align with normal PX4 NED/FRD frame. However, if the VOXL is oriented differently on your configuration, then the output from QVIO will align with however you have your VOXL board oriented which is fine! For example, on Seeker voxl-inspect-qvio shows Z pointing out the nose of the drone.

It’s the job of voxl-vision-px4 to both rotate AND translate VIO data into a local reference frame for PX4 to consume. It does this by looking at the relation between IMU frame and body frame in /etc/modalai/extrinsics.conf for the specific IMU that voxl-qvio-server advertises that it is using. This accounts for the position and orientation of the IMU relative to the drone’s center of mass.

For more details on how those coordinate frames relate to one another, see the voxl-vision-px4 apriltag relocalization page.


Source code available on Gitlab.