DORA 机器人中间件学习教程(1)—— Dora-rs安装

1、dora简介

Dora-rs[1] 是一个基于 Rust 实现的化机器人框架,其具有极高的实时性能。Dora-rs使用Rust语言做数据流的传输和调度管理,可以大大减少了数据的重复拷贝和传输。它提供了Rust语言和Python语言之间的无缝集成,减少了跨语言的性能代价。Dora-rs通过YAML脚本配置节点、节点之间的数据流。

多语言支持:Dora 目前提供 Rust 、Cpp 、Python三种语言。

性能:Dora-rs 性能是ROS2 Python API 的 17 倍!是 ROS2 Rust API 的 10 倍!与 ROS2 C/Cpp API 共享内存快 0.06 ms。(图片来源于github[1]) (对Python有很强的优化能力,对C++性能提升不大)

请添加图片描述)

2、dora安装

dora_安装文档
dora_rs版本为 V0.3.6
注意python版本 必须要3.11.5

我使用的环境是ubuntu20.04 + conda, 推荐安装conda然后再安装python https://blog.csdn.net/wyf2017/article/details/118676765

2.1 二进制安装

在linux上打开一个终端,输入以下指令

curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/dora-rs/dora/main/install.sh | bash

如果提示以下错误

请添加图片描述)
更新一下rustc的版本

apt autoremove rustc
apt install rustc 

或者 通过以下命令更新rustc版本

sudo apt autoremove rustc
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
export PATH=~/.cargo/bin:$PATH
sudo apt  install cargo

2.2从源码编译安装

step1: 从dora仓库下载源代码

git clone https://github.com/dora-rs/dora.git

step2: 编译源代码及C++库

cd dora 
cargo build -p dora-cli --release

# 编译c++接口
cd ../examples/c++-dataflow
cargo run --example cxx-dataflow  # compile C++ node
cargo build -p dora-node-api-c --release  # compile dora-node-api-c 

# 编译DORA-ROS2 bridge
cd ../c++-ros2-dataflow
source /opt/ros/galactic/setup.bash
cargo run --example cxx-ros2-dataflow --features ros2-examples

step3 将编译生成的dora 二进制文件链接到linux环境变量中

export PATH=$PATH:$(pwd) >> ~/.bashrc

step4 安装dora python的接口 注意这里的版本号 DORA_VERSION 要与主仓库的版本号对应

pip install dora-rs== DORA_VERSION ## For Python API
export PATH=$PATH:$(pwd) >> ~/.bashrc

3、运行测试程序

与官方给出的demo程序相同,我们先试用python创建程序验证程序dora-rs是否安装完整

3.1 first project

在终端中输入以下命令,创建dora工程(工程名为abc_project )

dora new abc_project --lang python
cd abc_project

打开该文件夹,这个工程下面创建一个yaml文件、一个节点文件夹,两个操作符(dora中称作operator,有点类似于功能节点、算子的概念), 该工程目录结构如下

├── dataflow.yml
├── node_1
│   └── node_1.py
├── op_1
│   └── op_1.py
└── op_2
    └── op_2.py

3.2 编写节点

1、其中dataflow.yml 文件的内容为:

nodes:
  - id: op_1
    operator:
      python: op_1/op_1.py
      inputs:
        tick: dora/timer/millis/100
      outputs:
        - some-output
  - id: op_2
    operator:
      python: op_2/op_2.py
      inputs:
        tick: dora/timer/secs/2
      outputs:
        - some-output

  - id: custom-node_1
    custom:
      source: python3
      args: ./node_1/node_1.py
      inputs:
        tick: dora/timer/secs/1
        input-1: op_1/some-output
        input-2: op_2/some-output

2、node_1.py 文件的内容为:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from dora import Node

node = Node()

event = node.next()
if event["type"] == "INPUT":
    print(
        f"""Node received:
    id: {event["id"]},
    value: {event["value"]},
    metadata: {event["metadata"]}"""
    )

3、op_1.py 文件的内容为:

from typing import Callable, Optional

from dora import DoraStatus


class Operator:
    """
    Template docstring
    """

    def __init__(self):
        """Called on initialisation"""
        pass

    def on_event(
        self,
        dora_event: dict,
        send_output: Callable[[str, bytes, Optional[dict]], None],
    ) -> DoraStatus:
        if dora_event["type"] == "INPUT":
            return self.on_input(dora_event, send_output)
        return DoraStatus.CONTINUE

    def on_input(
        self,
        dora_input: dict,
        send_output: Callable[[str, bytes, Optional[dict]], None],
    ):
        """

        Args:
            dora_input (dict): Input dict containing an `id`, `data` and `metadata`.
            send_output Callable[[str, bytes | pa.Array, Optional[dict]], None]:
                Function for sending output to the dataflow:
                - First argument is the `output_id`
                - Second argument is the data as either bytes or `pa.Array`
                - Third argument is dora metadata dict
                e.g.: `send_output("bbox", pa.array([100], type=pa.uint8()), dora_event["metadata"])`

        Returns:
            DoraStatus:
                CONTINUE means that the operator will
                    keep listening for further inputs.
                STOP means that the operator stop listening for inputs.

        """
        print(f"Received input {dora_input['id']}, with data: {dora_input['value']}")

        return DoraStatus.CONTINUE

    def __del__(self):
        """Called before being deleted"""
        pass

4、op_2.py 文件的内容为:

from typing import Callable, Optional

from dora import DoraStatus


class Operator:
    """
    Template docstring
    """

    def __init__(self):
        """Called on initialisation"""
        pass

    def on_event(
        self,
        dora_event: dict,
        send_output: Callable[[str, bytes, Optional[dict]], None],
    ) -> DoraStatus:
        if dora_event["type"] == "INPUT":
            return self.on_input(dora_event, send_output)
        return DoraStatus.CONTINUE

    def on_input(
        self,
        dora_input: dict,
        send_output: Callable[[str, bytes, Optional[dict]], None],
    ):
        """

        Args:
            dora_input (dict): Input dict containing an `id`, `data` and `metadata`.
            send_output Callable[[str, bytes | pa.Array, Optional[dict]], None]:
                Function for sending output to the dataflow:
                - First argument is the `output_id`
                - Second argument is the data as either bytes or `pa.Array`
                - Third argument is dora metadata dict
                e.g.: `send_output("bbox", pa.array([100], type=pa.uint8()), dora_event["metadata"])`

        Returns:
            DoraStatus:
                CONTINUE means that the operator will
                    keep listening for further inputs.
                STOP means that the operator stop listening for inputs.

        """
        print(f"Received input {dora_input['id']}, with data: {dora_input['value']}")

        return DoraStatus.CONTINUE

    def __del__(self):
        """Called before being deleted"""
        pass

3.3 启动程序

1、启动数据流

dora start dataflow.yml --name first-dataflow

开启程序以后在终端会输出一个类似于 “6a9279a7-e048-4e28-9616-cb3ae0adb774” 的一长串数字,这是数据流ID
参数 --name 后面的名称是我们自定义的节点名称,后续查看日志文件等操作,可以利用该自定义的名称替换数据流ID

2、结束该数据流

dora stop --name first-dataflow

3.4 查看节点输出

dora 可以通过log文件 查看节点输出(这一点不方便)

dora logs first-dataflow op_1
dora logs first-dataflow op_2
dora logs first-dataflow custom-node_1

其中 first-dataflow 是该程序的名称,也就是我们再启动命令时候 "- -name"后面跟的参数; custom-node_1 是yaml文件中一个节点的名称,

数据流 first-dataflow 下节点 op_1 的日志输出如下:
在这里插入图片描述

4 注意事项

1)若终端提示找不到 dora命令,则可以将 dora可执行文件所在目录加入到 ~/.bashrc最后一行,如在我电脑上dora安装与 ~ 目录,因此需要在 ~/.bashrc 文件中加入 PATH=$PATH:/home/crp

2) 若终端提示在python中没有 dora模块
在这里插入图片描述则按照提示信息执行命令安装dora 即可

pip install dora-rs==0.3.6 --force

参考资料

[1] https://github.com/dora-rs/dora
[2] https://dora.carsmos.ai/docs/guides/Installation/installing

dora-rs目前资料较少 欢迎大家点赞在评论区交流讨论(cenruping@vip.qq.com) O(∩_∩)O
或者加群水一波(1149897304)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值