DORA C++ ROS2 Bridge 实战:基于 codegen 头文件的 Service/Action/Topic 集成指南

发布时间:2026/9/18 18:17:45

DORA C++ ROS2 Bridge 实战:基于 codegen 头文件的 Service/Action/Topic 集成指南 DORA C ROS2 Bridge 实战基于 codegen 头文件的 Service/Action/Topic 集成指南【免费下载链接】doraDORA (Dataflow-Oriented Robotic Architecture) is middleware designed to streamline and simplify the creation of AI-based robotic applications. It offers low latency, composable, and distributed dataflow capabilities. Applications are modeled as directed graphs, also referred to as pipelines.项目地址: https://gitcode.com/GitHub_Trending/do/doraDORA 通过纯 Rust 的 DDS/RTPS 协议栈ros2-clientrustdds与 ROS2 生态话题、服务、动作、参数直接通信全程不链接rcl/rclcpp。本指南聚焦于 C 语言面利用 codegen 生成的头文件从 C 节点中直接创建 ROS2 service server、action client/server、action client 并发与 turtlesim 话题演示覆盖环境准备、运行方式、事件循环编程模型与已知限制帮助你快速把 C 节点接入 ROS2 数据流。两种 Bridge 表面C 属于 Native Code APIDORA 的 ROS2 bridge 提供两条使用路径详见 docs/ros2-bridge.mdYAML / dynamic bridge在 dataflow YAML 的节点上添加ros2:键由 daemon 自动拉起 bridge 二进制节点代码完全不感知 ROS2数据以 Apache Arrow 形式流通零代码接入Native code APIs在节点代码中以类型化 API 直接驱动 ROS2——Python 提供dora.Ros2ContextRust 与 C 提供基于.msg/.srv/.action定义在构建期生成的 codegen 表面。C 示例演示的正是这条路径。两条表面共享同一底层ros2-client/rustdds协议栈边界处统一执行 ArrowStructArray与 ROS2 CDR 之间的双向转换。C 节点通过dora-node-api.h接入 DORA 运行时通过ros2-bridge/msg/...系列头文件获得类型化消息结构数据以rust::Box与生成的结构体承载。从能力矩阵看examples/ros2-bridge/README.mdC 面覆盖 topic pub/sub、service server、action client、action server 与 turtlesim 演示service client、topic-only、parameter 等表面由 Rust 与 Python 示例覆盖矩阵中留空是有意为之——每个协议表面至少在一个语言中演示。示例清单与前置条件examples/ros2-bridge/c/README.md 列出了全部 C 示例及其依赖目录--example名称需要 source 的 ROS2 / peerservice-servercxx-ros2-dataflow-service-server是rclcpp minimal clientaction-clientcxx-ros2-dataflow-action-client是rclcpp action server¹action-client-concurrentcxx-ros2-dataflow-action-client-concurrent是rclcpp action server¹action-servercxx-ros2-dataflow-action-server否dora server client¹turtlecxx-ros2-dataflow是turtlesim¹ 由 dora 托管的 action server 无法被真实的rclclient 发现上游 ros2-client#4因此action-server示例在同一 dataflow 内配对了一个 dora C server 与一个 dora C client。同理延迟的get_result往返在上游ros2-client/rustdds中不稳定曾反复挂起 x86 nightly 任务并在 arm64 开发机上停滞所以 action 类示例不纳入 nightly CI——发布前应在 x86 Linux 上用scripts/ros2dev.sh qa验证issue #1170。所有 C 示例统一由--features ros2-examples门控。前置条件包括已 source 的 ROS2 安装、可用的 C 工具链与 CMake部分示例还需要示例消息包例如ros-humble-examples-rclcpp-minimal-client。运行方式一条命令拉起整个 dataflowC 示例全部作为dora-ros2-bridgecrate 的 Cargo[[example]]注册其run.rs会完成三件事先通过 cxxbridge 与clang把main.cc编译成build/下的可执行节点再以dora_cli::run(dataflow.yml)启动 dataflow最后按需 spawn 它需要的 ROS2 peer 进程。因此只需运行原文档命令source /opt/ros/humble/setup.bash cargo run -p dora-ros2-bridge --example cxx-ros2-dataflow-service-server --features ros2-examples cargo run -p dora-ros2-bridge --example cxx-ros2-dataflow-action-server --features ros2-examples以service-server为例它的run.rsexamples/ros2-bridge/c/service-server/run.rs会build_package(dora-node-api-cxx, [ros2-bridge])构建 C API crate 并生成target/cxxbridge/.../install下的头文件与.cc桥接源用clang -stdc17把main.cc、dora-node-api.cc、ros2-bridge/msg/example_interfaces.cc、ros2-bridge/impl.cc编译为build/service_server链接-l dora_node_api_cxxLinux 上附带-lm -lrt -ldl -lz -pthread后台线程执行 dataflow随后ros2 run examples_rclcpp_minimal_client client_main启动 rclcpp 对端来驱动服务调用。对应的 dataflowexamples/ros2-bridge/c/service-server/dataflow.yml仅声明了一个节点用dora/timer/millis/500的 tick 输入维持节点存活等待请求nodes: - id: cxx-service-server path: build/service_server inputs: tick: dora/timer/millis/500 outputs: []turtle示例还提供了手动运行路线examples/ros2-bridge/c/turtle/README.md在三个终端分别启动turtlesim_node、examples_rclcpp_minimal_service service_main与dora run dataflow.yml注意三个终端都需要source /opt/ros/distro/setup.bash且统一export RMW_IMPLEMENTATIONrmw_fastrtps_cppsource 是必需的ROS2 消息类型要在此环境中动态编译发现。事件循环编程模型matches / downcastC codegen 表面的核心范式是合并事件循环 模式匹配。节点先创建 DORA 节点与 ROS2 context二者的事件被合并为单一merged_events流随后循环消费事件并按类型分派examples/ros2-bridge/c/service-server/main.ccauto dora_node init_dora_node(); auto merged_events dora_events_into_combined(std::move(dora_node.events)); auto ros2_context init_ros2_context(); auto node ros2_context-new_node(/ros2_demo, add_two_ints_server); auto add_server create_service_server_example_interfaces_AddTwoInts(*node, /, add_two_ints, service_qos, merged_events); for (int i 0; i 1000; i) { auto event merged_events.next(); if (event.is_dora()) { // downcast_dora 后按 event_type 处理 Input / Stop / AllInputsClosed } else if (add_server-matches(event)) { auto request_event add_server-downcast(std::move(event)); auto request request_event-get_request(); example_interfaces::AddTwoInts_Response response {.sum request.a request.b}; add_server-send_response(request_event-get_id(), response); // rclcpp minimal client 是单次请求即退出serve 一次后 break } }其关键点event.is_dora()判断 DORA 侧事件downcast_dora后可用event_type、event_as_input读取输入add_server-matches(event)判断该事件是否为服务请求downcast后通过get_request()/get_id()取请求体与请求 IDsend_response(id, response)按 ID 关联回复——该 ID 在 Rust 侧用于把回复关联回ros2-client的原始请求tick输入只负责让节点在等待请求期间保持存活。该编程模型与 docs 中的 C surface 对照表完全一致docs/ros2-bridge.mdC surface创建函数事件循环入口topiccreate_topic_pkg_Typecreate_publisher/create_subscriptionmatches/downcastservice clientcreate_client_pkg_Namewait_for_service/send_request/matches/downcastservice servercreate_service_server_pkg_Namematches/downcastget_request/get_id/send_responseaction clientpkg::create_Name_action_clientwait_for_action/send_goal/request_result/matches_*/downcast_*action serverpkg::create_Name_action_servermatches/downcastget_goal/get_goal_id/publish_feedback/send_resultturtlesim 演示话题发布订阅 Service Clientturtle/main.cc 是覆盖面最广的示例一个 C 节点同时演示话题发布create_topic_geometry_msgs_Twistcreate_publisher在收到每个 tick 输入时构造随机的geometry_msgs::Twist嵌套linear/angularVector3并vel_publisher-publish(twist)驱动 turtlesim 移动话题订阅create_topic_turtlesim_Posecreate_subscription(..., merged_events)pose 消息进入合并事件流pose_subscription-matches(event)命中后用downcast取出pose.x/pose.y打印Service clientcreate_client_example_interfaces_AddTwoIntsadd_two_ints-wait_for_service(node)等待服务可用后send_request({.a 4, .b 5})响应同样以matches/downcast接收并断言response.sum 9常量访问sensor_msgs::const_NavSatStatus_STATUS_NO_FIX()验证 codegen 生成的常量接口可用断言其值为 -1。其 dataflowexamples/ros2-bridge/c/turtle/dataflow.yml声明了pose输出便于后续接入其他 DORA 节点消费 turtlesim 位姿数据。运行前需安装ros-distro-examples-rclcpp-minimal-service与ros-distro-turtlesim并统一 RMW 实现为rmw_fastrtps_cpp。Action Server从 C 节点托管 ROS2 动作action-server/main.cc 展示如何把 C 节点变成 ROS2Fibonacciaction server是 action client 示例的反向镜像不再send_goal downcast(result)而是匹配进入的目标、边计算边发布 feedback、最后发送 resultauto server example_interfaces::create_Fibonacci_action_server(*node, /, fibonacci, qos, merged_events); // 事件循环内 else if (server-matches(event)) { auto goal_event server-downcast(std::move(event)); auto goal_id goal_event-get_goal_id(); auto order goal_event-get_goal().order; // 计算 Fibonacci逐项发布 feedback for (std::int32_t k 1; k std::max(order, 1); k) { example_interfaces::Fibonacci_Feedback feedback; // .sequence 累积推送 server-publish_feedback(goal_id, feedback); } example_interfaces::Fibonacci_Result result; // .sequence 最终序列 server-send_result(goal_id, ::ActionStatusEnum::Succeeded, result); }要点QoS示例通过qos_default()后覆写durability Volatile、liveliness Automatic、reliable true、max_blocking_time 0.1、keep_last 1构造服务型 QoSgoal_id 关联get_goal_id()返回的 goal ID 必须在publish_feedback与send_result中原样回传桥接层据此把 feedback/result 关联到正确的 goaldocs 中 C handler 的写法是metadata-get_str(goal_id)再经new_metadata()set_string(goal_id, ...)透传对应底层实现见 apis/c/node/src/lib.rs 的new_metadata/send_arrow_output_with_metadata后者会把 metadata 参数并入输出事件状态枚举ActionStatusEnum::Succeeded / Aborted / Canceled控制返回给客户端的目标终态。Action Client目标发送与 feedback/result 流action-client/main.cc 演示完整的 action client 生命周期create_Fibonacci_action_client创建客户端 →client-wait_for_action(node)等待 action server → 收到 tick 输入后send_goal并request_result→ 事件循环中分别用matches_result/matches_status/matches_feedback三类匹配器处理} else if (client-matches_result(event)) { auto result_event client-downcast_result(std::move(event)); // result_event-get_result().sequence 为最终 Fibonacci 序列 // result_event-get_status() 可转为 std::int16_t 判断终态 if (status ::ActionStatusEnum::Succeeded) { /* 完成一轮发送下一 goal */ } else if (status ::ActionStatusEnum::Aborted || status ::ActionStatusEnum::Canceled) { return 1; } } else if (client-matches_status(event)) { // 状态变化事件目标被接受/执行中 } else if (client-matches_feedback(event)) { // 流式 feedback用 feedback_event-matches_goal(*goal_id) 过滤迟到的旧 goal 反馈 }示例做了两处健壮性处理一是迟到的 feedback 可能晚于 goal 完成到达此时goal_id已清空需跳过而非解引用空指针二是用feedback_event-matches_goal(*goal_id)丢弃不属于当前 goal 的反馈。并发目标回归测试修复 #1972 响应窃取action-client-concurrent是 issue #1972 的回归测试。修复前的生成客户端会为每个 goal 各自 spawn 一个 result receiver这些 receiver 互相窃取彼此的GetResult响应导致并发 goal 丢失结果。该示例examples/ros2-bridge/c/action-client-concurrent/main.cc一次性发出多个目标并要求每个目标都必须拿到结果在首个 tick 输入时一次性send_goalrequest_result全部目标使各目标的 result 往返重叠不同 order 意味着不同计算时长便于暴露串扰用std::vectorrust::BoxActionGoalId goals保存全部 goal ID收到 result 事件后通过result_event-matches_goal(goals[i])把结果归属到具体目标done[i]标记去重统计completed内置 60 秒 deadline任一目标未拿到结果即打印 response stealing? see #1972 并以退出码 1 快速失败避免回归时无限挂起。限制与注意事项围绕 C以及 native 面共同的已知约束务必在设计与排障时留意完整清单见 docs/ros2-bridge.mdDora 托管的 action server 无法被真实 rcl 客户端发现ros2-client#4action 示例必须把 dora server 与 dora client 配在同一 dataflowservice server 则不受影响真实ros2 service call可正常调用RMW 必须一致Fast-DDS 与 Cyclone 的 service/action 关联方式不同Enhanced与 Cyclone mapping桥接层在 codegen 期native 面从RMW_IMPLEMENTATION选择 mapping两侧不一致会导致调用挂起需在两端的 ROS2 环境统一设置没有wait_for_action_serverros2-client不提供该 API客户端首次send_goal在无 server 时会直接超时30 秒务必先启动 action server 再启动 dataflowaction 示例不进 nightly CI延迟get_result往返在上游rustdds中不稳定发布前需在 x86 Linux 用scripts/ros2dev.sh qa手动验证distro 约束桥接层启用ros2-client的humbledistro 特性选择 24 字节Gid用于图发现ROS2 在 Humble 与 Iron 之间把Gid从 24 字节改为 16 字节因此与 Iron 及以上版本栈的图发现不匹配话题、服务、动作的负载本身是普通 CDR跨 distro 仍可互操作。最佳实践小结运行前先 source ROS2 环境确保AMENT_PREFIX_PATH指向包含所需消息包的 workspace否则桥接层启动即失败RMW 实现全局统一把export RMW_IMPLEMENTATIONrmw_fastrtps_cpp或所选实现写入.bashrc避免 codegen 期 mapping 与运行时对端不一致action server 先于 dataflow 启动没有等待机制首个 goal 会 30 秒超时始终透传goal_idaction与request_idservice桥接层靠元数据关联请求与响应handler 漏传则无法匹配C 中分别用get_str(goal_id)读取、new_metadata()set_string透传事件循环中先is_dora()再逐类matches_*保持与 codegen 生成 API 一致的分派顺序并像示例那样防御迟到的 feedback 与不匹配的 goal 事件。以上全部示例与代码均位于 examples/ros2-bridge/c/能力总览见 examples/ros2-bridge/README.md完整参考见 docs/ros2-bridge.md。【免费下载链接】doraDORA (Dataflow-Oriented Robotic Architecture) is middleware designed to streamline and simplify the creation of AI-based robotic applications. It offers low latency, composable, and distributed dataflow capabilities. Applications are modeled as directed graphs, also referred to as pipelines.项目地址: https://gitcode.com/GitHub_Trending/do/dora创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/18 18:17:45

Wireshark实战:MQTT报文抓包深度解析与常见问题排查

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/18 18:12:45

Docker与K8s关系全解:从容器镜像到K8s编排落地实战

先把一个常见误区摆到台面上:很多人刚接触容器技术时,会把 Docker 和 Kubernetes(下称 K8s)当成“二选一”的竞品,甚至在群里问“现在都上 K8s 了,Docker 是不是要被淘汰了”。这个问题我这些年被问过不下几…

2026/9/18 19:22:55

运营报表数据异常自动分析与归因解释

运营报表数据异常自动分析与归因解释在很多企业的日常运营中,数据大盘每天都会发生各种波动:日活(DAU)突然下跌 15%、特定渠道的转化率骤降、退款率在某个时间段异常升高。 传统的做法是运营发现异常后,在群里艾特数据…

2026/9/18 19:22:55

基于YOLOv8与PyQt5的路面坑洞检测系统实战

1. 路面坑洞检测系统整体设计思路拆解1.1 为什么选择YOLOv8而不是传统图像处理方法做路面坑洞检测这件事,我最早试过用传统的边缘检测加阈值分割。OpenCV的Canny算子配合形态学操作,在光照均匀、坑洞边缘清晰的理想图片上确实能跑出结果,但一…

2026/9/18 19:22:55

维护者的情绪管理:面对恶意差评与无理索取

维护者的情绪管理:面对恶意差评与无理索取开源是一件充满理想主义色彩的事情,但只要你的项目获得了一定的曝光,你的 GitHub Issue 区就不可避免地会变成各种情绪的聚集地。 有的用户会因为一个微小的 Bug 在评论区破口大骂:“这么…

2026/9/18 19:22:55

轻量鉴权:基于 HMAC 签名的 API 认证

轻量鉴权:基于 HMAC 签名的 API 认证在构建微服务间通信、外部 Webhook 回调或轻量单体系统对外开放的 API 时,很多团队一上来就照搬复杂的 OAuth2、IdentityServer 或者是带有一堆配置的 JWT 刷新体系。 对于简单的服务端对服务端(S2S&#…

2026/9/18 19:22:55

C-NCAP 2024附录L详解:AEB/FCW测试时间基准与ADAS工程实践

简介:C-NCAP 2024版附录L是面向整车企业ADAS开发与测试工程师、安全评价人员及高校研究者的主动安全试验规程。文档完整规定了AEB、FCW等系统的试验术语、车辆坐标系、天气要求、VUT准备与预处理流程,并系统展开L.6.1的AEB C2C测试场景,如CCR…

2026/9/18 19:17:55

硬件工程师的硬核读法:如何用四层过滤法精读芯片资料

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/18 14:13:01

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/18 0:01:09

Google Colab 实战:运行模型、数据加载与报错排查

1. 为什么我劝你先搞懂 Colab 的运行模型1.1 Colab 到底是什么,跟本地跑代码差在哪Google Colab 简单说就是一台跑在浏览器里的 Linux 虚拟机,你打开一个 Notebook,背后就连上了一台带 GPU 的远程机器。你在单元格里敲的每一行 Python&#x…

2026/9/18 0:01:09

C语言数据类型与表达式详解

1. C语言数据与数据类型概述在C语言编程中,数据是程序处理的核心对象。理解数据的分类和特性是掌握C语言的基础。C语言中的数据主要分为四大类:常量、变量、表达式和函数。这些数据类型构成了C语言程序的基本元素,每种类型都有其独特的特性和…

2026/9/18 0:01:09

SQL时间字段指定时间段查询:区间语义、索引与时区避坑

上周排查一个线上问题&#xff0c;用户反馈"昨天的订单一条都没查到"&#xff0c;但数据库里明明躺着两千多条。最后定位下来&#xff0c;不是数据丢了&#xff0c;也不是接口挂了&#xff0c;而是那个查询条件把时间段写成了> 2024-05-20 00:00:00 AND < 2024…

2026/9/18 14:13:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行&#xff0c;Type-C接口算是典型的“看着简单&#xff0c;做起来全坑”的东西。光引脚就24个&#xff0c;高低速信号、电源、控制线全部塞在一个小小的连接器里&#xff0c;如果PCB布局不做规划&#xff0c;打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/18 14:13:02

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/18 14:13:02

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码