Tracking & Perception Messages (C++)

Object tracking, landmarks, segmentation, clock/time, and input message types.

Tracking

TypeKey FieldsUse Case
TrackedObjectbbox, predicted_bbox, track_id, confidence, class_id, velocity_x/y, accel_x/y, age, hits, time_since_update, state, class_name[16]Multi-object tracking
TrackingHeadernum_tracks, frame_id, timestamp_ns, total_tracks, active_tracksTracker metadata
horus::msg::TrackedObject obj{};
obj.track_id   = 42;
obj.bbox       = {320.0f, 180.0f, 64.0f, 128.0f};  // top-left x, y, width, height (pixels)
obj.velocity_x = 0.5f;   // pixels/frame or m/s
obj.velocity_y = 0.0f;
obj.confidence = 0.92f;
obj.age        = 15;     // frames since first detection
obj.hits       = 14;     // frames with a detection
obj.state      = 1;      // 0=tentative, 1=confirmed, 2=deleted

Landmarks

TypeKey FieldsUse Case
Landmarkx, y, visibility, index2D keypoint (pose estimation)
Landmark3Dx, y, z, visibility, index3D keypoint (pose estimation)
LandmarkArraynum_landmarks, dimension, instance_id, confidence, timestamp_ns, bbox_*Body/hand pose output

Landmark3D mirrors a Rust #[repr(C, packed)] type, so the C++ declaration carries __attribute__((packed)): it is 20 bytes with alignment 1, not 24. Read and write its members by value rather than taking pointers or references to them.

horus::msg::LandmarkArray pose{};
pose.num_landmarks = 21;    // hand keypoints
pose.dimension = 3;         // 3D
pose.confidence = 0.85f;
pose.bbox_x = 100.0f;       // bounding box
pose.bbox_y = 200.0f;
pose.bbox_width = 80.0f;
pose.bbox_height = 120.0f;

Segmentation

horus::msg::SegmentationMask mask{};
mask.width = 640;
mask.height = 480;
mask.num_classes = 21;    // number of semantic classes
mask.mask_type = 0;       // 0=semantic, 1=instance, 2=panoptic
// Pixel data stored separately via Image/TensorPool

Point Cloud Fields & Plane Detection

PointField and PlaneDetection have no C++ struct. The Rust types are repr(Rust) (no guaranteed field order or offsets), so <horus/msg/detection.hpp> deliberately does not declare them and no HORUS_TOPIC_IMPL is registered for them — see the "INTENTIONALLY NOT DECLARED" note at the bottom of that header. Use the pool-backed horus::PointCloud in <horus/pool.hpp> for point data instead.

Clock & Time

TypeKey FieldsUse Case
Clockclock_ns, realtime_ns, sim_speed, paused, source (SOURCE_WALL=0, SOURCE_SIM=1, SOURCE_REPLAY=2)Time synchronization
TimeReferencetime_ref_ns, source[32]External time source

Input

TypeKey FieldsUse Case
KeyboardInputkey_name[32], code, modifier_flags (horus::msg::MODIFIER_* bits: CTRL/ALT/SHIFT/SUPER/HYPER/META), pressed, timestamp_msKeyboard teleop
JoystickInputjoystick_id, event_type[16] ("button"/"axis"/"hat"/"connection"), element_id, element_name[32], value, pressed, timestamp_msGamepad events (one event per message, not a full state snapshot)
AudioFramesamples[MAX_AUDIO_SAMPLES] (4800 f32), num_samples, sample_rate, channels, encoding (AUDIO_ENCODING_F32=0, AUDIO_ENCODING_I16=1), frame_id[32]Audio processing

See Also