首页 / 资讯中心 / 文章详情

ROS2从入门到实战:话题、服务、动作与导航全解析

ROS2从入门到实战:话题、服务、动作与导航全解析 ★ FEATURED ARTICLE
1. 为什么ROS2值得你花时间啃下来如果你正在看这篇文章大概率是三种人之一刚买了本ROS2的书翻了两页就犯困的在校学生、被导师安排做机器人项目但完全不知道从哪下手的研究生、或者工作里突然要接一个ROS2相关的活儿但之前只玩过单片机的工程师。不管你是哪种我先把话说在前头——ROS2这东西入门确实有个陡坡但一旦翻过去你会发现后面全是下坡路。我自己是从ROS1时代过来的当年为了跑通一个简单的发布订阅在roscore和各种环境变量之间折腾了整整两天。后来ROS2出来一开始我是抗拒的觉得又是新坑。但真正用ROS2做完两个完整项目之后我的结论很明确ROS2不是ROS1的简单升级它是一次彻底的重构解决了ROS1时代很多让人咬牙切齿的问题。比如ROS1里那个单点故障的master节点一旦挂了整个系统就瘫了比如跨机器通信的配置复杂到让人想砸键盘比如实时性根本没法保证。ROS2用DDS数据分发服务作为通信中间件把这些问题从架构层面解决了。那ROS2到底能做什么简单说它是一套让机器人各个部件能互相“说话”的软件框架。你的激光雷达、摄像头、电机、机械臂、导航算法、路径规划模块全都可以通过ROS2的通信机制连接起来像一个团队一样协同工作。它不挑硬件不挑操作系统主要跑在Linux上但也能在Windows和macOS上跑不挑编程语言C和Python是主力社区也有Rust、Java等绑定。你想做移动机器人导航、机械臂抓取、无人机飞控、自动驾驶仿真ROS2都能给你提供基础设施。这篇文章我打算怎么讲我不会像教科书那样从“什么是节点”开始念定义。我会按照一个真实的学习路径来先搞清楚ROS2的通信骨架话题、服务、动作再动手装环境、建功能包、写代码然后进入仿真和真机实操最后聊一聊导航、机械臂这些进阶方向怎么切入。中间我会穿插大量我自己踩过的坑和实际项目中的经验这些东西你在官方文档里大概率看不到。注意这篇文章假设你有基本的Linux命令行操作能力知道cd、ls、sudo这些命令是干嘛的。如果完全没用过Linux建议先花半天时间熟悉一下Ubuntu的基本操作否则后面会很痛苦。2. ROS2的通信骨架话题、服务、动作到底怎么选2.1 话题通信最常用但也最容易用错的方式话题Topic是ROS2里最基础的通信方式采用的是发布-订阅模型。一个节点往某个话题上发消息另一个节点从这个话题上收消息双方互相不知道对方的存在只认话题名字和消息类型。这种解耦设计的好处是灵活——你可以随时增加或减少订阅者发布者完全不受影响。但这里有个新手特别容易犯的错误把什么数据都往话题上扔。我见过有人把机械臂的关节控制指令也用话题发结果发现指令丢失、时序混乱。话题适合什么适合高频、单向、允许丢包的数据流。比如激光雷达的扫描数据、摄像头的图像流、IMU的传感器读数、机器人的里程计信息。这些数据的特点是发得快、量大、偶尔丢一帧不影响整体。话题的消息类型是需要明确定义的。ROS2自带了很多标准消息类型比如sensor_msgs/msg/LaserScan、geometry_msgs/msg/Twist、nav_msgs/msg/Odometry。你也可以自定义消息类型这个后面讲功能包的时候会细说。实际操作中查看当前系统里有哪些话题、谁在发谁在收用这几个命令ros2 topic list # 列出所有活跃话题 ros2 topic info /chatter # 查看某个话题的详细信息 ros2 topic echo /chatter # 实时打印话题上的消息内容 ros2 topic hz /chatter # 查看话题的发布频率 ros2 topic bw /chatter # 查看话题的带宽占用这几个命令我在调试的时候用得最多的是ros2 topic hz和ros2 topic bw。前者帮你确认数据是不是按预期频率在发后者帮你判断网络带宽有没有被吃满。有一次我做多传感器融合发现IMU数据总是延迟用hz一查发现发布频率只有10Hz但实际应该是100Hz最后定位到是驱动配置的问题。实操心得话题的QoS服务质量配置是ROS2相比ROS1最大的改进之一但也是新手最容易忽略的地方。默认情况下ROS2的话题用的是“可靠传输”这意味着如果订阅者处理不过来发布者会等待。对于高频传感器数据这会导致发布者被拖慢。正确的做法是根据数据特性选择合适的QoS策略比如传感器数据用“尽力而为”Best Effort控制指令用“可靠”Reliable。这个后面在实操部分会详细讲。2.2 服务通信请求-响应模式的正确打开方式服务Service采用的是客户端-服务器模型。客户端发一个请求服务器处理后返回一个响应。这是一对一的同步通信客户端会阻塞等待响应。服务适合什么场景适合低频、需要确认结果、有明确请求响应关系的操作。比如查询机器人的电池电量、切换导航模式、保存地图、触发一次标定流程。服务的定义包含两部分请求Request和响应Response。ROS2内置了一些标准服务类型比如std_srvs/srv/SetBool、std_srvs/srv/Trigger。你也可以自定义服务类型。ros2 service list # 列出所有活跃服务 ros2 service type /spawn # 查看服务类型 ros2 service call /spawn turtlesim/srv/Spawn {x: 2.0, y: 2.0, theta: 0.0, name: turtle2}上面这个例子是调用turtlesim仿真器里的生成海龟服务。注意服务调用的语法服务名、服务类型、请求内容YAML格式。服务的一个关键限制是它是阻塞的。如果服务器处理请求需要很长时间客户端就会一直卡在那里。所以千万不要用服务来做耗时操作比如“规划一条从A到B的路径”这种可能需要几秒钟的计算应该用动作Action而不是服务。2.3 动作通信长时间任务的终极方案动作Action是ROS2里最复杂但也最强大的通信方式。它建立在话题和服务之上专门用于长时间运行、需要反馈进度、可以被取消的任务。动作的底层实现其实是用服务来发送目标请求和获取最终结果用话题来持续反馈执行进度。动作适合什么场景导航到某个目标点、机械臂执行一段轨迹、无人机飞一个航线、3D重建扫描。这些任务的共同特点是执行时间长几秒到几分钟、执行过程中需要知道进度、可能中途需要取消。ROS2内置了nav2_msgs/action/NavigateToPose、control_msgs/action/FollowJointTrajectory等标准动作类型。自定义动作类型包含三部分目标Goal、反馈Feedback、结果Result。ros2 action list # 列出所有活跃动作 ros2 action info /navigate_to_pose # 查看动作信息 ros2 action send_goal /navigate_to_pose nav2_msgs/action/NavigateToPose {pose: {header: {frame_id: map}, pose: {position: {x: 1.0, y: 2.0, z: 0.0}, orientation: {w: 1.0}}}} --feedback--feedback参数会持续打印执行过程中的反馈信息这在调试导航任务时特别有用。那到底怎么选我总结了一个简单的判断表通信方式适用场景数据频率是否需要响应典型例子话题传感器数据流、状态广播高频10Hz-1kHz不需要激光雷达、IMU、里程计服务配置查询、模式切换低频按需需要同步查询电量、保存地图动作导航、轨迹执行、扫描中低频按需需要异步反馈导航到点、机械臂抓取踩坑记录我曾经在一个项目里用服务来做机械臂的关节空间运动结果每次调用都要等好几秒而且如果中途想取消根本没办法。后来改成动作不仅能实时看到关节运动进度还能随时取消体验完全不一样。所以记住一句话只要操作可能超过1秒就优先考虑动作而不是服务。3. 环境搭建从零到跑通第一个节点3.1 Ubuntu版本选择与ROS2版本对应关系这是新手第一个容易迷糊的地方。ROS2的版本和Ubuntu版本是强绑定的选错了版本后面全是坑。截至我写这篇文章的时候主流的搭配是这样的ROS2版本对应Ubuntu版本支持状态推荐程度Humble HawksbillUbuntu 22.04LTS支持到2027年5月强烈推荐最稳定Iron IrwiniUbuntu 22.04非LTS支持到2024年11月不推荐新手Jazzy JaliscoUbuntu 24.04LTS支持到2029年5月推荐但生态还在完善Rolling Ridley最新Ubuntu滚动更新只适合开发者我的建议很直接如果你刚开始学用Ubuntu 22.04 ROS2 Humble。这是目前生态最完善、教程最多、遇到问题最容易搜到答案的组合。Jazzy虽然更新但很多第三方包还没跟上你可能会在安装某个依赖时卡住。如果你用的是Ubuntu 24.04那就装Jazzy。如果你非要在Ubuntu 22.04上装Jazzy也不是不行但需要从源码编译对新手来说没必要找这个麻烦。注意不要用WSLWindows Subsystem for Linux来学ROS2。虽然WSL2已经支持GUI了但ROS2的网络通信、USB设备访问、实时性在WSL里都有问题。我试过在WSL里跑Gazebo帧率低到没法看。老老实实装个双系统或者用一台单独的Ubuntu机器这是最省心的方案。3.2 安装ROS2 Humble的完整步骤安装之前先确认你的系统是干净的Ubuntu 22.04并且已经配置好了软件源。下面是完整流程# 第一步设置locale确保支持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 # 第二步添加ROS2的APT源 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 # 第三步安装ROS2 sudo apt update sudo apt install ros-humble-desktop -y # 第四步安装开发工具 sudo apt install ros-dev-tools -y # 第五步配置环境变量 echo source /opt/ros/humble/setup.bash ~/.bashrc source ~/.bashrc这里解释几个关键点。ros-humble-desktop包含了ROS2的核心库、RViz2可视化工具、演示程序和教程是最完整的安装选项。如果你磁盘空间紧张可以装ros-humble-ros-base只包含核心库但后面做仿真和可视化的时候还得补装。ros-dev-tools包含了colcon构建工具、rosdep依赖管理工具等开发必备的东西。安装完成后验证一下# 检查ROS2环境是否配置成功 printenv | grep ROS # 应该能看到ROS_DISTROhumble、ROS_VERSION2等环境变量 # 跑一个经典的talker-listener例子 # 终端1 ros2 run demo_nodes_cpp talker # 终端2 ros2 run demo_nodes_py listener如果终端2能看到终端1发出的“Hello World”消息恭喜你ROS2环境已经跑通了。实操心得安装过程中最常见的错误是网络问题导致的APT源访问失败。如果你看到类似“获取:1 http://packages.ros.org/ros2/ubuntu jammy InRelease [4,682 B] 错误:1”这样的报错先检查网络连接然后试试换一个镜像源。另外rosdep初始化的时候如果卡住可以试试rosdepc这个国内维护的版本速度会快很多。3.3 创建工作空间和功能包ROS2的代码组织方式和ROS1有很大不同。ROS2用ament作为构建系统colcon作为构建工具。一个标准的工作空间结构是这样的ros2_ws/ ├── src/ # 源代码目录 │ ├── package1/ │ └── package2/ ├── build/ # 构建中间文件 ├── install/ # 安装后的可执行文件 └── log/ # 构建日志创建和构建工作空间的流程# 创建工作空间 mkdir -p ~/ros2_ws/src cd ~/ros2_ws # 创建一个C功能包 cd src ros2 pkg create --build-type ament_cmake my_cpp_pkg --dependencies rclcpp std_msgs # 创建一个Python功能包 ros2 pkg create --build-type ament_python my_py_pkg --dependencies rclpy std_msgs # 回到工作空间根目录构建 cd ~/ros2_ws colcon build --symlink-install # 配置工作空间环境 source install/setup.bash--symlink-install这个参数很关键。它创建的是符号链接而不是拷贝文件这样你修改Python代码后不需要重新构建就能直接运行。对于C代码还是需要重新colcon build。功能包的目录结构my_cpp_pkg/ ├── CMakeLists.txt # 构建配置 ├── package.xml # 包描述和依赖 ├── include/my_cpp_pkg/ # 头文件 └── src/ # 源文件package.xml里需要声明依赖CMakeLists.txt里需要配置可执行文件的生成规则。这两个文件是C功能包的核心写错了就编译不过。踩坑记录colcon build的时候如果报“找不到某个包”的错误大概率是package.xml里漏写了依赖。ROS2的依赖管理比ROS1严格得多每个用到的包都必须在package.xml里声明。另外每次打开新终端都要source install/setup.bash忘了这一步就会找不到自己写的节点。我建议把这句话加到.bashrc里省得每次都手动敲。4. 动手写代码从发布订阅到自定义接口4.1 用C写一个发布者节点光跑demo没意思得自己写代码才算真正入门。下面是一个完整的C发布者节点每隔500毫秒发一条消息#include chrono #include memory #include rclcpp/rclcpp.hpp #include std_msgs/msg/string.hpp using namespace std::chrono_literals; class MinimalPublisher : public rclcpp::Node { public: MinimalPublisher() : Node(minimal_publisher), count_(0) { publisher_ this-create_publisherstd_msgs::msg::String(topic, 10); timer_ this-create_wall_timer( 500ms, std::bind(MinimalPublisher::timer_callback, this)); } private: void timer_callback() { auto message std_msgs::msg::String(); message.data Hello, ROS2! std::to_string(count_); RCLCPP_INFO(this-get_logger(), Publishing: %s, message.data.c_str()); publisher_-publish(message); } rclcpp::TimerBase::SharedPtr timer_; rclcpp::Publisherstd_msgs::msg::String::SharedPtr publisher_; size_t count_; }; int main(int argc, char * argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_sharedMinimalPublisher()); rclcpp::shutdown(); return 0; }这段代码里有几个关键点需要理解。create_publisher的第二个参数是队列长度当发布速度超过订阅者处理速度时最多缓存10条消息超出的会被丢弃。create_wall_timer创建的是一个周期性定时器500ms触发一次。rclcpp::spin是ROS2的事件循环它让节点保持运行并处理回调。对应的订阅者节点#include memory #include rclcpp/rclcpp.hpp #include std_msgs/msg/string.hpp class MinimalSubscriber : public rclcpp::Node { public: MinimalSubscriber() : Node(minimal_subscriber) { subscription_ this-create_subscriptionstd_msgs::msg::String( topic, 10, std::bind(MinimalSubscriber::topic_callback, this, std::placeholders::_1)); } private: void topic_callback(const std_msgs::msg::String::SharedPtr msg) const { RCLCPP_INFO(this-get_logger(), I heard: %s, msg-data.c_str()); } rclcpp::Subscriptionstd_msgs::msg::String::SharedPtr subscription_; }; int main(int argc, char * argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_sharedMinimalSubscriber()); rclcpp::shutdown(); return 0; }在CMakeLists.txt里添加add_executable(talker src/publisher_member_function.cpp) ament_target_dependencies(talker rclcpp std_msgs) add_executable(listener src/subscriber_member_function.cpp) ament_target_dependencies(listener rclcpp std_msgs) install(TARGETS talker listener DESTINATION lib/${PROJECT_NAME})然后colcon buildsource install/setup.bash分别运行ros2 run my_cpp_pkg talker和ros2 run my_cpp_pkg listener就能看到消息在传了。4.2 Python版本更快的原型开发Python在ROS2里同样重要尤其是做算法验证和快速原型的时候。同样的发布订阅Python代码要简洁得多import rclpy from rclpy.node import Node from std_msgs.msg import String class MinimalPublisher(Node): def __init__(self): super().__init__(minimal_publisher) self.publisher_ self.create_publisher(String, topic, 10) self.timer self.create_timer(0.5, self.timer_callback) self.count 0 def timer_callback(self): msg String() msg.data fHello, ROS2! {self.count} self.publisher_.publish(msg) self.get_logger().info(fPublishing: {msg.data}) self.count 1 def main(argsNone): rclpy.init(argsargs) node MinimalPublisher() rclpy.spin(node) node.destroy_node() rclpy.shutdown() if __name__ __main__: main()Python功能包需要在setup.py里配置入口点entry_points{ console_scripts: [ talker my_py_pkg.publisher_member_function:main, listener my_py_pkg.subscriber_member_function:main, ], },实操心得C和Python怎么选我的经验是算法原型用Python性能敏感的模块用C。比如图像处理、点云滤波、控制循环这些对实时性要求高的用C而任务调度、状态机、参数配置这些逻辑性的东西Python写起来快得多。ROS2允许你在同一个系统里混用两种语言节点之间通过话题通信完全透明。4.3 自定义消息和服务接口标准消息类型不够用的时候就需要自定义接口。比如你要做一个机器人状态监控系统需要同时上报位置、速度、电量、温度标准消息里没有现成的类型。创建自定义消息的步骤# 创建一个专门存放接口的功能包 ros2 pkg create --build-type ament_cmake my_interfaces在my_interfaces目录下创建msg/RobotStatus.msggeometry_msgs/Pose position geometry_msgs/Twist velocity float32 battery_level float32 temperature string status在CMakeLists.txt里添加find_package(rosidl_default_generators REQUIRED) find_package(geometry_msgs REQUIRED) rosidl_generate_interfaces(${PROJECT_NAME} msg/RobotStatus.msg DEPENDENCIES geometry_msgs )在package.xml里添加build_dependrosidl_default_generators/build_depend exec_dependrosidl_default_runtime/exec_depend member_of_grouprosidl_interface_packages/member_of_group构建之后就可以在代码里#include my_interfaces/msg/robot_status.hpp来使用了。注意自定义消息的字段命名要用小写字母加下划线这是ROS2的命名规范。另外消息里不要放太大的数组比如整张图像的数据那样会导致序列化和传输开销很大。图像应该用sensor_msgs/Image点云用sensor_msgs/PointCloud2这些标准类型已经做了优化。5. 仿真环境Gazebo和RViz2的配合使用5.1 Gazebo仿真不烧硬件也能调算法Gazebo是ROS2生态里最常用的物理仿真器。它能模拟重力、碰撞、摩擦、传感器噪声让你在没有真实机器人的情况下开发和测试算法。安装sudo apt install ros-humble-gazebo-ros-pkgs ros-humble-gazebo-ros2-control启动一个空的Gazebo世界gazebo --verbose但更常用的方式是通过launch文件启动同时加载机器人模型。以turtlesim为例虽然turtlesim不是Gazebo但逻辑类似launch文件的写法from launch import LaunchDescription from launch_ros.actions import Node def generate_launch_description(): return LaunchDescription([ Node( packageturtlesim, executableturtlesim_node, namesim ), Node( packageturtlesim, executableturtle_teleop_key, nameteleop, prefixxterm -e ), ])对于Gazebo你需要一个URDF统一机器人描述格式文件来定义机器人的外观和物理属性。URDF写起来比较繁琐推荐用xacroXML宏来简化。一个简单的差速轮式机器人URDF大概长这样robot namemy_robot link namebase_link visual geometry box size0.3 0.2 0.1/ /geometry /visual collision geometry box size0.3 0.2 0.1/ /geometry /collision inertial mass value1.0/ inertia ixx0.001 ixy0 ixz0 iyy0.001 iyz0 izz0.001/ /inertial /link !-- 左右轮、万向轮、激光雷达的link和joint定义省略 -- /robot踩坑记录Gazebo仿真里最常见的问题是机器人“抖”或者“飞”。这通常是物理参数设置不合理导致的。检查三个地方质量mass不能太小惯性矩阵inertia要合理碰撞体collision不要和视觉体visual差太多。另外Gazebo的实时因子real-time factor如果低于0.5说明你的电脑跑不动这个仿真需要简化模型或者降低传感器更新频率。5.2 RViz2数据可视化的利器RViz2是ROS2的3D可视化工具它不参与计算只是把话题上的数据画出来。你可以把它理解成一个“ROS2数据的示波器”。启动rviz2RViz2里最常用的几个显示类型LaserScan显示激光雷达数据需要设置话题名和坐标系PointCloud2显示点云数据做3D感知必备Image显示摄像头画面TF显示坐标变换树调试多传感器融合时必看RobotModel显示机器人模型需要加载URDFPath显示规划出的路径Map显示2D栅格地图配置好之后可以保存为.rviz文件下次直接rviz2 -d my_config.rviz加载。实操心得RViz2的“Fixed Frame”设置是新手最容易搞错的地方。如果你发现数据显示不出来或者位置完全不对先检查Fixed Frame是不是设置成了正确的坐标系通常是map、odom或base_link。另外TF树如果断了比如某个link没有发布变换RViz2会报错并拒绝显示相关数据。用ros2 run tf2_tools view_frames可以生成TF树的PDF图非常直观。5.3 用MoveIt2做机械臂运动规划MoveIt2是ROS2里做机械臂运动规划的标准工具。它集成了运动学求解、碰撞检测、路径规划、轨迹执行等功能。以Panda机械臂为例安装sudo apt install ros-humble-moveit ros-humble-moveit-resources-panda-moveit-config启动Panda的MoveIt2演示ros2 launch moveit_resources_panda_moveit_config demo.launch.py在RViz2里你会看到Panda机械臂的模型可以用鼠标拖拽末端执行器来设置目标位置MoveIt2会自动规划一条无碰撞的轨迹并执行。MoveIt2的核心概念规划组Planning Group定义哪些关节一起运动比如panda_arm是7个关节的机械臂panda_hand是夹爪场景Planning Scene包含机器人模型和周围环境的碰撞信息规划器Planner默认用OMPL开源运动规划库支持RRT、PRM等多种算法控制器Controller负责把规划出的轨迹发送给真实或仿真的机器人踩坑记录MoveIt2的配置生成器Setup Assistant是配置自己机械臂的必经之路但这个过程相当繁琐。我的建议是先拿Panda或UR5这些现成的配置跑通整个流程理解每个配置项的含义再去配置自己的机械臂。另外MoveIt2对URDF的要求比Gazebo更严格特别是关节限位、碰撞体、惯性矩阵这些缺一个都可能报错。6. 导航与进阶从仿真到真机的关键跨越6.1 Nav2导航栈让机器人自己走路Nav2是ROS2的导航框架它包含了地图构建、定位、路径规划、避障、恢复行为等完整功能。一个典型的Nav2启动流程# 终端1启动仿真环境 ros2 launch nav2_bringup tb3_simulation_launch.py # 终端2启动RViz2 ros2 run rviz2 rviz2 -d $(ros2 pkg prefix nav2_bringup)/share/nav2_bringup/rviz/nav2_default_view.rviz在RViz2里用“2D Pose Estimate”设置初始位置用“Nav2 Goal”设置目标点机器人就会自动规划路径并移动过去。Nav2的核心组件组件功能对应话题/服务AMCL蒙特卡洛定位/amcl_poseCostmap2D代价地图/global_costmap, /local_costmapPlanner Server全局路径规划/planController Server局部轨迹跟踪/cmd_velBehavior Server恢复行为/spin, /backup, /waitBT Navigator行为树导航/navigate_to_pose实操心得Nav2的调参是个体力活。最重要的几个参数inflation_radius膨胀半径决定了机器人离障碍物多远就开始避让、cost_scaling_factor代价衰减因子影响路径贴障碍物的程度、max_vel_theta最大角速度太大会导致机器人旋转时抖动。我的经验是先在仿真里把参数调到满意再上真机微调。真机上最大的变数是轮子打滑和传感器噪声仿真里跑得再好真机上也可能撞墙。6.2 从仿真到真机的 checklist仿真跑通了不代表真机能跑。从仿真迁移到真机有几个关键点必须检查坐标系标定激光雷达、摄像头、IMU的安装位置和朝向必须准确标定否则TF树是错的导航必挂时间同步多传感器融合对时间戳要求很高确保所有传感器使用同一时钟源通信带宽真机上的网络可能不如仿真环境稳定高频话题要考虑压缩或降频安全机制急停按钮、速度限制、碰撞检测这些在仿真里可以忽略真机上必须有电源管理电池电压下降会影响电机性能进而影响里程计精度踩坑记录我第一次把导航算法从仿真搬到真机的时候机器人原地转圈。查了半天发现是IMU的安装方向设错了仿真里IMU默认朝前真机上我装的时候转了90度但URDF里没改。所以真机部署前一定要用ros2 run tf2_tools view_frames确认TF树和实际安装一致。6.3 ROS2的学习路径建议最后聊一聊学习路径。ROS2的知识体系很庞大如果东学一点西学一点很容易迷失。我建议按这个顺序推进第一阶段1-2周装好环境跑通talker/listener理解话题、服务、动作的区别。能自己写一个简单的发布订阅节点。第二阶段2-3周学会创建功能包、自定义消息、写launch文件。能用RViz2可视化数据能用ros2 bag录制和回放数据。第三阶段3-4周进入仿真用Gazebo加载机器人模型用MoveIt2做机械臂规划用Nav2做移动机器人导航。第四阶段持续选一个具体方向深入比如多传感器融合、视觉SLAM、机械臂抓取、自动驾驶。这时候需要读论文、看源码、参与开源项目。我个人在实际操作中的体会是ROS2的学习曲线前陡后缓。前两周最痛苦各种环境问题、编译错误、概念混淆。但只要坚持把第一个完整的项目跑通后面就会越来越顺。另外不要试图把官方文档从头读到尾那样效率极低。正确的做法是带着问题去查文档遇到什么查什么查完立刻动手验证。ROS2的官方教程质量很高但光看不动手等于没学。关于版本选择我再啰嗦一句如果你现在开始学直接上Humble。不要因为看到Jazzy是新版本就去装Jazzy生态成熟度差太多了。等你把Humble玩熟了再迁移到新版本就是几天的事。ROS2的前景不用怀疑工业机器人、服务机器人、自动驾驶、无人机都在往ROS2上迁。现在投入时间学未来几年都用得上。
阅读完成 · 觉得有帮助?
咨询建站