# IMU

IMU（[惯性测量单元](https://en.wikipedia.org/wiki/Inertial_measurement_unit)）节点可用于从设备上的 IMU 芯片接收数据。我们的 OAK 设备使用以下两种 IMU 之一：

 * [BNO085](https://www.ceva-ip.com/product/bno-9-axis-imu/)（[数据手册在此](https://eu.mouser.com/datasheet/2/1480/BNO080_085_Datasheet-3196201.pdf)）9
   轴传感器，集成了加速度计、陀螺仪和磁力计。它还在 IMU 芯片内部进行传感器融合。我们已将[此驱动](https://github.com/hcrest/bno080-driver)高效集成到 DepthAI 中。
 * [BMI270](https://www.bosch-sensortec.com/products/motion-sensors/imus/bmi270/) 6 轴传感器，集成了加速度计和陀螺仪。

IMU 芯片通过 SPI 连接到 [RVC](https://docs.luxonis.com/hardware/platform/rvc/rvc2.md#rvc2)。请查看 [OAK
硬件文档](https://docs.luxonis.com/hardware.md)，了解您的 OAK 相机是否集成了 IMU。

## 放置方法

#### Python

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

#### C++

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

## 输入与输出

## 限制

 * 对于 BNO086，陀螺仪频率超过 400Hz 时，由于传感器硬件限制，可能偶尔出现抖动。

> 请注意，所有来自 Kickstarter 的 OAK-D-Lite 相机均未搭载 IMU。

## IMU 传感器频率

以下是每个（原始）IMU 传感器可用的离散 稳定频率。部分 IMU 的最大频率更高，例如 BNO086 陀螺仪的最大频率为 1000Hz，但稳定频率仅到 400Hz（受驱动限制）。

BNO086：

注意：BNO IMU 会将输入频率“向上取整”到下一个可用频率。例如，若设置频率为 101，则会被取整为 200Hz。

 * 加速度计：15Hz、31Hz、62Hz、125Hz、250Hz、500Hz
 * 陀螺仪：25Hz、33Hz、50Hz、100Hz、200Hz、400Hz
 * 磁力计：100Hz

BNO086 最大频率：

| BNO086 传感器 | 最大频率 |
| --- | --- |
| 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：

注意：BMI270 会将输入频率“向下取整”到下一个可用频率。例如，若设置频率为 99，则会被取整为 50Hz。此外，当输入频率大于 400Hz 时，当前最大频率约为 250Hz。

 * 加速度计：25Hz、50Hz、100Hz、200Hz、250Hz
 * 陀螺仪：25Hz、50Hz、100Hz、200Hz、250Hz

## 使用方法

#### Python

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

# 启用 ACCELEROMETER_RAW 和 GYROSCOPE_RAW，频率 100 Hz
imu.enableIMUSensor([dai.IMUSensor.ACCELEROMETER_RAW, dai.IMUSensor.GYROSCOPE_RAW], 100)
# 超过此阈值时，如果主机不阻塞且 USB 带宽可用，数据包将以 X 为一批发送
imu.setBatchReportThreshold(1)
# 每批中 IMU 数据包的最大数量，达到此值后设备将阻塞发送，直到主机能够接收
# 如果小于或等于 batchReportThreshold，则发送将始终在设备上阻塞
# 有助于降低设备的 CPU 负载和减少数据包丢失（当设备端多个节点导致 CPU 负载较高时）
imu.setMaxBatchReports(10)
```

#### C++

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

// 启用 ACCELEROMETER_RAW 和 GYROSCOPE_RAW，频率 100 Hz
imu->enableIMUSensor({dai::IMUSensor::ACCELEROMETER_RAW, dai::IMUSensor::GYROSCOPE_RAW}, 100);
// 超过此阈值时，如果主机不阻塞且 USB 带宽可用，数据包将以 X 为一批发送
imu->setBatchReportThreshold(1);
// 每批中 IMU 数据包的最大数量，达到此值后设备将阻塞发送，直到主机能够接收
// 如果小于或等于 batchReportThreshold，则发送将始终在设备上阻塞
// 有助于降低设备的 CPU 负载和减少数据包丢失（当设备端多个节点导致 CPU 负载较高时）
imu->setMaxBatchReports(10);
```

## IMU 传感器

启用 IMU 传感器时（imu.enableIMUSensor()），您可以选择以下传感器：

 * 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

以下是 所有传感器的描述：

### depthai.IMUSensor

Kind: Class

Available IMU sensors. More details about each sensor can be found in the
datasheet:

https://www.ceva-dsp.com/wp-content/uploads/2019/10/BNO080_085-Datasheet.pdf

Members:

ACCELEROMETER_RAW : Section 2.1.1

Acceleration of the device without any postprocessing, straight from the sensor.
Units are [m/s^2]

ACCELEROMETER : Section 2.1.1

Acceleration of the device including gravity. Units are [m/s^2]

LINEAR_ACCELERATION : Section 2.1.1

Acceleration of the device with gravity removed. Units are [m/s^2]

GRAVITY : Section 2.1.1

Gravity. Units are [m/s^2]

GYROSCOPE_RAW : Section 2.1.2

The angular velocity of the device without any postprocessing, straight from the
sensor. Units are [rad/s]

GYROSCOPE_CALIBRATED : Section 2.1.2

The angular velocity of the device. Units are [rad/s]

GYROSCOPE_UNCALIBRATED : Section 2.1.2

Angular velocity without bias compensation. Units are [rad/s]

MAGNETOMETER_RAW : Section 2.1.3

Magnetic field measurement without any postprocessing, straight from the sensor.
Units are [uTesla]

MAGNETOMETER_CALIBRATED : Section 2.1.3

The fully calibrated magnetic field measurement. Units are [uTesla]

MAGNETOMETER_UNCALIBRATED : Section 2.1.3

The magnetic field measurement without hard-iron offset applied. Units are
[uTesla]

ROTATION_VECTOR : Section 2.2

The rotation vector provides an orientation output that is expressed as a
quaternion referenced to magnetic north and gravity. It is produced by fusing
the outputs of the accelerometer, gyroscope and magnetometer. The rotation
vector is the most accurate orientation estimate available. The magnetometer
provides correction in yaw to reduce drift and the gyroscope enables the most
responsive performance.

GAME_ROTATION_VECTOR : Section 2.2

The game rotation vector is an orientation output that is expressed as a
quaternion with no specific reference for heading, while roll and pitch are
referenced against gravity. It is produced by fusing the outputs of the
accelerometer and the gyroscope (i.e. no magnetometer). The game rotation vector
does not use the magnetometer to correct the gyroscopes drift in yaw. This is a
deliberate omission (as specified by Google) to allow gaming applications to use
a smoother representation of the orientation without the jumps that an
instantaneous correction provided by a magnetic field update could provide. Long
term the output will likely drift in yaw due to the characteristics of
gyroscopes, but this is seen as preferable for this output versus a corrected
output.

GEOMAGNETIC_ROTATION_VECTOR : Section 2.2

The geomagnetic rotation vector is an orientation output that is expressed as a
quaternion referenced to magnetic north and gravity. It is produced by fusing
the outputs of the accelerometer and magnetometer. The gyroscope is specifically
excluded in order to produce a rotation vector output using less power than is
required to produce the rotation vector of section 2.2.4. The consequences of
removing the gyroscope are: Less responsive output since the highly dynamic
outputs of the gyroscope are not used More errors in the presence of varying
magnetic fields.

ARVR_STABILIZED_ROTATION_VECTOR : Section 2.2

Estimates of the magnetic field and the roll/pitch of the device can create a
potential correction in the rotation vector produced. For applications
(typically augmented or virtual reality applications) where a sudden jump can be
disturbing, the output is adjusted to prevent these jumps in a manner that takes
account of the velocity of the sensor system.

ARVR_STABILIZED_GAME_ROTATION_VECTOR : Section 2.2

While the magnetometer is removed from the calculation of the game rotation
vector, the accelerometer itself can create a potential correction in the
rotation vector produced (i.e. the estimate of gravity changes). For
applications (typically augmented or virtual reality applications) where a
sudden jump can be disturbing, the output is adjusted to prevent these jumps in
a manner that takes account of the velocity of the sensor system. This process
is called AR/VR stabilization.

#### ACCELEROMETER: typing.ClassVar[IMUSensor]

Kind: Class Variable

#### ACCELEROMETER_RAW: typing.ClassVar[IMUSensor]

Kind: Class Variable

#### ARVR_STABILIZED_GAME_ROTATION_VECTOR: typing.ClassVar[IMUSensor]

Kind: Class Variable

#### ARVR_STABILIZED_ROTATION_VECTOR: typing.ClassVar[IMUSensor]

Kind: Class Variable

#### GAME_ROTATION_VECTOR: typing.ClassVar[IMUSensor]

Kind: Class Variable

#### GEOMAGNETIC_ROTATION_VECTOR: typing.ClassVar[IMUSensor]

Kind: Class Variable

#### GRAVITY: typing.ClassVar[IMUSensor]

Kind: Class Variable

#### GYROSCOPE_CALIBRATED: typing.ClassVar[IMUSensor]

Kind: Class Variable

#### GYROSCOPE_RAW: typing.ClassVar[IMUSensor]

Kind: Class Variable

#### GYROSCOPE_UNCALIBRATED: typing.ClassVar[IMUSensor]

Kind: Class Variable

#### LINEAR_ACCELERATION: typing.ClassVar[IMUSensor]

Kind: Class Variable

#### MAGNETOMETER_CALIBRATED: typing.ClassVar[IMUSensor]

Kind: Class Variable

#### MAGNETOMETER_RAW: typing.ClassVar[IMUSensor]

Kind: Class Variable

#### MAGNETOMETER_UNCALIBRATED: typing.ClassVar[IMUSensor]

Kind: Class Variable

#### ROTATION_VECTOR: typing.ClassVar[IMUSensor]

Kind: Class Variable

#### __members__: typing.ClassVar[dict[str, IMUSensor]]

Kind: Class Variable

#### __eq__(self, other: typing.Any) -> bool: bool

Kind: Method

#### __getstate__(self) -> int: int

Kind: Method

#### __hash__(self) -> int: int

Kind: Method

#### __index__(self) -> int: int

Kind: Method

#### __init__(self, value: typing.SupportsInt)

Kind: Method

#### __int__(self) -> int: int

Kind: Method

#### __ne__(self, other: typing.Any) -> bool: bool

Kind: Method

#### __repr__(self) -> str: str

Kind: Method

#### __setstate__(self, state: typing.SupportsInt)

Kind: Method

#### __str__(self) -> str: str

Kind: Method

#### name

Kind: Property

#### value

Kind: Property

## 功能示例

 * [IMU 加速度计与陀螺仪](https://docs.luxonis.com/software/depthai/examples/imu_accelerometer_gyroscope.md)
 * [IMU 旋转向量](https://docs.luxonis.com/software/depthai/examples/imu_rotation_vector.md)

## 参考

### depthai.node.IMU(depthai.Node)

Kind: Class

IMU node for BNO08X.

#### enableFirmwareUpdate(self, arg0: bool)

Kind: Method

#### enableIMUSensor()

Kind: Method

#### getBatchReportThreshold(self) -> int: int

Kind: Method

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

#### getMaxBatchReports(self) -> int: int

Kind: Method

Maximum number of IMU packets in a batch report

#### setBatchReportThreshold(self, batchReportThreshold: typing.SupportsInt)

Kind: Method

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

#### setMaxBatchReports(self, maxBatchReports: typing.SupportsInt)

Kind: Method

Maximum number of IMU packets in a batch report

#### out

Kind: Property

Outputs IMUData message that carries IMU packets.

### 需要帮助？

请前往 [OAKChina 官网](https://www.oakchina.cn/) 获取技术支持或解答您的任何疑问。
