鸿蒙应用开发从入门到实战(二十):ArkUI内置弹窗组件 📅 发布时间:2026/7/13 18:45:10 👁️ 浏览次数: 奥冻逗硬我们在《ROS2概述和基于RK3588的环境搭建》中对ROS和ROS2做了对比其中最多的变化就是DDS。我们在前面文章中介绍的话题、服务、动作他们底层通信的具体实现过程都是靠DDS来完成的它相当于是ROS机器人系统中的神经网络。回到顶部一、通信模型DDS的核心是通信能够实现通信的模型和软件框架非常多这里我们列出常用的四种模型。1.1 点对点模型许多客户端连接到一个服务端每次通信时通信双方必须建立一条连接当通信节点增多时连接数也会增多。而且每个客户端都需要知道服务器的具体地址和所提供的服务一旦服务器地址发生变化所有客户端都会受到影响。1.2 Broker模型针对点对点模型进行了优化由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.1 DDS定义DDS的全称是Data Distribution Service也就是数据分发服务2004年由对象管理组织OMG发布和维护是一套专门为实时系统设计的数据分发/订阅标准最早应用于美国海军 解决舰船复杂网络环境中大量软件升级的兼容性问题现在已经成为强制标准。DDS强调以数据为中心可以提供丰富的服务质量策略以保障数据进行实时、高效、灵活地分发可满足各种分布式实时通信应用需求。这里也提一下对象管理组织OMG成立于1989年它的使命是开发技术标准为数以千计的垂直行业提供真实的价值比如我们可能听说过的统一建模语言SYSML和UML还有中间件标准CORBA等当然还有DDS。2.2 在ROS2中的应用DDS在ROS2系统中的位置至关重要所有上层建设都建立在DDS之上。在这个ROS2的架构图中蓝色和红色部分就是DDS。imgDDS其实是物联网中广泛应用的一种通信协议类似于我们常听说的5G通信一样DDS是一个国际标准能够实现该标准的软件系统并不是唯一的所以我们可以选择多个厂家提供的DDS系统比如这里的OpenSplice、FastRTPS还有更多厂家提供的每一家的性能不同适用的场景也不同。不过这就带来一个问题每个DDS厂家的软件接口肯定是不一样的如果我们按照某一家的接口写完了程序想要切换其他厂家的DDS不是要重新写代码么这当然不符合ROS提高软件复用率的目标。为了解决这个问题ROS2设计了一个ROS Middleware简称RMW也就是指定一个标准的接口比如如何发数据如何收数据数据的各种属性如何配置都定义好了如果厂家想要接入ROS社区就得按照这个标准写一个适配的接口把自家的DDS给移植过来这样就把问题交给了最熟悉自家DDS的厂商。对于我们这些用户来讲某一个DDS用的不爽只要安装另一个然后做一个简单的配置程序一行的都不用改轻松更换底层的通信系统。举一个例子比如我们在产品开发时可以先用开源版本的DDS满足基本需求部署交付的产品时再更换为商业版本更稳定的DDS这样可以减少开发成本。img总之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_effortpublisher: beginning looppublishing #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_effortrtdata: 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 --verboseType: std_msgs/msg/Int32Publisher count: 1Node name: _ros2cli_2064Node namespace: /Topic type: std_msgs/msg/Int32Endpoint type: PUBLISHERGID: 01.0f.50.2b.10.08.90.1b.00.00.00.00.00.00.05.03.00.00.00.00.00.00.00.00QoS profile:Reliability: BEST_EFFORTHistory (Depth): UNKNOWNDurability: TRANSIENT_LOCALLifespan: InfiniteDeadline: InfiniteLiveliness: AUTOMATICLiveliness lease duration: InfiniteSubscription count: 1Node name: _ros2cli_2200Node namespace: /Topic type: std_msgs/msg/Int32Endpoint type: SUBSCRIPTIONGID: 01.0f.50.2b.98.08.ab.93.00.00.00.00.00.00.05.04.00.00.00.00.00.00.00.00QoS profile:Reliability: BEST_EFFORTHistory (Depth): UNKNOWNDurability: VOLATILELifespan: InfiniteDeadline: InfiniteLiveliness: AUTOMATICLiveliness lease duration: Infinite3.2 DDS编程示例接下来我们尝试在代码中配置DDS以之前Hello World话题通信为例。我们首先创建my_learning_qos的Python版本的功能包piNanoPC-T6:~/dev_ws$ cd srcpiNanoPC-T6:~/dev_ws/src$ ros2 pkg create --build-type ament_python my_learning_qos3.2.1 发布者在my_learning_qos文件夹下创建qos_helloworld_pub.pyROS2 QoS示例-发布“Hello World”话题author: zysince : 2025/12/17import 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.pyROS2 QoS示例-订阅“Hello World”话题消息author: zysince : 2025/12/17import 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看效果确实差不多不过底层通信机理上可是有所不同的。
Microsoft Agent Framework/C#:了解Workflows的几种不同模式 囟木让奶对业务代码是否有“侵入性”?几乎没有 不需要改写代码 不需要 unsafe 不需要特殊编译选项 你写的是“好代码”,JIT 会越来越聪明地帮你榨干性能。 .NET 10 中的 JIT 编译器包括通过更好的代码生成和优化策略提高性能的重要增强功能。改进结构参… 2026/7/11 6:43:13
AIGlasses_for_navigation镜像免配置:内置FFmpeg+GStreamer全格式视频解码支持 AIGlasses_for_navigation镜像免配置:内置FFmpegGStreamer全格式视频解码支持 1. 引言 想象一下,你拿到一个全新的智能眼镜导航系统,里面包含了盲道识别、红绿灯检测、物品查找等一堆酷炫功能。你迫不及待地想试试,结果第一步就… 2026/7/8 5:04:20
bge-large-zh-v1.5入门必看:Embedding服务健康检查的5个关键指标解读 bge-large-zh-v1.5入门必看:Embedding服务健康检查的5个关键指标解读 1. 理解bge-large-zh-v1.5的核心价值 bge-large-zh-v1.5是一款专门为中文文本处理设计的嵌入模型,它能够将文字转换为高维度的数值向量,从而让计算机能够"理解&quo… 2026/7/13 5:15:24
2026年云端真机兼容性测试平台选型指南:主流机型测试平台功能与适用场景 从事APP兼容性测试工作已有五年,日常长期接触各类移动端测试方案,作为独立分享博主,不与任何测试厂商存在合作关系,仅结合实操经验客观分享各类云端真机平台的基础功能与适用场景,方便研发、测试人员按需参考。当下移动… 2026/7/13 18:43:40
OpenCAMLib完整指南:3步掌握开源数控加工算法库 OpenCAMLib完整指南:3步掌握开源数控加工算法库 【免费下载链接】opencamlib open source computer aided manufacturing algorithms library 项目地址: https://gitcode.com/gh_mirrors/op/opencamlib OpenCAMLib是一个功能强大的开源计算机辅助制造&#x… 2026/7/13 18:41:39
DsHidMini完整指南:让闲置PS3手柄在Windows系统重获新生的终极解决方案 DsHidMini完整指南:让闲置PS3手柄在Windows系统重获新生的终极解决方案 【免费下载链接】DsHidMini Virtual HID Mini-user-mode-driver for Sony DualShock 3 Controllers 项目地址: https://gitcode.com/gh_mirrors/ds/DsHidMini 你是否有一台闲置的索尼Du… 2026/7/13 18:35:38
深度解析Balena Etcher下载异常:从源码构建到分发优化的完整解决方案 深度解析Balena Etcher下载异常:从源码构建到分发优化的完整解决方案 【免费下载链接】etcher Flash OS images to SD cards & USB drives, safely and easily. 项目地址: https://gitcode.com/GitHub_Trending/et/etcher Balena Etcher作为开源镜像烧录… 2026/7/13 18:35:38
Kubernetes异构GPU资源调度突破:HAMi如何将AI集群GPU利用率提升100% Kubernetes异构GPU资源调度突破:HAMi如何将AI集群GPU利用率提升100% 【免费下载链接】HAMi Heterogeneous GPU Sharing on Kubernetes 项目地址: https://gitcode.com/GitHub_Trending/ha/HAMi 在AI计算资源日益稀缺的今天,技术决策者和架构师面临… 2026/7/13 18:31:37
如何快速配置洛雪音乐高品质音源:新手完整指南 如何快速配置洛雪音乐高品质音源:新手完整指南 【免费下载链接】lxmusic- lxmusic(洛雪音乐)全网最新最全音源 项目地址: https://gitcode.com/gh_mirrors/lx/lxmusic- 想要在洛雪音乐中享受全网最高品质的音乐体验吗?音源配置是关键!… 2026/7/13 18:29:36
HS2-HF Patch终极指南:如何用3步解决Honey Select 2的70+个痛点 HS2-HF Patch终极指南:如何用3步解决Honey Select 2的70个痛点 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch 你是否曾经在Honey Select 2中遇到过… 2026/7/13 0:01:19
语音转文字工具AsrTools:让音频整理变得简单高效 语音转文字工具AsrTools:让音频整理变得简单高效 【免费下载链接】AsrTools ✨ AsrTools: Smart Voice-to-Text Tool | Efficient Batch Processing | User-Friendly Interface | No GPU Required | Supports SRT/TXT Output | Turn your audio into accurate text … 2026/7/13 0:03:19
基于深度学习的蘑菇或花卉或动漫人物或中草药货水果蔬菜等识别系统31(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_ 基于深度学习的蘑菇或花卉或动漫人物或中草药货水果蔬菜等识别系统31(设计源文件万字报告讲解)(支持资料、图片参考_相关定制)_ 独家界面!不会重复,此项目属于本人原创,若有雷同,均是盗卖,各位买… 2026/7/13 0:05:20
Git reset 与 revert 深度对比:5个关键差异与 3 种典型应用场景 Git Reset 与 Revert 深度对比:5个关键差异与3种典型应用场景在团队协作开发中,代码版本管理如同行走钢丝——一步失误可能导致整个项目陷入混乱。作为Git进阶用户,你是否曾在深夜面对错误的提交束手无策?是否在强制推送后收到同事… 2026/7/13 8:31:55
GitHub 学生包申请避坑:5个常见失败原因与开发者工具调试方案 GitHub 学生包申请技术排障指南:5个高频失败场景与开发者工具实战方案第一次尝试申请GitHub学生包时,我盯着屏幕上那个不断转圈的加载动画整整15分钟,最终只等来了一行冰冷的错误提示。这可能是许多开发者共同的经历——明明按照教程操作&… 2026/7/13 9:31:08
冒烟测试用例设计规范:5%-10%覆盖率下的3类核心场景与执行标准 冒烟测试用例设计的黄金法则:5%-10%覆盖率下的精准筛选策略在快节奏的敏捷开发环境中,冒烟测试作为质量保障的第一道防线,其重要性不言而喻。当测试资源有限而时间紧迫时,如何从海量测试用例中精准筛选出那关键的5%-10%࿰… 2026/7/13 2:34:55