ROS 2实战入门:从零构建具身智能机器人系统核心能力

发布时间:2026/8/21 22:47:19
ROS 2实战入门:从零构建具身智能机器人系统核心能力 如果你正在考虑进入机器人或具身智能领域看着铺天盖地的“AI机器人”新闻和动辄百万年薪的招聘信息内心既兴奋又迷茫——那么这篇文章就是为你写的。很多人以为入行机器人就是学Python、调模型、跑算法。但当你真正打开一个招聘JD或者尝试参与一个真实的机器人项目时会发现完全不是那么回事。企业需要的不是只会调用API的“调参侠”而是能解决从“想法”到“物理世界动作”这一完整链条问题的工程师。这个链条的核心往往绕不开一个名字ROS 2。ROS 2Robot Operating System 2早已不是实验室里的玩具它正在成为工业机器人、自动驾驶、服务机器人乃至人形机器人领域的“事实标准”中间件。它解决的核心问题是如何让传感器、决策大脑AI模型和执行器电机、机械臂在复杂、实时、可靠的环境中高效、安全地对话。然而ROS 2的学习曲线并不平坦。网上教程要么过于零散只讲“Hello World”话题通信要么直接丢出一个庞大的开源项目让人无从下手。更关键的是你很难判断自己学的东西是否是企业真正看重的。基于对行业需求和技术栈的梳理本文将为你揭示在具身智能和机器人开发领域企业真正看重的四项核心能力并围绕这四项能力提供一份从零开始、直指实战的ROS 2入门与进阶指南。你将不仅学会ROS 2的基本操作更能理解它如何支撑起一个完整的机器人系统并亲手搭建一个可运行的仿真机器人项目。1. 企业视角具身智能开发者必备的四大核心能力在深入技术细节之前我们必须先厘清目标。企业招聘时表面要求是“熟悉ROS 2”、“掌握C/Python”但背后考察的是以下四项能直接产生价值的能力1.1 能力一系统思维与模块化设计能力机器人是一个复杂的软硬件耦合系统。开发者必须理解感知、规划、控制、人机交互等模块如何通过ROS 2这样的“通信总线”协同工作。这意味着你不能只盯着一个算法而要清楚数据流图像数据从相机驱动Camera Driver发出经过视觉处理节点Perception Node结果传递给路径规划节点Planner Node最后生成控制指令发给底层电机驱动Motor Driver。ROS 2的话题Topic和服务Service就是定义这些数据流接口的契约。节点Node的单一职责一个节点最好只做一件事如“识别红色物体”或“发布里程计”并通过ROS 2与其他节点解耦。这直接决定了代码的可维护性和团队协作效率。1.2 能力二通信中间件与工程化能力这是ROS 2的核心价值所在。你需要精通其通信机制并能在工程中妥善运用话题Topic vs 服务Service vs 动作Action何时用异步的、一对多的数据流Topic何时用同步的、请求-响应的RPC调用Service何时用可中途取消的、长时间运行的任务Action选错通信模式会导致系统延迟高、响应慢或逻辑复杂。质量服务QoS配置这是ROS 2相比ROS 1的飞跃。在真实的机器人上网络可能不稳定。你可以通过QoS策略决定丢失一些非关键的摄像头帧是否可以接受Best Effort控制指令是否必须可靠送达Reliable历史数据是否需要保留不理解QoS就无法构建健壮的机器人系统。Launch系统如何一键启动分布在多个计算设备上的几十个节点ROS 2的Launch文件Python编写是管理复杂系统启动的生命线。1.3 能力三仿真与调试能力不可能每次测试都动用实体机器人。高效开发者的大部分时间都在仿真环境中度过。Gazebo / Isaac Sim与ROS 2深度集成的物理仿真器。你可以在其中测试机器人模型、传感器噪声、控制算法甚至进行强化学习训练零硬件成本。RViz2ROS 2的可视化工具。它能将抽象的传感器数据点云、激光雷达扫描线、坐标变换TF、机器人模型URDF实时地显示出来是调试感知和定位算法的“眼睛”。ROS 2命令行工具ros2 topic echo/listros2 node inforos2 bag record/play。熟练使用这些工具进行系统状态监控、数据录制与回放是快速定位问题的基本功。1.4 能力四软硬件接口与驱动开发能力机器人最终要作用于物理世界。这意味着你必须与硬件打交道理解URDF/SDF模型如何用XML文件描述你的机器人连杆、关节、传感器、碰撞属性这是仿真和可视化RViz2的基础。编写或复用硬件驱动无论是相机、雷达还是电机控制器都需要一个ROS 2节点作为驱动将硬件数据发布为标准的ROS 2消息如sensor_msgs/Imagesensor_msgs/LaserScan。与微控制器如STM32通信通过micro-ROS项目可以将ROS 2的轻量级客户端嵌入到资源受限的MCU中实现与主控计算机如Jetson、工控机的高效通信。接下来我们将围绕这四项能力构建一个完整的ROS 2学习路径并通过一个智能小车仿真项目进行实战。2. ROS 2核心概念快速解读在动手之前我们需要统一语言。ROS 2的核心架构可以类比为一个高度组织化的公司或开源社区。概念类比作用与解释节点Node公司里的员工/部门一个可执行程序负责完成一项具体的计算任务如处理图像、计算控制量。一个系统由许多节点组成。话题Topic公司公告板/邮件列表异步通信渠道。节点可以发布Publish消息到某个话题也可以订阅Subscribe某个话题来接收消息。一对多单向流动。适合持续性的数据流如传感器数据、机器人状态。消息Message公告板上的通知格式在话题上传输的数据结构有严格定义的类型如geometry_msgs/Twist表示速度指令。服务Service一对一的请求-响应工作流同步通信模式。客户端节点发送一个请求Request服务端节点处理并返回一个响应Response。一对一双向。适合偶尔触发、需要确认结果的操作如开关传感器、查询状态。动作Action一个可跟踪、可取消的长期项目在服务的基础上增加了反馈Feedback和取消Cancel机制。适合长时间运行、需要过程反馈的任务如导航到目标点过程中反馈当前位置和状态。参数Parameter公司的配置文件节点运行时可以动态调整的配置项如控制器增益、算法阈值。可通过命令行或图形界面动态修改无需重启节点。启动文件Launch公司晨会流程清单一个Python脚本用于批量配置和启动一组节点以及设置它们的参数和重映射规则。理解了这些你就明白了ROS 2是如何通过“节点”分工并通过“话题/服务/动作”协作最终完成复杂任务的。3. 环境准备搭建你的第一个ROS 2工作空间我们选择ROS 2 Humble Hawksbill作为学习版本因为它是一个长期支持LTS版本社区支持好且相对稳定。操作系统Ubuntu 22.04 LTS这是ROS 2 Humble的官方推荐系统。3.1 安装ROS 2 Humble请严格按照官方步骤进行。打开终端依次执行以下命令# 1. 设置语言环境确保支持UTF-8 sudo apt update sudo apt install locales sudo locale-gen en_US en_US.UTF-8 sudo update-locale LC_ALLen_US.UTF-8 LANGen_US.UTF-8 export LANGen_US.UTF-8 # 2. 添加ROS 2软件源 sudo apt install software-properties-common sudo add-apt-repository universe sudo apt update sudo apt install curl -y sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg echo deb [arch$(dpkg --print-architecture) signed-by/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release echo $UBUNTU_CODENAME) main | sudo tee /etc/apt/sources.list.d/ros2.list /dev/null # 3. 安装ROS 2核心包 sudo apt update sudo apt upgrade -y sudo apt install ros-humble-desktop python3-argcomplete -y # 4. 设置环境变量每次打开新终端都需要执行或将其加入~/.bashrc source /opt/ros/humble/setup.bash echo source /opt/ros/humble/setup.bash ~/.bashrc3.2 创建工作空间WorkspaceROS 2的代码通常组织在工作空间中。我们来创建一个名为ros2_ws的工作空间。# 创建并进入工作空间目录 mkdir -p ~/ros2_ws/src cd ~/ros2_ws # 在工作空间根目录下安装依赖并编译此时src为空编译不会做任何事情 colcon buildcolcon是ROS 2的构建工具。编译后会在ros2_ws目录下生成build、install、log三个文件夹。install文件夹里就是可执行文件和Python包。4. 核心能力实战一创建节点与话题通信让我们通过一个经典示例——“发布者Talker”和“订阅者Listener”来实践节点和话题通信。4.1 创建Python功能包Package功能包是ROS 2中组织代码的基本单元。cd ~/ros2_ws/src # 创建一个名为py_pubsub的Python功能包依赖rclpy和std_msgs ros2 pkg create py_pubsub --build-type ament_python --dependencies rclpy std_msgs4.2 编写发布者节点Publisher Node创建发布者节点文件cd ~/ros2_ws/src/py_pubsub/py_pubsub touch publisher_member_function.py编辑publisher_member_function.py#!/usr/bin/env python3 # 文件路径~/ros2_ws/src/py_pubsub/py_pubsub/publisher_member_function.py import rclpy from rclpy.node import Node from std_msgs.msg import String import time class MinimalPublisher(Node): def __init__(self): # 初始化节点节点名为minimal_publisher super().__init__(minimal_publisher) # 创建一个发布者发布到topic话题消息类型为String队列长度为10 self.publisher_ self.create_publisher(String, topic, 10) # 创建一个定时器每0.5秒触发一次timer_callback函数 timer_period 0.5 # seconds self.timer self.create_timer(timer_period, self.timer_callback) self.i 0 def timer_callback(self): # 构造要发布的消息 msg String() msg.data Hello World: %d % self.i # 发布消息 self.publisher_.publish(msg) # 在终端打印日志 self.get_logger().info(Publishing: %s % msg.data) self.i 1 def main(argsNone): # 初始化ROS 2客户端库 rclpy.init(argsargs) # 创建节点实例 minimal_publisher MinimalPublisher() # 保持节点运行等待回调函数被触发 rclpy.spin(minimal_publisher) # 销毁节点并关闭rclpy minimal_publisher.destroy_node() rclpy.shutdown() if __name__ __main__: main()4.3 编写订阅者节点Subscriber Node创建订阅者节点文件cd ~/ros2_ws/src/py_pubsub/py_pubsub touch subscriber_member_function.py编辑subscriber_member_function.py#!/usr/bin/env python3 # 文件路径~/ros2_ws/src/py_pubsub/py_pubsub/subscriber_member_function.py import rclpy from rclpy.node import Node from std_msgs.msg import String class MinimalSubscriber(Node): def __init__(self): # 初始化节点节点名为minimal_subscriber super().__init__(minimal_subscriber) # 创建一个订阅者订阅topic话题消息类型为String回调函数为listener_callback self.subscription self.create_subscription( String, topic, self.listener_callback, 10) # 队列长度 # 防止变量被优化掉 self.subscription def listener_callback(self, msg): # 收到消息时的回调函数 self.get_logger().info(I heard: %s % msg.data) def main(argsNone): rclpy.init(argsargs) minimal_subscriber MinimalSubscriber() rclpy.spin(minimal_subscriber) minimal_subscriber.destroy_node() rclpy.shutdown() if __name__ __main__: main()4.4 修改package.xml和setup.py为了让系统识别我们的节点为可执行脚本需要修改配置文件。首先在package.xml的export标签内添加build_typeament_python/build_type然后编辑setup.py在console_scripts括号内添加入口点entry_points{ console_scripts: [ talker py_pubsub.publisher_member_function:main, listener py_pubsub.subscriber_member_function:main, ], },4.5 编译与运行# 回到工作空间根目录 cd ~/ros2_ws # 编译功能包 colcon build --packages-select py_pubsub # 激活工作空间的环境 source install/setup.bash打开第一个终端运行发布者ros2 run py_pubsub talker你应该看到终端每秒打印两次Publishing: Hello World: X。打开第二个终端先激活环境再运行订阅者cd ~/ros2_ws source install/setup.bash ros2 run py_pubsub listener在订阅者终端你应该看到同步打印出I heard: Hello World: X。恭喜你已经实现了ROS 2最核心的通信机制。你可以用ros2 topic list命令查看当前活跃的话题用ros2 topic echo /topic直接查看话题内容。5. 核心能力实战二使用Launch文件启动多节点系统手动开多个终端启动节点太低效。Launch文件是工程化的关键。在py_pubsub目录下创建launch文件夹和文件cd ~/ros2_ws/src/py_pubsub mkdir launch touch launch/pubsub_launch.py编辑pubsub_launch.py# 文件路径~/ros2_ws/src/py_pubsub/launch/pubsub_launch.py from launch import LaunchDescription from launch_ros.actions import Node def generate_launch_description(): return LaunchDescription([ Node( packagepy_pubsub, executabletalker, nametalker_node, # 可以覆盖节点原本的名字 outputscreen # 将日志输出到屏幕 ), Node( packagepy_pubsub, executablelistener, namelistener_node, outputscreen ), ])修改setup.py将launch文件安装到指定目录import os from glob import glob from setuptools import setup # ... 其他部分保持不变 ... setup( # ... 其他参数 ... data_files[ (share/ament_index/resource_index/packages, [resource/ package_name]), (share/ package_name, [package.xml]), # 添加这行安装launch目录下的所有文件 (os.path.join(share, package_name, launch), glob(launch/*.py)), ], # ... 其他参数 ... )重新编译并运行launch文件cd ~/ros2_ws colcon build --packages-select py_pubsub source install/setup.bash ros2 launch py_pubsub pubsub_launch.py一个命令两个节点同时启动。这才是管理机器人系统应有的方式。6. 核心能力实战三仿真环境搭建与可视化Gazebo RViz2现在我们进入更贴近真实机器人开发的环节仿真。我们将使用一个现成的TurtleBot3仿真模型。6.1 安装TurtleBot3仿真包cd ~/ros2_ws/src # 克隆仿真相关的功能包 git clone -b humble https://github.com/ROBOTIS-GIT/turtlebot3_simulations.git # 回到工作空间根目录编译 cd ~/ros2_ws rosdep install -i --from-path src --rosdistro humble -y # 安装依赖 colcon build --packages-select turtlebot3_gazebo source install/setup.bash6.2 在Gazebo中生成一个仿真世界并放入机器人# 设置机器人模型默认为burger export TURTLEBOT3_MODELburger # 启动Gazebo仿真环境一个空世界和TurtleBot3 ros2 launch turtlebot3_gazebo empty_world.launch.py等待Gazebo启动完毕你将看到一个TurtleBot3机器人站在空旷的地板上。6.3 使用RViz2可视化机器人打开另一个终端启动RViz2并加载TurtleBot3的配置cd ~/ros2_ws source install/setup.bash export TURTLEBOT3_MODELburger ros2 launch turtlebot3_bringup rviz2.launch.py在RViz2中你可以看到机器人的模型、激光雷达LaserScan的模拟数据红色的点云。这就是能力三仿真与调试的体现。6.4 通过话题控制机器人移动再打开一个终端我们通过发布速度指令话题来控制机器人cd ~/ros2_ws source install/setup.bash ros2 topic pub -r 10 /cmd_vel geometry_msgs/msg/Twist {linear: {x: 0.2, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 0.5}}这条命令会以10Hz的频率向/cmd_vel话题发布一个速度指令线速度0.2 m/s前进角速度0.5 rad/s左转。回到Gazebo和RViz2你会看到机器人开始做圆周运动关键理解/cmd_vel是ROS中移动机器人标准的速度指令话题。仿真器中的机器人模型订阅了这个话题并根据指令运动。在真实机器人上订阅这个话题的将是底层电机驱动节点。这就是系统思维我们通过一个标准接口控制机器人而不关心底层是仿真还是真实电机。7. 核心能力实战四理解坐标变换TF与传感器数据机器人各个部件底盘、激光雷达、相机都有自己的坐标系。TF库管理着这些坐标系之间的动态变换关系。7.1 查看TF树在机器人运行做圆周运动时在新的终端运行ros2 run tf2_tools view_frames.py这会生成一个frames.pdf文件。打开它你可以看到一张树状图显示了从odom里程计坐标系到base_footprint机器人底座再到base_scan激光雷达等坐标系之间的关系。RViz2正是利用TF树才能正确地将激光雷达数据显示在机器人模型上。7.2 订阅并处理激光雷达数据激光雷达数据是机器人感知环境的基础。让我们写一个简单的节点来订阅并处理它。创建一个新的功能包cd ~/ros2_ws/src ros2 pkg create laser_processor --build-type ament_python --dependencies rclpy sensor_msgs cd laser_processor/laser_processor touch laser_subscriber.py编辑laser_subscriber.py#!/usr/bin/env python3 # 文件路径~/ros2_ws/src/laser_processor/laser_processor/laser_subscriber.py import rclpy from rclpy.node import Node from sensor_msgs.msg import LaserScan import math class LaserProcessor(Node): def __init__(self): super().__init__(laser_processor) # 订阅 /scan 话题这是TurtleBot3仿真中激光雷达的数据 self.subscription self.create_subscription( LaserScan, /scan, self.scan_callback, 10) self.subscription def scan_callback(self, msg): # msg.ranges 是一个数组存储了每个角度上的距离值 # msg.angle_min, msg.angle_max 定义了扫描角度范围 # msg.angle_increment 是角度增量 # 示例找到正前方假设索引在中间的距离 front_index len(msg.ranges) // 2 front_distance msg.ranges[front_index] # 检查数据是否有效inf表示无穷远nan表示无效 if math.isfinite(front_distance): self.get_logger().info(f正前方距离: {front_distance:.2f} 米) # 简单的避障逻辑如果距离小于0.5米报警 if front_distance 0.5: self.get_logger().warn(前方有障碍物) else: self.get_logger().info(正前方无有效读数) def main(argsNone): rclpy.init(argsargs) node LaserProcessor() rclpy.spin(node) node.destroy_node() rclpy.shutdown() if __name__ __main__: main()修改setup.py添加入口点然后编译运行cd ~/ros2_ws colcon build --packages-select laser_processor source install/setup.bash ros2 run laser_processor laser_subscriber启动后移动机器人靠近Gazebo世界中的墙壁你会看到终端打印距离信息并在过近时报警。这模拟了一个最简单的避障感知逻辑。8. 项目整合构建一个简单的自动巡航节点现在我们将之前学到的能力整合起来创建一个节点它订阅激光雷达数据根据环境信息决策并发布速度指令让机器人在仿真世界中实现简单的“遇到障碍物就转弯”的自动巡航。在laser_processor包中创建新文件auto_cruise.py#!/usr/bin/env python3 # 文件路径~/ros2_ws/src/laser_processor/laser_processor/auto_cruise.py import rclpy from rclpy.node import Node from sensor_msgs.msg import LaserScan from geometry_msgs.msg import Twist import math class AutoCruise(Node): def __init__(self): super().__init__(auto_cruise) # 订阅激光雷达 self.scan_sub self.create_subscription( LaserScan, /scan, self.scan_callback, 10) # 发布速度指令 self.cmd_pub self.create_publisher(Twist, /cmd_vel, 10) # 定义一个定时器定期发布控制指令即使没有新的激光数据 self.timer self.create_timer(0.1, self.timer_callback) # 10Hz self.front_distance float(inf) self.state FORWARD # 状态机FORWARD, TURN def scan_callback(self, msg): # 简化处理只取前方一个小扇形区域的距离最小值 num_readings len(msg.ranges) # 假设正前方在中间查看前方±15度的数据 center_idx num_readings // 2 start_idx center_idx - int(15.0 / (msg.angle_increment * 180.0 / math.pi)) end_idx center_idx int(15.0 / (msg.angle_increment * 180.0 / math.pi)) start_idx max(0, start_idx) end_idx min(num_readings-1, end_idx) valid_distances [d for d in msg.ranges[start_idx:end_idx] if math.isfinite(d)] if valid_distances: self.front_distance min(valid_distances) else: self.front_distance float(inf) # 状态决策 if self.front_distance 0.6: # 障碍物阈值 self.state TURN elif self.front_distance 0.8 and self.state TURN: self.state FORWARD def timer_callback(self): msg Twist() if self.state FORWARD: msg.linear.x 0.15 msg.angular.z 0.0 self.get_logger().info(f前进前方距离: {self.front_distance:.2f}m) elif self.state TURN: msg.linear.x 0.05 msg.angular.z 0.5 # 左转 self.get_logger().info(f转弯前方距离: {self.front_distance:.2f}m) self.cmd_pub.publish(msg) def main(argsNone): rclpy.init(argsargs) node AutoCruise() rclpy.spin(node) node.destroy_node() rclpy.shutdown() if __name__ __main__: main()同样在setup.py中添加入口点auto_cruise laser_processor.auto_cruise:main然后编译。运行你的第一个自主机器人在一个终端启动Gazebo仿真ros2 launch turtlebot3_gazebo empty_world.launch.py在另一个终端运行自动巡航节点ros2 run laser_processor auto_cruise你会看到机器人在世界中前进遇到墙壁或障碍物时自动左转然后继续前进。虽然逻辑简单但它完整串联了感知激光雷达- 决策状态机- 控制发布cmd_vel的闭环。这就是一个最小可用的自主机器人原型。9. 常见问题与排查思路避坑指南在学习和开发过程中你一定会遇到各种问题。以下是典型问题及排查思路问题现象可能原因排查方式解决方案ros2命令未找到环境变量未设置执行echo $ROS_DISTRO执行source /opt/ros/humble/setup.bash或将其加入~/.bashrccolcon build失败提示缺少依赖功能包的依赖未安装查看编译错误信息确认缺失的包名使用rosdep install -i --from-path src --rosdistro humble -y安装所有依赖节点编译成功但ros2 run找不到环境未激活或入口点未正确声明1. 确认执行了source install/setup.bash2. 检查setup.py中console_scripts配置1. 激活工作空间环境2. 检查并修正setup.py重新编译话题数据收不到1. 话题名称不匹配2. 消息类型不匹配3. QoS策略不匹配1.ros2 topic list查看话题是否存在2.ros2 topic info /topic_name查看话题类型和订阅/发布者3.ros2 topic echo /topic_name手动测试1. 检查发布和订阅代码中的话题名2. 检查消息类型是否一致3. 检查发布和订阅节点的QoS配置深度、可靠性RViz2中看不到机器人模型或传感器数据1. TF树不完整或错误2. 显示插件未添加或配置错误1. 运行ros2 run tf2_tools view_frames.py检查TF树2. 在RViz2中检查Global Options的Fixed Frame设置通常应为odom或map1. 确保机器人驱动节点正确发布了TF变换2. 在RViz2中手动添加RobotModel、LaserScan等Display并正确设置其TopicGazebo中机器人不动速度指令话题不正确或未发布ros2 topic echo /cmd_vel查看是否有数据检查控制节点是否正确发布到/cmd_vel消息类型是否为geometry_msgs/Twist节点启动后立即崩溃Python语法错误或运行时导入错误查看终端输出的错误堆栈信息根据错误信息修正代码常见于import错误或ROS 2 API使用错误10. 最佳实践与进阶学习方向10.1 工程最佳实践包结构清晰将不同功能的节点放在不同的包中。例如perception_pkg、planning_pkg、control_pkg。使用参数服务器将算法阈值、配置文件等作为ROS参数便于在线调整和实验。使用node.declare_parameter()和node.get_parameter()。善用日志使用self.get_logger().info()/warn()/error()/debug()分级输出日志便于调试。编写Launch文件对于复杂系统务必使用Launch文件来管理节点启动、参数加载和重映射。版本控制使用Git管理你的工作空间src下的所有代码。.gitignore应忽略build、install、log目录。10.2 后续学习路径建议掌握了以上基础你可以按以下路径深入这正是企业项目所涉及的方向导航导航栈Nav2这是ROS 2中用于机器人自主移动的完整解决方案。学习如何配置Costmap、Planner、Controller让机器人实现从A点到B点的自主导航与避障。感知与视觉集成OpenCV和ROS 2处理相机图像。学习使用cv_bridge在ROS图像消息和OpenCV矩阵间转换实现物体识别、视觉SLAM等。机器人建模与URDF深入学习URDF为你自己的机器人创建精确的模型包括连杆、关节、传感器和碰撞属性。硬件接口与驱动尝试将ROS 2与真实硬件连接。可以从树莓派STM32电机驱动板开始使用micro-ROS或ros2_serial进行通信。机器人操作系统进阶研究ROS 2的生命周期节点管理节点状态、组件化节点提升性能、安全与权限系统等企业级特性。仿真进阶学习在Gazebo中添加自定义环境、传感器噪声甚至使用Isaac Sim进行高性能仿真和强化学习训练。回到开头的四大核心能力通过本教程的实践你已经初步触碰了每一项你构建了多节点系统使用了话题通信和Launch文件等工程化工具在仿真环境中调试并可视化了机器人并处理了传感器数据来驱动决策。具身智能和机器人开发是一条长赛道ROS 2是你不可或缺的“瑞士军刀”。不要停留在运行示例尝试修改代码改变机器人的行为增加新的传感器仿真中甚至为它设计一个新的任务。真正的能力始于你动手解决第一个属于自己的机器人问题之时。建议收藏本文在后续实践中反复查阅。