Imu

An Inertial Measurement Unit (IMU) message carrying three-axis linear acceleration, three-axis angular velocity, and an optional orientation quaternion. This is the primary message for motion sensing, sensor fusion, and orientation estimation on mobile robots, drones, and manipulators.

When to Use

Use Imu when your robot has an IMU sensor (accelerometer + gyroscope) and you need to publish raw or filtered inertial data. Common scenarios include balancing robots, drone flight controllers, dead-reckoning between GPS fixes, and detecting falls or collisions.

ROS2 Equivalent

sensor_msgs/Imu -- field layout is identical (orientation quaternion + angular velocity + linear acceleration + covariance matrices).

Rust Example

use horus::prelude::*;

// Create IMU reading from a 6-axis sensor
let mut imu = Imu::new();
imu.linear_acceleration = [0.0, 0.0, 9.81]; // m/s^2 (gravity on Z)
imu.angular_velocity = [0.0, 0.0, 0.1];     // rad/s (yawing slowly)

// Set orientation from Euler angles (roll, pitch, yaw)
imu.set_orientation_from_euler(0.0, 0.0, 1.57);

// Publish on a topic
let topic: Topic<Imu> = Topic::new("imu.data")?;
topic.send(&imu);

Python Example

from horus import Imu, Topic

# Create IMU reading (accel_x, accel_y, accel_z, gyro_x, gyro_y, gyro_z)
imu = Imu(0.0, 0.0, 9.81, 0.0, 0.0, 0.1)

# Publish on a topic
topic = Topic(Imu)
topic.send(imu)

# Access fields
print(f"Accel Z: {imu.accel_z}")
print(f"Gyro Z: {imu.gyro_z}")

Fields

FieldTypeUnitDescription
orientation[f64; 4]--Quaternion [x, y, z, w]. Default identity [0, 0, 0, 1]
orientation_covariance[f64; 9]--3x3 row-major covariance. Set [0] to -1 if no orientation data
angular_velocity[f64; 3]rad/sAngular velocity [x, y, z]
angular_velocity_covariance[f64; 9]--3x3 row-major covariance matrix
linear_acceleration[f64; 3]m/s²Linear acceleration [x, y, z]
linear_acceleration_covariance[f64; 9]--3x3 row-major covariance matrix
timestamp_nsu64nsTimestamp in nanoseconds since epoch

Methods

MethodSignatureDescription
new()-> ImuCreate with identity orientation and current timestamp
set_orientation_from_euler(roll, pitch, yaw: f64)Set orientation from Euler angles
has_orientation()-> boolTrue if orientation_covariance[0] >= 0
is_valid()-> boolTrue if all values are finite
angular_velocity_vec()-> Vector3Angular velocity as a Vector3
linear_acceleration_vec()-> Vector3Linear acceleration as a Vector3

Common Patterns

Sensor fusion pipeline:

IMU hardware --> Imu message --> complementary/Kalman filter --> Pose3D (orientation)
                             \-> dead reckoning --> Odometry (position estimate)

Fall detection:

use horus::prelude::*;

fn check_freefall(imu: &Imu) -> bool {
    let accel = imu.linear_acceleration_vec();
    let magnitude = (accel.x * accel.x + accel.y * accel.y + accel.z * accel.z).sqrt();
    magnitude < 1.0 // Near-zero gravity = freefall
}

Covariance conventions: Set orientation_covariance[0] to -1.0 when orientation is not available (e.g., gyro-only sensor). Consumers should call has_orientation() before reading the quaternion.