网站建设搜索wordpress discussion settings
网站建设搜索,wordpress discussion settings,在线教育网站流量是怎样做的,编辑目录中的字体 wordpress我们在《ROS2概述和基于RK3588的环境搭建》中对ROS和ROS2做了对比#xff0c;其中最多的变化就是DDS。我们在前面文章中介绍的话题、服务、动作#xff0c;他们底层通信的具体实现过程#xff0c;都是靠DDS来完成的#xff0c;它相当于是ROS机器人系统中的神经网络。 一、通…我们在《ROS2概述和基于RK3588的环境搭建》中对ROS和ROS2做了对比其中最多的变化就是DDS。我们在前面文章中介绍的话题、服务、动作他们底层通信的具体实现过程都是靠DDS来完成的它相当于是ROS机器人系统中的神经网络。一、通信模型DDS的核心是通信能够实现通信的模型和软件框架非常多这里我们列出常用的四种模型。1.1 点对点模型许多客户端连接到一个服务端每次通信时通信双方必须建立一条连接当通信节点增多时连接数也会增多。而且每个客户端都需要知道服务器的具体地址和所提供的服务一旦服务器地址发生变化所有客户端都会受到影响。1.2Broker模型针对点对点模型进行了优化由Broker集中处理所有人的请求并进一步找到真正能响应该服务的角色这样客户端就不用关心服务器的具体地址了。不过问题也很明显Broker作为核心它的处理速度会影响所有节点的效率当系统规模增长到一定程度Broker就会成为整个系统的性能瓶颈。更麻烦是如果Broker发生异常可能导致整个系统都无法正常运转之前的ROS1系统使用的就是类似这样的架构。1.3 广播模型所有节点都可以在通道上广播消息并且节点都可以收到消息。这个模型解决了服务器地址的问题而且通信双方也不用单独建立连接但是广播通道上的消息太多了所有节点都必须关心每条消息其实很多是和自己没有关系的。1.4 以数据为中心的DDS模型这种模型与广播模型有些类似所有节点都可以在DataBus上发布和订阅消息。但它的先进之处在于通信中包含了很多并行的通路每个节点可以只关心自己感兴趣的消息忽略不感兴趣的消息有点像是一个旋转火锅各种好吃的都在这个DataBus传送我们只需要拿自己想吃的就行其他的和我们没有关系。以数据为中心更本质的体现是数据域(Domain)概念。一个DDS Domain定义了一个独立的虚拟网络空间只有拥有相同Domain ID的参与者(对应ROS2节点)才能相互发现和通信。这就像一栋办公楼不同的Domain ID是不同的楼层同楼层的公司(节点)可以自由交流不同楼层则完全隔离互不干扰。二、DDSDDS并不是一个新的通信方式在ROS2之前DDS已经广泛应用在很多领域比如航空国防交通医疗能源等。比如在自动驾驶领域通常会存在感知预测决策和定位等模块这些模块都需要非常高速和频繁地交换数据。借助DDS可以很好地满足它们的通信需求。2.1DDS定义DDS的全称是Data Distribution Service也就是数据分发服务2004年由对象管理组织OMG发布和维护是一套专门为实时系统设计的数据分发/订阅标准最早应用于美国海军 解决舰船复杂网络环境中大量软件升级的兼容性问题现在已经成为强制标准。DDS强调以数据为中心可以提供丰富的服务质量策略以保障数据进行实时、高效、灵活地分发可满足各种分布式实时通信应用需求。这里也提一下对象管理组织OMG成立于1989年它的使命是开发技术标准为数以千计的垂直行业提供真实的价值比如我们可能听说过的统一建模语言SYSML和UML还有中间件标准CORBA等当然还有DDS。2.2 在ROS2中的应用DDS在ROS2系统中的位置至关重要所有上层建设都建立在DDS之上。在这个ROS2的架构图中蓝色和红色部分就是DDS。DDS其实是物联网中广泛应用的一种通信协议类似于我们常听说的5G通信一样DDS是一个国际标准能够实现该标准的软件系统并不是唯一的所以我们可以选择多个厂家提供的DDS系统比如这里的OpenSplice、FastRTPS还有更多厂家提供的每一家的性能不同适用的场景也不同。不过这就带来一个问题每个DDS厂家的软件接口肯定是不一样的如果我们按照某一家的接口写完了程序想要切换其他厂家的DDS不是要重新写代码么这当然不符合ROS提高软件复用率的目标。为了解决这个问题ROS2设计了一个ROS Middleware简称RMW也就是指定一个标准的接口比如如何发数据如何收数据数据的各种属性如何配置都定义好了如果厂家想要接入ROS社区就得按照这个标准写一个适配的接口把自家的DDS给移植过来这样就把问题交给了最熟悉自家DDS的厂商。对于我们这些用户来讲某一个DDS用的不爽只要安装另一个然后做一个简单的配置程序一行的都不用改轻松更换底层的通信系统。举一个例子比如我们在产品开发时可以先用开源版本的DDS满足基本需求部署交付的产品时再更换为商业版本更稳定的DDS这样可以减少开发成本。总之DDS的加入让ROS2系统更加稳定也更加灵活当然复杂度也会高一些。这样我们不用再纠结ROS的通信系统是否稳定、该如何优化等问题更多精力都可以放在其他三个部分专注优化我们的机器人应用功能。2.3 服务质量QoSDDS为ROS的通信系统提供提供了哪些特性呢我们通过这个通信模型图来看下DDS中的基本结构是DomainDomain将各个应用程序绑定在一起进行通信回忆下之前我们配置NanoPC-T6开发板和ubuntu虚拟机通信的时候配置的那个Domain ID就是对全局数据空间的分组定义只有处于同一个Domain小组中的节点才能互相通信这样可以避免无用数据占用的资源。DDS中另外一个重要特性就是质量服务策略QoSQoS是一种网络传输策略应用程序指定所需要的网络传输质量行为QoS服务实现这种行为要求尽可能地满足客户对通信质量的需求可以理解为数据提供者和接收者之间的合约。具体会有哪些策略比如DEADLINE表示通信数据必须要在每次截止时间内完成一次通信HISTORY表示针对历史数据的一个缓存大小RELIABILITY表示数据通信的模式配置成BEST_EFFORT就是尽力传输模式网络情况不好的时候也要保证数据流畅此时可能会导致数据丢失配置成RELIABLE就是可信赖模式可以在通信中尽量保证图像的完整性我们可以根据应用功能场景选择合适的通信模式DURABILITY可以配置针对晚加入的节点也保证有一定的历史数据发送过去可以让新节点快速适应系统。2.3.1 机器人案例举一个机器人的例子便于大家理解2.3.1 无人机案例比如我们遥控一个无人机航拍如果网络情况不好的话遥控器向无人机发送运动指令的过程可以用reliable通信模式保证每一个命令都可以顺利发送给无人机但是可能会有一些延时无人机传输图像的过程可以用best effort模式保证视频的流畅性但是可能会有掉帧。如果此时出现一个黑客黑入我们的网络也没有关系我们可以给ROS2的通信数据进行加密黑客也没有办法直接控制无人机。DDS的加入让ROS2的通信系统焕然一新多众多样的通信配置可以更好的满足不同场景下的机器人应用。三、DDS案例3.1 在命令行中配置DDS我们先来试一试在命令行中配置DDS的参数。3.1.1 发布者启动第一个终端我们使用best_effort创建一个发布者节点循环发布任意数据piNanoPC-T6:~$ ros2 topic pub /chatter std_msgs/msg/Int32 data: 42 --qos-reliability best_effort publisher: beginning loop publishing #1: std_msgs.msg.Int32(data42) publishing #2: std_msgs.msg.Int32(data42) publishing #3: std_msgs.msg.Int32(data42) publishing #4: std_msgs.msg.Int32(data42)3.1.2 订阅者在另外一个终端中如果我们使用reliable模型订阅同一话题则无法实现数据通信piNanoPC-T6:~$ ros2 topic echo /chatter --qos-reliability reliable [WARN] [1765976222.618569414] [_ros2cli_2137]: New publisher discovered on topic /chatter, offering incompatible QoS. No messages will be received from it. Last incompatible policy: RELIABILITY修改为同样的best_effort才能实现数据传输CpiNanoPC-T6:~ros2 topic echo /chatter --qos-reliability best_effortrt data: 42 --- data: 42 --- data: 42 --- data: 42 --- data: 42 --- data: 42 --- data: 42 ---3.1.3 查看QoS策略如何去查看ROS2系统中每一个发布者或者订阅者的QoS策略呢在topic命令后边跟一个--verbose参数就行了piNanoPC-T6:~$ ros2 topic info /chatter --verbose Type: std_msgs/msg/Int32 Publisher count: 1 Node name: _ros2cli_2064 Node namespace: / Topic type: std_msgs/msg/Int32 Endpoint type: PUBLISHER GID: 01.0f.50.2b.10.08.90.1b.00.00.00.00.00.00.05.03.00.00.00.00.00.00.00.00 QoS profile: Reliability: BEST_EFFORT History (Depth): UNKNOWN Durability: TRANSIENT_LOCAL Lifespan: Infinite Deadline: Infinite Liveliness: AUTOMATIC Liveliness lease duration: Infinite Subscription count: 1 Node name: _ros2cli_2200 Node namespace: / Topic type: std_msgs/msg/Int32 Endpoint type: SUBSCRIPTION GID: 01.0f.50.2b.98.08.ab.93.00.00.00.00.00.00.05.04.00.00.00.00.00.00.00.00 QoS profile: Reliability: BEST_EFFORT History (Depth): UNKNOWN Durability: VOLATILE Lifespan: Infinite Deadline: Infinite Liveliness: AUTOMATIC Liveliness lease duration: Infinite3.2DDS编程示例接下来我们尝试在代码中配置DDS以之前Hello World话题通信为例。我们首先创建my_learning_qos的Python版本的功能包piNanoPC-T6:~/dev_ws$ cd src piNanoPC-T6:~/dev_ws/src$ ros2 pkg create --build-type ament_python my_learning_qos3.2.1 发布者在my_learning_qos文件夹下创建qos_helloworld_pub.py ROS2 QoS示例-发布“Hello World”话题 author: zy since : 2025/12/17 import rclpy # ROS2 Python接口库 from rclpy.node import Node # ROS2 节点类 from std_msgs.msg import String # 字符串消息类型 from rclpy.qos import QoSProfile, QoSReliabilityPolicy, QoSHistoryPolicy # ROS2 QoS类 创建一个发布者节点 class PublisherNode(Node): def __init__(self, name): super().__init__(name) # ROS2节点父类初始化 qos_profile QoSProfile( # 创建一个QoS原则 # reliabilityQoSReliabilityPolicy.BEST_EFFORT, reliabilityQoSReliabilityPolicy.RELIABLE, historyQoSHistoryPolicy.KEEP_LAST, depth1 ) self.pub self.create_publisher(String, chatter, qos_profile) # 创建发布者对象(消息类型、话题名、QoS原则) self.timer self.create_timer(0.5, self.timer_callback) # 创建一个定时器(单位为秒的周期定时执行的回调函数) def timer_callback(self): # 创建定时器周期执行的回调函数 msg String() # 创建一个String类型的消息对象 msg.data Hello World # 填充消息对象中的消息数据 self.pub.publish(msg) # 发布话题消息 self.get_logger().info(Publishing: %s % msg.data)# 输出日志信息提示已经完成话题发布 def main(argsNone): # ROS2节点主入口main函数 rclpy.init(argsargs) # ROS2 Python接口初始化 node PublisherNode(qos_helloworld_pub) # 创建ROS2节点对象并进行初始化 rclpy.spin(node) # 循环等待ROS2退出 node.destroy_node() # 销毁节点对象 rclpy.shutdown() # 关闭ROS2 Python接口完成代码的编写后需要设置功能包的编译选项让系统知道Python程序的入口打开功能包的setup.py文件加入如下入口点的配置entry_points{ console_scripts: [ qos_helloworld_pub my_learning_qos.qos_helloworld_pub:main, ], },3.2.2 订阅者在my_learning_qos文件夹下创建qos_helloworld_sub.py ROS2 QoS示例-订阅“Hello World”话题消息 author: zy since : 2025/12/17 import rclpy # ROS2 Python接口库 from rclpy.node import Node # ROS2 节点类 from std_msgs.msg import String # ROS2标准定义的String消息 from rclpy.qos import QoSProfile, QoSReliabilityPolicy, QoSHistoryPolicy # ROS2 QoS类 创建一个订阅者节点 class SubscriberNode(Node): def __init__(self, name): super().__init__(name) # ROS2节点父类初始化 qos_profile QoSProfile( # 创建一个QoS原则 # reliabilityQoSReliabilityPolicy.BEST_EFFORT, reliabilityQoSReliabilityPolicy.RELIABLE, historyQoSHistoryPolicy.KEEP_LAST, depth1 ) self.sub self.create_subscription( String, chatter, self.listener_callback, qos_profile) # 创建订阅者对象(消息类型、话题名、订阅者回调函数、QoS原则) def listener_callback(self, msg): # 创建回调函数执行收到话题消息后对数据的处理 self.get_logger().info(I heard: %s % msg.data) # 输出日志信息提示订阅收到的话题消息 def main(argsNone): # ROS2节点主入口main函数 rclpy.init(argsargs) # ROS2 Python接口初始化 node SubscriberNode(qos_helloworld_sub) # 创建ROS2节点对象并进行初始化 rclpy.spin(node) # 循环等待ROS2退出 node.destroy_node() # 销毁节点对象 rclpy.shutdown() # 关闭ROS2 Python接口完成代码的编写后需要设置功能包的编译选项让系统知道Python程序的入口打开功能包的setup.py文件加入如下入口点的配置entry_points{ console_scripts: [ qos_helloworld_pub my_learning_qos.qos_helloworld_pub:main, qos_helloworld_sub my_learning_qos.qos_helloworld_sub:main, ], },DDS本身是一个非常复杂的系统ROS2使用的也只是冰山一角这一节我们主要认识了DDS更多使用方法和相关内容可以参考文章最后的链接进行学习。3.2.3 编译运行编译程序piNanoPC-T6:~/dev_ws$ colcon build --paths src/my_learning_qos启动第一个终端运行发布者节点piNanoPC-T6:~/dev_ws$ ros2 run my_learning_qos qos_helloworld_pub [INFO] [1765977701.017109522] [qos_helloworld_pub]: Publishing: Hello World [INFO] [1765977701.481142094] [qos_helloworld_pub]: Publishing: Hello World [INFO] [1765977701.981325128] [qos_helloworld_pub]: Publishing: Hello World [INFO] [1765977702.481208424] [qos_helloworld_pub]: Publishing: Hello World [INFO] [1765977702.980783816] [qos_helloworld_pub]: Publishing: Hello World [INFO] [1765977703.481164427] [qos_helloworld_pub]: Publishing: Hello World启动第二个终端运行订阅者节点piNanoPC-T6:~/dev_ws$ ros2 run my_learning_qos qos_helloworld_sub [INFO] [1765977718.509490470] [qos_helloworld_sub]: I heard: Hello World [INFO] [1765977718.981377865] [qos_helloworld_sub]: I heard: Hello World [INFO] [1765977719.483689245] [qos_helloworld_sub]: I heard: Hello World [INFO] [1765977719.982267400] [qos_helloworld_sub]: I heard: Hello World [INFO] [1765977720.483497158] [qos_helloworld_sub]: I heard: Hello World [INFO] [1765977720.983902698] [qos_helloworld_sub]: I heard: Hello World [INFO] [1765977721.484018419] [qos_helloworld_sub]: I heard: Hello World [INFO] [1765977721.981400832] [qos_helloworld_sub]: I heard: Hello World [INFO] [1765977722.483140196] [qos_helloworld_sub]: I heard: Hello World看效果确实差不多不过底层通信机理上可是有所不同的。[1] 古月居ROS2入门教程学习笔记[2]ROS on DDS[3]https://docs.ros.org/en/humble/Concepts/About-Different-Middleware-Vendors.html[4]https://docs.ros.org/en/humble/How-To-Guides/Working-with-multiple-RMW-implementations.html[5]https://www.bilibili.com/video/BV12z4y167w2[6]DDS通信中间件——QoS策略