Crates.io | meadow |
lib.rs | meadow |
version | 0.1.0 |
source | src |
created_at | 2022-04-28 23:19:15.877128 |
updated_at | 2024-01-21 00:28:23.491811 |
description | Robotics-focused middleware for embedded Linux |
homepage | |
repository | https://github.com/quietlychris/meadow |
max_upload_size | |
id | 577060 |
size | 208,575 |
meadow
is an experimental robotics-focused middleware for embedded Linux. It is built with a high preference for catching errors at compile-time over runtime and a focus on developer ergonomics, and can natively operate on any serde
-compatible data type.
use meadow::*;
// `meadow` should be able to operate on any `serde`-compatible data types
// (the standard library Debug and Clone traits are also required)
#[derive(Debug, Clone, Serialize, Deserialize)]
struct Coordinate {
x: f32,
y: f32,
}
fn main() -> Result<(), meadow::Error> {
// The Host is running on localhost, but any network interface such as WiFi
// or Ethernet are available as well
let mut host: Host = HostConfig::default().build()?;
host.start()?;
// Other tasks can operate while the host is running in the background
// Build a Node. Nodes can run over TCP, UDP, or QUIC
let addr = "127.0.0.1:25000".parse::<std::net::SocketAddr>().unwrap();
let node: Node<Udp, Idle, Coordinate> = NodeConfig::new("position")
.with_config(node::NetworkConfig::<Udp>::default().set_host_addr(addr))
.build()?;
// Nodes use strict typestates; without using the activate() method first,
// the compiler won't let allow publish() or request() methods on an Idle Node
let node: Node<Udp, Active, Coordinate> = node.activate()?;
// Since Nodes are statically-typed, the following lines would fail at
// compile-time due to type errors
// node.publish(1usize).unwrap()
// let result: bool = node.request().unwrap();
node.publish(Coordinate { x: 0.0, y: 0.0 })?;
// Nodes can also be subscribers, which will request topic updates from the Host
// at a given rate
let subscriber = NodeConfig::<Tcp, Coordinate>::new("position")
.with_config(node::NetworkConfig::<Tcp>::default().set_host_addr(addr))
.build()?
.subscribe(std::time::Duration::from_micros(100))?;
for i in 0..5 {
// Could get this by reading a GPS, for example
let c = Coordinate {
x: i as f32,
y: i as f32,
};
node.publish(c)?;
let result: Msg<Coordinate> = node.request()?;
// or could use the value held by the subscribed node
let subscription = subscriber.get_subscribed_data();
println!("request: {:?}, subscription: {:?}", result, subscription);
}
Ok(())
}
Meadow is more similar to ZeroMQ than to higher-level frameworks like ROS/2, but uses central coordination process similar to MOOS-IvP, resulting in a star-shaped network topology.
meadow currently supports the following messaging patterns:
Protocol | Publish | Request | Subscribe | Encryption |
---|---|---|---|---|
TCP | X | X | X | |
UDP | X | X | X | |
QUIC | X | X | X | X |
Meadow's subscriber functionality currently works a bit differently than many other middlewares; rather than having the most recent data on the subscribed topic pushed to it by the Host upon receive, the Host will the most recent data subscribed topic as a requested rate to the Node, which will cache it locally to be available on-demand rather than on-request.
Under the hood, meadow
relies on:
sled
: High-performance embedded, thread-safe databasetokio
: Asynchronous runtime, enabling a large number of simultaneous connectionspostcard
: Efficient #![no_std]
-compatible, serde-based de/serializer designed for embedded or constrained environments. meadow
should be able to operate native on any serde
-compatible data types.Preliminary benchmark data is showing round-trip message times (publish-request-reply) on locahost
using the --release
compilation profile, on the README's Coordinate
data (strongly-typed, 8 bytes) to be <100 microseconds. Statistical benchmarks on different data profiles can be run via criterion
via cargo bench
.
If you are doing robotics development, meadow
is probably fast enough to move your data around (unless you're trying to do something like video streaming, in which case you should probably be using dedicated endpoints).
As mentioned above, this library should be considered experimental. While the goal is eventually to make this available at a level of maturity, stability, and reliability of other middlewares, meadow
is not there yet. This library is being used as a dependency for robotics research, with interprocess communication focused on dozens of nodes on localhost
or a few over a WLAN connection. While meadow
can work for other use-cases, it has not been extensively tested in those areas. If you are using this library in other areas and come across issues or unexpected behavior, well-formatted bug reports or pull requests addressing those problems are welcomed.
The following projects are built with Meadow:
This library is licensed under the Mozilla Public License, version 2.0 (MPL-2.0)