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
| Field | Type | Unit | Description |
|---|---|---|---|
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/s | Angular 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_ns | u64 | ns | Timestamp in nanoseconds since epoch |
Methods
| Method | Signature | Description |
|---|---|---|
new() | -> Imu | Create with identity orientation and current timestamp |
set_orientation_from_euler | (roll, pitch, yaw: f64) | Set orientation from Euler angles |
has_orientation() | -> bool | True if orientation_covariance[0] >= 0 |
is_valid() | -> bool | True if all values are finite |
angular_velocity_vec() | -> Vector3 | Angular velocity as a Vector3 |
linear_acceleration_vec() | -> Vector3 | Linear 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.