libbno055-linux¶
View the Official Web Documentation (API, Architecture, Integration Guides)
C++17 BNO055 library and ROS 2 nodes for Linux.
Features¶
Standalone C++17 library: Link natively via CMake without ROS dependencies.
Native I2C & UART Support: Fully implements the BNO055 binary protocol for both I2C (
/dev/i2c-*) and USB-to-UART (/dev/ttyUSB*) using fast, low-level POSIX APIs.Full Telemetry Parity: Publishes standard IMU data, raw unfiltered data (
imu/raw), gravity vectors (imu/gravity), and calibration status via JSON (~/calib_status) anddiagnostic_msgs::msg::DiagnosticStatus(~/status).Hardware Reset & Calibration Services: Provides
~/resetfor software-triggered hardware resets and~/calibration_requestfor dynamic calibration state queries.ROS 2 nodes: Provides high-performance standard and lifecycle node interfaces.
Automatic Recovery: Implements automatic recovery for
EIOfaults, clock stretching issues, and UARTBUS_OVER_RUNerrors.No heap allocations: Avoids dynamic memory allocation in hot sensor readout paths.
Zero-copy publishers: Implements zero-copy memory transport (
std::unique_ptr) for ROS 2 publishers.Built-in I2C mocking: Provides built-in I2C mocking for compilation and testing on macOS/Windows.
High-Performance EKF Burst Read (New): Sequentially reads 18 bytes of raw sensor outputs (Accel, Mag, Gyro) in a single transaction, reducing bus latency by 3x.
Linux GPIO Interrupt (IRQ) Driven Mode (New): Bypasses polling loops. Detects rising edge events on the physical INT pin using Linux
poll(), triggering callbacks at sub-millisecond latency.Single-Precision float Optimizations (New): Swapped double-precision floats to 32-bit floats across all vectors and quaternion math to unlock hardware FPU speeds on ARM processors (e.g., Raspberry Pi).
High-Performance & State Estimation (EKF) Features¶
If you are developing a custom state estimator (Extended Kalman Filter / Complementary Filter) or using robot_localization, raw sensor throughput and latency determinism are critical.
libbno055-linux provides:
18-Byte Burst Read: Reads Accelerometer, Magnetometer, and Gyroscope raw variables in a single sequential bus transaction (~450µs at 400kHz I2C).
High-Frequency Polling: Low-jitter background polling threads up to 200Hz.
GPIO Interrupt (IRQ) Driven Mode: POSIX
poll()edge event detection on the physical INT pin for sub-millisecond response.
[!TIP] Complete C++ code examples for these APIs, EKF configuration files (
ekf.yaml) for ROS 2robot_localization, and kernel real-time scheduling setup are located in the Advanced Integration & Kernel Tuning Guide. For function signatures and types, see the API Reference.
Quick Start¶
A. Standalone C++ (No-ROS)¶
Build and Install:
sudo apt update && sudo apt install -y build-essential cmake git clone https://github.com/lazytatzv/libbno055-linux.git cd libbno055-linux && mkdir build && cd build cmake .. -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=ON make -j$(nproc) && sudo make install
Write your code (
main.cpp):#include <libbno055-linux/bno055.hpp> #include <iostream> #include <thread> int main() { // Initialize via I2C (Default) // bno055lib::BNO055 imu(0x28, "/dev/i2c-1"); // OR Initialize via UART bno055lib::BNO055::UARTConfig uart_cfg; uart_cfg.port = "/dev/ttyUSB0"; uart_cfg.baudrate = 115200; bno055lib::BNO055 imu(uart_cfg); // Initialize in NDOF fusion mode if (!imu.begin(bno055lib::OpMode::NDOF)) { std::cerr << "Sensor initialization failed!\n"; return 1; } // Configure automatic calibration loading & saving imu.enableAutoCalibration("/etc/robot_config/bno055_offsets.bin"); for (int i = 0; i < 10; ++i) { // Orientation (Euler Angles converted from Quaternion) if (auto q = imu.getQuaternionNoexcept()) { auto euler = bno055lib::toEulerDegrees(*q); std::cout << "Euler (deg): Roll=" << euler.x << " Pitch=" << euler.y << " Yaw=" << euler.z << "\n"; } // Acceleration if (auto acc = imu.getAccelerometerNoexcept()) { std::cout << "Accel (m/s^2): X=" << acc->x << " Y=" << acc->y << " Z=" << acc->z << "\n"; } // Calibration Status auto calib = imu.getCalibrationStatus(); std::cout << "Calibration: SYS=" << static_cast<int>(calib.sys) << " GYRO=" << static_cast<int>(calib.gyro) << "\n"; // Temperature std::cout << "Temperature: " << static_cast<int>(imu.getTemperature()) << " C\n\n"; std::this_thread::sleep_for(std::chrono::milliseconds(100)); } return 0; }
Compile and Run:
g++ -std=c++17 main.cpp -lbno055-linux -lpthread -o imu_demo ./imu_demo
B. ROS 2 (colcon workspace)¶
Clone and Build:
# Clone inside your ROS 2 workspace src directory cd ~/ros2_ws/src git clone https://github.com/lazytatzv/libbno055-linux.git # Resolve dependencies and build cd ~/ros2_ws rosdep install --from-paths src --ignore-src -y colcon build --packages-select libbno055_linux source install/setup.bash
Launch with Parameters: Launch the high-performance zero-copy node (default) or the lifecycle node:
ros2 launch libbno055_linux bno055_launch.py
C. ROS 2 API Reference¶
Published Topics¶
Topic Name |
Message Type |
Description |
|---|---|---|
|
|
Fused IMU data (Orientation, Angular Velocity, Linear Acceleration). |
|
|
Raw, unfiltered Accelerometer and Gyroscope data. |
|
|
Raw Magnetic Field data. |
|
|
Ambient Temperature data. |
|
|
Gravity vector (available in fusion modes). |
|
|
Hardware and calibration status compatibility topic. |
|
|
JSON formatted real-time calibration levels (Sys, Gyro, Accel, Mag). |
|
|
Standard ROS 2 diagnostics stream (heartbeat, error rates, dropped reads). |
Services¶
Service Name |
Service Type |
Description |
|---|---|---|
|
|
Saves the current calibration offsets to the file specified in parameters. |
|
|
Immediately responds with a JSON string of the current calibration status. |
|
|
Triggers a software hardware-reset of the BNO055 and reinitializes it automatically. |
Core Parameters¶
Parameter |
Default |
Description |
|---|---|---|
|
|
|
|
|
Path to the I2C device node (used if |
|
|
I2C address of the sensor ( |
|
|
Path to the UART device node (used if |
|
|
Baudrate for the UART connection. |
|
|
Sensor fusion mode ( |
|
|
Publishing frequency in Hz. |
|
|
TF frame ID attached to message headers. |
|
|
Enable automatic loading and saving of the calibration binary profile. |
Detailed Project Documentation¶
For advanced configuration, integration, and detailed specifications, please refer to the dedicated markdown files in the docs/ directory or view the Official Web Documentation.
API Reference: Full class, struct, and function reference for
bno055lib::BNO055.Advanced Integration & Kernel Tuning Guide: Details on CMake integration, ROS 2 configuration parameters, I2C speed configurations (400kHz), UART driver optimizations,
PREEMPT_RTscheduler priorities, and isolated CPU cores.Architecture & Design Decisions: Details on PIMPL compilation firewall, thread safety, auto-recovery state machine,
TransportDI abstraction, float math FPU optimizations, and lock granularity scopes.Sensor Overview & Calibration: Detailed specs on BNO055 fusion modes, sensor coordinate systems, and saving/restoring calibration offsets.
Troubleshooting & FAQ: Solutions for I2C permission denied, Raspberry Pi clock stretching lockups, and indoor magnetic interference.
Hardware Configuration (Prerequisites)¶
Ensure the physical sensor is wired correctly and I2C permissions are set up on your Linux machine.
1. Wiring (Raspberry Pi Example)¶
BNO055 Pin |
Raspberry Pi Pin |
Description |
|---|---|---|
Vin |
|
Power supply |
GND |
|
Ground |
SDA |
|
I2C Data |
SCL |
|
I2C Clock |
ADR |
|
Sets address to |
2. Permissions & I2C Enable¶
Enable the I2C interface via
sudo raspi-config(Interface Options -> I2C).Add your user to the
i2cgroup to run programs withoutsudo:sudo usermod -aG i2c $USER
Note: Log out and log back in for changes to take effect.
License¶
This project is licensed under the MIT License - see the LICENSE file for details.