尧图精选

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

🕒 发布时间:2026/9/18 18:17:29 📁 来源:尧图网络
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),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →