欢迎使用 Dora-rs
Dora 是一个用于构建响应式数据流应用的轻量级框架,专为机器人、边缘计算和实时系统设计。
为什么选择 Dora?
- 模块化:通过 Operator 组合复杂流水线
- 低延迟:Rust 核心 + 零拷贝通信
- 多语言:Rust 与 Python 节点无缝协作
- 轻量部署:无中心调度器,单二进制即可运行
快速体验(需 Rust)
cargo install dora-cli
dora new hello-dora && cd hello-dora
dora run
项目文档
- Dora 手把手教程 - 通过例子学习 Dora 的使用方法
- OpenLoong 样例 - OpenLoong 机器人相关文档
- 自动驾驶入门 - 使用 CARLA 模拟器学习自动驾驶
教程
欢迎来到 DORA-RS 实践教程!本教程将帮助你从零开始学习如何使用 DORA 构建机器人应用。
概述
DORA (Dataflow-Oriented Robotic Architecture) 是一个现代化的机器人框架,提供:
- 模块化设计 - 将复杂系统拆分为独立节点
- 低延迟通信 - 基于共享内存和零拷贝传输
- 多语言支持 - Python、Rust、C/C++ 混合编程
- 轻量级部署 - 无需复杂的依赖配置
学习路径
新手入门
如果你是 DORA 新手,建议按以下顺序学习:
- 安装 - 安装 DORA CLI 和依赖
- echo 示例 - 了解基本的数据流概念
- Python 数据流 - 创建你的第一个 Python 节点
- 使用相机 - 学习处理视频流
多语言开发
根据你熟悉的编程语言选择:
AI 与感知
对 AI 应用感兴趣?推荐学习:
机器人控制
需要控制真实机器人?查看:
- Lebai 机械臂 - 乐白机械臂驱动
- SO-101 机械臂 - SO-101 MuJoCo 仿真
- Franka Panda - Franka 机械臂驱动
- UR5 - Universal Robots UR5 驱动
源码仓库
所有示例的完整源码请访问:gitcode.com/dora-org/dora-examples
获取帮助
安装
Dora 提供了多种安装方式
pip install dora-rs-cli
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/dora-rs/dora/releases/latest/download/dora-cli-installer.sh | sh
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/dora-rs/dora/releases/latest/download/dora-cli-installer.sh | sh
powershell -ExecutionPolicy ByPass -c "irm https://github.com/dora-rs/dorareleases/latest/download/dora-cli-installer.ps1 | iex"
cargo install dora-cli
docker pull ghcr.io/dora-rs/dora-slim #拉取镜像
docker run ghcr.io/dora-rs/dora-slim dora --help #运行容器
git clone https://github.com/dora-rs/dora.git
cd dora
cargo build --release -p dora-cli
PATH=$PATH:$(pwd)/target/release
Important
本文主要围绕主分支的最新代码展开,如果想获得完全相同体验请尽量使用主分支上的Dora。 所有的样例以及部分多编程语言涉及到的特定包(Rust Crates)只在源码中给出,现阶段推荐从源码安装
确认完成安装
$ dora --version
dora-cli 0.3.11
从源码安装dora(以Ubuntu24.04为例)
安装Rust
安装rustup,rustup是管理Rust版本、编译工具链的重要工具
$ sudo apt install curl -y # 安装curl,如果未安装
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # 弹出选项,回车选择默认安装即可
$ export PATH=$PATH:$HOME/.cargo/bin # 设置环境变量

获取Dora源代码
$ sudo apt install git -y # 安装git,如果未安装
$ git clone https://github.com/dora-rs/dora.git
$ cd dora
编译Dora-CLI
Dora-CLI是非常实用的命令行工具,它提供了许多方便的命令来管理Dora项目。
$ sudo apt install build-essential -y # 安装C/C++编译环境相关的包(包括g++等),如果未安装
$ cargo build --release --package dora-cli
添加到环境变量
$ export PATH=$PATH:$(pwd)/target/release # 添加到环境变量
或者可以选择官方提供的脚本
$ ./install.sh
DORA 机器人框架概述
DORA (Data Oriented Robot Architecture) 是一个新兴的机器人框架,其核心在于为基于人工智能的机器人应用提供低延迟、高可组合性和分布式数据流能力。
该框架的关键优势在于:
- 基于 Rust 语言的底层架构
- 对多种编程语言(包括 Python 和 C/C++)的支持
- 高效的通信机制,如共享内存和 Zenoh 网络协议
社区参与度方面,DORA 在 GitHub 上获得了显著关注,并通过训练营等活动积极拓展用户群体。项目的发展趋势表明,DORA 正致力于提升其分布式能力、与 ROS2 的互操作性,并扩展其节点生态系统。
一、DORA 中间件介绍
1.1 核心概念与架构
节点 (Nodes)
节点是独立的、隔离的进程,通过 dora 库与其他节点通信。这种隔离的设计在安全性至上的应用场景中尤为重要,并且能够实现细粒度的资源管理,例如将 CPU 核心绑定到特定的自定义节点上。
💡 如果一个节点发生故障,这种隔离特性可以有效地防止整个系统崩溃。
操作器 (Operators)
操作器是轻量级的、协同的、基于库的组件,由 dora 运行时节点执行。操作器可以利用 dora 运行时提供的各种高级功能,例如:
- 优先级调度
- 原生截止时间支持
这种设计使得在同一台机器上运行数千个操作器成为可能,从而提高了资源利用率。
协调器 (Coordinator)
协调器负责从 YAML 文件中读取数据流配置,进行验证,并将节点和操作器部署到指定的或自动确定的机器上。协调器还具备以下功能:
| 功能 | 描述 |
|---|---|
| 健康监控 | 监控操作器的健康状态 |
| 自动缩放 | 云节点的自动缩放能力 |
| 复制与重启 | 操作器的复制与重启机制 |
协调器的这些功能表明 DORA 具备支持复杂、分布式机器人系统的能力,并为云端部署提供了可能性。
数据流模型
DORA 的应用被建模为有向图或管道,这种数据流模型强调了中间件的可组合性。
- 开发者能够轻松地交换和替换机器人应用中的组件
- 提高了开发的灵活性和模块化程度
- 有助于可视化和理解系统内的信息和控制流
数据流的配置采用 YAML 声明式编程。使用 YAML 进行配置简化了机器人应用的部署和管理,降低了用户的入门门槛。声明式配置允许开发者定义应用的期望状态,而无需指定执行步骤。
1.2 关键技术特性
⚡ 低延迟
DORA 非常注重低延迟通信,这主要得益于:
- 使用 Rust 语言实现的核心(高性能特点)
- 基于共享内存的发布/订阅 (PubSub) 机制
这种对低延迟的强调使得 DORA 非常适合需要实时数据处理和控制的机器人应用。
🔧 可组合性
可组合性是 DORA 的另一个关键特性:
- 允许开发者创建包含多种编程语言组件的应用
- 操作器和自定义节点可以被复用和隔离
- 语言无关性和组件复用能力显著提高了开发效率
🌐 分布式能力
DORA 具备强大的分布式能力:
- 通过集成 Zenoh 网络协议实现机器间通信
- 利用 OpenTelemetry 进行分布式遥测
内置的分布式计算支持对于将机器人应用扩展到单个机器之外至关重要,从而能够支持跨多个机器人或云基础设施的复杂部署。
🌍 多语言支持
| 语言 | 特点 |
|---|---|
| Rust | 性能卓越,适合核心功能开发 |
| Python | 易于使用,适合快速原型设计和 AI 集成 |
| C/C++ | 广泛应用于系统级编程和硬件接口 |
1.3 通信基础设施
本地通信:共享内存 + Apache Arrow
DORA 在单台机器内部使用共享内存和 Apache Arrow 数据格式来实现零拷贝消息传递。
┌─────────────┐ 零拷贝 ┌─────────────┐
│ 节点 A │ ──────────→ │ 节点 B │
│ │ 共享内存 │ │
└─────────────┘ └─────────────┘
优势:
- 显著降低系统开销和延迟
- 最小化 CPU 使用率
- 最大化数据吞吐量
- 对实时处理传感器数据至关重要
机器间通信:Zenoh 协议
对于机器间的通信,DORA 集成了 Zenoh 协议,以实现鲁棒的网络通信:
- 处理网络断连
- 网络地址转换 (NAT) 穿透
- 发布/订阅功能
- 对网络问题的弹性
选择 Zenoh 作为通信层突显了 DORA 构建可靠且可扩展的分布式机器人系统的决心。
ROS2 桥接
⚠️ 注意: ROS2 桥接目前处于不稳定状态
DORA 提供了 ROS2 桥接功能:
- 无编译消息传递:简化与 ROS2 生态系统的集成
- 自动类型转换:ROS2 消息与 Arrow 数组之间的自动转换
ROS 拥有庞大的用户基础和丰富的软件包库。与 ROS2 的桥接使得 DORA 能够利用现有的生态系统并吸引熟悉 ROS 的开发者。
echo
Dora中,一个逻辑功能通常作为节点(Node)。不同逻辑功能的交互依赖于信息的交互(Dataflow)。为了方便不同节点之间的组合,Dora使用yaml文件来声明消息的“流动”。
yaml不仅声明了不同节点消息的输入、输出,还可以声明节点构建(编译、安装)的过程。在使用这些节点之前需要先进行构建。
构建
Tip
如果使用uv管理的python可在命令中加入
--uv参数 进入examples/echo文件夹,执行命令
# Create a virtual environment if it doesn't exist
$ uv venv -p 3.11 --seed
$ dora build dataflow.yml --uv
$ dora run dataflow.yml --uv
输出:
Using Python 3.11.12 environment at: ...
Resolved 4 packages in 1.20s
Built pyarrow-sender @ ...
Prepared 1 package in 693ms
Installed 1 package in 1ms
~ pyarrow-sender==0.3.11 (...)
Using Python 3.11.12 environment at: ...
Resolved 4 packages in 4ms
Built dora-echo @ ...
Prepared 1 package in 507ms
Installed 1 package in 1ms
+ dora-echo==0.3.11 (...)
Using Python 3.11.12 environment at: ...
Resolved 4 packages in 3ms
Built pyarrow-assert @ ...
Prepared 1 package in 499ms
Installed 1 package in 1ms
~ pyarrow-assert==0.3.11 (...)
运行
依据yaml文件运行Dora框架:
$ dora run dataflow.yaml # --uv
输出:
... INFO run_inner: dora_daemon::log: pyarrow-assert finished successfully...
各节点的作用
node-hub提供了很多现成的方便复用的节点
Dora中通过环境变量为节点提供参数
pyarrow-sender节点:生成了内容为DATA的信息dora-echo节点:将输入的内容发送出去pyarrow-assert节点:判断接收消息与DATA是否一致
额外的尝试
更改pyarrow-sender或pyarrow-assert的DATA参数,在二者不一致时运行会产生报错
输出:
... [ERROR]
Dataflow failed:
Node `pyarrow-assert` failed: exited with code 1 with stderr output: ...
源码
完整源码请参考:dora-examples/echo
多守护进程(Daemon)
Dora通过Coordinator来协调多个Daemon的运行。Daemon可以来自不同的机器。这是Dora分布式的基础。
启动准备
启动一个协调器(Coordinator)
$ dora coordinator
其运行ip与端口的绑定设置,可通过添加--help参数来查看,样例中用默认的设置即可。
启动守护进程(Daemon)
$ dora daemon --machine-id A
$ dora daemon --machine-id B
分别启动两个分别名为A和B的守护进程。
可以通过--coordinator-addr和--coordinator-port来指定协调器的地址和端口。
具体可以参考dora daemon --help。
构建
$ dora build dataflow.yml
可以通过--coordinator-addr和--coordinator-port来指定协调器的地址和端口。
具体可以参考dora build --help。
运行
$ dora start dataflow.yml
可以通过--coordinator-addr和--coordinator-port来指定协调器的地址和端口。
具体可以参考dora start --help。
源码
完整源码请参考:dora-examples/multiple-daemons
构建与加载
Dora-cli 中常用的命令
Dora命令行工具提供了build和start等命令。
coordinator启动一个coordinator进程,用于调度协调。daemon在本地启动一个daemon进程,用于运行dataflow,可以指定连接到任一coordinator。start启动一份dataflow,可以指定连接到任一coordinator。run相当于在本地自行创建一个coordinator、daemon并在其上加载对应的dataflow.yml。- …
YAML配置文件
Dora通过使用YAML配置文件来描述dataflow。 形如:
nodes:
- id: rust-node
_unstable_deploy:
machine: A
build: cargo build --release -p rust-dataflow-example-node
path: $DORA_EXAMPLES/target/release/rust-dataflow-example-node
inputs:
tick: dora/timer/millis/10
outputs:
- random
- id: rust-status-node
_unstable_deploy:
machine: A
build: cargo build --release -p rust-dataflow-example-status-node
path: $DORA_EXAMPLES/target/release/rust-dataflow-example-status-node
inputs:
tick: dora/timer/millis/100
random: rust-node/random
outputs:
- status
- id: rust-sink
_unstable_deploy:
machine: B
build: cargo build --release -p rust-dataflow-example-sink
path: $DORA_EXAMPLES/target/release/rust-dataflow-example-sink
inputs:
message: rust-status-node/status
通过环境变量更灵活的启动
在build和path字段中都可以使用环境变量,例如$DORA_EXAMPLES。
这使得节点的位置可以更加灵活的放置。
值得注意的是,这两个字段中的环境变量会使用daemon所处运行环境的环境变量。
构建字段的技巧
Dora的build字段参考了Github Action的设计,但是其功能并不完备。
build字段允许通过多行来声明需要多个命令的构建。
如果需要借助脚本或更复杂的参数时可以使用bash -c "..."
编程语言
Dora的核心部分及大部分功能虽然使用Rust编写,但是也为其它编程语言提供了可编程接口支持多种编程语言,包括Python、C++等。
在本节中将展示不同编程语言中Dora的使用。
C/C++
需要预先准备的包
为了实现C/C++多语言混合编程,需要准备好相关的包。 需要从源码安装Dora,并且构建相关包:
- 运行时
$ cargo build -p dora-runtime # --release
- 如果需要使用C API
$ cargo build -p dora-node-api-c # --release
$ cargo build -p dora-operator-api-c # --release
- 如果需要使用Rust API
$ cargo build -p dora-node-api-cxx # --release
$ cargo build -p dora-operator-api-cxx # --release
当使用启用release编译时,需注意将连接的地址target/debug替换为target/release
如果对Rust与C++的混合编译感兴趣,可以参阅cxx.rs
C++ 样例
数据流
Dora相关包的准备
需要预先准备的包 官方样例中使用clang++进行编译,实测g++也是可以使用的,对于大部分的Linux发行版(如Ubuntu等)使用默认安装的g++即可。
C API
构建
alias CXX='clang++' # CXX='g++'
mkdir build
# 构建算子
CXX -c operator-c-api/operator.cc -std=c++17 -o operator-c-api/operator.o -fPIC
CXX -shared operator-c-api/operator.o -ldora_operator_api_c -L../../target/debug/ -o ./build/liboperator_c_api.so
# 构建节点
CXX node-c-api/main.cc -lm -lrt -ldl -pthread -L../../target/debug -ldora_node_api_c -o ./build/node_c_api
#TBD#
#TBD#
Rust API
构建
alias CXX='clang++' # CXX='g++'
mkdir -p build
# 构建算子
cp ../../target/cxxbridge/dora-operator-api-cxx/src/lib.rs.h ./build/dora-operator-api.h
cp ../../target/cxxbridge/dora-operator-api-cxx/src/lib.rs.cc ./build/operator-bridge.cc
CXX -c ./operator-rust-api/operator.cc -std=c++17 -I./operator-rust-api -o operator-rust-api/operator.o -fPIC
CXX -c ./build/operator-bridge.cc -std=c++17 -I./operator-rust-api -o ./build/operator-bridge.o -fPIC
CXX -shared ./operator-rust-api/operator.o ./build/operator-bridge.o -ldora_operator_api_cxx -L../../target/debug/ -o ./build/liboperator_rust_api.so
# 构建节点
cp ../../target/cxxbridge/dora-node-api-cxx/src/lib.rs.h ./build/dora-node-api.h
cp ../../target/cxxbridge/dora-node-api-cxx/src/lib.rs.cc ./build/node-bridge.cc
CXX ./node-rust-api/main.cc ./build/node-bridge.cc -lm -lrt -ldl -pthread -L../../target/debug -ldora_node_api_cxx -o ./build/node_rust_api
#TBD#
#TBD#
运行
$ dora run dataflow.yaml
相关节点功能概览
node-c-api:使用C API对接收到的数据进行计数,并返回计数node-rust-api: 使用Rust API对接收到的数据进行计数,并返回计数operator-c-api:使用C API接受数据并除以2后发出operator-rust-api:使用Rust API对接收到的所有消息进行计数,并将收到的消息发出
源码
完整源码请参考:dora-examples/c++-dataflow
数据流(Arrow Dataflow)
Apache Arrow 是通用的、列式格式的、快速数据交换和内存中分析工具。支持多种语言。
安装Arrow
更详细的安装说明与选项请参考Arrow官方安装文档。
$ sudo apt update
$ sudo apt install -y -V ca-certificates lsb-release wget
$ wget https://packages.apache.org/artifactory/arrow/$(lsb_release --id --short | tr 'A-Z' 'a-z')/apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb
$ sudo apt install -y -V ./apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb
$ sudo apt update
$ sudo apt install -y -V libarrow-dev # For C++
构建
通过pkg-config --libs arrow和pkg-config --cflags arrow获得系统安装的Arrow库相关的编译设置
$ mkdir build
$ cp ../../target/cxxbridge/dora-node-api-cxx/src/lib.rs.cc ./build/node-bridge.cc
$ cp ../../target/cxxbridge/dora-node-api-cxx/src/lib.rs.h ./build/dora-node-api.h
$ alias CXX=g++
$ CXX ./build/node-bridge.cc ./node-rust-api/main.cc -std=c++17 -lm -lrt -ldl -pthread -ldora_node_api_cxx -L../../target/debug/ $(pkg-config --libs arrow) $(pkg-config --cflags arrow) -o ./build/node_rust_api
运行
dora run dataflow.yml
源码
完整源码请参考:dora-examples/cxx-arrow-dataflow
C数据流
构建C API相关包
$ cargo build -p dora-node-api-c
$ cargo build -p dora-operator-api-c
Node
Source
$ alias C=gcc # 用clang亦可以
$ C node.c -lm -lrt -ldl -pthread -ldora_node_api_c -L../../target/debug/ -o ./build/c_node
Sink
$ C sink.c -lm -lrt -ldl -pthread -ldora_node_api_c -L../../target/debug/ -o ./build/c_sink
Operator
$ C -c operator.c -o build/operator.o -fPIC # 编译
$ C -shared build/operator.o -L../../target/debug/ -ldora_operator_api_c -o ./build/liboperator.so
源码
完整源码请参考:dora-examples/c-dataflow
CMake数据流
CMake是一个跨平台的构建系统,它允许开发者使用简单的脚本来描述项目的依赖关系和构建规则,从而实现跨平台的构建。C/C++ Dora项目也可以使用CMake来构建。
构建
$ cmake -DDORA_ROOT_DIR=../../ -B./build . # 通过DORA_ROOT_DIR变量指定Dora项目的根目录
$ cmake --build ./build
$ cmake --install ./build
运行
$ dora run dataflow.yml
源码
完整源码请参考:dora-examples/cmake-dataflow
ROS2数据流
确保ROS2环境已正确安装和配置
Dora通过ros2-client与ROS进行交互 C++ API为了与ROS通信,需要启用ROS2桥接功能。
准备相关依赖
由于例子与turtlesim和AddTwoInts相关
$ sudo apt install ros-jazzy-turtlesim ros-jazzy-examples-rclcpp-minimal-service
生成带有ROS2 message 的 Dora API
$ source /opt/ros/jazzy/setup.bash
$ cargo build --package dora-node-api-cxx --features ros2-bridge
Note
- 当需要使用新的消息接口时,即包更新或
AMENT_PREFIX_PATH更新时需要重新进行生成- 在v0.3.13前,环境变量中残留的无消息ROS2 package会导致默认的
--debug构建失败,请尝试在使用cargo生成API时添加--release参数
整理需要用到的头文件、C++源文件
$ mkdir build
$ cp ../../target/cxxbridge/dora-node-api-cxx/dora-node-api.cc ./build/dora-node-api.cc
$ cp ../../target/cxxbridge/dora-node-api-cxx/dora-node-api.h ./build/dora-node-api.h
$ cp ../../target/cxxbridge/dora-node-api-cxx/dora-ros2-bindings.cc ./build/dora-ros2-bindings.cc
$ cp ../../target/cxxbridge/dora-node-api-cxx/dora-ros2-bindings.h ./build/dora-ros2-bindings.h
Note
- 在v0.3.13版本前,所有的消息及与Dora相关的API生成在
dora-node-api.h和dora-ros2-bindings.h中,其对应的.cc需要与使用了该接口的C++源文件一起编译- 在v0.3.13版本后,不同的ROS2消息生成在独立的文件中,具体可以查看生成API后查看
target/cxxbridge/dora-node-api-cxx/install。请根据需要自行编译需要的C++源文件- 截至v0.3.13版本(2025-11-24),Dora C++ API尚未支持ROS2中的Action通信机制
编译
$ alias CXX=g++ # clang++ 也可以
$ CXX ./node-rust-api/main.cc ./build/dora-ros2-bindings.cc ./build/dora-node-api.cc -std=c++17 -lm -lrt -ldl -lz -pthread -ldora_node_api_cxx -L ../../target/debug/ -o ./build/node_rust_api
Note
如果生成时使用了
--release参数则需将链接目录target/debug/改为target/release
运行
打开另外两个终端
需要使用rmw_fastrtps_cppJazzy 中应该是默认的,如果在.bashrc等地方设置成了别的注意要设置回来。
更改设置后重启daemon,ros2 daemon stop, ros2 daemon start
启动turtlesim
$ source /opt/ros/jazzy/setup.bash
$ ros2 run turtlesim turtlesim_node
启动AddTwoInts服务
$ source /opt/ros/jazzy/setup.bash
$ ros2 run examples_rclcpp_minimal_service service_main
启动Dora节点
$ dora run dataflow.yml
源码
完整源码请参考:dora-examples/cxx-ros2-dataflow
CXX数据流
本示例展示如何使用C++创建dora算子(operator)和自定义节点(node)。
Dora目前尚未提供原生C++ API,但我们可以为C或Rust API创建适配器。operator-rust-api和node-rust-api文件夹实现了基于dora Rust API的示例算子和节点,使用cxx crate进行桥接。operator-c-api和node-c-api展示了如何基于dora的C API创建算子和节点。
项目结构
cxx-dataflow/
├── dataflow.yml # 数据流定义文件
├── node-c-api/ # 基于C API的节点实现
├── node-rust-api/ # 基于Rust API的节点实现
├── operator-c-api/ # 基于C API的算子实现
└── operator-rust-api/ # 基于Rust API的算子实现
数据流配置
nodes:
- id: cxx-node-rust-api
path: build/node_rust_api
inputs:
tick: dora/timer/millis/300
outputs:
- counter
- id: cxx-node-c-api
path: build/node_c_api
inputs:
tick: cxx-node-rust-api/counter
outputs:
- counter
编译和运行
快速运行
使用run.rs二进制文件可以自动执行所有构建步骤并启动数据流:
cargo run --example cxx-dataflow
预期输出
运行成功后,你将看到类似以下的输出:
2026-01-02T00:55:11.194863Z INFO dora_daemon::log: Received input tick (counter: 1) build_id=None dataflow_id=Some("019b7c33-867d-7a38-ae09-3d76187688f0") node_id=Some("cxx-node-rust-api")
2026-01-02T00:55:11.195698Z INFO dora_daemon::log: Received input (counter: 1) data: [1, ] build_id=None dataflow_id=Some("019b7c33-867d-7a38-ae09-3d76187688f0") node_id=Some("cxx-node-c-api")
2026-01-02T00:55:11.494528Z INFO dora_daemon::log: Received input tick (counter: 2) build_id=None dataflow_id=Some("019b7c33-867d-7a38-ae09-3d76187688f0") node_id=Some("cxx-node-rust-api")
2026-01-02T00:55:11.495464Z INFO dora_daemon::log: Received input (counter: 2) data: [2, ] build_id=None dataflow_id=Some("019b7c33-867d-7a38-ae09-3d76187688f0") node_id=Some("cxx-node-c-api")
2026-01-02T00:55:11.794526Z INFO dora_daemon::log: Received input tick (counter: 3) build_id=None dataflow_id=Some("019b7c33-867d-7a38-ae09-3d76187688f0") node_id=Some("cxx-node-rust-api")
2026-01-02T00:55:11.795299Z INFO dora_daemon::log: Received input (counter: 3) data: [3, ] build_id=None dataflow_id=Some("019b7c33-867d-7a38-ae09-3d76187688f0") node_id=Some("cxx-node-c-api")
2026-01-02T00:55:12.094486Z INFO dora_daemon::log: Received input tick (counter: 4) build_id=None dataflow_id=Some("019b7c33-867d-7a38-ae09-3d76187688f0") node_id=Some("cxx-node-rust-api")
2026-01-02T00:55:12.095222Z INFO dora_daemon::log: Received input (counter: 4) data: [4, ] build_id=None dataflow_id=Some("019b7c33-867d-7a38-ae09-3d76187688f0") node_id=Some("cxx-node-c-api")
2026-01-02T00:55:12.394238Z INFO dora_daemon::log: Received input tick (counter: 5) build_id=None dataflow_id=Some("019b7c33-867d-7a38-ae09-3d76187688f0") node_id=Some("cxx-node-rust-api")
2026-01-02T00:55:12.395092Z INFO dora_daemon::log: Received input (counter: 5) data: [5, ] build_id=None dataflow_id=Some("019b7c33-867d-7a38-ae09-3d76187688f0") node_id=Some("cxx-node-c-api")
2026-01-02T00:55:12.694241Z INFO dora_daemon::log: Received input tick (counter: 6) build_id=None dataflow_id=Some("019b7c33-867d-7a38-ae09-3d76187688f0") node_id=Some("cxx-node-rust-api")
日志显示了两个节点之间的数据流:cxx-node-rust-api接收定时器tick,然后将计数器值发送给cxx-node-c-api。
手动构建
如果需要手动构建,请按以下步骤操作:
- 创建
build文件夹 - 使用
cargo build构建Rust API crates - 编译C节点和算子库
- 构建dora coordinator和runtime
- 使用dora-daemon运行数据流
源码
完整源码请参考:dora-examples/cxx-dataflow
Python
为了更方便的管理Python包,Dora推荐使用uv进行管理
安装UV
$ sudo apt install curl # 安装curl,如果未安装
$ curl -LsSf https://astral.sh/uv/install.sh | sh
Python 样例
数据流
官方的Node Hub文件夹中提供了许多现成的节点 本例中用到的有
opencv-video-capture用于读取摄像头dora-yolo用于进行目标检测dora-rerun用于进行可视化
dataflow.yml除了用于描述输入输出外,还可以通过build字段进行简单的构建或安装
准备Python环境
$ uv venv -p 3.10 --seed
安装对应的包
当在dora build时加上--uv标签,会自动在使用pip前添加uv以使用uv管理的Python版本
$ dora build dataflow.yml --uv
运行
$ dora run dataflow.yml --uv
默认的视图中可能只包含照片项,在弹出的rerun窗口中右键时间轴上的/项,点击添加到新的视图中

动态节点
$ dora build dataflow_dynamic.yml --uv # 安装所需要的节点
$ dora up # 启动本地的 daemon 和 coordinator
$ dora start dataflow_dynamic.yml --uv
在另外一个中端窗口运行
$ uv run opencv-plot --name plot
源码
完整源码请参考:dora-examples/python-dataflow
算子(Operator)
Operator提供了更加轻量化的方案,并且有更多Dora的高级功能,拥有更快的通信速度。
安装依赖
$ uv venv -p 3.11 --seed # 创建环境
$ uv pip install -e ../../apis/python/node # 安装Dora Python API
$ source .venv/bin/activate
$ pip install -r requirements.txt # 安装依赖,如果要体验dataflow_llm,则使用requirements_llm.txt
由于Operator暂未适配--uv标签作为启动参数,为了使用uv管理的Python,所以要在终端中source .venv/bin/activate
$ dora run dataflow.yml

源码
完整源码请参考:dora-examples/python-dataflow
异步
$ uv venv -p 3.11 --seed # 创建环境
$ uv pip install -e ../../apis/python/node # 安装Dora Python API
$ dora build dataflow.yml --uv # 安装依赖
运行
$ dora run dataflow.yml --uv
本例较为简单展示了使用Python通过异步方式进行消息IO。
receive_data.py异步接收数据send_data.py发送数据
源码
完整源码请参考:dora-examples/python-async
多Python环境共存
uv通过VIRTUAL_ENV环境变量可以切换不同的Python的环境,则只需要在dataflow.yml中配置即可
构建环境
$ uv venv -p 3.11 -n env_1
$ uv venv -p 3.11 -n env_2
$ dora build dataflow.yml --uv
运行
$ dora run dataflow.yml --uv
运行效果应与python-dataflow一致。
源码
完整源码请参考:dora-examples/python-multi-env
ROS2数据流
准备相关依赖
由于例子与turtlesim和AddTwoInts相关
$ sudo apt install ros-jazzy-turtlesim ros-jazzy-examples-rclcpp-minimal-service
准备Python环境
$ uv venv -p 3.10 --seed
$ uv pip install -e ../../apis/node
启动
启动turtlesim
$ source /opt/ros/jazzy/setup.bash
$ ros2 run turtlesim turtlesim_node
启动AddTwoInts服务
$ source /opt/ros/jazzy/setup.bash
$ ros2 run examples_rclcpp_minimal_service service_main
$ source /opt/ros/jazzy/setup.bash
$ dora run dataflow.yml --uv
源码
完整源码请参考:dora-examples/python-ros2-dataflow
Python Dora-Zenoh集成示例
本示例展示如何使用Python将Dora与Zenoh连接进行双向通信。
概述
两个组件相互通信:
- Dora节点(Python):向Zenoh主题发布和订阅消息
- Zenoh应用(Python):通过Zenoh与Dora节点交换消息
结构
dataflow.yml:Dora数据流配置dora_node.py:集成Zenoh的Dora节点实现zenoh_app.py:独立的Zenoh应用程序requirements.txt:Python依赖
前置条件
- Python 3.8+
- Dora已安装并在PATH中可用,或通过
DORA环境变量设置 - Python包:
dora-rs和eclipse-zenoh
安装
安装所需的Python包:
pip install -r requirements.txt
工作原理
-
Dora节点:
- 每500ms向
dora/data发布“Hello“消息 - 订阅
zenoh/data上的消息 - 持续运行直到按Ctrl+C
- 每500ms向
-
Zenoh应用:
- 订阅
dora/data - 接收5条消息后,开始向
zenoh/data发布 - 继续双向收发直到按Ctrl+C
- 订阅
运行示例
方式1:手动运行(推荐用于测试)
终端1 - 启动Dora数据流:
dora up
dora start dataflow.yml
终端2 - 运行Zenoh应用:
python3 zenoh_app.py
停止:
- 在终端2按
Ctrl+C停止Zenoh应用 - 在终端1按
Ctrl+C停止Dora节点,或运行:
dora destroy dataflow.yml
方式2:使用Dora Daemon
dora daemon --run-dataflow dataflow.yml
然后在另一个终端:
python3 zenoh_app.py
预期输出
来自dora_node.py:
Initializing Zenoh session...
Declaring Zenoh publisher for 'dora/data'...
Declaring Zenoh subscriber for 'zenoh/data'...
Dora node with Zenoh integration started!
Press Ctrl+C to stop...
Publishing message: Hello from Dora node! Message #1
Publishing message: Hello from Dora node! Message #2
Publishing message: Hello from Dora node! Message #3
...
>> [Subscriber] Received PUT ('zenoh/data': 'Hello from Zenoh app, payload counter: 0')
>> [Subscriber] Received PUT ('zenoh/data': 'Hello from Zenoh app, payload counter: 1')
...
(持续运行直到按Ctrl+C)
来自zenoh_app.py:
Opening Zenoh session...
Subscribing to dora/data...
Waiting for 5 messages from Dora node before publishing...
>> [Subscriber] Received PUT ('dora/data': 'Hello from Dora node! Message #1')
>> [Subscriber] Received PUT ('dora/data': 'Hello from Dora node! Message #2')
...
>> [Subscriber] Received PUT ('dora/data': 'Hello from Dora node! Message #5')
Received 5 messages! Creating publisher for 'zenoh/data'...
Publishing to Dora node (Press Ctrl+C to stop)...
<< [Publisher] Sent payload(counter = 0)
>> [Subscriber] Received PUT ('dora/data': 'Hello from Dora node! Message #6')
<< [Publisher] Sent payload(counter = 1)
>> [Subscriber] Received PUT ('dora/data': 'Hello from Dora node! Message #7')
...
(持续双向通信直到按Ctrl+C)
故障排除
- 确保Zenoh可以通信(检查防火墙设置)
- 确保已安装
dora-rs和eclipse-zenoh - 检查是否使用Python 3.8+
源码
完整源码请参考:dora-examples/python-zenoh-dataflow
Rust
Rust 样例
Rust数据流
源码
完整源码请参考:dora-examples/rust-dataflow
Rust网址数据流
源码
完整源码请参考:dora-examples/rust-dataflow-url
通过git获取节点
源码
完整源码请参考:dora-examples/rust-dataflow-git
Rust ROS2数据流
源码
完整源码请参考:dora-examples/rust-ros2-dataflow
Dora-Zenoh集成示例
本示例展示如何将Dora与Zenoh连接进行双向通信。
概述
两个组件相互通信:
- Dora节点:向Zenoh主题发布和订阅消息
- Zenoh应用:通过Zenoh与Dora节点交换消息
结构
dataflow.yml:Dora数据流配置dora-node/:集成Zenoh的Dora节点实现zenoh-app/:订阅数据的独立Zenoh应用程序main.rs:Dora数据流运行器
前置条件
- Rust和Cargo
- Dora已安装并在PATH中可用,或通过
DORA环境变量设置 - Zenoh依赖已安装
确保DORA环境变量设置正确:
export DORA=/Users/demo/dora
工作原理
nodes:
- id: dora-zenoh-publisher
build: bash -c "cd dora-node && cargo build --release"
path: ./dora-node/target/aarch64-apple-darwin/release/dora-node
inputs:
tick: dora/timer/millis/500
id:节点标识符build:编译节点的命令path:编译后二进制文件的位置inputs:Dora提供一个每500ms发送tick的定时器给此节点
Dora节点:
- 向
dora/data发布“Hello“消息 - 订阅
zenoh/data上的消息
Zenoh应用:
- 订阅
zenoh/data - 向
dora/data发布消息
运行示例
cargo run --release --example zenoh-dataflow
预期输出
2025-11-02T18:10:49.943542Z INFO dora_daemon::log: Initializing Zenoh session... build_id=None dataflow_id=Some("019a45c3-c5d2-7725-85d1-e741573b765e") node_id=Some("dora-zenoh-publisher")
2025-11-02T18:10:49.951918Z INFO dora_daemon::log: Declaring Zenoh publisher for 'dora/data'... build_id=None dataflow_id=Some("019a45c3-c5d2-7725-85d1-e741573b765e") node_id=Some("dora-zenoh-publisher")
>> [Subscriber] Received PUT ('dora/data': 'Hello from Dora node! Message #1')
2025-11-02T18:10:49.962553Z INFO dora_daemon::log: Declaring Zenoh subscriber for 'zenoh/data'... build_id=None dataflow_id=Some("019a45c3-c5d2-7725-85d1-e741573b765e") node_id=Some("dora-zenoh-publisher")
2025-11-02T18:10:49.972699Z INFO dora_daemon::log: Dora node with Zenoh integration started! build_id=None dataflow_id=Some("019a45c3-c5d2-7725-85d1-e741573b765e") node_id=Some("dora-zenoh-publisher")
2025-11-02T18:10:49.977408Z INFO dora_daemon::log: Publishing message: Hello from Dora node! Message #1 build_id=None dataflow_id=Some("019a45c3-c5d2-7725-85d1-e741573b765e") node_id=Some("dora-zenoh-publisher")
2025-11-02T18:10:50.444696Z INFO dora_daemon::log: Publishing message: Hello from Dora node! Message #2 build_id=None dataflow_id=Some("019a45c3-c5d2-7725-85d1-e741573b765e") node_id=Some("dora-zenoh-publisher")
>> [Subscriber] Received PUT ('dora/data': 'Hello from Dora node! Message #2')
2025-11-02T18:10:50.944559Z INFO dora_daemon::log: Publishing message: Hello from Dora node! Message #3 build_id=None dataflow_id=Some("019a45c3-c5d2-7725-85d1-e741573b765e") node_id=Some("dora-zenoh-publisher")
>> [Subscriber] Received PUT ('dora/data': 'Hello from Dora node! Message #3')
2025-11-02T18:10:51.445510Z INFO dora_daemon::log: Publishing message: Hello from Dora node! Message #4 build_id=None dataflow_id=Some("019a45c3-c5d2-7725-85d1-e741573b765e") node_id=Some("dora-zenoh-publisher")
源码
完整源码请参考:dora-examples/rust-zenoh-dataflow
进阶
Dora 官方提供了很多开箱即用的Node-hub, 其中包括但不限于:
可视化
Rerun为多种物理AI数据提供了非常优秀的可视化方案,
本例中用dora-rerun节点可视化opencv-video-capture节点采集到的图像。
概述
dataflow.yml 定义了一个简单的数据流图,包含两个节点:
- camera: 使用
opencv-video-capture从摄像头捕获视频帧 - rerun: 使用
dora-rerun在 Rerun 可视化工具中显示捕获的帧
开始使用
确保已安装 dora:
pip install dora-rs
构建和运行
cd examples/rerun-viewer
dora build dataflow.yml
dora up
dora start dataflow.yml
配置
可以通过 dataflow.yml 中的环境变量配置 camera 节点:
CAPTURE_PATH: 相机设备索引(默认:0)IMAGE_WIDTH: 输出图像宽度(默认:640)IMAGE_HEIGHT: 输出图像高度(默认:480)ENCODING: 图像编码格式(默认:rgb8)
源码
完整源码请参考:dora-examples/rerun-viewer
相机示例
本示例展示如何使用 dora-rs 捕获摄像头画面并显示。
概述
数据流定义了一个简单的图,包含两个节点:
- camera: 使用
opencv-video-capture从摄像头捕获画面 - plot: 使用
opencv-plot在窗口中显示捕获的画面
开始使用
确保已安装 dora。
pip install dora-rs
构建和运行
cd examples/camera
dora build dataflow.yml
dora up
dora start dataflow.yml
数据流配置
nodes:
- id: camera
build: pip install opencv-video-capture
path: opencv-video-capture
inputs:
tick: dora/timer/millis/20
outputs:
- image
env:
CAPTURE_PATH: 0
IMAGE_WIDTH: 640
IMAGE_HEIGHT: 480
- id: plot
build: pip install opencv-plot
path: opencv-plot
inputs:
image:
source: camera/image
queue_size: 1
配置选项
可以通过环境变量配置相机节点:
CAPTURE_PATH: 相机设备索引(默认:0)IMAGE_WIDTH: 输出图像宽度(默认:640)IMAGE_HEIGHT: 输出图像高度(默认:480)
Jupyter Notebook 变体
提供了 Jupyter notebook 变体,包含 dataflow_jupyter.yml 和 notebook.ipynb。
dora build dataflow_jupyter.yml
dora up
dora start dataflow_jupyter.yml
# 然后在 Jupyter 中打开 notebook.ipynb
源码
完整源码请参考:dora-examples/camera
AV1 编码示例
本示例演示使用 rav1e(编码器)和 dav1d(解码器)进行实时 AV1 视频编码和解码,并通过 Rerun 进行可视化。
源代码:av1-encoding
概述
该数据流捕获摄像头画面,使用 AV1 编码,解码后再次编码,再解码,最后显示结果。这模拟了一个往返编码管道,用于测试视频压缩质量。
camera -> rav1e (编码) -> dav1d (解码) -> rav1e (编码) -> dav1d (解码) -> rerun (显示)
节点
- camera:使用
opencv-video-capture从摄像头捕获画面 - rav1e-local:使用
dora-rav1e将画面编码为 AV1 格式 - dav1d-remote:使用
dora-dav1d解码 AV1 画面 - rav1e-remote:对解码后的画面重新编码为 AV1
- dav1d-local:最终解码 AV1 画面
- plot:使用
dora-rerun在 Rerun 查看器中可视化解码后的画面
前置条件
- Rust 工具链(用于构建 rav1e/dav1d 节点)
- Python 3.8+
- 摄像头
快速开始
1. 安装 dora
# 安装 dora CLI
cargo install dora-cli
# 安装 Python 包(版本必须与 CLI 匹配)
pip install dora-rs
重要:确保 dora CLI 版本与 dora-rs Python 包版本匹配:
dora --version # 检查 CLI 版本
pip show dora-rs # 检查 Python 包版本
2. 克隆 dora-hub(获取节点源码)
git clone https://github.com/dora-rs/dora-hub.git
cd dora-hub
3. 构建节点
# 构建 AV1 编码器/解码器节点
cargo build -p dora-rav1e --release
cargo build -p dora-dav1d --release
# 安装 Python 节点
pip install -e node-hub/opencv-video-capture
pip install -e node-hub/dora-rerun
4. 运行数据流
cd examples/av1-encoding
# 启动 dora 守护进程
dora up
# 构建并启动数据流
dora build dataflow.yml
dora start dataflow.yml
5. 查看输出
连接 Rerun 查看器以查看视频流:
rerun --connect rerun+http://127.0.0.1:9876/proxy
6. 停止数据流
dora stop
配置
相机节点
通过 dataflow.yml 中的环境变量进行配置:
| 变量 | 描述 | 默认值 |
|---|---|---|
CAPTURE_PATH | 相机设备索引 | 0 |
IMAGE_WIDTH | 输出图像宽度 | 1280 |
IMAGE_HEIGHT | 输出图像高度 | 720 |
AV1 编码器 (rav1e)
| 变量 | 描述 | 默认值 |
|---|---|---|
RAV1E_SPEED | 编码速度预设(0-10,越高越快) | 10 |
数据流变体
本示例包含多种数据流配置:
- dataflow.yml:本地机器版本(单机,推荐)
- dataflow_distributed.yml:分布式部署版本(需要在
encoder和decoder机器上运行 dora 守护进程) - dataflow_reachy.yml:Reachy 机器人深度相机配置
故障排除
版本不匹配错误
如果出现类似 invalid type: map, expected a YAML tag starting with '!' 的错误:
# 检查版本是否匹配
dora --version
pip show dora-rs
# 如需升级
cargo install dora-cli --version X.Y.Z
pip install dora-rs==X.Y.Z
节点未找到错误
如果节点启动失败并显示 “No such file or directory”:
- 确保已构建 Rust 节点:
cargo build -p dora-rav1e -p dora-dav1d --release - 检查 dataflow.yml 中的
path是否指向正确的二进制文件位置
相机无法工作
- 在 macOS 上检查相机权限:系统偏好设置 > 隐私与安全性 > 相机
- 尝试不同的
CAPTURE_PATH值(0、1、2…)
架构
+--------+ +-------------+ +-------------+
| camera | --> | rav1e-local | --> | dav1d-remote|
+--------+ +-------------+ +-------------+
|
v
+------+ +------------+ +--------------+
| plot | <-- | dav1d-local| <-- | rav1e-remote |
+------+ +------------+ +--------------+
源代码
- dora-rav1e - AV1 编码器节点
- dora-dav1d - AV1 解码器节点
- opencv-video-capture - 相机捕获节点
- dora-rerun - Rerun 可视化节点
深度相机
本示例演示如何从深度相机捕获RGB图像和深度数据,并在Rerun中进行可视化。
概述
数据流从深度相机(Intel RealSense或iOS LiDAR)捕获帧,输出RGB图像和深度数据,并在Rerun查看器中显示。
depth_camera -> rerun (显示 RGB + 深度)
支持的设备
- Intel RealSense:D400系列深度相机(D415、D435、D455等)
- iOS LiDAR:带有LiDAR扫描仪的iPhone Pro / iPad Pro
节点
- camera:从深度相机捕获RGB图像和深度数据
- Intel RealSense使用
dora-pyrealsense - iOS设备使用
dora-ios-lidar
- Intel RealSense使用
- plot:使用
dora-rerun在Rerun查看器中可视化RGB图像和深度数据
前置条件
- Python 3.8+
- 以下深度相机之一:
- Intel RealSense D400系列相机
- 带有LiDAR的iPhone Pro / iPad Pro
Intel RealSense
- 安装librealsense2 SDK
iOS LiDAR
- 带有LiDAR的iOS设备(iPhone 12 Pro或更新版本,iPad Pro 2020或更新版本)
- 在iOS设备上安装Record3D应用
开始使用
1. 安装dora
# 安装dora CLI
cargo install dora-cli
# 安装Python包(必须与CLI版本匹配)
pip install dora-rs
重要:确保dora CLI版本与dora-rs Python包版本匹配:
dora --version # 检查CLI版本
pip show dora-rs # 检查Python包版本
2. 运行数据流
Intel RealSense
cd examples/depth_camera
# 启动dora守护进程
dora up
# 构建并启动数据流
dora build realsense.yaml
dora start realsense.yaml
iOS LiDAR
- 在iOS设备上打开Record3D应用
- 在Record3D设置中启用USB流模式
- 通过USB连接iOS设备
cd examples/depth_camera
# 启动dora守护进程
dora up
# 构建并启动数据流
dora build ios.yaml
dora start ios.yaml
3. 查看输出
连接Rerun查看器以查看RGB和深度流:
rerun --connect rerun+http://127.0.0.1:9876/proxy
4. 停止数据流
dora stop
配置
iOS LiDAR节点
通过ios.yaml或ios-dev.yaml中的环境变量进行配置:
| 变量 | 描述 | 默认值 |
|---|---|---|
IMAGE_WIDTH | 输出图像宽度 | 640 |
IMAGE_HEIGHT | 输出图像高度 | 480 |
数据流变体
本示例包含多个数据流配置:
- realsense.yaml:Intel RealSense相机(生产环境)
- realsense-dev.yaml:Intel RealSense相机(开发环境,可编辑安装)
- ios.yaml:iOS LiDAR相机(生产环境)
- ios-dev.yaml:iOS LiDAR相机(开发环境,可编辑安装)
故障排除
Intel RealSense未检测到
- 确保已安装librealsense2 SDK
- 检查USB连接(使用USB 3.0端口以获得最佳性能)
- 如果权限被拒绝,尝试使用sudo运行:使用包含sudo的
realsense-dev.yaml
iOS设备未检测到
- 确保Record3D应用正在运行且USB流已启用
- 检查iOS设备与计算机之间的USB连接
- 在出现提示时信任计算机
版本不匹配错误
如果看到类似invalid type: map, expected a YAML tag starting with '!'的错误:
# 检查版本是否匹配
dora --version
pip show dora-rs
# 如需升级
cargo install dora-cli --version X.Y.Z
pip install dora-rs==X.Y.Z
架构
+---------------+ +------+
| depth_camera | --> | plot |
| (image+depth) | +------+
+---------------+
源码
完整源码请参考:dora-examples/depth_camera
- dora-pyrealsense - Intel RealSense相机节点
- dora-ios-lidar - iOS LiDAR相机节点
- dora-rerun - Rerun可视化节点
MediaPipe 姿态识别
本示例演示使用 MediaPipe 和 dora-rs 进行人体姿态检测,并通过 Rerun 进行可视化。
源代码:mediapipe
概述
该数据流从摄像头捕获画面,使用 MediaPipe 检测人体姿态关键点,并在 Rerun 中可视化结果。
camera -> dora-mediapipe (姿态检测) -> rerun (显示)
节点
- camera:使用
opencv-video-capture从摄像头捕获画面 - dora-mediapipe:处理画面以检测人体姿态关键点
- plot:使用
dora-rerun可视化摄像头画面和检测到的姿态点
前置条件
- 连接到电脑的摄像头
- Python 3.8+
- dora-rs
快速开始
1. 安装 dora
# 安装 dora CLI
cargo install dora-cli
# 安装 Python 包(版本必须与 CLI 匹配)
pip install dora-rs
重要:确保 dora CLI 版本与 dora-rs Python 包版本匹配:
dora --version # 检查 CLI 版本
pip show dora-rs # 检查 Python 包版本
2. 构建并运行
cd examples/mediapipe
# 构建数据流
dora build dataflow.yml
# 启动 dora 守护进程
dora up
# 启动数据流
dora start dataflow.yml
3. 查看输出
连接 Rerun 查看器以查看带有姿态关键点的视频流:
rerun --connect rerun+http://127.0.0.1:9876/proxy
如果默认未显示姿态点,请尝试在 Rerun 界面中添加 2D 查看器。
4. 停止数据流
dora stop
演示
配置
相机节点
通过 dataflow.yml 中的环境变量进行配置:
| 变量 | 描述 | 默认值 |
|---|---|---|
CAPTURE_PATH | 相机设备索引 | 0 |
IMAGE_WIDTH | 输出图像宽度 | 640 |
IMAGE_HEIGHT | 输出图像高度 | 480 |
ENCODING | 图像编码格式 | rgb8 |
输出
dora-mediapipe 节点输出:
- points2d:每帧检测到的 2D 姿态关键点坐标
RealSense 变体
提供 RealSense 深度相机变体用于 3D 姿态估计。详情请参阅 dora-hub 中的原始示例。
架构
+--------+ +----------------+ +------+
| camera | --> | dora-mediapipe | --> | plot |
+--------+ +----------------+ +------+
源代码
- dora-mediapipe - MediaPipe 姿态检测节点
- opencv-video-capture - 相机捕获节点
- dora-rerun - Rerun 可视化节点
物体识别示例
本示例演示使用 YOLO(You Only Look Once)和 dora-rs 进行实时物体检测,并通过 Rerun 进行可视化。
源代码:object-detection
概述
该数据流从摄像头捕获画面,通过 YOLO 进行物体检测,并在 Rerun 中显示带有边界框的结果。
camera -> dora-yolo (物体检测) -> rerun (显示带边界框)
节点
- camera:使用
opencv-video-capture从摄像头捕获画面 - object-detection:使用
dora-yolo(YOLOv8) 检测画面中的物体 - plot:使用
dora-rerun可视化摄像头画面和边界框
前置条件
- 连接到电脑的摄像头
- Python 3.8+
- dora-rs
快速开始
1. 安装 dora
# 安装 dora CLI
cargo install dora-cli
# 安装 Python 包(版本必须与 CLI 匹配)
pip install dora-rs
重要:确保 dora CLI 版本与 dora-rs Python 包版本匹配:
dora --version # 检查 CLI 版本
pip show dora-rs # 检查 Python 包版本
2. 构建并运行
cd examples/object-detection
# 构建数据流
dora build yolo.yml
# 启动 dora 守护进程
dora up
# 启动数据流
dora start yolo.yml
使用 UV(推荐)
uv venv --seed -p 3.11
dora build yolo.yml --uv
dora run yolo.yml --uv
3. 查看输出
连接 Rerun 查看器以查看带有检测物体的视频流:
rerun --connect rerun+http://127.0.0.1:9876/proxy
4. 停止数据流
dora stop
配置
相机节点
通过 yolo.yml 中的环境变量进行配置:
| 变量 | 描述 | 默认值 |
|---|---|---|
CAPTURE_PATH | 相机设备索引 | 0 |
IMAGE_WIDTH | 输出图像宽度 | 640 |
IMAGE_HEIGHT | 输出图像高度 | 480 |
YOLO 节点
dora-yolo 节点默认使用 YOLOv8。它可以检测 COCO 数据集中的 80 种常见物体类别,包括:
- 人、车辆(汽车、公交车、卡车、自行车、摩托车)
- 动物(狗、猫、鸟、马等)
- 常见物品(椅子、桌子、笔记本电脑、手机等)
输出
dora-yolo 节点输出:
- bbox:每帧检测到的物体的边界框坐标和类别标签
架构
+--------+ +------------------+ +------+
| camera | --> | object-detection | --> | plot |
+--------+ | (dora-yolo) | +------+
| +------------------+ ^
| |
+---------------------------------------+
(image)
故障排除
模型下载
首次运行时,YOLO 会自动下载模型权重。根据网络连接情况,这可能需要一些时间。
相机无法工作
- 在 macOS 上检查相机权限:系统偏好设置 > 隐私与安全性 > 相机
- 尝试不同的
CAPTURE_PATH值(0、1、2…)
版本不匹配错误
如果出现类似 invalid type: map, expected a YAML tag starting with '!' 的错误:
# 检查版本是否匹配
dora --version
pip show dora-rs
# 如需升级
cargo install dora-cli --version X.Y.Z
pip install dora-rs==X.Y.Z
源代码
- dora-yolo - YOLO 物体检测节点
- opencv-video-capture - 相机捕获节点
- dora-rerun - Rerun 可视化节点
LLM 语音助手示例
本示例演示使用 Qwen 大语言模型和 dora-rs 构建语音交互 AI 助手。它可以捕获语音、转录文字、使用 Qwen 生成回复,并将回复朗读出来。
源代码:llm
概述
该数据流创建了一个完整的语音助手管道:
麦克风 -> VAD -> Whisper (语音转文字) -> Qwen (LLM) -> Kokoro (文字转语音) -> 扬声器
|
v
rerun (显示)
节点
- dora-microphone:从麦克风捕获音频
- dora-vad:语音活动检测 - 检测你何时在说话
- dora-distil-whisper:使用 Distil-Whisper 模型进行语音转文字
- dora-qwen:大语言模型 (Qwen) 用于生成回复
- dora-kokoro-tts:使用 Kokoro 进行文字转语音
- dora-pyaudio:通过扬声器播放音频
- plot:使用
dora-rerun在 Rerun 查看器中可视化对话
前置条件
- Python 3.11+
- dora-rs
- 麦克风和扬声器
- 足够的 GPU/RAM 用于本地运行 LLM(或 API 访问)
系统依赖
macOS
brew install portaudio
brew install espeak-ng
Linux
sudo apt-get install portaudio19-dev
sudo apt-get install espeak
快速开始
1. 安装 dora
# 安装 dora CLI
cargo install dora-cli
# 安装 Python 包(版本必须与 CLI 匹配)
pip install dora-rs
重要:确保 dora CLI 版本与 dora-rs Python 包版本匹配:
dora --version # 检查 CLI 版本
pip show dora-rs # 检查 Python 包版本
2. 构建并运行
cd examples/llm
# 创建虚拟环境
uv venv --seed -p 3.11
# 构建数据流
dora build qwen-dev.yml --uv
# 运行数据流
dora run qwen-dev.yml --uv
3. 查看输出
连接 Rerun 查看器以查看对话:
rerun --connect rerun+http://127.0.0.1:9876/proxy
4. 交互
直接对着麦克风说话。助手会:
- 检测你何时开始/停止说话 (VAD)
- 将你的语音转录为文字 (Whisper)
- 使用 Qwen LLM 生成回复
- 将回复朗读给你 (Kokoro TTS)
5. 停止数据流
dora stop
配置
Whisper 节点
| 变量 | 描述 | 默认值 |
|---|---|---|
TARGET_LANGUAGE | 转录目标语言 | english |
TTS 节点
| 变量 | 描述 | 默认值 |
|---|---|---|
ACTIVATION_WORDS | 触发 TTS 回复的关键词 | you |
数据流变体
- qwen-dev.yml:标准语音助手
- qwen-dev-interruption.yml:支持打断的语音助手(当你开始说话时会停止朗读)
架构
+------------+ +---------+ +------------------+
| 麦克风 | --> | VAD | --> | distil-whisper |
+------------+ +---------+ | (语音转文字) |
+------------------+
|
v
+------------+ +-------------+ +---------+
| pyaudio | <-- | kokoro-tts | <-- | qwen |
| (扬声器) | | (文字转 | | (LLM) |
+------------+ | 语音) | +---------+
+-------------+ |
v
+--------+
| plot |
| (rerun)|
+--------+
故障排除
麦克风无法工作
- 在系统设置中检查麦克风权限
- 确保选择了正确的音频输入设备
- 先用其他应用测试麦克风
没有音频输出
- 检查扬声器/耳机连接
- 验证音频输出设备设置
- 确保 portaudio 安装正确
模型下载
首次运行时,模型(Whisper、Qwen、Kokoro)会自动下载。根据网络连接和模型大小,这可能需要一些时间。
版本不匹配错误
如果出现类似 invalid type: map, expected a YAML tag starting with '!' 的错误:
# 检查版本是否匹配
dora --version
pip show dora-rs
# 如需升级
cargo install dora-cli --version X.Y.Z
pip install dora-rs==X.Y.Z
源代码
- dora-microphone - 麦克风捕获节点
- dora-vad - 语音活动检测节点
- dora-distil-whisper - 语音转文字节点
- dora-qwen - Qwen LLM 节点
- dora-kokoro-tts - 文字转语音节点
- dora-pyaudio - 音频播放节点
- dora-rerun - Rerun 可视化节点
OpenAI服务器示例
本示例演示如何使用dora-openai-server在Dora数据流中创建一个OpenAI兼容的API服务器。
概述
dora-openai-server节点暴露一个OpenAI兼容的HTTP API,可以接收来自标准OpenAI客户端的请求,并通过Dora数据流进行路由。这使得LLM功能可以与其他Dora节点无缝集成。
注意:Dora OpenAI Server仍处于实验阶段,未来可能会有变化。
OpenAI客户端 -> dora-openai-server -> dora-echo -> 响应
节点
- dora-openai-server:在
http://localhost:8000暴露OpenAI兼容的API- 处理
/v1/chat/completions端点 - 支持文本和图像输入(URL和base64)
- 处理
- dora-echo:简单的回显节点,将接收到的输入作为响应返回
前置条件
开始使用
1. 设置环境
cd examples/openai-server
# 创建虚拟环境
uv venv -p 3.11 --seed
# 安装dora Python API(本地开发时)
uv pip install -e ../../apis/python/node --reinstall
2. 构建并运行数据流
# 构建数据流
dora build dataflow.yml --uv
# 启动dora守护进程
dora up
# 运行数据流
dora run dataflow.yml --uv
3. 使用OpenAI客户端测试
在另一个终端中:
python openai_api_client.py
4. 停止数据流
dora stop
API功能
OpenAI服务器支持:
聊天补全
标准聊天补全请求:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="dummy_api_key")
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"},
],
)
图像输入(URL)
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "What is in this image?"},
{
"type": "image_url",
"image_url": {"url": "https://example.com/image.jpg"},
},
],
}
],
)
图像输入(Base64)
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "What is in this image?"},
{
"type": "image_url",
"image_url": {"url": "data:image/png;base64,iVBORw0KGgo..."},
},
],
}
],
)
数据流配置
默认的dataflow.yml:
nodes:
- id: dora-openai-server
build: pip install dora-openai-server
path: dora-openai-server
outputs:
- v1/chat/completions
inputs:
v1/chat/completions: dora-echo/echo
- id: dora-echo
build: pip install dora-echo
path: dora-echo
inputs:
echo: dora-openai-server/v1/chat/completions
outputs:
- echo
数据流变体
- dataflow.yml:基本回显示例(Python)
- dataflow-rust.yml:Rust变体
- qwenvl.yml:与Qwen VL模型集成
架构
+----------------+ +------------------+ +-----------+
| OpenAI客户端 | --> | dora-openai- | --> | dora-echo |
| (HTTP请求) | | server | | |
+----------------+ | (localhost:8000) | +-----------+
+------------------+ |
^ |
+-----------------------+
(响应)
源码
完整源码请参考:dora-examples/openai-server
- dora-openai-server - OpenAI兼容API服务器节点
- dora-echo - 简单回显节点
语音到语音示例
本示例演示使用dora-rs构建的实时语音到语音管道。它捕获您的声音,使用Whisper进行转录,并使用Kokoro TTS将转录内容朗读出来。
概述
数据流创建了一个完整的语音回声管道:
麦克风 -> VAD -> Whisper (STT) -> Kokoro (TTS) -> 扬声器
|
v
rerun (显示)
节点
- dora-microphone:从麦克风捕获音频
- dora-vad:语音活动检测 - 检测您何时在说话
- dora-distil-whisper:使用Distil-Whisper模型进行语音转文字
- dora-kokoro-tts:使用Kokoro进行文字转语音输出
- dora-pyaudio:通过扬声器播放音频
- dora-rerun:在Rerun查看器中可视化转录内容
前置条件
- Python 3.11+
- dora-rs
- 麦克风和扬声器
- 已安装portaudio和espeak-ng
系统依赖
macOS
brew install portaudio
brew install espeak-ng
Linux
sudo apt-get install portaudio19-dev
sudo apt-get install espeak
开始使用
1. 安装dora
# 安装dora CLI
cargo install dora-cli
# 安装Python包(必须与CLI版本匹配)
pip install dora-rs
重要:确保dora CLI版本与dora-rs Python包版本匹配:
dora --version # 检查CLI版本
pip show dora-rs # 检查Python包版本
2. 构建并运行
cd examples/speech-to-speech
# 创建虚拟环境
uv venv --seed -p 3.11
# 构建数据流
dora build kokoro-dev.yml --uv
# 运行数据流
dora run kokoro-dev.yml --uv
3. 查看输出
连接Rerun查看器以查看转录内容:
rerun --connect rerun+http://127.0.0.1:9876/proxy
4. 交互
只需对着麦克风说话。管道将:
- 检测您何时开始/停止说话(VAD)
- 将您的语音转录为文字(Whisper)
- 将转录内容朗读给您(Kokoro TTS)
5. 停止数据流
dora stop
配置
Whisper节点
| 变量 | 描述 | 默认值 |
|---|---|---|
TARGET_LANGUAGE | 转录的目标语言 | english |
数据流变体
- kokoro-dev.yml:使用Kokoro TTS进行语音合成
- outtetts-dev.yml:使用OuteTTS进行语音合成
- outtetts.yml:使用OuteTTS的生产版本
架构
+------------+ +---------+ +------------------+
| 麦克风 | --> | VAD | --> | distil-whisper |
+------------+ +---------+ | (语音转文字) |
+------------------+
|
v
+------------+ +-------------+ +---------+
| pyaudio | <-- | kokoro-tts | <-- | whisper |
| (扬声器) | | (文字转 | | (STT) |
+------------+ | 语音) | +---------+
+-------------+ |
v
+--------+
| plot |
| (rerun)|
+--------+
故障排除
麦克风无法工作
- 在系统设置中检查麦克风权限
- 确保选择了正确的音频输入设备
- 先用其他应用程序测试麦克风
无音频输出
- 检查扬声器/耳机连接
- 验证音频输出设备设置
- 确保portaudio已正确安装
PyAudio架构不匹配(macOS Apple Silicon)
如果看到类似incompatible architecture (have 'x86_64', need 'arm64')的错误:
# 删除旧的pyaudio并使用正确的架构重新安装
pip uninstall pyaudio
ARCHFLAGS="-arch arm64" pip install --no-cache-dir --no-binary :all: pyaudio
模型下载
首次运行时,模型(Whisper、Kokoro)将自动下载。这可能需要一些时间,取决于您的网络连接和模型大小。
版本不匹配错误
如果看到类似invalid type: map, expected a YAML tag starting with '!'的错误:
# 检查版本是否匹配
dora --version
pip show dora-rs
# 如需升级
cargo install dora-cli --version X.Y.Z
pip install dora-rs==X.Y.Z
源码
完整源码请参考:dora-examples/speech-to-speech
- dora-microphone - 麦克风捕获节点
- dora-vad - 语音活动检测节点
- dora-distil-whisper - 语音转文字节点
- dora-kokoro-tts - 文字转语音节点
- dora-pyaudio - 音频播放节点
- dora-rerun - Rerun可视化节点
语音到文字
概述
此数据流创建一个完整的语音转文字流水线:
麦克风 -> VAD -> Whisper (STT) -> Rerun (显示)
流水线从麦克风捕获音频,检测您何时在说话,使用 Whisper 模型将语音转录为文字,并在 Rerun 查看器中显示结果。
节点
- dora-microphone:从麦克风捕获音频
- dora-vad:语音活动检测 - 检测您何时在说话
- dora-distil-whisper:使用 Distil-Whisper 模型进行语音转文字
- dora-rerun:在 Rerun 查看器中可视化转录结果
先决条件
- Python 3.11+
- dora-rs
- 麦克风
- uv(Python 包管理器)
快速开始
1. 安装 dora
# 安装 dora CLI
cargo install dora-cli
# 或安装 Python 包(必须与 CLI 版本匹配)
pip install dora-rs
2. 构建和运行
cd examples/speech-to-text
# 创建虚拟环境
uv venv --seed -p 3.11
# 构建数据流
dora build whisper.yml --uv
# 运行数据流
dora run whisper.yml --uv
3. 查看结果
# 连接到 Rerun 查看器
rerun --connect rerun+http://127.0.0.1:9876/proxy
配置
Whisper 节点配置
| 变量 | 描述 | 默认值 |
|---|---|---|
TARGET_LANGUAGE | 转录目标语言 | english |
数据流变体
whisper.yml:使用预打包节点的生产版本whisper-dev.yml:用于本地开发的开发版本
架构
+------------+ +---------+ +------------------+
| 麦克风 | --> | VAD | --> | distil-whisper |
+------------+ +---------+ | (语音转文字) |
+------------------+
|
v
+--------+
| rerun |
| (显示) |
+--------+
故障排除
麦克风问题
- 检查系统麦克风权限
- 验证是否选择了正确的音频输入设备
- 首先在其他应用程序中测试麦克风
模型下载缓慢
- 首次运行需要下载 Whisper 模型,可能需要一些时间
- 确保网络连接稳定
- 模型在首次下载后会被缓存
中国用户可以使用 hf-mirror 镜像加速模型下载:
HF_ENDPOINT=https://hf-mirror.com dora build whisper.yml --uv
Rerun 版本不匹配
- 如果看到版本警告,请安装匹配的 Rerun SDK:
pip install rerun-sdk==<version>
源码
完整源码请参考:dora-examples/speech-to-text
物体追踪
概述
此数据流使用 Facebook 的 CoTracker 创建实时物体追踪流水线:
相机 -> 物体检测 -> CoTracker -> Rerun (显示)
流水线从相机捕获视频,使用 YOLO 检测物体,使用 CoTracker 在帧之间追踪检测到的物体,并在 Rerun 查看器中显示结果。
节点
- opencv-video-capture:从相机捕获视频
- dora-yolo:使用 YOLOv8 进行物体检测
- dora-cotracker:使用 Facebook CoTracker3 进行点追踪
- dora-rerun:在 Rerun 查看器中可视化追踪结果
先决条件
- Python 3.10+
- dora-rs
- 相机(摄像头)
- 推荐 GPU(CUDA、MPS 或 CPU 回退)
快速开始
1. 安装 dora
# 安装 dora CLI
cargo install dora-cli
# 或安装 Python 包(必须与 CLI 版本匹配)
pip install dora-rs
2. 构建和运行
cd examples/tracker
# 构建数据流
dora build facebook_cotracker.yml
# 运行数据流
dora run facebook_cotracker.yml
3. 查看结果
# 连接到 Rerun 查看器
rerun --connect rerun+http://127.0.0.1:9876/proxy
配置
CoTracker 节点配置
| 变量 | 描述 | 默认值 |
|---|---|---|
DEVICE | 推理设备 (cuda/mps/cpu) | 自动检测 |
COTRACKER_WINDOW_SIZE | 追踪帧缓冲区大小 | 16 |
INTERACTIVE_MODE | 启用交互模式 | false |
COTRACKER_CHECKPOINT | 自定义模型检查点路径 | None |
相机节点配置
| 变量 | 描述 | 默认值 |
|---|---|---|
CAPTURE_PATH | 相机设备索引或视频路径 | 0 |
IMAGE_WIDTH | 捕获宽度 | 640 |
IMAGE_HEIGHT | 捕获高度 | 480 |
ENCODING | 图像编码 (rgb8/bgr8) | rgb8 |
数据流变体
facebook_cotracker.yml:使用 YOLO 进行物体检测 + CoTracker 进行追踪qwenvl_cotracker.yml:使用 Qwen2.5-VL(视觉语言模型)进行检测 + CoTracker 进行追踪
架构
YOLO + CoTracker 流水线
+--------+ +------+ +-----------+ +--------+
| 相机 | --> | YOLO | --> | CoTracker | --> | Rerun |
+--------+ +------+ +-----------+ +--------+
| ^
|____________________________|
(图像流)
VLM + CoTracker 流水线
+--------+ +---------+ +------------+ +-----------+ +--------+
| 相机 | --> | Qwen-VL | --> | parse_bbox | --> | CoTracker | --> | Rerun |
+--------+ +---------+ +------------+ +-----------+ +--------+
| ^
|___________________________________________________|
(图像流)
工作原理
- 物体检测:YOLO(或 VLM)检测每帧中的物体并输出边界框
- 点生成:CoTracker 将边界框转换为追踪点(每个框 5 个点)
- 点追踪:CoTracker 使用深度学习在连续帧之间追踪这些点
- 可视化:追踪点绘制在帧上并在 Rerun 中显示
故障排除
相机问题
- 检查系统相机权限
- 验证
CAPTURE_PATH中的相机设备索引是否正确 - 首先在其他应用程序中测试相机
模型下载缓慢
- 首次运行需要下载 CoTracker 和 YOLO 模型,可能需要一些时间
- 确保网络连接稳定
- 模型在首次下载后会被缓存
GPU 内存问题
- 减小
IMAGE_WIDTH和IMAGE_HEIGHT以降低内存使用 - 设置
DEVICE=cpu使用 CPU(较慢但内存占用较少) - 减小
COTRACKER_WINDOW_SIZE以减少帧缓冲
Rerun 版本不匹配
- 如果看到版本警告,请安装匹配的 Rerun SDK:
pip install rerun-sdk==<version>
源码
完整源码请参考:dora-examples/tracker
翻译
概述
此数据流创建实时语音翻译流水线:
麦克风 -> VAD -> Whisper (STT) -> 翻译 -> Rerun (显示)
流水线从麦克风捕获音频,检测语音活动,使用 Whisper 转录语音,翻译成另一种语言,并在 Rerun 查看器中显示结果。
节点
- dora-microphone:从麦克风捕获音频
- dora-vad:语音活动检测 - 检测您何时在说话
- dora-distil-whisper:使用 Distil-Whisper 模型进行语音转文字
- dora-argotranslate:使用 Argos Translate 进行离线翻译
- dora-phi4:使用 Microsoft Phi-4 进行多模态翻译(替代方案)
- dora-rerun:在 Rerun 查看器中可视化转录和翻译结果
- dora-kokoro-tts:翻译输出的文字转语音(可选)
- dora-pyaudio:TTS 音频输出(可选)
先决条件
- Python 3.11+
- dora-rs
- 麦克风
- uv(Python 包管理器)
- Phi-4 推荐使用 GPU(flash-attn 需要 CUDA)
快速开始
1. 安装 dora
# 安装 dora CLI
cargo install dora-cli
# 或安装 Python 包(必须与 CLI 版本匹配)
pip install dora-rs
2. 构建和运行
使用 Phi-4(多模态翻译)
cd examples/translation
# 创建虚拟环境
uv venv --seed -p 3.11
# 构建数据流
dora build phi4-dev.yml --uv
# 运行数据流
dora run phi4-dev.yml --uv
# 开始用英语、中文、德语、法语、意大利语、日语、西班牙语或葡萄牙语说话
使用 Argos Translate(离线翻译)
cd examples/translation
# 创建虚拟环境
uv venv --seed -p 3.11
# 构建英语到中文翻译
dora build dataflow_en_zh.yml --uv
# 运行数据流
dora run dataflow_en_zh.yml --uv
3. 查看结果
# 连接到 Rerun 查看器
rerun --connect rerun+http://127.0.0.1:9876/proxy
配置
Whisper 节点配置
| 变量 | 描述 | 默认值 |
|---|---|---|
TARGET_LANGUAGE | 口语输入的语言 | english |
TRANSLATE | 启用 Whisper 翻译 | false |
Argos Translate 配置
| 变量 | 描述 | 默认值 |
|---|---|---|
SOURCE_LANGUAGE | 源语言代码(如 en、zh、fr) | 必填 |
TARGET_LANGUAGE | 目标语言代码(如 en、zh、fr) | 必填 |
Phi-4 配置
| 变量 | 描述 | 默认值 |
|---|---|---|
LEAD_MODALITY | 主要输入模态 | audio |
数据流变体
Argos Translate 流水线
dataflow_en_zh.yml:英语到中文dataflow_zh_en.yml:中文到英语dataflow_en_fr.yml:英语到法语dataflow_fr_en.yml:法语到英语dataflow_en_zh_terminal.yml:英语到中文(终端输出)dataflow_zh_en_terminal.yml:中文到英语(终端输出)dataflow_en_zh_terminal_argo.yml:英语到中文(终端显示)
Phi-4 流水线
phi4-dev.yml:带 TTS 输出的多模态翻译(支持 8+ 种语言)
架构
Argos Translate 流水线
+------------+ +---------+ +------------------+ +------------------+
| 麦克风 | --> | VAD | --> | distil-whisper | --> | argos-translate |
+------------+ +---------+ | (语音转文字) | | (翻译) |
+------------------+ +------------------+
|
v
+--------+
| rerun |
| (显示) |
+--------+
Phi-4 流水线(带 TTS)
+------------+ +---------+ +------------------+ +------------------+
| 麦克风 | --> | VAD | --> | Phi-4 | --> | kokoro-tts |
+------------+ +---------+ | (多模态 AI) | | (文字转语音) |
+------------------+ +------------------+
| |
v v
+--------+ +-----------+
| rerun | | pyaudio |
| (显示) | | (扬声器) |
+--------+ +-----------+
支持的语言
Argos Translate
- 英语 (en)
- 中文 (zh)
- 法语 (fr)
- 德语 (de)
- 西班牙语 (es)
- 意大利语 (it)
- 葡萄牙语 (pt)
- 以及更多…
Phi-4 多模态
- 英语
- 中文
- 德语
- 法语
- 意大利语
- 日语
- 西班牙语
- 葡萄牙语
故障排除
麦克风问题
- 检查系统麦克风权限
- 验证是否选择了正确的音频输入设备
- 首先在其他应用程序中测试麦克风
模型下载缓慢
- 首次运行需要下载 Whisper 和翻译模型,可能需要一些时间
- 确保网络连接稳定
- 模型在首次下载后会被缓存
Phi-4 Flash Attention 错误
- flash-attn 需要 CUDA 和 Linux
- 安装命令:
pip install flash-attn --no-build-isolation - 对于非 CUDA 系统,请使用 Argos Translate 流水线
Argos 语言包未找到
- 安装语言包:
argospm install translate-en_zh - 检查可用包:
argospm search
Rerun 版本不匹配
- 如果看到版本警告,请安装匹配的 Rerun SDK:
pip install rerun-sdk==<version>
源码
完整源码请参考:dora-examples/translation
视觉语言模型 (VLM) 示例
概述
此数据流使用 Qwen2.5-VL 创建视觉语言交互管道:
相机 -> Qwen2.5-VL -> Rerun (显示)
该管道从相机捕获视频,使用视觉语言模型处理图像以理解和描述所见内容,并在 Rerun 查看器中显示结果。它还可以集成语音功能,实现完整的多模态体验。
节点
- opencv-video-capture:从相机捕获视频
- dora-qwen2-5-vl:视觉语言模型 (Qwen2.5-VL) 用于图像理解
- dora-qwenvl:原始 QwenVL 模型(备选)
- dora-rerun:可视化相机画面和 VLM 响应
- dora-microphone:捕获语音输入的音频(可选)
- dora-vad:语音活动检测(可选)
- dora-distil-whisper:语音转文字,用于语音提问(可选)
- dora-kokoro-tts:文字转语音,用于语音回复(可选)
- dora-pyaudio:TTS 音频输出(可选)
前置条件
- Python 3.11+
- dora-rs
- 相机(网络摄像头)
- uv(Python 包管理器)
- 推荐使用 GPU(CUDA/MPS 可加速推理)
快速开始
1. 安装 dora
# 安装 dora CLI
cargo install dora-cli
# 或安装 Python 包(必须与 CLI 版本匹配)
pip install dora-rs
2. 构建和运行
仅视觉模式(简单)
cd examples/vlm
# 创建虚拟环境
uv venv --seed -p 3.11
# 构建数据流
dora build qwen2-5-vl-vision-only-dev.yml --uv
# 运行数据流
dora run qwen2-5-vl-vision-only-dev.yml --uv
语音到语音模式(完整)
cd examples/vlm
# 创建虚拟环境
uv venv --seed -p 3.11
# 构建数据流
dora build qwenvl.yml --uv
# 运行数据流
dora run qwenvl.yml --uv
无需克隆仓库
uv venv -p 3.11 --seed
dora build https://raw.githubusercontent.com/dora-rs/dora/main/examples/vlm/qwenvl.yml --uv
dora run https://raw.githubusercontent.com/dora-rs/dora/main/examples/vlm/qwenvl.yml --uv
3. 查看结果
# 连接到 Rerun 查看器
rerun --connect rerun+http://127.0.0.1:9876/proxy
配置
相机节点配置
| 变量 | 描述 | 默认值 |
|---|---|---|
CAPTURE_PATH | 相机设备索引或视频路径 | 0 |
IMAGE_WIDTH | 捕获宽度 | 640 |
IMAGE_HEIGHT | 捕获高度 | 480 |
VLM 节点配置
| 变量 | 描述 | 默认值 |
|---|---|---|
DEFAULT_QUESTION | 关于图像的提问 | Describe the image in three words. |
IMAGE_RESIZE_RATIO | 输入图像的缩放比例 | 1.0 |
USE_MODELSCOPE_HUB | 使用 ModelScope 代替 HuggingFace | false |
Whisper 节点配置
| 变量 | 描述 | 默认值 |
|---|---|---|
TARGET_LANGUAGE | 语音识别语言 | english |
数据流变体
仅视觉
qwen2-5-vl-vision-only-dev.yml:相机 + Qwen2.5-VL + Rerun(简单视觉模式)
语音到语音
qwenvl.yml:使用 QwenVL + OuteTTS 的完整管道,支持语音输入/输出qwen2-5-vl-speech-to-speech-dev.yml:使用 Qwen2.5-VL + Kokoro TTS 的完整管道qwenvl-dev.yml:使用本地节点路径的开发版本
架构
仅视觉管道
+--------+ +-------------+ +--------+
| 相机 | --> | Qwen2.5-VL | --> | Rerun |
+--------+ | (VLM) | | (显示) |
+-------------+ +--------+
语音到语音管道
+------------+ +---------+ +---------+
| 麦克风 | --> | VAD | --> | Whisper |
+------------+ +---------+ | (STT) |
+---------+
|
v
+--------+ +-------------+ +---------+ +--------+
| 相机 | --> | Qwen2.5-VL | <-- | 问题 | | Rerun |
+--------+ | (VLM) | +---------+ | (显示) |
+-------------+ +--------+
| ^
v |
+---------+ +---------+ |
| Kokoro | --> | PyAudio |-------------+
| (TTS) | | (扬声器)|
+---------+ +---------+
功能特性
- 实时视觉理解:描述场景、识别物体、读取文字
- 语音交互:使用语音询问相机所见内容
- 语音回复:通过文字转语音听取 VLM 的回答
- 可定制提示:配置默认问题用于自动分析
- 多模型支持:可选择 Qwen2.5-VL 或原始 QwenVL
应用场景
- 无障碍辅助:为视障用户描述周围环境
- 质量检测:带语音反馈的自动化视觉检测
- 互动演示:语音控制的图像分析
- 机器人:自主系统的视觉理解
- 教育:视觉内容的交互式学习
故障排除
相机问题
- 检查系统相机权限
- 验证
CAPTURE_PATH中的相机设备索引是否正确 - 先在其他应用中测试相机
模型下载慢
- 首次运行需要下载可能数 GB 的 VLM 模型
- 确保网络连接稳定
- 模型在首次下载后会被缓存
- 在中国可使用
USE_MODELSCOPE_HUB=true加速下载
GPU 内存问题
- Qwen2.5-VL 需要较大的 GPU 内存
- 减小
IMAGE_RESIZE_RATIO以降低内存使用 - 如有可用,使用较小的模型变体
麦克风问题(语音到语音)
- 检查系统麦克风权限
- 验证是否选择了正确的音频输入设备
- 先在其他应用中测试麦克风
Rerun 版本不匹配
- 如果看到版本警告,安装匹配的 Rerun SDK:
pip install rerun-sdk==<version>
源码
- opencv-video-capture
- dora-qwen2-5-vl
- dora-qwenvl
- dora-rerun
- dora-distil-whisper
- Qwen2.5-VL (Alibaba)
场景应用
DORA-RS Lebai 机械臂驱动
用于控制Lebai LM3机械臂的DORA-RS驱动节点。该驱动通过DORA数据流接收目标关节角度和笛卡尔位姿,并据此控制机器人。
前置条件
1. Lebai L-Master Docker(仿真器)
启动Lebai仿真器:
docker run -d --name lebai-master \
-p 80:80 \
-p 5180:5180 \
-p 5181:5181 \
lebai/lmaster:latest
打开以下链接验证仿真器是否运行:http://localhost/dashboard
2. 安装Python依赖
重要:dora-rs Python包版本必须与dora-cli版本完全匹配。
pip install -r requirements.txt
# 验证版本是否匹配
dora --version # 应显示 0.3.11
pip show dora-rs # 应显示 0.3.11
项目结构
lebai/
├── lebai_driver_node.py # 主DORA驱动节点
├── goal_publisher_node.py # 用于测试的目标发布节点示例
├── dataflow.yml # DORA数据流配置
├── requirements.txt # Python依赖
├── LM3_test.py # 原始独立测试脚本
└── README.md
使用方法
快速开始
-
启动Lebai仿真器(参见前置条件)
-
运行DORA数据流:
dora up
dora start dataflow.yml
运行后,你应该能在仿真器中看到机械臂运动:

- 查看日志:
dora logs lebai_driver
- 停止数据流:
dora stop
dora destroy
单独运行节点
用于开发/测试,可直接运行节点:
# 终端1:启动DORA守护进程
dora up
# 终端2:启动数据流
dora start dataflow.yml
# 或独立运行进行测试
python lebai_driver_node.py
节点接口
输入
| 输入ID | 格式 | 描述 |
|---|---|---|
target_joints | JSON | 目标关节角度(弧度) |
target_pose | JSON | 目标笛卡尔位姿 |
command | String | 控制命令 |
target_joints 格式
简单数组:
[0.0, -1.0, 1.0, 0.0, 1.57, 0.0]
带参数:
{
"joints": [0.0, -1.0, 1.0, 0.0, 1.57, 0.0],
"acceleration": 0.6,
"velocity": 0.3,
"wait": true
}
target_pose 格式
{
"x": 0.3,
"y": 0.0,
"z": 0.4,
"rx": 3.14,
"ry": 0.0,
"rz": 0.0
}
命令
| 命令 | 描述 |
|---|---|
start | 连接/重新连接机器人 |
stop | 断开机器人连接 |
home | 移动到初始位置 |
get_joints | 获取当前关节位置 |
输出
| 输出ID | 格式 | 描述 |
|---|---|---|
current_joints | JSON数组 | 当前关节位置(弧度) |
status | String | idle、moving、completed、error、stopped |
error | JSON | 状态为error时的错误详情 |
配置
环境变量
在dataflow.yml中设置或运行前导出:
| 变量 | 默认值 | 描述 |
|---|---|---|
LEBAI_IP | 127.0.0.1 | 机器人/仿真器IP地址 |
LEBAI_SIMULATION | true | 真实机器人设为false |
LEBAI_ACCELERATION | 0.6 | 默认加速度(rad/s^2) |
LEBAI_VELOCITY | 0.3 | 默认速度(rad/s) |
示例:真实机器人配置
nodes:
- id: lebai_driver
path: lebai_driver_node.py
inputs:
target_joints: planner/joints
outputs:
- current_joints
- status
- error
env:
LEBAI_IP: "192.168.1.100" # 你的机器人IP
LEBAI_SIMULATION: "false" # 真实机器人模式
LEBAI_ACCELERATION: "0.4" # 为安全起见降低速度
LEBAI_VELOCITY: "0.2"
集成示例
与运动规划器集成
nodes:
- id: motion_planner
path: your_planner.py
inputs:
goal: user_input/goal
outputs:
- joints
- id: lebai_driver
path: lebai_driver_node.py
inputs:
target_joints: motion_planner/joints
outputs:
- current_joints
- status
与视觉系统集成
nodes:
- id: camera
path: camera_node.py
outputs:
- image
- id: vision
path: vision_node.py
inputs:
image: camera/image
outputs:
- target_pose
- id: lebai_driver
path: lebai_driver_node.py
inputs:
target_pose: vision/target_pose
outputs:
- status
故障排除
连接失败
-
检查仿真器/机器人是否运行:
curl http://localhost/dashboard -
验证端口映射(Docker):
docker ps docker logs lebai-master -
检查环境变量中的IP地址
运动不执行
- 在仪表板中检查机器人状态
- 确保机器人已启用(调用了start_sys)
- 检查输出中的错误:
dora logs lebai_driver
DORA无法启动
-
确保DORA守护进程正在运行:
dora up -
检查数据流语法:
dora check dataflow.yml
节点初始化错误
如果看到RuntimeError: Could not initiate node from environment variable和invalid type: map, expected a YAML tag starting with '!':
-
版本不匹配 - dora-rs Python包版本必须与dora-cli匹配:
# 检查版本 dora --version pip show dora-rs # 安装匹配版本修复 pip install dora-rs==0.3.11 # 匹配你的CLI版本 -
修复后重启DORA守护进程:
dora destroy dora up dora start dataflow.yml
源码
完整源码请参考:dora-examples/lebai
DORA-RS SO-101 Follower Arm Driver (MuJoCo Simulation)
A DORA-RS driver node for controlling the SO-101 follower arm using MuJoCo physics simulation. Uses the official SO-ARM100 model from TheRobotStudio.
The SO-101 is a 6-DOF low-cost robot arm commonly used in the LeRobot teleoperation project.
Features
- Official SO-ARM100 MuJoCo model with accurate CAD meshes
- 6-DOF control (5 arm joints + gripper)
- Smooth quintic trajectory interpolation
- OpenCV-based visualization (works on macOS without mjpython)
- DORA dataflow integration
Prerequisites
1. Install DORA-RS
Install the DORA CLI:
# Using cargo (recommended)
cargo install dora-cli
# Check version
dora --version
2. Install Python Dependencies
IMPORTANT: The dora-rs Python package version must match the dora-cli version exactly.
pip install -r requirements.txt
# Verify versions match
dora --version # Note the version
pip show dora-rs # Should match CLI version
Project Structure
so101/
├── so101_driver_node.py # Main DORA driver node with MuJoCo simulation
├── goal_publisher_node.py # Example goal publisher for testing
├── dataflow.yml # DORA dataflow configuration
├── requirements.txt # Python dependencies
├── so101_new_calib.xml # MuJoCo model (from SO-ARM100)
├── scene.xml # Scene configuration
├── assets/ # STL mesh files
├── README.md
└── RELEASE.md
Usage
Quick Start
- Run the DORA dataflow:
cd so101
dora up
dora start dataflow.yml
- Monitor the logs:
dora logs so101_driver
- Stop the dataflow:
dora stop
dora destroy
Node Interfaces
Inputs
| Input ID | Format | Description |
|---|---|---|
target_joints | JSON | Target joint angles for all 6 joints |
command | String | Control commands |
target_joints Format
Simple array (6 values):
[0.0, 0.5, -0.8, 0.3, 0.0, 1.0]
With parameters:
{
"joints": [0.0, 0.5, -0.8, 0.3, 0.0, 1.0],
"duration": 1.5
}
Joint Descriptions
| Index | Name | Description | Range (rad) |
|---|---|---|---|
| 0 | shoulder_pan | Base rotation | -1.92 to 1.92 |
| 1 | shoulder_lift | Shoulder pitch | -1.75 to 1.75 |
| 2 | elbow_flex | Elbow pitch | -1.69 to 1.69 |
| 3 | wrist_flex | Wrist pitch | -1.66 to 1.66 |
| 4 | wrist_roll | Wrist roll | -2.74 to 2.84 |
| 5 | gripper | Gripper | -0.17 to 1.75 |
Commands
| Command | Description |
|---|---|
start | Initialize simulation |
stop | Close simulation |
home | Move to home position |
get_joints | Get current joint positions |
Outputs
| Output ID | Format | Description |
|---|---|---|
current_joints | JSON array | Current joint positions |
status | String | idle, moving, completed, error, stopped |
error | JSON | Error details when status is error |
Configuration
Environment Variables
Set these in dataflow.yml or export before running:
| Variable | Default | Description |
|---|---|---|
SO101_SHOW_VIEWER | true | Show OpenCV visualization window |
SO101_TIMESTEP | 0.002 | Simulation timestep (seconds) |
SO101_CONTROL_FREQ | 50 | Control loop frequency (Hz) |
Integration Examples
With LeRobot Teleoperation
nodes:
- id: leader_arm
path: leader_arm_node.py
outputs:
- joint_positions
- id: so101_driver
path: so101_driver_node.py
inputs:
target_joints: leader_arm/joint_positions
outputs:
- current_joints
- status
With Policy Inference
nodes:
- id: camera
path: camera_node.py
outputs:
- image
- id: policy
path: policy_node.py
inputs:
image: camera/image
current_joints: so101_driver/current_joints
outputs:
- action
- id: so101_driver
path: so101_driver_node.py
inputs:
target_joints: policy/action
outputs:
- current_joints
- status
Troubleshooting
Viewer Not Showing
The driver uses OpenCV for rendering, which works with regular Python on macOS:
# In dataflow.yml - ensure viewer is enabled
env:
SO101_SHOW_VIEWER: "true"
Model Not Found
Ensure all files are present:
so101_new_calib.xml- Main model fileassets/directory with all STL meshes
DORA Not Starting
-
Ensure DORA daemon is running:
dora up -
Check dataflow syntax:
dora check dataflow.yml
Model Credits
The SO-101 model is from the SO-ARM100 project by TheRobotStudio, generated using the onshape-to-robot plugin.
License
MIT License
远程
Franka Panda 机械臂驱动
用于控制 Franka Panda 机械臂的 DORA-RS 驱动节点。此驱动使用 PyBullet 进行仿真,并通过 DORA 数据流接受目标关节角度和笛卡尔位姿。
功能特性
- Franka Panda 机器人 7 自由度关节控制
- 带逆运动学的笛卡尔位姿控制
- 夹爪控制(开/关)
- PyBullet 物理仿真(可选 GUI)
- 兼容真实 Franka 机器人(需要 libfranka)
先决条件
1. 安装 DORA-RS
安装 DORA CLI:
cargo install dora-cli
# 检查版本
dora --version
2. 安装 Python 依赖
重要:dora-rs Python 包版本必须与 dora-cli 版本完全匹配。
pip install -r requirements.txt
# 验证版本匹配
dora --version # 检查 CLI 版本
pip show dora-rs # 应与 CLI 版本匹配
项目结构
franka/
├── franka_driver_node.py # 主 DORA 驱动节点(PyBullet 仿真)
├── goal_publisher_node.py # 测试用目标发布器示例
├── dataflow.yml # DORA 数据流配置
├── requirements.txt # Python 依赖
└── README.md
使用方法
快速开始
- 运行 DORA 数据流:
dora up
dora start dataflow.yml

- 监控日志:
dora logs franka_driver
- 停止数据流:
dora stop
dora destroy
使用 GUI 运行
在 dataflow.yml 中设置 FRANKA_GUI: "true" 以查看 PyBullet 可视化:
env:
FRANKA_GUI: "true"
节点接口
输入
| 输入 ID | 格式 | 描述 |
|---|---|---|
target_joints | JSON | 目标关节角度(7 个值),单位:弧度 |
target_pose | JSON | 目标笛卡尔位姿 |
command | String | 控制命令 |
gripper | String/Float | 夹爪命令 |
target_joints 格式
简单数组:
[0.0, -0.785, 0.0, -2.356, 0.0, 1.571, 0.785]
带参数:
{
"joints": [0.0, -0.785, 0.0, -2.356, 0.0, 1.571, 0.785],
"velocity": 0.3,
"wait": true
}
target_pose 格式
{
"x": 0.4,
"y": 0.0,
"z": 0.5,
"rx": 3.14,
"ry": 0.0,
"rz": 0.0
}
命令
| 命令 | 描述 |
|---|---|
start | 连接到仿真 |
stop | 断开仿真连接 |
home | 移动到初始位置 |
get_joints | 获取当前关节位置 |
get_pose | 获取当前末端执行器位姿 |
夹爪命令
| 命令 | 描述 |
|---|---|
open | 打开夹爪(0.04m 宽度) |
close | 关闭夹爪(0.0m 宽度) |
0.0-0.04 | 设置特定手指宽度 |
输出
| 输出 ID | 格式 | 描述 |
|---|---|---|
current_joints | JSON 数组 | 当前 7 个关节位置,单位:弧度 |
current_pose | JSON 对象 | 当前末端执行器位姿 |
status | String | idle、moving、completed、error、stopped |
error | JSON | 状态为 error 时的错误详情 |
配置
环境变量
在 dataflow.yml 中设置或在运行前导出:
| 变量 | 默认值 | 描述 |
|---|---|---|
FRANKA_SIMULATION | true | 使用 PyBullet 仿真 |
FRANKA_GUI | false | 显示 PyBullet GUI |
FRANKA_TIME_STEP | 0.001 | 仿真时间步长 |
FRANKA_MAX_VELOCITY | 0.5 | 最大关节速度(rad/s) |
FRANKA_MAX_FORCE | 240.0 | 最大关节力(N) |
Franka Panda 规格
关节限位(弧度)
| 关节 | 下限 | 上限 |
|---|---|---|
| J1 | -2.8973 | 2.8973 |
| J2 | -1.7628 | 1.7628 |
| J3 | -2.8973 | 2.8973 |
| J4 | -3.0718 | -0.0698 |
| J5 | -2.8973 | 2.8973 |
| J6 | -0.0175 | 3.7525 |
| J7 | -2.8973 | 2.8973 |
初始位置
home_position = [0.0, -0.785, 0.0, -2.356, 0.0, 1.571, 0.785]
集成示例
与运动规划器集成
nodes:
- id: motion_planner
path: your_planner.py
inputs:
goal: user_input/goal
outputs:
- joints
- id: franka_driver
path: franka_driver_node.py
inputs:
target_joints: motion_planner/joints
outputs:
- current_joints
- status
与视觉系统集成
nodes:
- id: camera
path: camera_node.py
outputs:
- image
- id: vision
path: vision_node.py
inputs:
image: camera/image
outputs:
- target_pose
- id: franka_driver
path: franka_driver_node.py
inputs:
target_pose: vision/target_pose
outputs:
- status
故障排除
PyBullet 无法启动
-
确保已安装 pybullet:
pip install pybullet -
检查显示问题(GUI 模式):
export DISPLAY=:0 # Linux
DORA 无法启动
-
确保 DORA 守护进程正在运行:
dora up -
检查数据流语法:
dora check dataflow.yml
节点初始化错误
如果看到 RuntimeError: Could not initiate node from environment variable:
-
版本不匹配 - dora-rs Python 包版本必须与 dora-cli 匹配:
# 检查版本 dora --version pip show dora-rs # 安装匹配版本修复 pip install dora-rs==<version> # 匹配您的 CLI 版本 -
修复后重启 DORA 守护进程:
dora destroy dora up dora start dataflow.yml
真实机器人支持
对于真实 Franka Panda 机器人支持,您需要:
- 安装 libfranka
- Franka 控制接口(FCI)访问权限
- 实时内核(推荐)
将 PyBullet 调用替换为 libfranka 调用以控制真实机器人。
源码
完整源码请参考:dora-examples/franka
UR5 机械臂驱动
用于通过 RTDE 协议控制 Universal Robots UR5 机械臂的 DORA-RS 驱动节点。此驱动通过 DORA 数据流接受目标关节角度和笛卡尔位姿,并相应地控制机器人。
功能特性
- 纯 Python RTDE 实现(无原生依赖)
- 支持 Apple Silicon(M1/M2/M3/M4)Mac
- 支持 URSim Docker 仿真器和真实 UR5 机器人
- 关节空间(moveJ)和笛卡尔空间(moveL)运动
先决条件
1. URSim Docker(仿真器)
启动 Universal Robots 仿真器(URSim):
# Apple Silicon(M1/M2/M3/M4)- 需要 Rosetta
docker run -d --name ursim \
-e ROBOT_MODEL=UR5 \
-p 5900:5900 \
-p 6080:6080 \
-p 29999:29999 \
-p 30001-30004:30001-30004 \
--platform=linux/amd64 \
universalrobots/ursim_e-series
# Intel Mac / Linux
docker run -d --name ursim \
-e ROBOT_MODEL=UR5 \
-p 5900:5900 \
-p 6080:6080 \
-p 29999:29999 \
-p 30001-30004:30001-30004 \
universalrobots/ursim_e-series
访问仿真器:
- VNC 查看器:
localhost:5900(密码:easybot) - 网页浏览器:
http://localhost:6080/vnc.html
重要:启动 URSim 后,您必须通过 VNC 完成以下步骤:
- 启动机器人:点击红色电源按钮(左下角)-> 点击“ON“ -> 点击“START“
- 确认安全配置(仅首次):
- 进入汉堡菜单(右上角)-> Settings -> System -> Safety
- 点击底部的“Confirm Safety Configuration“
- 接受默认配置
- 验证机器人模式:机器人应显示绿色的“RUNNING“
2. 安装 DORA-RS
安装 DORA CLI:
cargo install dora-cli
# 检查版本
dora --version
3. 安装 Python 依赖
重要:dora-rs Python 包版本必须与 dora-cli 版本完全匹配。
pip install -r requirements.txt
# 验证版本匹配
dora --version # 检查 CLI 版本
pip show dora-rs # 应与 CLI 版本匹配
项目结构
ur5/
├── ur5_driver_node.py # 主 DORA 驱动节点(纯 Python RTDE)
├── goal_publisher_node.py # 测试用目标发布器示例
├── test_connection.py # 连接测试脚本
├── dataflow.yml # DORA 数据流配置
├── requirements.txt # Python 依赖
└── README.md
使用方法
快速开始
-
启动 URSim 仿真器(参见先决条件)
-
通过 VNC 在 URSim 中启动机器人
-
运行 DORA 数据流:
cd ur5
dora up
dora start dataflow.yml
- 监控日志:
dora logs ur5_driver
- 停止数据流:
dora stop
dora destroy
节点接口
输入
| 输入 ID | 格式 | 描述 |
|---|---|---|
target_joints | JSON | 目标关节角度,单位:弧度 |
target_pose | JSON | 目标笛卡尔位姿 |
command | String | 控制命令 |
target_joints 格式
简单数组(6 个关节:基座、肩部、肘部、腕1、腕2、腕3):
[0.0, -1.5708, 1.5708, -1.5708, -1.5708, 0.0]
带参数:
{
"joints": [0.0, -1.5708, 1.5708, -1.5708, -1.5708, 0.0],
"acceleration": 0.5,
"velocity": 0.3,
"wait": true
}
target_pose 格式
{
"x": 0.3,
"y": 0.0,
"z": 0.4,
"rx": 3.14,
"ry": 0.0,
"rz": 0.0
}
命令
| 命令 | 描述 |
|---|---|
start | 连接/重新连接到机器人 |
stop | 停止运动并断开连接 |
home | 移动到初始位置 |
get_joints | 获取当前关节位置 |
get_pose | 获取当前 TCP 位姿 |
输出
| 输出 ID | 格式 | 描述 |
|---|---|---|
current_joints | JSON 数组 | 当前关节位置,单位:弧度 |
current_pose | JSON 字典 | 当前 TCP 位姿(x, y, z, rx, ry, rz) |
status | String | idle、moving、completed、error、stopped |
error | JSON | 状态为 error 时的错误详情 |
配置
环境变量
在 dataflow.yml 中设置或在运行前导出:
| 变量 | 默认值 | 描述 |
|---|---|---|
UR5_IP | 127.0.0.1 | 机器人/仿真器 IP 地址 |
UR5_ACCELERATION | 0.5 | 默认加速度(rad/s^2 或 m/s^2) |
UR5_VELOCITY | 0.3 | 默认速度(rad/s 或 m/s) |
示例:真实机器人配置
nodes:
- id: ur5_driver
path: ur5_driver_node.py
inputs:
target_joints: planner/joints
outputs:
- current_joints
- current_pose
- status
- error
env:
UR5_IP: "192.168.1.100" # 您的机器人 IP
UR5_ACCELERATION: "0.3" # 为安全起见减速
UR5_VELOCITY: "0.2"
集成示例
与运动规划器集成
nodes:
- id: motion_planner
path: your_planner.py
inputs:
goal: user_input/goal
outputs:
- joints
- id: ur5_driver
path: ur5_driver_node.py
inputs:
target_joints: motion_planner/joints
outputs:
- current_joints
- status
与视觉系统集成
nodes:
- id: camera
path: camera_node.py
outputs:
- image
- id: vision
path: vision_node.py
inputs:
image: camera/image
outputs:
- target_pose
- id: ur5_driver
path: ur5_driver_node.py
inputs:
target_pose: vision/target_pose
outputs:
- status
故障排除
连接失败
-
检查 URSim 是否正在运行:
docker ps | grep ursim docker logs ursim -
验证机器人已在 URSim 中启动(通过 VNC 连接到
localhost:5900) -
检查 RTDE 端口是否可访问:
nc -zv 127.0.0.1 30004 -
检查环境变量中的 IP 地址
运动未执行
- 确保机器人已启动且在 URSim 中释放了制动器
- 检查机器人是否处于远程控制模式(真实机器人)
- 检查示教器/URSim 中的保护性停止
- 检查输出中的错误:
dora logs ur5_driver
DORA 无法启动
-
确保 DORA 守护进程正在运行:
dora up -
检查数据流语法:
dora check dataflow.yml
节点初始化错误
如果看到 RuntimeError: Could not initiate node from environment variable:
-
版本不匹配 - dora-rs Python 包版本必须与 dora-cli 匹配:
# 检查版本 dora --version pip show dora-rs # 安装匹配版本修复 pip install dora-rs==<version> # 匹配您的 CLI 版本 -
修复后重启 DORA 守护进程:
dora destroy dora up dora start dataflow.yml
RTDE “Safety Setup Not Confirmed” 错误
如果看到“SafetySetup has not been confirmed yet“错误:
- 通过 VNC 连接到 URSim(
localhost:5900) - 进入 Settings(汉堡菜单)-> System -> Safety
- 点击底部的“Confirm Safety Configuration“
- 重启驱动
测试连接脚本
运行包含的测试脚本以验证连接:
python test_connection.py
这将测试:
- Dashboard Server(端口 29999)
- RTDE 接口(端口 30004)
- URScript 接口(端口 30002)
RTDE 协议说明
UR RTDE(实时数据交换)协议提供:
- 500Hz 实时机器人状态数据流
- 低延迟命令接口
- 同步和异步运动控制
与其他接口的主要区别:
- 比主/辅接口更可靠
- 比 Dashboard Server 延迟更低
- 直接访问伺服控制
源码
完整源码请参考:dora-examples/ur5
其他样例
基准测试
源码
完整源码请参考:dora-examples/cuda-benchmark
概述
使用 CUDA Zero Copy 代替常规共享内存 (CPU) 的延迟测试示例。
安装
pip install dora-rs-cli # if not already present
# Install pyarrow with gpu support
conda install pyarrow "arrow-cpp-proc=*=cuda" -c conda-forge
## Test installation with
python -c "import pyarrow.cuda"
# Install numba for translation from arrow to torch
pip install numba
## Test installation with
python -c "import numba.cuda"
# Install torch if it's not already present
pip install torch
## Test installation with
python -c "import torch; assert torch.cuda.is_available()"
运行
dora run cpu_bench.yml
dora run cuda_bench.yml
cat benchmark_data.csv
运行演示代码
dora up
dora start demo_bench.yml --detach
python demo_receiver.py
dora destroy
Python Arrow 测试
本文档介绍 dora-rs 中 Apache Arrow 数据格式的使用方法。
什么是 Arrow?
dora-rs 使用 Apache Arrow 作为数据通信格式。Arrow 是一种跨语言的列式内存数据格式,具有以下特点:
- 零拷贝读取 - 高效的数据传输,无需复制数据
- 跨语言支持 - Rust、Python、C++ 等语言无缝协作
- 标准化格式 - 统一的数据表示方式
核心概念
在 Arrow 中,所有数据都是数组。即使是标量值,也必须封装在列表中:
import pyarrow as pa
# 标量值也需要封装为数组
value = pa.array([42]) # 不是 42,而是 [42]
数据类型转换
从 Arrow 数组转换
# 获取 dora 事件中的 Arrow 数组
arrow_array = dora_event["value"]
# 转换为 Python 列表
list_data = arrow_array.to_pylist()
# 转换为 NumPy 数组(零拷贝,只读)
numpy_array = arrow_array.to_numpy()
# 转换为 Pandas Series
pandas_series = arrow_array.to_pandas()
转换为 Arrow 数组
import pyarrow as pa
import numpy as np
import pandas as pd
# 从 Python 列表创建
numeric_array = pa.array([1, 2, 3])
# 从字符串列表创建
string_array = pa.array(["Hello", "World"])
# 从字典/结构体创建
struct_array = pa.array([{"a": 1, "b": 2, "c": [1, 2, 3]}])
# 从 NumPy 数组创建
numpy_array = pa.array(np.array([1, 2, 3]))
# 从 Pandas Series 创建
df = pd.DataFrame({'col1': [1, 2, 3]})
pandas_array = pa.array(df["col1"])
支持的数据类型
| 数据类型 | 示例 | 说明 |
|---|---|---|
| 数值列表 | pa.array([1, 2, 3]) | 整数、浮点数 |
| 字符串数组 | pa.array(["Hello"]) | 文本数据 |
| 字典/结构体 | pa.array([{"a": 1}]) | 嵌套数据结构 |
| NumPy 数组 | pa.array(np.array([1, 2])) | 科学计算数据 |
| Pandas Series | pa.array(df["col"]) | 数据分析数据 |
在 dora 节点中使用
发送数据
from dora import Node
import pyarrow as pa
node = Node()
# 发送数值数组
node.send_output("numbers", pa.array([1, 2, 3, 4, 5]))
# 发送字符串
node.send_output("message", pa.array(["Hello from dora!"]))
# 发送图像数据(NumPy 数组)
import numpy as np
image = np.random.randint(0, 255, (480, 640, 3), dtype=np.uint8)
node.send_output("image", pa.array(image.flatten()))
接收数据
from dora import Node
node = Node()
for event in node:
if event["type"] == "INPUT":
# 获取 Arrow 数组
arrow_array = event["value"]
# 转换为需要的格式
data = arrow_array.to_numpy()
# 处理数据...
零拷贝优势
Arrow 的零拷贝特性使得数据传输非常高效:
# 零拷贝读取 - 直接访问内存,不复制数据
numpy_array = arrow_array.to_numpy() # 只读访问
# 如果需要修改,需要显式复制
numpy_array_copy = arrow_array.to_numpy().copy() # 可写
最佳实践
- 使用原生类型 - 尽量使用 Arrow 原生支持的类型
- 批量处理 - 将多个值打包成数组,而非单独发送
- 零拷贝 - 尽量使用零拷贝读取,避免不必要的内存分配
- 类型一致 - 保持发送和接收端的数据类型一致
源码
完整源码请参考:dora-examples/pyarrow-test
参考文档
附录
词汇表
- 节点(Node)
- 算符(Operator)
- 协作器(Coordinator)
其具体关系请参阅Dora设计
ROS2安装
ROS2安装的详细文档,请以ROS2官方文档为准
locale # check for UTF-8
sudo apt update && sudo apt install locales
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8
locale # verify settings
启用需要的仓库
sudo apt install software-properties-common
sudo add-apt-repository universe
sudo apt update && sudo apt install curl -y
export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F "tag_name" | awk -F\" '{print $4}')
curl -L -o /tmp/ros2-apt-source.deb "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release && echo $VERSION_CODENAME)_all.deb" # If using Ubuntu derivates use $UBUNTU_CODENAME
sudo dpkg -i /tmp/ros2-apt-source.deb
安装相应包
sudo apt install ros-jazzy-desktop
# or sudo apt install ros-jazzy-desktop
教程
欢迎来到全新开启的Dora on Windows11实践教程!本教程将帮助你从零开始学习如何使用 DORA 构建机器人应用。 该教程面向新手,但是需要对Windows11操作系统有一定的了解。
目录
安装
基础环境
操作系统:Windows 11系统
终端:我们的教程使用的终端都是PowerShell,不是CMD,也不是WSL。
我这里使用的是当前最新的版本:1.23.13503.0
查看版本命令:$PSVersionTable.PSVersion
PS E:\projects\Dora> $PSVersionTable.PSVersion
Major Minor Patch PreReleaseLabel BuildLabel
----- ----- ----- --------------- ----------
7 5 4
PS E:\projects\Dora> $PSVersionTable
Name Value
---- -----
PSVersion 7.5.4
PSEdition Core
GitCommitId 7.5.4
OS Microsoft Windows 10.0.26200
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
如果你还没有最新版的PowerShell,在Microsoft Store中进行下载或更新。
安装 Rustup
Dora 是基于 Rust 开发的,安装 Dora 之前,先安装 Rust 环境。
Rustup 是 Rust 官方的跨平台 Rust 安装工具,同时提供了 Rust 版本管理能力。
要将程序编译为 exe 文件,Rust 需要一个链接器、库和 Windows API 导入库。需要安装 Visual Studio。
如果你还没有安装 Visual Studio,可以使用自动安装,那么 rustup-init 将会提供自动安装前置条件的选项。它会安装 Visual Studio Community 版,该版本对个人、学术及开源用途是免费的,非常合适。如果你希望根据自己的 Visual Studio 来安装,可以参考 https://rust-lang.github.io/rustup/installation/windows-msvc.html 完整的安装说明。
从 https://rustup.rs/ 下载 rustup-init.exe。
如果你想自定义安装位置,可以在执行之前设置环境变量。
# ==========================================================
# Rust 全家桶环境变量配置脚本 (2026 更新版)
# 参考:https://rust-lang.github.io/rustup/environment-variables.html
# ==========================================================
# --- 1. 基础路径定义 ---
$baseDir = "E:\Dev\SDK"
$rustupHome = Join-Path $baseDir "Rustup"
$cargoHome = Join-Path $baseDir "Cargo"
$cargoBin = Join-Path $cargoHome "bin"
# --- 2. 核心存储路径 ---
[Environment]::SetEnvironmentVariable("RUSTUP_HOME", $rustupHome, "User")
[Environment]::SetEnvironmentVariable("CARGO_HOME", $cargoHome, "User")
# --- 3. 性能与行为优化 (根据最新文档新增) ---
# [网络] 如果你在国内,建议取消下面两行的注释以使用字节跳动或清华镜像,加快下载速度
# [Environment]::SetEnvironmentVariable("RUSTUP_DIST_SERVER", "https://rsproxy.cn", "User")
# [Environment]::SetEnvironmentVariable("RUSTUP_UPDATE_ROOT", "https://rsproxy.cn/rustup", "User")
# [并发] 增加并发下载数(默认随组件数,强制指定可提高稳定性)
[Environment]::SetEnvironmentVariable("RUSTUP_CONCURRENT_DOWNLOADS", "4", "User")
# [IO/线程] 设置 IO 线程数,提升解压速度 (最大 8)
[Environment]::SetEnvironmentVariable("RUSTUP_IO_THREADS", "8", "User")
# [内存] 解压时允许使用的最大 RAM (单位: 字节),此处设为 1GB
[Environment]::SetEnvironmentVariable("RUSTUP_UNPACK_RAM", "1073741824", "User")
# [自动安装] 默认开启。如果运行未安装的工具链命令,rustup 会自动下载
[Environment]::SetEnvironmentVariable("RUSTUP_AUTO_INSTALL", "1", "User")
# [超时] 增加下载超时时间到 300 秒 (默认 180),防止网络波动导致中断
[Environment]::SetEnvironmentVariable("RUSTUP_DOWNLOAD_TIMEOUT", "300", "User")
# --- 4. 界面与反馈 ---
# 强制显示彩色输出和进度条
[Environment]::SetEnvironmentVariable("RUSTUP_TERM_COLOR", "always", "User")
[Environment]::SetEnvironmentVariable("RUSTUP_TERM_PROGRESS_WHEN", "always", "User")
# --- 5. 安全地更新系统 Path ---
$oldPath = [Environment]::GetEnvironmentVariable("Path", "User")
if ($oldPath -notlike "*$cargoBin*") {
$cleanPath = if ([string]::IsNullOrWhiteSpace($oldPath)) { "" } else { $oldPath.TrimEnd(';') }
$newPath = $cleanPath + ";" + $cargoBin
[Environment]::SetEnvironmentVariable("Path", $newPath, "User")
Write-Host "✅ Path 已更新,指向: $cargoBin" -ForegroundColor Green
} else {
Write-Host "ℹ️ Path 中已存在 Cargo 路径,跳过更新。" -ForegroundColor Cyan
}
Write-Host "`n🚀 Rust 环境变量配置完成!请重启终端(如 PowerShell/CMD)使设置生效。" -ForegroundColor Yellow
执行 rustup-init.exe 命令开始安装。
PS C:\Users\dora> rustup-init.exe
重新启动终端,验证 Rustup 安装。
PS C:\Users\dora> rustup -V
rustup 1.28.2 (e4f3ad6f8 2025-04-28)
info: This is the version for the rustup toolchain manager, not the rustc compiler.
info: No `rustc` is currently active
使用 rustup default stable 命令安装默认版本的 Rust。
PS C:\Users\dora> rustup default stable
info: syncing channel updates for 'stable-x86_64-pc-windows-msvc'
763.9 KiB / 1012.7 KiB ( 75 %) 17.8 KiB/s in 1m 45s ETA: 13s
error: could not download file from 'https://static.rust-lang.org/dist/channel-rust-stable.toml' to 'C:\Users\Miao\.rustup\tmp\u71xqzsnptzibr6m_file.toml': error decoding response body: request or response body error: operation timed out
PS C:\Users\dora> rustup default stable
info: syncing channel updates for 'stable-x86_64-pc-windows-msvc'
1012.7 KiB / 1012.7 KiB (100 %) 15.6 KiB/s in 2m 22s
info: latest update on 2025-12-11, rust version 1.92.0 (ded5c06cf 2025-12-08)
info: downloading component 'cargo'
9.4 MiB / 9.4 MiB (100 %) 1.3 MiB/s in 31s
...
info: installing component 'rustc'
68.6 MiB / 68.6 MiB (100 %) 24.6 MiB/s in 2s
info: installing component 'rustfmt'
info: default toolchain set to 'stable-x86_64-pc-windows-msvc'
stable-x86_64-pc-windows-msvc installed - rustc 1.92.0 (ded5c06cf 2025-12-08)
完成后确认安装是否成功。
PS C:\Users\dora> rustup default stable
info: using existing install for 'stable-x86_64-pc-windows-msvc'
info: default toolchain set to 'stable-x86_64-pc-windows-msvc'
stable-x86_64-pc-windows-msvc unchanged - rustc 1.92.0 (ded5c06cf 2025-12-08)
PS C:\Users\dora> rustc -V
rustc 1.92.0 (ded5c06cf 2025-12-08)
PS C:\Users\dora> cargo -V
cargo 1.92.0 (344c4567c 2025-10-21)
安装 uv
必要步骤。
uv 是使用 Rust 构建的一款高性能 Python 版本管理工具。
uv 源码仓库:https://github.com/astral-sh/uv
我们已经安装了 Rust,所以使用 cargo 进行安装:
PS C:\Users\dora> rustup default stable
info: using existing install for 'stable-x86_64-pc-windows-msvc'
info: default toolchain set to 'stable-x86_64-pc-windows-msvc'
stable-x86_64-pc-windows-msvc unchanged - rustc 1.92.0 (ded5c06cf 2025-12-08)
PS C:\Users\dora> cargo install --locked uv
Updating crates.io index
Downloaded uv v0.9.24
Downloaded 1 crate (2.0MiB) in 4.38s
Installing uv v0.9.24
Updating crates.io index
Updating crates.io index
Downloaded adler2 v2.0.1
...
Compiling uv-requirements v0.0.13
Finished `release` profile [optimized] target(s) in 3m 52s
Installing E:\Dev\SDK\Cargo\bin\uv.exe
Installing E:\Dev\SDK\Cargo\bin\uvx.exe
Installed package `uv v0.9.24` (executables `uv.exe`, `uvx.exe`)
PS C:\Users\dora> uv -V
uv 0.9.24
PS C:\Users\dora> Get-Command uv
CommandType Name Version Source
----------- ---- ------- ------
Application uv.exe 0.0.0.0 E:\Dev\SDK\Cargo\bin\uv.exe
PS C:\Users\dora>
如果想自定义安装位置,可以修改以下环境变量再安装:
# ==========================================================
# UV 全家桶环境变量配置脚本 (基于 0.9.x+ 文档)
# https://docs.astral.sh/uv/reference/environment/
# 目标:将所有下载、缓存、Python解释器及工具锁定在非系统盘
# ==========================================================
# 1. 定义基础路径
$baseDir = "E:\Dev\SDK\uv"
# 2. 定义变量映射 (严格对照官方文档)
$envMap = @{
# uv 程序本身的安装位置 (uv self update 也会更新到这里)
"UV_INSTALL_DIR" = "$baseDir\bin"
# 全局缓存(Wheels, 源文件, 索引缓存等)- 占用空间最大
"UV_CACHE_DIR" = "$baseDir\cache"
# 已经解压安装好的 Python 解释器存放地
"UV_PYTHON_INSTALL_DIR" = "$baseDir\python"
# 下载 Python 安装包压缩包时的临时存放地 (防止占用C盘Temp)
"UV_PYTHON_CACHE_DIR" = "$baseDir\python-cache"
# 通过 'uv tool install' 安装的工具虚拟环境位置
"UV_TOOL_DIR" = "$baseDir\tools"
# 工具的可执行文件快捷方式存放地
"UV_TOOL_BIN_DIR" = "$baseDir\tools-bin"
}
Write-Host "正在初始化 UV 离线/自定义路径环境..." -ForegroundColor Cyan
# 3. 批量创建物理目录
foreach ($path in $envMap.Values) {
if (!(Test-Path $path)) {
New-Item -ItemType Directory -Path $path -Force | Out-Null
Write-Host "已创建目录: $path"
}
}
# 4. 批量设置用户环境变量
foreach ($name in $envMap.Keys) {
[Environment]::SetEnvironmentVariable($name, $envMap[$name], "User")
Write-Host "已设置环境变量: $name -> $($envMap[$name])"
}
# 5. 将必要的 Bin 目录加入 Path (用户 Path)
$oldPath = [Environment]::GetEnvironmentVariable("Path", "User")
# 我们需要把 uv 本身和 uv tool 安装的工具都加入 Path
$targetBins = @($envMap["UV_INSTALL_DIR"], $envMap["UV_TOOL_BIN_DIR"])
foreach ($binPath in $targetBins) {
if ($oldPath -notlike "*$binPath*") {
$oldPath = $oldPath.TrimEnd(';') + ";" + $binPath
Write-Host "已将路径加入 Path: $binPath" -ForegroundColor Green
}
}
[Environment]::SetEnvironmentVariable("Path", $oldPath, "User")
Write-Host "`n配置完成!请重启所有终端(或重启资源管理器)生效。" -ForegroundColor Yellow
Write-Host "验证方法:执行 'uv python dir' 和 'uv cache dir' 查看输出路径。"
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
重启 PowerShell,执行 uv -V 验证 uv 是否安装成功。
(dora) PS E:\projects\Dora> uv -V
uv 0.9.21 (0dc9556ad 2025-12-30)
安装 Git
必要步骤。
从 https://git-scm.com/ 下载最新版本的 Git 安装程序。
一路默认安装。
完成后重新打开 PowerShell。
验证 Git 安装成功。
PS C:\Windows\System32> git -v
git version 2.47.1.windows.1
准备工程文件
必要步骤。
克隆 Dora 源码
源码安装方式需要。
从 https://github.com/dora-rs/dora 克隆 Dora 的源代码工程。
通过编译源码的方式安装 Dora 时需要用到这个工程。
克隆 dora-examples 工程
从 https://github.com/dora-rs/dora-examples
或者 https://gitcode.com/dora-org/dora-examples
克隆示例工程。
克隆 dora-rs-org 工程(文档源码,可以不用)
从 https://github.com/dora-rs-org/dora-rs-org 克隆 Dora 文档工程。
安装 Dora
通过源码安装的Dora是全局的,当环境变量设置正确的时候,你可以随时在任何目录下使用Dora的命令。
由于我们使用了uv作为Python版本管理工具,所以从Python安装的Dora是安装到uv的Python环境中的,只有当你激活的Python环境安装了Dora,你才能在该环境下使用Python安装的Dora的命令。
同时,通过Python安装Dora时,也会安装Python操作Dora的Api依赖,这些依赖是运行Python实现的Node所必要的。
通过源码安装
PS E:\projects\Dora> git clone https://github.com/dora-rs/dora.git
Cloning into 'dora'...
remote: Enumerating objects: 41094, done.
remote: Counting objects: 100% (1234/1234), done.
remote: Compressing objects: 100% (492/492), done.
remote: Total 41094 (delta 1029), reused 754 (delta 740), pack-reused 39860 (from 4)
Receiving objects: 100% (41094/41094), 13.69 MiB | 4.32 MiB/s, done.
Resolving deltas: 100% (24984/24984), done.
PS E:\projects\Dora> cd dora
PS E:\projects\Dora\dora> dir
Directory: E:\projects\Dora\dora
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 2026-01-06 12:46 .github
d---- 2026-01-06 12:46 apis
d---- 2026-01-06 12:46 binaries
d---- 2026-01-06 12:46 docker
d---- 2026-01-06 12:46 docs
d---- 2026-01-06 12:46 examples
d---- 2026-01-06 12:46 libraries
d---- 2026-01-06 12:46 tests
-a--- 2026-01-06 12:46 161 _typos.toml
-a--- 2026-01-06 12:46 3040 .gitignore
-a--- 2026-01-06 12:46 207024 Cargo.lock
-a--- 2026-01-06 12:46 5674 Cargo.toml
-a--- 2026-01-06 12:46 56777 Changelog.md
-a--- 2026-01-06 12:46 3142 CONTRIBUTING.md
-a--- 2026-01-06 12:46 1373 dist-workspace.toml
-a--- 2026-01-06 12:46 1495 flake.nix
-a--- 2026-01-06 12:46 4167 install.ps1
-a--- 2026-01-06 12:46 4899 install.sh
-a--- 2026-01-06 12:46 11554 LICENSE
-a--- 2026-01-06 12:46 574 NOTICE.md
-a--- 2026-01-06 12:46 17370 README.md
PS E:\projects\Dora\dora>
进入工程目录,执行编译命令:cargo build --release --package dora-cli。
PS E:\projects\Dora\dora> cargo build --release --package dora-cli
Updating crates.io index
Downloaded aligned-vec v0.5.0
Downloaded cipher v0.4.4
Downloaded dirs v4.0.0
...
warning: `dora-cli` (lib) generated 6 warnings (run `cargo fix --lib -p dora-cli` to apply 2 suggestions)
Finished `release` profile [optimized] target(s) in 3m 09s
看到这个说明编译成功了,中间可能会看到一些warning,不用管。
验证一下编译结果
PS E:\projects\Dora\dora> .\target\release\dora.exe -V
dora-cli 0.4.0
出现版本号,说明程序编译正常
接下来我们将dora命令加入到环境变量,方便使用
# 执行结果
# 永久添加目标目录到当前用户的 PATH 环境变量
PS E:\projects\Dora\dora\target\release> [Environment]::SetEnvironmentVariable(
>> "Path",
>> [Environment]::GetEnvironmentVariable("Path", "User") + ";E:\projects\Dora\dora\target\release",
>> "User"
>> )
PS E:\projects\Dora\dora\target\release>
重新启动Powershell测试dora -V命令,显示版本号说明环境变量设置成功。
恭喜你,完成dora的安装。
通过Python安装
# 创建 python 环境
PS E:\projects\Dora\dora-examples\examples\echo> uv venv -p 3.11 --seed
Using CPython 3.11.14
Creating virtual environment with seed packages at: .venv
+ pip==25.3
+ setuptools==80.9.0
+ wheel==0.45.1
Activate with: .venv\Scripts\activate
# 查看虚拟环境安装位置(.venv文件夹就是虚拟环境存放的位置)
PS E:\projects\Dora\dora-examples\examples\echo> dir
Directory: E:\projects\Dora\dora-examples\examples\echo
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 2026-01-12 19:44 .venv
d---- 2026-01-11 10:15 out
-a--- 2026-01-07 14:30 4 .gitignore
-a--- 2026-01-10 3:22 489 dataflow.yml
-a--- 2026-01-07 14:30 225 README.md
# 安装Dora-rs-cli
# 如果使用国内源可以加上(推荐) -i https://pypi.tuna.tsinghua.edu.cn/simple/
PS E:\projects\Dora\dora-examples\examples\echo> uv pip install dora-rs-cli -i https://pypi.tuna.tsinghua.edu.cn/simple/
Resolved 5 packages in 589ms
Prepared 5 packages in 1.04s
Installed 5 packages in 114ms
+ dora-rs==0.4.0
+ dora-rs-cli==0.4.0
+ pyarrow==22.0.0
+ pyyaml==6.0.3
+ uv==0.9.24
# 查看已经安装的包
PS E:\projects\Dora\dora-examples\examples\echo> uv pip list
Package Version
----------- -------
dora-rs 0.4.0
dora-rs-cli 0.4.0
pip 25.3
pyarrow 22.0.0
pyyaml 6.0.3
setuptools 80.9.0
uv 0.9.24
wheel 0.45.1
确认完成安装
# 通过 uv 执行虚拟环境中安装的dora命令
PS E:\projects\Dora\dora-examples\examples\echo> uv run dora -V
dora-cli 0.4.0
# 激活虚拟环境
PS E:\projects\Dora\dora-examples\examples\echo> .\.venv\Scripts\activate
# 查看dora命令的位置,发现它来自我们的虚拟环境
(echo) PS E:\projects\Dora\dora-examples\examples\echo> Get-Command dora
CommandType Name Version Source
----------- ---- ------- ------
Application dora.exe 0.0.0.0 E:\projects\Dora\dora-examples\examples\echo\.venv/Scripts…
# 离开虚拟环境
(echo) PS E:\projects\Dora\dora-examples\examples\echo> deactivate
# 查看dora命令的位置,发现它来自我们之前通过源码编译的发布位置
PS E:\projects\Dora\dora-examples\examples\echo> Get-Command dora
CommandType Name Version Source
----------- ---- ------- ------
Application dora.exe 0.0.0.0 E:\projects\Dora\dora\target\release\dora.exe
0.0.0.0 E:\Dev\SDK\Cargo\bin\uv.exe
基础
echo
运行示例
示例代码位置:
https://github.com/dora-rs/dora-examples/tree/main/examples/echo
# 激活 rust 环境
PS E:\projects\Dora\dora-examples\examples\echo> rustup default stable
info: using existing install for 'stable-x86_64-pc-windows-msvc'
info: default toolchain set to 'stable-x86_64-pc-windows-msvc'
stable-x86_64-pc-windows-msvc unchanged - rustc 1.92.0 (ded5c06cf 2025-12-08)
# 创建 python 环境
PS E:\projects\Dora\dora-examples\examples\echo> uv venv -p 3.11 --seed
Using CPython 3.11.14
Creating virtual environment with seed packages at: .venv
+ pip==25.3
+ setuptools==80.9.0
+ wheel==0.45.1
Activate with: .venv\Scripts\activate
# 手动安装依赖(方便使用国内源加速)
PS E:\projects\Dora\dora-examples\examples\echo> uv pip install dora-echo -i https://pypi.tuna.tsinghua.edu.cn/simple/
Resolved 5 packages in 543ms
Prepared 2 packages in 796ms
Installed 2 packages in 113ms
+ dora-echo==0.4.0
+ numpy==1.26.4
PS E:\projects\Dora\dora-examples\examples\echo> uv pip install pyarrow-assert pyarrow-sender -i https://pypi.tuna.tsinghua.edu.cn/simple/
Resolved 6 packages in 171ms
Prepared 2 packages in 38ms
Installed 2 packages in 77ms
+ pyarrow-assert==0.4.0
+ pyarrow-sender==0.4.0
# dora 构建dataflow,这一步会自动安装依赖
PS E:\projects\Dora\dora-examples\examples\echo> dora build dataflow.yml --uv
dora-echo: DEBUG building node
dora-echo: INFO running build command: `pip install dora-echo` in E:\projects\Dora\dora-examples\examples\echo
dora-echo: stdout Audited 1 package in 1ms
pyarrow-assert: DEBUG building node
pyarrow-assert: INFO running build command: `pip install pyarrow-assert` in E:\projects\Dora\dora-examples\examples\echo
pyarrow-assert: stdout Audited 1 package in 1ms
pyarrow-sender: DEBUG building node
pyarrow-sender: INFO running build command: `pip install pyarrow-sender` in E:\projects\Dora\dora-examples\examples\echo
# dora 运行dataflow
PS E:\projects\Dora\dora-examples\examples\echo> dora run dataflow.yml --uv
[!TIP] ℹ️ uv venv -p 3.11 –seed 在当前目录下安装虚拟环境
venvuv 的核心子命令,用于创建 Python 虚拟环境,等价于python -m venv
-p是 –python 的简写,指定虚拟环境使用的 Python 版本为 3.11
--seed作用是自动为新虚拟环境安装最新版的核心工具:
[!TIP] ℹ️ dora build dataflow.yml –uv 构建 / 编译 dataflow.yml 中定义的所有 Dora 节点(如 Python/Rust 节点),完成依赖安装、代码编译等前置准备
build触发节点构建流程(如执行 pip install 安装 Python 节点依赖、编译 Rust 节点)dataflow.yml指定数据流应用的配置文件(定义节点、数据流、依赖等)--uv强制使用 uv 替代原生 pip/venv 管理 Python 依赖 / 虚拟环境,提升安装 / 构建速度
[!TIP] ℹ️ dora run dataflow.yml –uv 启动 dataflow.yml 定义的完整数据流应用(先自动触发 build 构建,再运行 coordinator / 节点)
run启动数据流运行时,加载所有节点并执行数据流逻辑--uv运行时仍用 uv 管理 Python 环境,保证与构建阶段环境一致 特性:无需先手动执行 build,run 会自动完成构建后再启动应用
日志分析
# 执行命令:运行 dataflow.yml 配置文件,并使用 uv 管理 Python 环境
PS E:\projects\Dora\dora\examples\echo> dora run dataflow.yml --uv
# --- 阶段 1:描述符校验 (Descriptor Validation) ---
# 系统检查配置文件。由于节点定义了 build 命令,dora 默认这些节点是动态生成的,跳过静态路径检查。
2026-01-07T03:20:29.980024Z INFO dora_core::descriptor::validate: skipping path check for node with build command
2026-01-07T03:20:29.980398Z INFO dora_core::descriptor::validate: skipping path check for node with build command
2026-01-07T03:20:29.980638Z INFO dora_core::descriptor::validate: skipping path check for node with build command
# --- 阶段 2:通信基础设施初始化 (Zenoh Runtime) ---
# 初始化底层通信中间件 Zenoh。ZID 是当前节点在分布式网络中的唯一身份标识。
2026-01-07T03:20:29.980995Z INFO zenoh::net::runtime: Using ZID: 2147f674895baddd40cbe90101a9a508
# Zenoh 正在尝试绑定本地所有可用的网络接口(IPv6/IPv4),监听 5053 端口用于节点间发现。
2026-01-07T03:20:29.984823Z INFO zenoh::net::runtime::orchestrator: Zenoh can be reached at: tcp/[fe80::4e53:daaa:1c91:ae52]:5053
2026-01-07T03:20:29.984939Z INFO zenoh::net::runtime::orchestrator: Zenoh can be reached at: tcp/192.168.2.52:5053
2026-01-07T03:20:29.985032Z INFO zenoh::net::runtime::orchestrator: Zenoh can be reached at: tcp/172.17.128.1:5053
# 开启组播监听,用于自动发现局域网内的其他机器。
2026-01-07T03:20:29.985273Z INFO zenoh::net::runtime::orchestrator: zenohd listening scout messages on 224.0.0.224:7446
# --- 阶段 3:进程启动与孵化 (Node Spawning) ---
# 调度器 (Spawner) 准备启动 YAML 中定义的各个节点。
11:20:30 DEBUG dora-echo: daemon::spawner spawning node
11:20:30 DEBUG pyarrow-assert: daemon::spawner spawning node
11:20:30 DEBUG pyarrow-sender: daemon::spawner spawning node
11:20:30 INFO dora daemon finished building nodes, spawning...
# 节点 1 (dora-echo): 启动进程。注意这里通过 uv 运行,PID 为 38632。
11:20:30 INFO dora-echo: spawner spawning `uv` in `E:\projects\Dora\dora\examples\echo`
11:20:30 DEBUG dora-echo: spawner spawned node with pid 38632
# 节点 2 (pyarrow-assert): 启动进程,用于断言/验证数据。PID 为 57420。
11:20:30 INFO pyarrow-assert: spawner spawning `uv` in `E:\projects\Dora\dora\examples\echo`
11:20:30 DEBUG pyarrow-assert: spawner spawned node with pid 57420
# 节点 3 (pyarrow-sender): 启动进程,负责发送测试数据。PID 为 53296。
11:20:30 INFO pyarrow-sender: spawner spawning `uv` in `E:\projects\Dora\dora\examples\echo`
11:20:30 DEBUG pyarrow-sender: spawner spawned node with pid 53296
# --- 阶段 4:运行就绪与数据传输 (Dataflow Active) ---
# 节点依次报告 Ready 状态,表明内部逻辑已加载完成并成功挂载到 dora 运行时。
11:20:30 INFO dora-echo: daemon node is ready
11:20:32 INFO pyarrow-sender: daemon node is ready
11:20:32 INFO pyarrow-assert: daemon node is ready
# 全员就绪,数据流正式“开闸”运行。
11:20:32 INFO daemon all nodes are ready, starting dataflow
# 各个 Python 进程初始化 OpenTelemetry,用于导出监控和指标数据。
11:20:32 INFO pyarrow-sender: opentelemetry Global meter provider is set...
11:20:32 INFO dora-echo: opentelemetry Global meter provider is set...
11:20:32 INFO pyarrow-assert: opentelemetry Global meter provider is set...
# --- 阶段 5:任务结束与清理 (Teardown) ---
# pyarrow-sender 发送完数据后首先完成任务,正常退出。
11:20:32 stdout pyarrow-sender:
11:20:32 DEBUG pyarrow-sender: daemon handling node stop with exit status Success
11:20:32 INFO pyarrow-sender: daemon pyarrow-sender finished successfully
# dora-echo 处理完回传数据并退出。
11:20:32 stdout dora-echo:
11:20:32 stdout pyarrow-assert:
11:20:32 DEBUG dora-echo: daemon handling node stop with exit status Success
11:20:32 INFO dora-echo: daemon dora-echo finished successfully
# 核心守护进程 (Daemon) 检测到所有必需节点已完成。
2026-01-07T03:20:32.994153Z INFO run_inner: dora_daemon: exiting daemon because all required dataflows are finished...
# 最后完成校验的 pyarrow-assert 退出,标志着整个逻辑链条验证通过。
11:20:32 DEBUG pyarrow-assert: daemon handling node stop with exit status Success
2026-01-07T03:20:32.994325Z INFO run_inner: zenoh::api::session: close session zid=2147...
11:20:32 INFO pyarrow-assert: daemon pyarrow-assert finished successfully
# 最终报告:数据流在当前机器 ID 下运行圆满结束。
11:20:32 INFO daemon dataflow finished on machine `d26831a9-90a8-4593-a48c-d51b960c55f2`
讲解 Dataflow
# dataflow.yml
nodes:
# 节点 1: 数据源发送者
- id: pyarrow-sender
build: pip install pyarrow-sender # 运行前自动安装依赖包
path: pyarrow-sender # 寻找 entry_points 中注册的可执行命令
outputs:
- data # 定义输出端口:向外广播数据
env:
DATA: "[1, 2, 3, 4, 5]" # 通过环境变量设置要发送的初始测试数据
# 节点 2: 中转转发者 (即你之前看的 main.py 逻辑)
- id: dora-echo
build: pip install dora-echo
path: dora-echo
inputs:
data: pyarrow-sender/data # 订阅输入:接收来自 pyarrow-sender 的 data 输出
outputs:
- data # 将接收到的数据原样转发给下游
# 节点 3: 数据校验者
- id: pyarrow-assert
build: pip install pyarrow-assert
path: pyarrow-assert
inputs:
data: dora-echo/data # 订阅输入:接收来自 dora-echo 的转发数据
env:
DATA: "[1, 2, 3, 4, 5]" # 预期数据值,用于与接收到的数据进行比对断言
讲解 Node
搜索Python官方源:https://pypi.org/
Dora Node Hub:https://dora-rs.ai/docs/nodes/
echo sample node的源码:https://github.com/dora-rs/dora-hub/tree/main/node-hub/dora-echo
# dora-hub/node-hub/dora-echo/dora_echo/main.py
"""TODO: Add docstring."""
import argparse
import os
from dora import Node
# 检测是否在持续集成 (CI) 环境中运行
RUNNER_CI = True if os.getenv("CI") == "true" else False
def main():
# 配置命令行参数,允许动态指定节点名称(默认为 "echo")
parser = argparse.ArgumentParser(description="Simple arrow sender")
parser.add_argument(
"--name",
type=str,
required=False,
help="The name of the node in the dataflow.",
default="echo",
)
args = parser.parse_args()
# 初始化 dora 节点,建立与守护进程 (Daemon) 的连接
node = Node(
args.name,
)
# 核心事件循环:迭代处理来自数据流的所有事件
for event in node:
# 仅处理类型为 "INPUT" 的事件(即上游发送的数据)
if event["type"] == "INPUT":
# 零拷贝转发:将接收到的 ID、值和元数据原样送出到下游
node.send_output(event["id"], event["value"], event["metadata"])
if __name__ == "__main__":
main()
# node-hub/dora-echo/tests/test_dora_echo.py
"""TODO: Add docstring."""
import pytest
def test_import_main():
"""验证 main 函数可以被正常导入并执行基础运行时检查"""
from dora_echo.main import main
# 预期抛出 RuntimeError:因为 main() 内部会初始化 Node(),
# 而当前环境缺少 dora daemon 守护进程,这是验证环境隔离性的常见手段。
with pytest.raises(RuntimeError):
main()
# node-hub/dora-echo/pyproject.toml
[project]
name = "dora-echo"
version = "0.4.0"
authors = [
{ name = "Haixuan Xavier Tao", email = "tao.xavier@outlook.com" },
{ name = "Enzo Le Van", email = "dev@enzo-le-van.fr" },
]
description = "Dora echo"
license = { text = "MIT" }
readme = "README.md"
# 确保环境兼容性,最低支持 Python 3.8
requires-python = ">=3.8"
# 核心依赖:dora-rs 框架、特定版本的 numpy 和高性能数据格式库 pyarrow
dependencies = ["dora-rs >= 0.3.9", "numpy < 2.0.0", "pyarrow >= 5.0.0"]
[dependency-groups]
# 开发环境工具:包含单元测试 (pytest) 和高性能代码规范检查器 (ruff)
dev = ["pytest >=8.1.1", "ruff >=0.9.1"]
[project.scripts]
# 注册终端命令:安装后可直接在命令行输入 `dora-echo` 调用 main 函数
dora-echo = "dora_echo.main:main"
[tool.ruff.lint]
# 代码质量扫描配置:启用文档样式、性能、导入排序等多种 lint 规则
extend-select = [
"D", # pydocstyle: 检查文档字符串
"UP", # Ruff's UP rule: 升级旧版语法
"PERF", # Ruff's PERF rule: 性能优化建议
"RET", # Ruff's RET rule: 返回值逻辑优化
"RSE", # Ruff's RSE rule: 异常处理规范
"NPY", # Ruff's NPY rule: NumPy 特定规则
"N", # Ruff's N rule: 变量命名规范
"I", # Ruff's I rule: 自动排序 import
]
做一点小修改
修改dataflow.yml文件,修改pyarrow-sender节点发送的数据,模拟一个错误数据。
# dataflow.yml
nodes:
- id: pyarrow-sender
build: pip install pyarrow-sender
path: pyarrow-sender
outputs:
- data
env:
DATA: "[1, 2, 3, 4, 0]" # 模拟错误数据
再次运行查看运行日志,可以发现pyarrow-assertNode发现了异常数据。
PS E:\projects\Dora\dora-examples\examples\echo> dora run .\dataflow.yml --uv
2026-01-12T18:42:00.240647Z INFO dora_core::descriptor::validate: skipping path check for node with build command
2026-01-12T18:42:00.240777Z INFO dora_core::descriptor::validate: skipping path check for node with build command
2026-01-12T18:42:00.240856Z INFO dora_core::descriptor::validate: skipping path check for node with build command
2026-01-12T18:42:00.241187Z INFO zenoh::net::runtime: Using ZID: 8aae42e2236f709b07e9eb1a86b8ee90
2026-01-12T18:42:00.244888Z INFO zenoh::net::runtime::orchestrator: Zenoh can be reached at: tcp/[fe80::c2f2:9df0:d13:8a7d]:12927
2026-01-12T18:42:00.244991Z INFO zenoh::net::runtime::orchestrator: Zenoh can be reached at: tcp/192.168.2.52:12927
2026-01-12T18:42:00.245128Z INFO zenoh::net::runtime::orchestrator: Zenoh can be reached at: tcp/172.17.128.1:12927
2026-01-12T18:42:00.245377Z INFO zenoh::net::runtime::orchestrator: zenohd listening scout messages on 224.0.0.224:7446
02:42:00 DEBUG dora-echo: daemon::spawner spawning node
02:42:00 DEBUG pyarrow-assert: daemon::spawner spawning node
02:42:00 DEBUG pyarrow-sender: daemon::spawner spawning node
02:42:00 INFO dora daemon finished building nodes, spawning...
02:42:00 INFO dora-echo: spawner spawning `uv` in `E:\projects\Dora\dora-examples\examples\echo`
02:42:00 DEBUG dora-echo: spawner spawned node with pid 39664
02:42:00 INFO pyarrow-assert: spawner spawning `uv` in `E:\projects\Dora\dora-examples\examples\echo`
02:42:00 DEBUG pyarrow-assert: spawner spawned node with pid 38992
02:42:00 INFO pyarrow-sender: spawner spawning `uv` in `E:\projects\Dora\dora-examples\examples\echo`
02:42:00 INFO dora-echo: daemon node is ready
02:42:00 DEBUG pyarrow-sender: spawner spawned node with pid 12848
02:42:01 INFO pyarrow-assert: daemon node is ready
02:42:01 INFO pyarrow-sender: daemon node is ready
02:42:01 INFO daemon all nodes are ready, starting dataflow
02:42:01 INFO dora-echo: opentelemetry Global meter provider is set. Meters can now be created using global::meter() or global::meter_with_scope().
02:42:01 INFO pyarrow-assert: opentelemetry Global meter provider is set. Meters can now be created using global::meter() or global::meter_with_scope().
02:42:01 stdout pyarrow-sender:
02:42:01 stdout pyarrow-sender:
02:42:01 DEBUG pyarrow-sender: daemon handling node stop with exit status Success (restart: false)
02:42:01 INFO pyarrow-sender: daemon pyarrow-sender finished successfully
02:42:01 stdout pyarrow-assert: Traceback (most recent call last):
02:42:01 stdout dora-echo:
02:42:01 stdout pyarrow-assert: File "<frozen runpy>", line 198, in _run_module_as_main
02:42:01 stdout dora-echo:
02:42:01 DEBUG dora-echo: daemon handling node stop with exit status Success (restart: false)
02:42:01 INFO dora-echo: daemon dora-echo finished successfully
02:42:01 stdout pyarrow-assert: File "<frozen runpy>", line 88, in _run_code
02:42:01 stdout pyarrow-assert: File "E:\projects\Dora\dora-examples\examples\echo\.venv\Scripts\pyarrow-assert.exe\__main__.py", line 10, in <module>
02:42:01 stdout pyarrow-assert: File "E:\projects\Dora\dora-examples\examples\echo\.venv\Lib\site-packages\pyarrow_assert\main.py", line 52, in main
02:42:01 stdout pyarrow-assert: assert value == data, f"Expected {data}, got {value}"
02:42:01 stdout pyarrow-assert: ^^^^^^^^^^^^^
02:42:01 stdout pyarrow-assert: AssertionError: Expected [
02:42:01 stdout pyarrow-assert: 1,
02:42:01 stdout pyarrow-assert: 2,
02:42:01 stdout pyarrow-assert: 3,
02:42:01 stdout pyarrow-assert: 4,
02:42:01 stdout pyarrow-assert: 5
02:42:01 stdout pyarrow-assert:
02:42:01 stdout pyarrow-assert: ], got [
02:42:01 stdout pyarrow-assert: 1,
02:42:01 stdout pyarrow-assert: 2,
02:42:01 stdout pyarrow-assert: 3,
02:42:01 stdout pyarrow-assert: 4,
02:42:01 stdout pyarrow-assert: 0
02:42:01 stdout pyarrow-assert: ]
02:42:01 stdout pyarrow-assert:
02:42:01 DEBUG pyarrow-assert: daemon handling node stop with exit status ExitCode(1) (restart: false)
2026-01-12T18:42:01.574980Z INFO run_inner: dora_daemon: exiting daemon because all required dataflows are finished self.daemon_id=DaemonId { machine_id: None, uuid: 99c7e046-b3df-4954-aae8-69a8bcf4dfd1 }
02:42:01 ERROR pyarrow-assert: daemon exited with code 1 with stderr output:
---------------------------------------------------------------------------------
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "E:\projects\Dora\dora-examples\examples\echo\.venv\Scripts\pyarrow-assert.exe\__main__.py", line 10, in <module>
File "E:\projects\Dora\dora-examples\examples\echo\.venv\Lib\site-packages\pyarrow_assert\main.py", line 52, in main
assert value == data, f"Expected {data}, got {value}"
^^^^^^^^^^^^^
AssertionError: Expected [
1,
2,
3,
4,
5
], got [
1,
2,
3,
4,
0
]
---------------------------------------------------------------------------------
2026-01-12T18:42:01.575162Z INFO run_inner: zenoh::api::session: close session zid=8aae42e2236f709b07e9eb1a86b8ee90 self.daemon_id=DaemonId { machine_id: None, uuid: 99c7e046-b3df-4954-aae8-69a8bcf4dfd1 }
02:42:01 INFO daemon dataflow finished on machine `99c7e046-b3df-4954-aae8-69a8bcf4dfd1`
[ERROR]
Dataflow failed:
Node `pyarrow-assert` failed: exited with code 1 with stderr output:
---------------------------------------------------------------------------------
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "E:\projects\Dora\dora-examples\examples\echo\.venv\Scripts\pyarrow-assert.exe\__main__.py", line 10, in <module>
File "E:\projects\Dora\dora-examples\examples\echo\.venv\Lib\site-packages\pyarrow_assert\main.py", line 52, in main
assert value == data, f"Expected {data}, got {value}"
^^^^^^^^^^^^^
AssertionError: Expected [
1,
2,
3,
4,
5
], got [
1,
2,
3,
4,
0
]
---------------------------------------------------------------------------------
Location:
binaries\cli\src\common.rs:33:17
坑1 - uv 和 conda 混用
如果你的环境中还包含conda/miniconda之类的工具,最好卸载或者禁用自动激活。
禁用自动激活执行:conda config --set auto_activate_base false 。
关闭所有Powershell,再启动。
验证:
当激活uv管理的环境时,查看python/pip的位置:
PS E:\projects\Dora\dora\examples\echo> .\.venv\Scripts\activate
(echo) PS E:\projects\Dora\dora\examples\echo> Get-Command pip
CommandType Name Version Source
----------- ---- ------- ------
Application pip.exe 0.0.0.0 E:\projects\Dora\dora\examples\echo\.ven…
(echo) PS E:\projects\Dora\dora\examples\echo> Get-Command python
CommandType Name Version Source
----------- ---- ------- ------
Application python.exe 3.11.1415… E:\projects\Dora\dora\examples\echo\.ven…
(echo) PS E:\projects\Dora\dora\examples\echo> python -m pip -V
pip 25.3 from E:\projects\Dora\dora\examples\echo\.venv\Lib\site-packages\pip (python 3.11)
(echo) PS E:\projects\Dora\dora\examples\echo>
可以发现,他们指向的都是虚拟环境所在的位置,这种情况符合预期,如果不一样,需要排查,解决环境问题。
坑2 - uv 环境和 pip install
dora run --uv
--uv 标志的作用
当你执行 dora build dataflow.yml --uv 时,dora 会识别到你想使用 uv 作为包管理器。
dora会在当前目录下寻找.venv文件夹。- 它会自动设置环境变量(如
VIRTUAL_ENV),确保所有的build指令都在该虚拟环境下执行。
当 dora build 运行时,它会执行这个 build 字符串。因为你加了 --uv,这个 pip 实际上等同于调用 .venv/bin/pip (Linux/macOS) 或 .venv\Scripts\pip (Windows)。
💡 可编辑模式 -e 在 Python 中,通常你安装一个包时,
pip会把代码 复制 到.venv/lib/site-packages目录下。如果你修改了源代码,安装好的包不会发生变化。可编辑模式 (
pip install -e .) 的区别在于:
- 它不会复制文件,而是在
site-packages中创建一个 符号链接(Link) 或一个特殊的.pth文件,指向你开发目录的代码。- 实时生效:当你修改了
../../node-hub/pyarrow-sender里的.py文件,你不需要重新运行pip install或dora build。下次dora run时,它直接加载的就是你修改后的代码。这种方式非常适合用于开发调试阶段,避免了反复构建和安装的麻烦。
目录
介绍
Openloong是由人形机器人(上海)有限公司运营的开源项目,目标是推动人形机器人全场景应用、助力具身智能时代的到来。
项目背景
在具身智能领域,开源人形机器人项目 Openloong 具有重要的研究与应用价值。当前该项目使用 ROS 作为中间件,但 ROS 存在诸多问题。其架构设计在大规模、复杂的具身智能系统中面临挑战,数据传输性能有局限,AI能力也存在困难。而 Dora-rs 机器人中间件在AI 框架支持,运行速度、软件质量以及安全可信等方面优势突出,能契合机器人对下一代软件平台的严苛要求。因此,有必要将 dora-rs 机器人框架移植到 Openloong 项目中,以解决现有问题。
Dora Openloong的目标是改进 Openloong 项目的架构设计,解决 ROS 架构在复杂具身智能系统中的通信拓扑复杂、AI 能力弱等问题,提高系统的可扩展性。提升数据传输性能,降低通信延迟,确保在处理大量实时数据时系统的实时性,满足机器人实时避障、快速响应交互指令等场景的需求。优化计算资源管理,在资源受限的嵌入式设备上充分利用硬件资源,提高系统性能,减少对机器人续航能力和运行效率的影响。提供便捷的AI预集成框架,增加对机器人AI能力的支持。
项目实现
本项目在ospp2025-openloong仓库提供了一系列开发示例并提供了相关文档, 旨在帮助用户快速上手Openloong-Dora框架, 这些示例包含: Openloong机器人导航、Openloong上肢控制、Openloong底盘控制、Openloong抓取示例等,示例使用Python语言实现;
开发环境准备
Dora环境
dora环境安装见dora官方文档
Openloong微服务框架gRPC安装
- 依赖
- python 3.7或更高版本
- pip 9.0.1或更高版本
- 安装gprc:
python -m pip install grpcio #或者在系统范围内安装 sudo python -m pip install grpcio
-
安装gprc工具
python -m pip install grpcio-tools从Github仓库下载官方最新版本代码以及相关示例
git clone -b v1.73.0 --depth 1 --shallow-submodules https://github.com/grpc/grpc在
examples/python/helloworld目录下运行:python greeter_server.py在另一个终端中,
examples/python/helloworld目录下运行:python greeter_client.py以上顺利完成可启动gRPC服务
-
可能踩坑
在递归克隆gRPC仓库时容易在克隆子模块时失败, 导致模块缺失, 后续编译(C++版本)虽然可能顺利通过, 但会缺少部分功能无法运行gRPC框架;
openloong实例
在dora-rs/ospp2025openloong仓库
Openloong-proto文件夹提供了openloong的gRPC-proto控制接口
GPS导航
使用gRPC微服务获取机器人当前位置
在dora-rs/ospp2025openloong仓库gps_navigaton_gprc文件夹提供了机器人GPS导航server和client的python实现
-
使用gRPC编译proto
在安装有gRPC的python环境中执行:
python -m grpc_tools.protoc -I./protoFiles --python_out=proto --pyi_out=proto --grpc_python_out=proto protoFiles/gps_navigation.protogRPC会读取proto文件
protoFiles/gps_navigation.proto并将生成的文件放在proto目录下 -
启动gRPC server服务
在安装有gRPC的python环境下执行
python gps_navigation_server.py -
启动gRPC client服务 在安装有gRPC的python环境下执行
python gps_navigation_client.py -
执行预期效果
上肢控制
在dora-rs/ospp2025openloong仓库
upper_controller文件夹提供了机器人上肢控制器server和client的python实现
-
使用gRPC编译proto
在安装有gRPC的python环境中执行:
python -m grpc_tools.protoc -I./protoFiles --python_out=proto --pyi_out=proto --grpc_python_out=proto protoFiles/upper_controller.protogRPC会读取proto文件
protoFiles/upper_controller.proto并将生成的文件放在proto目录下 -
启动gRPC server服务
在安装有gRPC的python环境下执行
python upper_controller_server.py -
启动gRPC client服务
在安装有gRPC的python环境下执行
python upper_controller_client.py -
执行预期效果
openloong-dora工作流
在dora-rs/ospp2025openloong仓库openloong-dora-workflow文件夹提供了使用dora工作流控制机器人底盘定点移动和机械臂抓取的python实现
-
使用gRPC编译proto
在安装有gRPC的python环境中执行以下命令生成上肢控制的相关代码:
python -m grpc_tools.protoc -I./protoFiles --python_out=proto --pyi_out=proto --grpc_python_out=proto protoFiles/upper_controller.proto在安装有gRPC的python环境中执行以下命令生成底盘控制的相关代码:
python -m grpc_tools.protoc -I./protoFiles --python_out=proto --pyi_out=proto --grpc_python_out=proto protoFiles/chassis_controller.protogRPC会读取proto文件
protoFiles/upper_controller.proto和protoFiles/chassis_controller.proto并将生成的文件放在proto目录下 -
启动gRPC server服务
在安装有gRPC的python环境下执行以下命令启动上肢控制器
python upper_controller_server.py在安装有gRPC的python环境下执行以下命令启动底盘控制器
python chassis_controller_server.py -
启动dora工作流 在安装有dora和gRPC的python环境执行:
dora run workflow/dataflow.yml --uv -
预期执行效果
dora数据流正常打印交互信息, 机器人工作状态正常, demo在B站演示视频查看
自动驾驶入门
dora-drives 是一个循序渐进的教程,让初学者可以使用简单的入门套件从零开始编写自己的自动驾驶程序。
为什么选择 dora-drives?
我们相信编程自动驾驶车辆是学习机器人应用的完美起点,因为:
- 自动驾驶是许多机器人应用的基础
- 自动驾驶概念简单易懂
- 网上有大量可用的数据集、模型和文档
源代码
文档
介绍
dora-drives 是一个循序渐进的教程,让初学者可以使用简单的入门套件从零开始编写自己的自动驾驶程序。
为什么选择 dora-drives?
我们相信编程自动驾驶车辆是学习机器人应用的完美起点,因为:
- 自动驾驶是基础 - 自动驾驶是许多机器人应用的基础
- 简单易懂 - 自动驾驶概念简单,容易解释
- 丰富的资源 - 网上有大量可用的数据集、模型和文档
项目仓库
更多文档
完整文档请访问:https://dora-rs.ai/docs/guides/dora-drives
讨论
我们的主要交流渠道是 GitHub 项目讨论页面:https://github.com/orgs/dora-rs/discussions
欢迎就任何话题、问题或想法与我们交流。
安装
克隆仓库
git clone https://gitcode.com/dora-rs/dora-drives.git
cd dora-drives
安装依赖
# 创建 conda 环境
conda create -n dora3.7 python=3.7 -y
conda activate dora3.7
# 安装 PyTorch
conda install pytorch=1.11.0 torchvision=0.12.0 cudatoolkit=11.3 -c pytorch -y
# 安装 Python 依赖
pip install --upgrade pip
pip install -r install_requirements.txt
pip install -r requirements.txt
安装 dora
如果尚未安装 dora,可以使用以下命令:
sudo wget https://github.com/dora-rs/dora/releases/download/v0.2.5/dora-v0.2.5-x86_64-Linux.zip && sudo unzip dora-v0.2.5-x86_64-Linux.zip -d /usr/local/bin
更多信息
详细安装说明请参见:https://dora-rs.ai/docs/guides/dora-drives/installation
快速开始
本教程将引导您逐步运行自动驾驶数据流,从简单的物体检测到完整的自动驾驶系统。
启动 CARLA 模拟器
首先,使用 Docker 启动 CARLA 模拟器:
# 拉取 CARLA Docker 镜像
docker pull carlasim/carla:0.9.13
# 启动 CARLA 模拟器
docker run --privileged --gpus all --net=host -e DISPLAY=$DISPLAY carlasim/carla:0.9.13 /bin/bash ./CarlaUE4.sh -carla-server -world-port=2000 -RenderOffScreen
模拟器将在 localhost:2000 运行。
数据流配置文件
graphs/oasis/ 目录包含多个数据流配置文件,每个文件展示自动驾驶的不同功能层级:
| 配置文件 | 功能 | 复杂度 |
|---|---|---|
oasis_agent_yolov5.yaml | 物体检测 | 入门 |
oasis_agent_obstacle_location.yaml | 障碍物定位 | 中级 |
oasis_agent_planning.yaml | 路径规划 | 中级 |
oasis_full.yaml | 完整自动驾驶 | 高级 |
1. 物体检测 (oasis_agent_yolov5.yaml)
这是最简单的数据流,演示如何使用 YOLOv5 检测 CARLA 模拟器中的物体。
数据流结构
┌─────────────┐ ┌─────────┐ ┌──────┐
│ oasis_agent │────▶│ yolov5 │────▶│ plot │
│ (相机图像) │ │(物体检测)│ │(可视化)│
└─────────────┘ └─────────┘ └──────┘
节点说明
| 节点 | 功能 | 输入 | 输出 |
|---|---|---|---|
oasis_agent | 从 CARLA 获取传感器数据 | tick | image, position, speed, lidar_pc |
yolov5 | YOLOv5 物体检测 | image | bbox (边界框) |
plot | 可视化检测结果 | image, bbox, position | - |
运行命令
dora up
dora start graphs/oasis/oasis_agent_yolov5.yaml --attach
预期输出
运行后会显示一个窗口,展示 CARLA 模拟器的相机画面,检测到的物体会用边界框标注。

2. 障碍物定位 (oasis_agent_obstacle_location.yaml)
在物体检测的基础上,结合 LIDAR 点云数据计算障碍物的全局坐标。
数据流结构
┌─────────────┐ ┌─────────┐ ┌────────────────────┐ ┌──────┐
│ oasis_agent │────▶│ yolov5 │────▶│ obstacle_location │────▶│ plot │
│ (相机+LIDAR)│ │(物体检测)│ │ (障碍物定位) │ │(可视化)│
└─────────────┘ └─────────┘ └────────────────────┘ └──────┘
节点说明
| 节点 | 功能 | 输入 | 输出 |
|---|---|---|---|
oasis_agent | 获取相机和 LIDAR 数据 | tick | image, lidar_pc, position |
yolov5 | 物体检测 | image | bbox |
obstacle_location_op | 融合 LIDAR 计算障碍物位置 | lidar_pc, bbox, position | obstacles (全局坐标) |
plot | 可视化障碍物位置 | image, bbox, obstacles, position | - |
工作原理
- 计算点云中每个点的角度
- 将边界框像素角度映射到实际点
- 将 LIDAR 相对坐标转换为全局坐标
坐标系统
使用 Unreal Engine 坐标系:
- Z 轴:向上
- X 轴:向前
- Y 轴:向右
运行命令
dora up
dora start graphs/oasis/oasis_agent_obstacle_location.yaml --attach
预期输出
检测到的障碍物会在边界框中显示一个点,表示其估计的全局坐标位置。

3. 路径规划 (oasis_agent_planning.yaml)
添加 GPS 路由和运动规划功能,使车辆能够规划避障路径。
数据流结构
┌────────────┐
┌────▶│ carla_gps │────┐
┌─────────────┐ ┌─────────┐ │ (GPS路由) │ │ ┌─────────┐
│ oasis_agent │────▶│ yolov5 │ └────────────┘ ├────▶│ fot_op │
│ │ └─────────┘ │ │(轨迹规划)│
│ │────▶│obstacle_location│───────────────┘ └─────────┘
└─────────────┘ └─────────────────┘
节点说明
| 节点 | 功能 | 输入 | 输出 |
|---|---|---|---|
carla_gps_op | 使用 GlobalRoutePlanner 计算 GPS 路由 | opendrive, objective_waypoints, position | gps_waypoints |
fot_op | Frenet 最优轨迹规划器 | position, speed, obstacles, gps_waypoints | waypoints |
GPS 路由
使用 CARLA 的 GlobalRoutePlanner 计算两点间的路线,航点格式为 [x, y, speed]。
运动规划
Frenet Optimal Trajectory (FOT) 规划器综合考虑:
- 当前位置和速度
- 障碍物位置
- GPS 航点
生成最优的避障轨迹。
运行命令
dora up
dora start graphs/oasis/oasis_agent_planning.yaml --attach
预期输出
可视化窗口会显示规划的路径轨迹,包括 GPS 航点和避障路径。

4. 完整自动驾驶 (oasis_full.yaml)
完整的自动驾驶系统,包含感知、规划和控制三个模块。
数据流结构
┌─────────────┐
│ oasis_agent │◀──────────────────────────────────────────┐
│ (传感器) │ │
└──────┬──────┘ │
│ │
▼ │
┌─────────────┐ ┌────────────────────┐ │
│ yolov5 │────▶│ obstacle_location │ │
│ (物体检测) │ │ (障碍物定位) │ │
└─────────────┘ └─────────┬──────────┘ │
│ │
┌──────────────────────┼──────────────────┐ │
│ │ │ │
▼ ▼ ▼ │
┌─────────────┐ ┌─────────────┐ ┌──────────────┐ │
│ carla_gps │────▶│ fot_op │────▶│ pid_control │─┘
│ (GPS路由) │ │ (轨迹规划) │ │ (PID控制) │
└─────────────┘ └─────────────┘ └──────────────┘
新增节点
| 节点 | 功能 | 输入 | 输出 |
|---|---|---|---|
pid_control_op | PID 控制器 | position, speed, waypoints | control (throttle, steering, brake) |
PID 控制器
将规划的航点转换为车辆控制命令:
- throttle: 油门 (0-1)
- steering: 转向 (-1 到 1)
- brake: 刹车 (0-1)
控制命令发送回 oasis_agent,形成闭环控制。
运行命令
dora up
dora start graphs/oasis/oasis_full.yaml --attach
预期输出
车辆将自动行驶,实时检测障碍物、规划路径并控制车辆。可视化窗口显示完整的感知和规划信息。

进阶扩展
可以添加更多功能节点:
| 功能 | 操作符 | 说明 |
|---|---|---|
| 车道检测 | yolop_op.py | 检测道路车道线 |
| 目标跟踪 | strong_sort.py | 多目标跟踪 |
| 交通标志识别 | traffic_sign.py | 识别交通标志 |
故障排除
模拟器连接失败
确保 CARLA 在 localhost:2000 运行:
# 检查容器状态
docker ps
# 查看容器日志
docker logs <container_id>
GPU 内存不足
调整 YOLOv5 配置:
env:
PYTORCH_DEVICE: cpu # 使用 CPU 而非 GPU
显示问题
如果使用无头模式,确保设置了正确的 DISPLAY 环境变量。
源代码
完整文档
Dora-nav 导航
基于开源机器人中间件DORA的导航框架,该导航框架基于激光点云实现环境地图构建与室内/室外定位,采用轨迹跟踪的方法实现路径跟随导航。
激光雷达使用RoboScience Helios 16,小车底盘使用mickrobot 四轮差速小车。
目录说明:在“~“目录下存放dora 运行文件及 DORA_NAV文件夹
功能特点
- 激光点云环境地图构建
- 室内/室外定位
- 轨迹跟踪路径跟随导航
- 多模态数据可视化
文档导航
介绍
DORA_NAV 是基于开源机器人中间件 DORA 的导航框架,该导航框架基于激光点云实现环境地图构建与室内/室外定位,采用轨迹跟踪的方法实现路径跟随导航。
硬件配置
- 激光雷达:RoboScience Helios 16
- 小车底盘:mickrobot 四轮差速小车
目录说明
| 目录/文件 | 说明 |
|---|---|
| include | 存放头文件 |
| driver | 存放dora支持的传感器驱动节点,主要使用rslidar_driver |
| mapping | ndt建图节点 |
| localization | 小车定位节点,实现小车定位,输出小车轨迹 |
| planning | 道路参数供给 + 任务决策执行 |
| map | 参考路径管理 + 坐标转换 + 定位信息输出 |
| control | 主要存放dora支持的移动机器人及底盘节点 |
| rerun | 多模态数据可视化工具 |
| data | 存放path.yml的输出 |
| out | 存放path.yml和run.yml的日志 |
| path.yml | Dora数据流框架的节点配置文件,从激光雷达数据采集到位姿估计输出的完整数据流链路 |
| run.yml | Dora数据流框架的节点配置文件,定义系统中11个核心节点的运行参数、数据依赖关系和数据流链路 |
| road_msg.txt | 定义的道路属性 |
数据流架构
run.yml 定义了从「传感器数据采集」→「定位与路径处理」→「规划决策」→「车辆控制」→「数据可视化」的端到端全流程,让各模块按配置自动协同运行。
环境配置
依赖环境
- ROS2 Humble
- dora v0.3.9
- rust v1.91.1
- rerun 0.27.2
安装 dora v0.3.9
参考官方文档:https://github.com/dora-rs/dora
dora-api 编译
/dora/apis 目录下有C、C++、python、rust语言的桥接库,需要手动编译:
cargo build -p dora-node-api-cxx --release
dora-node-api-cxx是 cargo.toml 中定义的 name
编译产物在 /target/release 目录下,不加 --release,编译的是测试版本,编译产物在 /target/debug 目录下。
编译完成之后先运行一个示例,验证桥接库可用,参考官方文档:https://dora-rs.org/dora-by-examples/basic/cpp/ros2-dataflow.html
桥接库的使用案例:https://github.com/dora-rs/dora/tree/zenoh/examples
注意:dora v0.3.9的桥接库只能通过循环语句,不使用回调函数。
仓库一段时间会有更新。C++-ROS2-DORA桥接库,2025.11,13号前更新过仓库,有调整文件名,编译产物现在是
dora-ros2-bindings.h,dora-ros2-bindings.cc。
安装 RoboScience lidar SDK
参考官方文档:https://github.com/RoboSense-LiDAR/rslidar_sdk
安装 rerun
与rust有依赖关系,先确认rust版本再确定rerun的版本:
git clone https://github.com/rerun-io/rerun.git
cd rerun
mkdir build && cd build
cmake .. -DBUILD_CPP_SDK=ON -DBUILD_SHARED_LIBS=ON # 启用动态库和C++ SDK
make
sudo make install
/rerun/Cmakelists.txt同时链接了 Dora(libdora_node_api_c.a)和 Rerun(rerun_sdk)两个含 Rust 运行时的静态库,导致符号重复定义,通过将 Rerun 改为动态库解决了编译链接冲突。
安装依赖库
# pcl库
sudo apt-get install libpcl-dev
# eigen库
sudo apt install libeigen3-dev
yaml-cpp: https://github.com/jbeder/yaml-cpp
节点功能
driver 驱动节点
主要存放dora支持的传感器驱动节点,/driver/rslidar_driver 存放 RoboScience lidar 的驱动。
文件清单
| 文件 | 说明 |
|---|---|
| rslidar_driver_pcap.cc | 基于 Dora 框架的 RoboSense 激光雷达驱动节点,核心功能是读取激光雷达的点云数据(支持实时硬件或 PCAP 离线文件),将点云数据标准化打包后,通过 Dora 框架的输出接口发送给下游模块 |
| rslidar_driver.cc | 基于 Dora 框架的 RoboSense 激光雷达驱动增强版节点,优化了配置灵活性、数据打包格式、内存管理,支持实时雷达与离线 PCAP 无缝切换 |
LiDAR 配置
-
安装对应版本的 rslidar_sdk,详情参考官方文档:https://github.com/RoboSense-LiDAR/rslidar_sdk
-
确认 lidar 的 ip 地址(10.0.0.200),详情见 robosense 官网用户手册:https://cdn.robosense.cn/20240201110717_15556.pdf
-
设置本机的 ip 为 10.0.0.102,子网掩码为 255.255.255.0,先 ping 通 10.0.0.200
ping 10.0.0.200
ping 不通时,检查电脑的有线连接是否开启,检查 lidar 与电脑是否直连,检查激光雷达的供电
- 进入 rslidar_sdk,从 rviz 上看一下点云是否能正常显示
cd rslidar_ws
source install/setup.bash
ros2 launch rslidar_sdk start.py
录制 PCAP 文件
确定网卡,使用 tcpdump 抓取点云数据:
ip address show
sudo tcpdump -i enp131s0 -w env.pcap -c 3000000 'udp dst port 7788 or 6699'
参考官方文档:https://github.com/RoboSense-LiDAR/rs_driver/blob/main/doc/howto/13_how_to_capture_pcap_file_CN.md
mapping 建图节点
ndt_mapping 建图
基于 NDT (Normal Distributions Transform) 算法的建图模块。
文件清单:
| 文件 | 说明 |
|---|---|
| dora_node.cc | ndt建图dora节点 |
| dora_ndt_mapper.cc | ndt建图类 |
| ndt_cpu | ndt算法实现 |
| ndt_mapping_config.yml | ndt建图参数 |
| dataflow_pcap.yml | Dora数据流文件 |
Source: https://github.com/Kin-Zhang/simple_ndt_slam
ROS 下的 lidarslam 建图
如果 ndt_mapping 建图效果不好,可以使用 ROS 下的 lidarslam 建图:
参考官方文档:https://github.com/rsasaki0109/lidarslam_ros2
cd ros2_ws
source install/setup.bash
ros2 launch lidarslam lidarslam.launch.py
ros2 bag play rslidar_laser_bag_0.db3 # 新开终端,播放rosbag
ros2 service call /map_save std_srvs/Empty # 新开终端,保存地图
localization 定位节点
dora-hdl_localization
实现小车定位,输出小车轨迹。
文件清单:
| 文件 | 说明 |
|---|---|
| dora_hdl_node.cpp | 基于 Dora 框架的 HDL 激光雷达定位节点,接收激光雷达点云数据(可选 IMU 数据),结合预加载的全局 PCD 地图,实现小车的实时定位 |
| pose_estimator.cpp | HDL 定位的核心位姿估计模块 |
map 路径管理节点
基于 Dora 框架的「参考路径管理 + 坐标转换 + 定位信息输出」。
文件清单:
| 文件 | 说明 |
|---|---|
| pub_road/src/pubroad.cpp | 从本地文本文件 Waypoints.txt 中读取预定义的参考路径,将路径数据打包为二进制格式后发布给下游模块 |
| road_line_publisher/frenet.cpp | 笛卡尔坐标系与 Frenet 坐标系之间的转换 |
| road_line_publisher/road_lane.cpp | 输入事件处理参考路径和车辆位置数据,输出转换后的定位信息 |
planning 规划节点
道路参数供给 + 任务决策执行。
文件清单:
| 文件 | 说明 |
|---|---|
| task_exc/main.cc | 中央控制核心,整合定位等多源数据,执行自动倒车等任务,发布车辆控制指令 |
| task_pub/main.cc | 道路属性发布模块,按 10Hz 频率读取 road_msg.txt 文件中的道路属性键值对 |
control 控制节点
主要基于 C/C++ 实现,读取键盘数据并控制 mickrobot 四轮差速小车移动。
# 连接小车的串口,加权限
ls /dev/ttyUSB*
sudo chmod 777 /dev/ttyUSB0
rerun 可视化节点
点云数据可视化工具。
注意:rerun 的读取 map 的路径,按需修改
编译运行
编译说明
- 每个节点下都有一个
readme.md,请仔细阅读 - 建议使用 vscode 打开 DORA_NAV,方便修改
./vscode/c_cpp_properties.json中的 includepath - 建议先修改文件夹下的
CMakeLists.txt中的路径 - 找不到头文件时,确认一下
c_cpp_properties.json中 includepath,如果路径正确,ctrl+左键进入头文件的实现代码中,检查是否有未找到的头文件 - 重新编译前先删除 build 目录下所有的文件
cd build && rm -rf *
- 所有节点编译完毕,确认
run-test.yml中可执行文件的路径(./指当前目录) - yml 文件注重缩进,只能用空格缩进,格式参考 dora中文社区
编译各节点
编译 driver
cd rslidar_driver
mkdir build && cd build
cmake ..
make
编译 ndt_mapping
# 编译 ndt_cpu
cd mapping/ndt_mapping/ndt_cpu
mkdir build && cd build
cmake ..
make
# 编译 ndt_mapping
cd mapping/ndt_mapping
mkdir build && cd build
cmake ..
make
编译 localization
cd localization/dora-hdl_localization
mkdir build && cd build
cmake ..
make
编译 map
cd map/pub_road
mkdir build && cd build
cmake ..
make
cd ../..
cd road_line_publisher
mkdir build && cd build
cmake ..
make
编译 planning
cd planning/mission_planning
mkdir build && cd build
cmake ..
make
cd ../..
cd routing_planning
mkdir build && cd build
cmake ..
make
编译 control
cd control/dora_mickrobot
mkdir build && cd build
cmake ..
make
编译 rerun
cd rerun
mkdir build && cd build
cmake ..
make
运行
运行建图
dora up
dora start dataflow_pcap.yml # 如果想在终端中看日志输出,执行 dora run dataflow_pcap.yml
日志输出在 ndt_mapping/out 目录下,保存的地图在 DORA_NAV/mapping/ndt_mapping/saved_map 目录下。
查看地图:
sudo apt install pcl-tools
pcl_viewer -multiview 1 path_to_pcd_files
运行定位
dora up
dora run path.yml
path.yml 启动后,会把路径点记录到 /DORA_NAV/data/path,日志输出在同级目录下的 /out。
对路径点进行间隔采样生成 Waypoints.txt:
python3 sample.py
运行导航
dora up
dora run run.yml
调试建议
- 有节点报错,新建一个 yml 文件,依次调试节点,注意一个节点的 inputs 涉及到的节点必须存在
- 日志的输出在 yml 文件同级的
/out目录下 - 哪个节点有报错先考虑读取文件的路径是否正确,文件的权限是否正确
- 节点之间输入输出关系使用
dora graph查看,用浏览器打开,查看数据流图
Dora-moveit 机械臂
GEN72 多视角拍摄系统 - 基于 Dora-rs 数据流架构的完整机械臂控制系统,用于工业管道检测,支持 MuJoCo 仿真和真实机器人。

概述
该系统实现了自动化多视点摄影的管道检测任务。机械臂移动到预定义的视点,拍摄图像,然后返回原位 - 全程采用无碰撞运动规划。
主要特性
- 双模式运行:MuJoCo 仿真 + 真实 GEN72 机器人支持
- 高级逆运动学:TracIK 求解器,成功率约 95%
- 碰撞检测:
- 几何碰撞(球体、盒子、圆柱体)
- 3D LiDAR 点云集成(已准备好,默认禁用)
- Realman SDK 碰撞检测框架
- 多视角拍摄:自动化 3 视点摄影工作流
- 平滑运动:可配置速度的轨迹插值
- 保持逻辑:运动完成后防止控制漂移
文档导航
介绍
系统架构
┌─────────────────────────────────────────────────────────────────┐
│ GEN72 System Architecture │
├─────────────────────────────────────────────────────────────────┤
│ │
│ multi_view_capture_node.py (Workflow Controller) │
│ │ │
│ ├──► ik_op.py (TracIK Solver) │
│ │ └──► Cartesian pose → Joint angles │
│ │ │
│ ├──► planner_ompl_with_collision_op.py (RRT-Connect) │
│ │ ├──► Collision-free path planning │
│ │ └──► Point cloud + geometric collision │
│ │ │
│ ├──► trajectory_executor.py (Interpolation) │
│ │ └──► Smooth waypoint interpolation │
│ │ │
│ └──► Robot Control Node │
│ ├──► MuJoCo Simulator (main.py) │
│ └──► Real GEN72 Robot (gen72_robot_node.py) │
│ │
└─────────────────────────────────────────────────────────────────┘
文件结构
dora-moveit/
├── run_mujoco.bat # 启动 MuJoCo 仿真
├── run_real_robot.bat # 启动真实机器人控制
│
├── dataflow_gen72_mujoco.yml # MuJoCo 数据流配置
├── dataflow_gen72_real.yml # 真实机器人数据流配置
│
├── multi_view_capture_node.py # 主工作流控制器
├── trajectory_executor.py # 轨迹插值
├── ik_op.py # TracIK 逆运动学
├── planner_ompl_with_collision_op.py # RRT-Connect 运动规划器
├── planning_scene_op.py # 场景管理
│
├── gen72_robot_node.py # 真实机器人控制(Realman SDK)
├── robot_config.py # GEN72 参数与碰撞几何
│
├── rm_robot_interface.py # Realman SDK 接口
├── rm_ctypes_wrap.py # Realman SDK C 包装器
├── api_c.dll # Realman SDK 库
│
├── requirements.txt # Python 依赖
├── README.md # 说明文件
└── RELEASE.md # 版本历史
性能指标
| 指标 | MuJoCo | 真实机器人 |
|---|---|---|
| IK 成功率 | ~95% | ~95% |
| 规划时间 | 0.05-0.15s | 0.05-0.15s |
| 运动速度 | 1.0 waypoint/s | 0.25 waypoint/s |
| 控制频率 | 20 Hz | 5 Hz |
| 典型工作流时间 | ~30s | ~60s |
快速开始
环境准备
# Python 环境
conda create -n dora-moveit python=3.9
conda activate dora-moveit
# 安装依赖
pip install -r requirements.txt
# 安装 Dora
pip install dora-rs
# 安装 MuJoCo(用于仿真)
pip install mujoco
pip install -e dora-mujoco/
运行仿真
# 启动 MuJoCo 仿真
./run_mujoco.bat
# 或手动执行:
dora up
dora build dataflow_gen72_mujoco.yml
dora start dataflow_gen72_mujoco.yml
运行效果:
- MuJoCo 窗口打开,GEN72 机器人在 HOME 位置
- 系统规划到 3 个视点的无碰撞路径
- 机器人在每个视点拍摄图像
- 返回 HOME 并进入空闲状态
运行真实机器人
重要:确保机器人已上电,工作区域清空,紧急停止按钮可触及。
# 启动真实机器人控制
./run_real_robot.bat
# 或手动执行:
dora up
dora build dataflow_gen72_real.yml
dora start dataflow_gen72_real.yml
故障排除
MuJoCo 问题
问题:“Model not found” 错误
# 解决方案:设置 MODEL_NAME 环境变量
export MODEL_NAME="path/to/GEN72_with_actuators.xml"
问题:Joint1 在完成后仍然旋转
# 解决方案:检查 HOLD 逻辑超时
# 在 main.py 中: self.cmd_timeout = 0.2 # 如需增加
真实机器人问题
问题:连接失败
# 检查:
# 1. 机器人已上电
# 2. 网络连接(ping 192.168.1.19)
# 3. 防火墙设置
# 4. SDK DLL 在正确路径
问题:机器人运动不平滑
# 解决方案:调整控制频率
# 在 dataflow_gen72_real.yml 中:
tick: dora/timer/millis/200 # 增加以获得更平滑的运动
安全指南
运行真实机器人前
- 电源检查:确保机器人已上电并初始化
- 工作区域:清除机器人工作区域内的所有障碍物
- 紧急停止:确认紧急停止按钮可触及
- 限位:确认关节限位正确配置
- 速度:测试时从低速(10%)开始
紧急程序
- 立即停止:按紧急停止按钮
- 软件停止:在终端按
Ctrl+C - 断电:使用主电源开关
碰撞避免
- 系统使用 10mm 安全边距
- 地平面在 z=-0.05m
- 自碰撞检查已启用
- 相邻连杆(±1)跳过以增加灵活性
系统配置
GEN72 机器人参数
- 自由度(DOF):7 关节
- HOME 位置:
[0.0, -0.5, 0.0, 0.0, 0.0, 0.5, 0.0](弧度) - IP 地址:192.168.1.19:8080
- 控制模式:通过 Realman SDK 的位置控制
拍摄视点
在 multi_view_capture_node.py 中定义:
targets = [
CaptureTarget("view1", [0.4, 0.2, 0.5]), # 右视点
CaptureTarget("view2", [0.4, -0.2, 0.5]), # 左视点
CaptureTarget("view3", [0.5, 0.0, 0.4]) # 中心视点
]
添加新视点
编辑 multi_view_capture_node.py:
self.targets = [
CaptureTarget("view1", [0.4, 0.2, 0.5]),
CaptureTarget("view4", [0.3, 0.3, 0.6]), # 添加新视点
]
控制频率
| 模式 | 频率 | 插值速度 |
|---|---|---|
| MuJoCo 仿真 | 20 Hz (50ms) | 0.05 |
| 真实机器人 | 5 Hz (200ms) | 0.05 |
调整运动速度
仿真(dataflow_gen72_mujoco.yml):
tick: dora/timer/millis/50 # 减小以加快速度
真实机器人(dataflow_gen72_real.yml):
tick: dora/timer/millis/200 # 减小以加快速度(最小:50ms)
插值(trajectory_executor.py):
self.interpolation_speed = 0.05 # 增加以加快速度(最大:0.2)
真实机器人速度(gen72_robot_node.py):
self.robot.rm_movej(joint_deg, 10, ...) # 增加 10%(最大:100%)
碰撞球体配置
在 robot_config.py 中定义:
link_spheres = {
"link1": [([0, 0, 0.1], 0.08)],
"link2": [([0, 0, 0.15], 0.07)],
...
}
启用点云碰撞
- 确保点云数据可用
- 修改
planner_ompl_with_collision_op.py:
self.use_point_cloud = True
- 在数据流中连接点云输入
组件详情
multi_view_capture_node.py
工作流控制器,协调整个拍摄序列。
输入
joint_positions:当前机器人状态ik_solution,ik_status:IK 求解器结果trajectory,plan_status:运动规划器结果execution_status:轨迹执行反馈
输出
ik_request:IK 的目标位姿plan_request:运动规划请求scene_command:场景更新
状态机
idle→ 请求视点的 IKwaiting_for_ik→ 请求运动规划waiting_for_planning→ 等待轨迹waiting_for_execution→ 监控执行capturing→ 拍摄图像- 对所有视点重复
returning_home→ 返回 HOMEidle→ 完成
trajectory_executor.py
在航点之间插值以实现平滑运动。
关键参数
interpolation_speed:0.05(每个周期 5% 进度)tick_rate:50ms(MuJoCo)/ 200ms(真实机器人)
功能特性
- 航点之间的线性插值
- HOLD 模式:空闲时返回当前关节状态
- 防止轨迹完成后的控制漂移
ik_op.py
基于 TracIK 的逆运动学求解器。
求解器:TracIK(高级,成功率约 95%)
备用:数值 IK(阻尼最小二乘)
输入:6D 位姿 [x, y, z, roll, pitch, yaw]
输出:7D 关节配置
planner_ompl_with_collision_op.py
带碰撞检测的 RRT-Connect 运动规划器。
算法:RRT-Connect(双向 RRT)
碰撞边距:10mm 安全缓冲
最大规划时间:5 秒
碰撞检测
- 自碰撞检查(跳过相邻连杆)
- 环境碰撞(障碍物、地平面)
- 点云碰撞(框架已准备好)
gen72_robot_node.py
通过 Realman SDK 的真实机器人控制。
连接
- IP:192.168.1.19:8080
- 线程模式:三线程(mode=2)
- 级别:3
单位转换
- 系统内部使用弧度
- SDK 使用角度
- 自动转换:
np.deg2rad()/np.rad2deg()
控制
- 命令:
rm_movej(joints_deg, speed=10%, r=0, connect=0, block=1) - 更新频率:5 Hz(200ms tick)
robot_config.py
GEN72 机器人配置:
参数
- 关节限位、HOME 位置、URDF 路径
- 碰撞几何(每个连杆的球体)
- 连杆尺寸和偏移
关键修复记录
1. MuJoCo 控制漂移(已修复)
问题:工作流完成后 Joint1 继续旋转。
根本原因:MuJoCo 的 PD 控制器使用过时的目标位置,导致持续的误差累积。
解决方案:在 main.py:127-137 中实现基于超时的 HOLD 逻辑:
if now - self.last_cmd_time > self.cmd_timeout:
self.data.ctrl[:self.num_joints] = current_q # 强制 HOLD
2. 轨迹执行器漂移(已修复)
问题:空闲时执行器返回过时的航点位置。
解决方案:修改 trajectory_executor.py:step() 以返回当前关节状态:
if not self.is_executing:
return self.current_joints.copy() # 不是 last_command
3. 真实机器人 API 集成(已修复)
问题:连接失败和不正确的 API 使用。
解决方案:
- 使用
rm_thread_mode_e(2)作为线程模式 - 检查
handle.id == -1以确定连接错误 - 解析元组返回值:
result[1].joint - 添加角度/弧度转换