My device is an OAK-D-LR, and its IMU model is the BNO086. I have configured the sampling frequencies for the accelerometer (acc) and gyroscope (gyro) according to the frequency rules specified at https://docs.luxonis.com/software/depthai-components/nodes/imu/#IMU-IMU%20sensor%20frequencies, as shown in the code below.
int main()
{
/// Create pipeline
dai::Pipeline pipeline;
// IMU
auto imu = pipeline.create<dai::node::IMU>();
// enable ACCELEROMETER_RAW at 250 hz rate
imu->enableIMUSensor(dai::IMUSensor::ACCELEROMETER_RAW, 250);
// enable GYROSCOPE_RAW at 200 hz rate
imu->enableIMUSensor(dai::IMUSensor::GYROSCOPE_RAW, 200);
// it's recommended to set both setBatchReportThreshold and setMaxBatchReports to 20 when integrating in a pipeline with a lot of input/output connections
// above this threshold packets will be sent in batch of X, if the host is not blocked and USB bandwidth is available
imu->setBatchReportThreshold(3);
// 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(30);
auto xoutIMU = pipeline.create<dai::node::XLinkOut>();
xoutIMU->setStreamName("imu");
imu->out.link(xoutIMU->input);
// Connect to device and start pipeline
dai::Device device(pipeline);
std::thread imuThread(imuThreadFunction, std::ref(device));
while(true)
{
// main thread process
}
return 0;
}
void imuThreadFunction(dai::Device& device) {
std::ofstream fw_imu_acc("acc.csv");
std::ofstream fw_imu_gyr("gyr.csv");
auto imuQueue = device.getOutputQueue("imu", 50, true);
while(true) {
try {
auto imuData = imuQueue->get<dai::IMUData>();
auto imuPackets = imuData->packets;
for (auto imuPacket : imuData->packets)
{
auto accValues = imuPacket.acceleroMeter;
auto gyrValues = imuPacket.gyroscope;
size_t t_acc_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(accValues.getTimestampDevice().time_since_epoch()).count();
size_t t_gyr_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(gyrValues.getTimestampDevice().time_since_epoch()).count();
write_imu(t_acc_ns, accValues.x, accValues.y, accValues.z, fw_imu_acc);
write_imu(t_gyr_ns, gyrValues.x, gyrValues.y, gyrValues.z, fw_imu_gyr);
}
}
catch (const std::exception &e)
{
std::cerr << "IMU thread error: " << e.what() << std::endl;
}
}
std::cout << "IMU Thread finished." << std::endl;
}
I analyzed the data obtained from the acc and gyro to determine their respective frame rates. My method was to calculate the difference between consecutive timestamps and then take the reciprocal. Following this, I plotted a histogram of the frequencies.
acc:

gyro:

The results show that the gyroscope's frequency is almost consistently stable at 200Hz, which aligns with my expectations. However, the accelerometer's frequency exhibits two peaks: a dominant peak corresponding to a frame rate of 250Hz and a secondary peak at 125Hz. It appears as though some of the accelerometer data is being dropped.
I would like to know if DepthAI is intentionally performing some operation that actively discards accelerometer data.
Furthermore, I experimented with other frequency settings. For instance, I set the accelerometer to 125Hz and the gyroscope to 100Hz. The results showed a similar pattern: the data stream with the higher frequency always experiences some frame loss (corresponding to two peaks on the histogram), while the frame rate of the lower-frequency stream consistently meets expectations.