mecha10_core/messages/mod.rs
1// Shared Message Types
2//
3// This module provides common message types used across the Mecha10 framework.
4// These are the standard "vocabulary" for robot nodes to communicate with each other.
5//
6// Message types are organized by category:
7// - sensor: Raw sensor data (Image, LaserScan, Odometry, IMU, GPS)
8// - actuator: Actuator commands (Twist, JointState, Gripper)
9// - perception: High-level perception (Detection, Pose, Tracking)
10// - navigation: Navigation primitives (Goal, Path, Waypoint)
11// - system: System-level messages (Health, Status, Command)
12
13pub mod actuator;
14pub mod navigation;
15pub mod perception;
16pub mod sensor;
17pub mod system;
18
19// Re-export commonly used types
20pub use actuator::{GripperCommand, JointState, Twist};
21pub use navigation::{NavigationGoal, NavigationStatus, Path, Waypoint};
22pub use perception::{BoundingBox, Detection, Pose};
23pub use sensor::{GpsData, Image, Imu, LaserScan, Odometry};
24pub use system::{HealthLevel, HealthStatus, NodeStatus, SystemCommand};
25
26/// Message trait marker
27///
28/// All types that can be sent through the pub/sub system must implement this trait.
29/// This is typically done via `#[derive(Message)]` which also implements:
30/// - Debug
31/// - Clone
32/// - Serialize
33/// - Deserialize
34pub trait Message: Send + Sync + 'static {}
35
36/// Timestamped message wrapper
37///
38/// Wraps any message payload with metadata (timestamp, publisher).
39/// This is commonly used for sensor data and motor commands that need timing information.
40///
41/// # Example
42/// ```
43/// use mecha10_core::messages::{RedisMessage, Twist};
44/// use mecha10_core::prelude::now_micros;
45///
46/// let twist = Twist { linear: 0.5, angular: 0.3 };
47/// let msg = RedisMessage::new(twist, "teleop", now_micros());
48/// ```
49#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
50pub struct RedisMessage<T> {
51 /// Message payload
52 pub payload: T,
53 /// Publisher node ID (optional for backwards compatibility)
54 #[serde(default)]
55 pub publisher: String,
56 /// Unix timestamp in microseconds
57 pub timestamp: u64,
58}
59
60impl<T> RedisMessage<T> {
61 /// Create a new timestamped message
62 pub fn new(payload: T, publisher: impl Into<String>, timestamp: u64) -> Self {
63 Self {
64 payload,
65 publisher: publisher.into(),
66 timestamp,
67 }
68 }
69}
70
71// Implement Message for all standard types
72impl Message for Image {}
73impl Message for LaserScan {}
74impl Message for Odometry {}
75impl Message for Imu {}
76impl Message for GpsData {}
77impl Message for Twist {}
78impl Message for JointState {}
79impl Message for GripperCommand {}
80impl Message for Detection {}
81impl Message for Pose {}
82impl Message for NavigationGoal {}
83impl Message for NavigationStatus {}
84impl Message for Path {}
85impl Message for Waypoint {}
86impl Message for HealthStatus {}
87impl Message for NodeStatus {}
88impl Message for SystemCommand {}
89
90// Implement Message for primitive types
91impl Message for bool {}
92impl Message for f32 {}
93impl Message for f64 {}
94impl Message for i32 {}
95impl Message for i64 {}
96impl Message for u32 {}
97impl Message for u64 {}
98impl Message for String {}
99// Vec<T> types covered by generic Vec<T> implementation below
100impl Message for [f32; 2] {}
101impl Message for [f32; 3] {}
102impl Message for [f32; 6] {}
103// Vec<[f32; N]> covered by generic Vec<T>
104// Vec<Vec<u8>> covered by generic Vec<T>
105// Vec<(T1, T2)> covered by generic Vec<T>
106
107// Implement Message for types module duplicates
108impl Message for crate::types::Image {}
109impl Message for crate::types::LaserScan {}
110impl Message for crate::types::IMU {}
111// MotorStatus already has Message impl in actuator.rs
112
113// Implement Message for external types
114impl Message for serde_json::Value {}
115
116// Generic implementations for Vec and tuples
117impl<T: Send + Sync + 'static> Message for Vec<T> {}
118// Note: References cannot implement Message since they don't satisfy 'static bound
119impl<T1: Send + Sync + 'static, T2: Send + Sync + 'static> Message for (T1, T2) {}
120
121// Implement Message for TracedMessage
122impl<T: Send + Sync + 'static> Message for crate::tracing_otel::TracedMessage<T> {}
123
124// Implement Message for RedisMessage
125impl<T: Send + Sync + 'static> Message for RedisMessage<T> {}