Link Search Menu Expand Document


voxl-imu-server uses the Snapdragon SDSP (Sensors DSP) to read IMU data at up to 32khz and publish to MPA Pipes with minimal CPU use and latency. It supports up to 4 simultaneous IMUs including IMU0 and IMU1 on VOXL along with up to 2 auxilliary IMUs connected to external SPI ports.

It currently supports the MPU9250, ICM20948, and ICM42688 with internal DLPF and FIFO buffer support guaranteeing repeatable discrete IMU sampling.

Furthermore, voxl-imu-server provides 6-DOF static calibration that calculates and applies static gyroscope and accelerometer offsets, as well as accelerometer scale correction for all 3 axis. An optional temperature calibration routine is also available that measures and corrects for temperature drift using a quadratic model.

While voxl-imu-server can be run manually in interactive mode with a handful of debugging tools, it is generally left running in the background as a service. It will not initialize and spend resources reading an IMU FIFO until a client such as voxl-qvio-server or voxl-inspect-imu subscribes to an IMU pipe.

See the voxl-flight-datasheet-imus page for details on IMU type and Location on VOXL.


Use voxl-configure-imu-server to enable/disable the service. This is all that should be necessary on VOXL. It will set up the IMU sample rates and low pass cutoff frequencies to default values suitable for VIO. These are set at 1khz sample rate and 92hz cutoff frequency respectively. If you absolutely need to change these values then they can be edited in /etc/modalai/voxl-imu-server.conf. Note that currently the calibration routines assume 1khz samples rates and may not run as expected at different sample rates.

Output Type

Data is published at /run/mpa/imu0 and /run/mpa/imu1 with the type imu_data_t as defined in modal_pipe_interfaces.h.

 * This is the data structure that imu servers should make available to clients
 * on the data pipe. (40 bytes long)
typedef struct imu_data_t{
	uint32_t magic_number;  ///< Set to IMU_IMAGE_MAGIC_NUMBER for frame syncing
	float accl_ms2[3];      ///< XYZ acceleration in m/s^2
	float gyro_rad[3];      ///< XYZ gyro rotation in rad/s
	float temp_c;           ///< temp in C, IMU_INVALID_TEMPERATURE_VALUE if no thermometer present
	uint64_t timestamp_ns;  ///< timestamp in nanoseconds, uses system clock_monotonic
} __attribute__((packed)) imu_data_t;

Currently all 3 supported IMUs are configured for their full dynamic range of +-16g and +-2000DPS. All 3 IMUs also publish temperature data.

Inspect Tools

You can inspect imu data with voxl-inspect-imu, voxl-inspect-vibration and voxl-logger.


See the Calibrate IMU page.


The code is available on Gitlab