Skip to main content
The VESC firmware includes a full inertial measurement unit (IMU) subsystem that reads accelerometer and gyroscope data, fuses the measurements into an attitude estimate, and exposes roll, pitch, and yaw angles to applications such as balance controllers and ride-assist systems.

Supported IMU chips

The active chip is selected by the IMU_TYPE enum in datatypes.h:

BMI160

Bosch 6-axis IMU (accelerometer + gyroscope). Supported over both I²C and SPI. Widely used on VESC Express and custom hardware.

ICM20948

TDK InvenSense 9-axis IMU (accelerometer + gyroscope + magnetometer). Supported over I²C. Includes magnetometer support for heading estimation.

LSM6DS3

STMicroelectronics 6-axis IMU (accelerometer + gyroscope). Supported over I²C.

MPU9150 / MPU9250

TDK InvenSense 9-axis IMU family. Supported over I²C via the imu_init_mpu9x50 path.
The IMU_TYPE_INTERNAL option uses an IMU soldered directly onto the VESC controller PCB, wired to fixed I²C or SPI pins defined in the hardware configuration.

What IMU data is used for

The firmware provides processed IMU output to application-layer code through the following functions:

Primary use cases

  • Self-balancing (balance board / unicycle): Pitch angle and angular rate are the primary feedback signals for the PID or LQR balancing controller.
  • Ride-assist and lean detection: Roll angle is used to detect when the rider leans into a turn.
  • Motor orientation correction: imu_derotate() transforms sensor-frame vectors to the motor-frame, compensating for the physical mounting angle of the controller.
  • Custom applications via LispBM: Roll, pitch, yaw, and raw sensor values are exposed to LispBM scripts for user-defined control logic.

AHRS — attitude and heading reference system

Raw gyroscope and accelerometer data is fused into a quaternion-based attitude estimate by the AHRS module (imu/ahrs.c). The firmware implements three filter variants, selectable through the AHRS_MODE enum:
Sebastian Madgwick’s gradient-descent algorithm. Uses only accelerometer and gyroscope data (6-DOF). Controlled by a single beta gain parameter that trades dynamic response for noise rejection.
Madgwick’s implementation of Mahony’s complementary filter. Also 6-DOF (gyro + accel). Controlled by proportional gain kp and integral gain ki. The integral term compensates for gyroscope bias drift.
Extended Madgwick filter that incorporates magnetometer data when available (e.g., ICM20948, MPU9150). Provides absolute heading (yaw) in addition to roll and pitch.

Configuration parameters (imu_config)

The full IMU configuration is stored in the imu_config struct:

Tuning guidance

Calibration

The IMU module supports runtime calibration:
Run calibration with the vehicle stationary on a level surface. The accelerometer offsets are stored in imu_config.accel_offsets and gyro_offsets and written to flash with the rest of the app configuration.

Custom data callback

For advanced use cases — such as a custom IMU chip or external sensor fusion — you can inject raw sensor data directly into the AHRS pipeline:
When a callback is registered, the firmware skips the hardware chip read and calls your function instead, passing pre-allocated arrays for acceleration (m/s²), angular rate (rad/s), magnetometer (µT), and the time step dt in seconds.