Python Message Library

55+ typed message classes for Python robotics. Binary-compatible with Rust, zero-copy shared memory transport.

Which messages do I need?

I'm building a...Start with these
Mobile robotCmdVel, Odometry, LaserScan, Imu
Robot armJointState, JointCommand, WrenchStamped, TrajectoryPoint
DroneImu, NavSatFix, MotorCommand, BatteryState
Vision systemImage, Detection, PointCloud, DepthImage
Multi-robotPose2D, Heartbeat, DiagnosticStatus, TransformStamped
TeleoperationJoystickInput, CmdVel, EmergencyStop

Availability

All message types are available via the Rust bindings:

from horus import (
    # Geometry
    CmdVel, Pose2D, Pose3D, Twist, Vector3, Point3, Quaternion,
    TransformStamped, PoseStamped, PoseWithCovariance, TwistWithCovariance,
    Accel, AccelStamped,
    # Control
    MotorCommand, ServoCommand, DifferentialDriveCommand, PidConfig,
    TrajectoryPoint, JointCommand,
    # Sensor
    Imu, Odometry, LaserScan, JointState, BatteryState, RangeSensor,
    NavSatFix, MagneticField, Temperature, FluidPressure, Illuminance,
    Clock, TimeReference,
    # Diagnostics
    Heartbeat, DiagnosticStatus, EmergencyStop, ResourceUsage,
    DiagnosticValue, DiagnosticReport, NodeHeartbeat, SafetyStatus,
    # Force/Haptics
    WrenchStamped, ForceCommand, ContactInfo,
    ImpedanceParameters, HapticFeedback,
    # Navigation
    NavGoal, GoalResult, PathPlan, Waypoint, NavPath,
    VelocityObstacle, VelocityObstacles, OccupancyGrid, CostMap,
    # Input
    JoystickInput, KeyboardInput,
    # Detection/Perception
    BoundingBox2D, BoundingBox3D, Detection, Detection3D,
    SegmentationMask, TrackedObject, TrackingHeader,
    Landmark, Landmark3D, LandmarkArray,
    PointField, PlaneDetection, PlaneArray,
    # Vision
    CompressedImage, CameraInfo, RegionOfInterest, StereoInfo,
    # Pool-backed domain types
    Image, PointCloud, DepthImage,
)

Overview

Key Features:

  • Full Rust parity — All 55+ Rust message types are available in Python
  • Zero-copy IPC — POD types transfer via shared memory with no serialization overhead
  • Cross-language compatible — Binary-compatible with Rust message types
  • Nanosecond timestamps — All messages include timestamp_ns field
  • Typed Topic support — Use Topic(CmdVel) for type-safe pub/sub

Message Categories

Each category has a dedicated page with deep documentation — every method explained with narratives, code examples, and common mistakes.

CategoryTypesKey MethodsPage
GeometryVector3, Point3, Quaternion, Pose2D, Pose3D, Twist, CmdVel, TransformStamped, covariance types, Accelfrom_euler(), distance_to(), normalize(), dot(), cross(), stop(), zero(), identity()Deep docs →
SensorLaserScan, Imu, Odometry, JointState, BatteryState, NavSatFix, Clock, TimeReference, + simple typesangle_at(), set_orientation_from_euler(), is_critical(), distance_to(), position(name)Deep docs →
ControlMotorCommand, ServoCommand, DifferentialDriveCommand, PidConfig, TrajectoryPoint, JointCommandvelocity(), from_degrees(), from_twist(), proportional(), pi(), pd(), add_position()Deep docs →
NavigationNavGoal, NavPath, Waypoint, GoalResult, OccupancyGrid, CostMap, PathPlanis_reached(), closest_waypoint_index(), world_to_grid(), is_free(), calculate_progress()Deep docs →
DiagnosticsDiagnosticStatus, EmergencyStop, ResourceUsage, SafetyStatus, DiagnosticReport, Heartbeatok(), warn(), error(), engage(), release(), is_cpu_high(), is_safe()Deep docs →
Force & HapticsWrenchStamped, ForceCommand, ImpedanceParameters, HapticFeedback, ContactInfo, TactileArrayforce_magnitude(), exceeds_limits(), compliant(), stiff(), vibration(), surface_contact()Deep docs →
PerceptionDetection, Detection3D, BoundingBox2D/3D, TrackedObject, Landmark, LandmarkArray, SegmentationMask, PlaneDetectioniou(), is_confident(), confirm(), speed(), coco_pose(), distance_to_point()Deep docs →
VisionImage, PointCloud, DepthImage, CameraInfo, CompressedImage, StereoInfo, RegionOfInterestto_numpy(), from_numpy(), focal_lengths(), depth_from_disparity(), contains()Deep docs →
Input & AudioJoystickInput, KeyboardInput, AudioFramenew_button(), new_axis(), is_ctrl(), mono(), stereo()Deep docs →

Cross-Language Compatibility

All 55+ Python message types are binary-compatible with Rust via zero-copy shared memory:

CategoryPython ClassesCount
GeometryPose2D, Pose3D, Twist, Vector3, Point3, Quaternion, TransformStamped, PoseStamped, PoseWithCovariance, TwistWithCovariance, Accel, AccelStamped12
ControlCmdVel, MotorCommand, ServoCommand, DifferentialDriveCommand, PidConfig, TrajectoryPoint, JointCommand7
SensorImu, Odometry, LaserScan, JointState, BatteryState, RangeSensor, NavSatFix, MagneticField, Temperature, FluidPressure, Illuminance, Clock, TimeReference13
DiagnosticsHeartbeat, DiagnosticStatus, EmergencyStop, ResourceUsage, DiagnosticValue, DiagnosticReport, NodeHeartbeat, SafetyStatus8
Force/HapticsWrenchStamped, ForceCommand, ContactInfo, ImpedanceParameters, HapticFeedback, TactileArray6
NavigationNavGoal, GoalResult, PathPlan, Waypoint, NavPath, VelocityObstacle, VelocityObstacles, OccupancyGrid, CostMap9
InputJoystickInput, KeyboardInput2
Detection/PerceptionBoundingBox2D, BoundingBox3D, Detection, Detection3D, SegmentationMask, TrackedObject, TrackingHeader, Landmark, Landmark3D, LandmarkArray, PointField, PlaneDetection, PlaneArray13
VisionCompressedImage, CameraInfo, RegionOfInterest, StereoInfo4
Domain (pool)Image, PointCloud, DepthImage3

Example — Python to Rust:

# Python sender
from horus import Topic, Twist
topic = Topic(Twist)
topic.send(Twist(linear_x=1.0, angular_z=0.5))
// Rust receiver
use horus::prelude::*;
let topic: Topic<Twist> = Topic::new("twist")?;
if let Some(twist) = topic.recv() {
    println!("linear_x={}, angular_z={}", twist.linear[0], twist.angular[2]);
}

Usage Patterns

Robot Controller with Multiple Sensors

from horus import Node, Topic, CmdVel, LaserScan, Imu

scan_topic = Topic(LaserScan)
imu_topic = Topic(Imu)
cmd_topic = Topic(CmdVel)

def controller_tick(node):
    scan = scan_topic.recv()
    imu = imu_topic.recv()
    if scan:
        min_dist = min(scan.ranges) if scan.ranges else None
        if min_dist and min_dist < 0.5:
            cmd_topic.send(CmdVel(0.0, 0.0))  # Stop
        else:
            cmd_topic.send(CmdVel(linear=0.5, angular=0.0))

node = Node(name="controller", tick=controller_tick, rate=10)

See Also