Odometry
Combines a 2D pose (position + heading) with a twist (velocity) and covariance. The standard output from wheel encoders, visual odometry, or any localization system.
When to Use
Use Odometry when you need to publish or consume the robot's estimated position and velocity. Typically published by a drive node that integrates wheel encoder counts, and consumed by planners, fusion nodes, or logging systems.
ROS2 Equivalent
nav_msgs/Odometry — similar structure (pose + twist + covariances).
Rust Example
use horus::prelude::*;
// Robot at (1.5, 2.0) heading 45 degrees, moving forward at 0.3 m/s
let odom = Odometry {
pose: Pose2D { x: 1.5, y: 2.0, theta: 0.785 },
twist: Twist {
linear: [0.3, 0.0, 0.0],
angular: [0.0, 0.0, 0.05],
timestamp_ns: 0,
},
pose_covariance: [0.0; 36],
twist_covariance: [0.0; 36],
timestamp_ns: 0,
};
let topic: Topic<Odometry> = Topic::new("odom")?;
topic.send(odom);
Python Example
import horus
odom = horus.Odometry(
pose=horus.Pose2D(x=1.5, y=2.0, theta=0.785),
twist=horus.Twist(linear=[0.3, 0.0, 0.0], angular=[0.0, 0.0, 0.05]),
)
Fields
| Field | Type | Unit | Description |
|---|---|---|---|
pose | Pose2D | m, rad | Current position and heading estimate |
twist | Twist | m/s, rad/s | Current velocity estimate |
pose_covariance | [f64; 36] | -- | 6x6 covariance for pose (x, y, z, roll, pitch, yaw) |
twist_covariance | [f64; 36] | -- | 6x6 covariance for velocity |
timestamp_ns | u64 | ns | Timestamp |
Common Patterns
Publish from Drive Node
fn tick(&mut self) {
// Read wheel encoders
let left_ticks = self.read_left_encoder();
let right_ticks = self.read_right_encoder();
// Integrate to get pose
self.x += dx * self.theta.cos();
self.y += dx * self.theta.sin();
self.theta += dtheta;
self.odom_pub.send(Odometry {
pose: Pose2D { x: self.x, y: self.y, theta: self.theta },
twist: Twist {
linear: [self.speed, 0.0, 0.0],
angular: [0.0, 0.0, self.omega],
timestamp_ns: 0,
},
pose_covariance: [0.0; 36],
twist_covariance: [0.0; 36],
timestamp_ns: 0,
});
}
Fuse with IMU
See Multi-Sensor Fusion — combines odometry heading with IMU yaw using a complementary filter.