IMU

IMU (inertial measurement unit) node can be used to receive data from the IMU chip on the device. Our OAK devices use either:

  • BNO085 (datasheet here) 9-axis sensor, combining accelerometer, gyroscope, and magnetometer. It also does sensor fusion on the (IMU) chip itself. We have efficiently integrated this driver into the DepthAI.

  • BMI270 6-axis sensor, combining accelerometer and gyroscope.

The IMU chip is connected to the RVC over SPI. See OAK Hardware documentation to check whether your OAK camera has IMU integrated.

How to place it

pipeline = dai.Pipeline()
imu = pipeline.create(dai.node.IMU)
dai::Pipeline pipeline;
auto imu = pipeline.create<dai::node::IMU>();

Inputs and Outputs

┌──────────────┐
│              │
│              │      out
│     IMU      ├─────────►
│              │
│              │
└──────────────┘

Message types

Limitations

  • For BNO086, gyroscope frequency above 400Hz can produce some jitter from time to time due to sensor HW limitation.

IMU sensor frequencies

Below are the discrete stable frequencies available for each (raw) IMU sensor. Some maximum IMU frequencies are higher, eg. for BNO086, maximum frequency for gyroscope is 1000Hz, but up to 400Hz is stable (due to driver limitation).

BNO086:

Note that BNO IMU “rounds up” the input frequency to the next available frequency. For example, if you set the frequency to 101 it will round it to 200Hz.

  • Accelerometer: 15Hz, 31Hz, 62Hz, 125Hz, 250Hz 500Hz

  • Gyroscope: 25Hz, 33Hz, 50Hz, 100Hz, 200Hz, 400Hz

  • Magnetometer: 100Hz

BNO086 max frequency:

BNO086 Sensor

Max Frequency

ACCELEROMETER_RAW

512 Hz

ACCELEROMETER

512 Hz

LINEAR_ACCELERATION

400 Hz

GRAVITY

400 Hz

GYROSCOPE_RAW

1000 Hz

GYROSCOPE_CALIBRATED / GYROSCOPE_UNCALIBRATED

100 Hz

MAGNETOMETER_RAW

100 Hz

MAGNETOMETER_CALIBRATED / MAGNETOMETER_UNCALIBRATED

100 Hz

ROTATION_VECTOR

400 Hz

GAME_ROTATION_VECTOR

400 Hz

GEOMAGNETIC_ROTATION_VECTOR

100 Hz

ARVR_STABILIZED_ROTATION_VECTOR

100 Hz

ARVR_STABILIZED_GAME_ROTATION_VECTOR

100 Hz

BMI270:

Note that BMI279 “rounds down” the input frequency to the next available frequency. For example, if you set the frequency to 99 it will round it to 50Hz. Additionally, the current max frequency of ~250 Hz is set when the input is >400Hz.

  • Accelerometer: 25Hz, 50Hz, 100Hz, 200Hz, 250Hz

  • Gyroscope: 25Hz, 50Hz, 100Hz, 200Hz, 250Hz

Usage

pipeline = dai.Pipeline()
imu = pipeline.create(dai.node.IMU)

# enable ACCELEROMETER_RAW and GYROSCOPE_RAW at 100 hz rate
imu.enableIMUSensor([dai.IMUSensor.ACCELEROMETER_RAW, dai.IMUSensor.GYROSCOPE_RAW], 100)
# above this threshold packets will be sent in batch of X, if the host is not blocked and USB bandwidth is available
imu.setBatchReportThreshold(1)
# maximum number of IMU packets in a batch, if it's reached device will block sending until host can receive it
# if lower or equal to batchReportThreshold then the sending is always blocking on device
# useful to reduce device's CPU load  and number of lost packets, if CPU load is high on device side due to multiple nodes
imu.setMaxBatchReports(10)
dai::Pipeline pipeline;
auto imu = pipeline.create<dai::node::IMU>();

// enable ACCELEROMETER_RAW and GYROSCOPE_RAW at 100 hz rate
imu->enableIMUSensor({dai::IMUSensor::ACCELEROMETER_RAW, dai::IMUSensor::GYROSCOPE_RAW}, 100);
// above this threshold packets will be sent in batch of X, if the host is not blocked and USB bandwidth is available
imu->setBatchReportThreshold(1);
// maximum number of IMU packets in a batch, if it's reached device will block sending until host can receive it
// if lower or equal to batchReportThreshold then the sending is always blocking on device
// useful to reduce device's CPU load  and number of lost packets, if CPU load is high on device side due to multiple nodes
imu->setMaxBatchReports(10);

IMU sensors

When enabling the IMU sensors (imu.enableIMUSensor()), you can select between the following sensors:

  • ACCELEROMETER_RAW

  • ACCELEROMETER

  • LINEAR_ACCELERATION

  • GRAVITY

  • GYROSCOPE_RAW

  • GYROSCOPE_CALIBRATED

  • GYROSCOPE_UNCALIBRATED

  • MAGNETOMETER_RAW

  • MAGNETOMETER_CALIBRATED

  • MAGNETOMETER_UNCALIBRATED

  • ROTATION_VECTOR

  • GAME_ROTATION_VECTOR

  • GEOMAGNETIC_ROTATION_VECTOR

  • ARVR_STABILIZED_ROTATION_VECTOR

  • ARVR_STABILIZED_GAME_ROTATION_VECTOR

Here are descriptions of all sensors:

class depthai.IMUSensor

Members:

ACCELEROMETER_RAW

ACCELEROMETER

LINEAR_ACCELERATION

GRAVITY

GYROSCOPE_RAW

GYROSCOPE_CALIBRATED

GYROSCOPE_UNCALIBRATED

MAGNETOMETER_RAW

MAGNETOMETER_CALIBRATED

MAGNETOMETER_UNCALIBRATED

ROTATION_VECTOR

GAME_ROTATION_VECTOR

GEOMAGNETIC_ROTATION_VECTOR

ARVR_STABILIZED_ROTATION_VECTOR

ARVR_STABILIZED_GAME_ROTATION_VECTOR

Reference

class depthai.node.IMU
class Id

Node identificator. Unique for every node on a single Pipeline

enableFirmwareUpdate(self: depthai.node.IMU, arg0: bool)None
enableIMUSensor(*args, **kwargs)

Overloaded function.

  1. enableIMUSensor(self: depthai.node.IMU, sensorConfig: depthai.IMUSensorConfig) -> None

  2. enableIMUSensor(self: depthai.node.IMU, sensorConfigs: list[depthai.IMUSensorConfig]) -> None

  3. enableIMUSensor(self: depthai.node.IMU, sensor: depthai.IMUSensor, reportRate: int) -> None

  4. enableIMUSensor(self: depthai.node.IMU, sensors: list[depthai.IMUSensor], reportRate: int) -> None

getAssetManager(*args, **kwargs)

Overloaded function.

  1. getAssetManager(self: depthai.Node) -> depthai.AssetManager

  2. getAssetManager(self: depthai.Node) -> depthai.AssetManager

getBatchReportThreshold(self: depthai.node.IMU)int
getInputRefs(*args, **kwargs)

Overloaded function.

  1. getInputRefs(self: depthai.Node) -> list[depthai.Node.Input]

  2. getInputRefs(self: depthai.Node) -> list[depthai.Node.Input]

getInputs(self: depthai.Node)list[depthai.Node.Input]
getMaxBatchReports(self: depthai.node.IMU)int
getName(self: depthai.Node)str
getOutputRefs(*args, **kwargs)

Overloaded function.

  1. getOutputRefs(self: depthai.Node) -> list[depthai.Node.Output]

  2. getOutputRefs(self: depthai.Node) -> list[depthai.Node.Output]

getOutputs(self: depthai.Node)list[depthai.Node.Output]
getParentPipeline(*args, **kwargs)

Overloaded function.

  1. getParentPipeline(self: depthai.Node) -> depthai.Pipeline

  2. getParentPipeline(self: depthai.Node) -> depthai.Pipeline

setBatchReportThreshold(self: depthai.node.IMU, batchReportThreshold: int)None
setMaxBatchReports(self: depthai.node.IMU, maxBatchReports: int)None
class dai::node::IMU : public dai::NodeCRTP<Node, IMU, IMUProperties>

IMU node for BNO08X.

Public Functions

IMU(const std::shared_ptr<PipelineImpl> &par, int64_t nodeId)

Constructs IMU node.

IMU(const std::shared_ptr<PipelineImpl> &par, int64_t nodeId, std::unique_ptr<Properties> props)
void enableIMUSensor(IMUSensorConfig sensorConfig)

Enable a new IMU sensor with explicit configuration

void enableIMUSensor(const std::vector<IMUSensorConfig> &sensorConfigs)

Enable a list of IMU sensors with explicit configuration

void enableIMUSensor(IMUSensor sensor, uint32_t reportRate)

Enable a new IMU sensor with default configuration

void enableIMUSensor(const std::vector<IMUSensor> &sensors, uint32_t reportRate)

Enable a list of IMU sensors with default configuration

void setBatchReportThreshold(std::int32_t batchReportThreshold)

Above this packet threshold data will be sent to host, if queue is not blocked

std::int32_t getBatchReportThreshold() const

Above this packet threshold data will be sent to host, if queue is not blocked

void setMaxBatchReports(std::int32_t maxBatchReports)

Maximum number of IMU packets in a batch report

std::int32_t getMaxBatchReports() const

Maximum number of IMU packets in a batch report

void enableFirmwareUpdate(bool enable)

Public Members

Output out = {*this, "out", Output::Type::MSender, {{DatatypeEnum::IMUData, false}}}

Outputs IMUData message that carries IMU packets.

Public Static Attributes

static constexpr const char *NAME = "IMU"

Got questions?

Head over to Discussion Forum for technical support or any other questions you might have.