Robot Example
This is a simple example of real-time pub-sub messaging using DetMQ for a robot control. A high level robot control send target positions to a low level position control low using deterministic messaging.
Define Message Format
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub enum RoboCommand {
Home,
Run(Isometry3<f64>),
}
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
pub enum RoboResponse {
Ready(Isometry<f64, U3, Unit<Quaternion<f64>>>),
}
Create real-time publish-subscribe channel
// Create scope
let mut highlevel =
Scope::new(&ScopeCfg::new(args.detmqserver.as_str(), "ctx_highlevel")).unwrap();
// Create Publishers
let mut pub_highlevel = highlevel.new_publisher("highlevel").unwrap();
// Create Subscribers
let mut sub_highlevel = highlevel.new_subscriber("highlevel").unwrap();
// Subscribe highlevel subscriber to "STATUS" topic using the local IPC transport with max latency of 5000µs
highlevel
.add_subscription(
"highlevel",
Subscription::new(
"ctx_lowlevel",
"lowlevel",
"STATUS",
5000, /* Max latency, specialty of DetMQ */
detmq::endpoints::TransportType::Ipc,
),
)
.unwrap();
// Create lowlevel subscriber and publisher
let mut lowlevel =
Scope::new(&ScopeCfg::new(args.detmqserver.as_str(), "ctx_lowlevel")).unwrap();
let mut pub_lowlevel = lowlevel.new_publisher("lowlevel").unwrap();
let mut sub_lowlevel = lowlevel.new_subscriber("lowlevel").unwrap();
// Subscribe lowlevel subscriber to "COMMAND" topic using the local IPC transport
lowlevel
.add_subscription(
"lowlevel",
Subscription::new(
"ctx_highlevel",
"highlevel",
"COMMAND",
5000,
detmq::endpoints::TransportType::Ipc,
),
)
.unwrap();
Use the messaging API
// Create robo command message containing HOME command
let robo_cmd = RoboCommand::Home;
let size = encode_into_slice(robo_cmd, &mut msg_buffer, SERIALIZATION_CONFIG).unwrap();
// Send robo command message over COMMAND topic
let ret = pub_highlevel.send_raw("COMMAND".as_bytes(), &msg_buffer[0..size]);
info!("HIGH: Homing command sent on topic COMMAND: {:?}", ret);
// Wait for response using blocking poll mode
let (topic_len, msg_len) = sub_highlevel
.recv_raw_blocking(
&mut topic_buffer,
&mut msg_buffer,
detmq::endpoints::BlockMethod::Poll,
)
.unwrap();
/// Wait for response from low-level robot and deserialize state message
let topic = std::str::from_utf8(&topic_buffer[0..topic_len]).unwrap();
let (robo_response, _) =
decode_from_slice::<RoboResponse, _>(&msg_buffer[0..msg_len], SERIALIZATION_CONFIG)
.unwrap();
info!("HIGH: State response received on topic {}", topic);
info!("HIGH: Entering position control mode");