2 个不稳定版本

0.1.0 2024年1月21日
0.0.0 2022年4月28日

#36 in 机器人

MPL-2.0 许可证

110KB
2.5K SLoC

crates.io Documentation CI

Meadow

meadow 是一个针对嵌入式 Linux 的实验性机器人中间件。它更注重在编译时捕获错误而不是运行时,并侧重于开发者的人体工程学,并且可以原生地在任何 serde 兼容的数据类型上运行。

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 与 ZeroMQ 更相似,而不是像 ROS/2 这样的高级框架,但使用类似于 MOOS-IvP 的中央协调过程,从而形成一个星形网络拓扑。

meadow 当前支持以下消息模式

协议 发布 请求 订阅 加密
TCP X X X
UDP X X X
QUIC X X X X

Meadow 的订阅功能目前与其他许多中间件的工作方式略有不同;不是由主机在接收时将订阅主题的最新数据推送到它,而是主机将订阅主题的最新数据作为请求速率发送到节点,节点将本地缓存这些数据以按需可用,而不是按请求提供。

关键依赖

在底层,meadow 依赖于

  • sled:高性能嵌入式、线程安全数据库
  • tokio:异步运行时,允许大量并发连接
  • postcard:高效的 #![no_std]-兼容、基于 serde 的 de/serializer,适用于嵌入式或受限环境。 meadow 应该能够在任何 serde-兼容的数据类型上本地运行。

基准测试

初步基准数据显示,使用 --release 编译配置,在 locahost 上进行往返消息时间(发布-请求-回复)测试,在 README 的 Coordinate 数据(强类型,8字节)上的时间小于100微秒。可以通过 criterion 在不同的数据配置文件上运行统计基准测试,方法是通过 cargo bench

如果您正在进行机器人开发,meadow 可能足够快,可以处理您的数据(除非您正在尝试类似视频流这样的操作,在这种情况下,您可能应该使用专用端点)。

稳定性

如上所述,此库应被视为 实验性的。虽然目标是最终达到与其他中间件相当的水平,包括成熟度、稳定性和可靠性,但 meadow 目前还没有达到这一点。此库正在用作机器人研究的一个依赖项,主要关注在 localhost 上的几十个节点或通过 WLAN 连接的几个节点之间的进程间通信。虽然 meadow 可以适用于其他用例,但这些领域尚未进行广泛测试。如果您在其他领域使用此库并遇到问题或意外行为,欢迎提交格式良好的错误报告或针对这些问题的拉取请求。

其他资源

以下项目是用 Meadow 构建的

  • Tutlesim:简单的二维自主仿真器
  • Orientation:使用 Meadow 和 Bevy 实现实时 3D 姿态可视化 BNO055 IMU

许可证

此库采用 Mozilla Public License,版本 2.0(MPL-2.0)许可

依赖关系

~6–18MB
~245K SLoC