ROS2 C++开发中如何实现UDP通信连接
ROS2 C++ 实现UDP不可靠通信的方法
ROS2 底层基于DDS实现通信逻辑,没有提供和ROS1 ros::TransportHints().Unreliable() 完全同名的接口,要实现和ROS1 UDP通信一致的低延迟、不做丢包重传的传输效果,核心是通过配置QoS(服务质量)策略实现,具体操作如下:
核心原理
ROS1里手动指定UDP的Unreliable()配置,对应ROS2 QoS中的BEST_EFFORT(尽力传输)可靠性策略:
- ROS2默认使用
RELIABLE可靠性策略,传输层会做丢包重传、顺序校验,效果和ROS1默认TCP通信一致 - 配置为
BEST_EFFORT策略后,DDS底层会自动使用UDP传输,不做重传校验,延迟更低,完全匹配ROS1开启UDP通信的效果
具体C++代码实现
注意:通信两端(发布端、订阅端)的QoS可靠性策略必须兼容,否则无法正常建立连接收不到消息,两端都要配置为BEST_EFFORT。
手动自定义QoS配置
- 发布端示例代码
#include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" class UdpPubNode : public rclcpp::Node { public: UdpPubNode() : Node("udp_pub") { // 初始化QoS,设置队列深度为10 rclcpp::QoS qos(10); // 配置为尽力传输,对应UDP通信 qos.reliability(RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT); // 创建发布者 pub_ = this->create_publisher<std_msgs::msg::String>("udp_test_topic", qos); // 定时发消息的业务逻辑可自行补充 } private: rclcpp::Publisher<std_msgs::msg::String>::SharedPtr pub_; };
- 订阅端示例代码
#include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" class UdpSubNode : public rclcpp::Node { public: UdpSubNode() : Node("udp_sub") { rclcpp::QoS qos(10); // 必须和发布端一致配置BEST_EFFORT qos.reliability(RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT); sub_ = this->create_subscription<std_msgs::msg::String>( "udp_test_topic", qos, [](const std_msgs::msg::String::SharedPtr msg) { RCLCPP_INFO(rclcpp::get_logger("udp_sub"), "收到消息: %s", msg->data.c_str()); } ); } private: rclcpp::Subscription<std_msgs::msg::String>::SharedPtr sub_; };
快捷QoS预设使用
ROS2内置了专门面向传感器这类低延迟、允许丢包场景的QoS预设rclcpp::SensorDataQoS(),默认就配置了BEST_EFFORT可靠性策略,不需要手动逐行配置,直接传入创建发布/订阅的接口即可,效果和手动配置完全一致:
// 发布端直接用预设 auto pub = this->create_publisher<sensor_msgs::msg::LaserScan>("scan", rclcpp::SensorDataQoS()); // 订阅端也用相同预设 auto sub = this->create_subscription<sensor_msgs::msg::LaserScan>("scan", rclcpp::SensorDataQoS(), callback);
注意事项
- 不需要手动指定传输层协议:ROS2的RMW抽象层会根据QoS策略自动选择适配的传输方式,配置
BEST_EFFORT后会自动走UDP,不需要像ROS1那样显式声明使用UDP - 特殊场景如果需要强制禁用TCP、仅允许UDP传输,可以通过对应DDS厂商的配置文件做传输层规则过滤,绝大多数业务场景下配置
BEST_EFFORTQoS即可满足UDP通信的需求,不需要修改底层DDS配置 - 除了可靠性策略,QoS的历史规则、存活检测等参数可以根据业务需求自行调整,不影响UDP传输的生效
内容的提问来源于stack exchange,提问作者KKYA
相关产品推荐
相关产品推荐

