☰
ROS2入门不迷路:从零搭建环境到跑通最小Demo(逻辑+代码全解析)
2026/9/26 4:05:51 网站建设 项目流程

ROS2入门不迷路:从零搭建环境到跑通最小Demo(逻辑+代码全解析)

标签:#ROS2 #机器人操作系统 #Humble #入门教程 #C++


前言

刚接触ROS2的新手,最怕的就是环境装半天装不好、代码跑不通不知道哪错了。本文从零开始,用国内一键脚本装环境,通过话题通信和服务通信两个最小Demo,把ROS2最核心的通信逻辑讲清楚。代码注释适中,适合想快速上手跑通的新手。

废话不多说,直接开干。


一、环境搭建

1.1 一键安装(推荐国内用户)

用鱼香ROS的一键脚本,省心省力:

wgethttp://fishros.com/install-Ofishros&&.fishros

运行后选择安装ROS2 Humble Desktop,装完再跑一次脚本,配置 rosdep。

1.2 验证安装

ros2 doctor

输出All checks passed就完事,环境没问题。


二、验证环境:跑通内置Demo

ROS2自带了示例节点,先跑一下确认环境没问题。

打开两个终端,分别执行:

# 终端1:发布消息ros2 run demo_nodes_cpp talker# 终端2:接收消息ros2 run demo_nodes_cpp listener

终端2能持续收到终端1发的消息,说明通信链路通了,环境OK。


三、话题通信:自己写最小Demo

3.1 核心逻辑串一下

话题通信就是发布/订阅模式,类似广播电台:

  1. 发布端:创建节点 → 创建发布者(指定话题名)→ 循环发消息
  2. 订阅端:创建节点 → 创建订阅者(指定同一个话题名)→ 收到消息触发回调
  3. 两边话题名对得上,就能通

3.2 建包

mkdir-p~/ros2_ws/srccd~/ros2_ws/src ros2 pkg create demo --build-type ament_cmake--dependenciesrclcpp std_msgs

3.3 发布端talker.cpp

在src/demo/src/下新建talker.cpp:

#include"rclcpp/rclcpp.hpp"#include"std_msgs/msg/string.hpp"usingnamespacestd::chrono_literals;intmain(intargc,char**argv){rclcpp::init(argc,argv);// 初始化ROS2autonode=rclcpp::Node::make_shared("talker");// 创建节点// 创建发布者,话题名"chatter",队列长度10autopub=node->create_publisher<std_msgs::msg::String>("chatter",10);std_msgs::msg::String msg;msg.data="hello";rclcpp::Raterate(1s);// 每秒发一次while(rclcpp::ok()){pub->publish(msg);// 发消息RCLCPP_INFO(node->get_logger(),"发了: %s",msg.data.c_str());rate.sleep();}rclcpp::shutdown();return0;}

3.4 订阅端listener.cpp

在src/demo/src/下新建listener.cpp:

#include"rclcpp/rclcpp.hpp"#include"std_msgs/msg/string.hpp"intmain(intargc,char**argv){rclcpp::init(argc,argv);autonode=rclcpp::Node::make_shared("listener");// 订阅"chatter"话题,收到消息执行回调autosub=node->create_subscription<std_msgs::msg::String>("chatter",10,[](conststd_msgs::msg::String::SharedPtr msg){RCLCPP_INFO(rclcpp::get_logger("listener"),"收到: %s",msg->data.c_str());});rclcpp::spin(node);// 阻塞等待消息rclcpp::shutdown();return0;}

3.5 修改CMakeLists.txt

在src/demo/CMakeLists.txt末尾添加:

add_executable(talker src/talker.cpp) ament_target_dependencies(talker rclcpp std_msgs) add_executable(listener src/listener.cpp) ament_target_dependencies(listener rclcpp std_msgs) install(TARGETS talker listener DESTINATION lib/${PROJECT_NAME} ) ament_package()

3.6 编译运行

cd~/ros2_ws colcon build --packages-select demosourceinstall/setup.bash

打开两个终端:

# 终端1ros2 run demo talker# 终端2ros2 run demo listener

终端2持续打印收到: hello,通了。


四、服务通信:请求/响应模式

4.1 核心逻辑串一下

服务通信是一问一答模式,类似打电话:

  1. 服务端:创建节点 → 创建服务(指定服务名+回调函数)→ 阻塞等待请求
  2. 客户端:创建节点 → 创建客户端(指定同一个服务名)→ 构造请求 → 发送并等待结果
  3. 两边服务名对得上,客户端才能拿到返回值

4.2 建包

cd~/ros2_ws/src ros2 pkg create svc_demo --build-type ament_cmake--dependenciesrclcpp example_interfaces

4.3 服务端server.cpp

在src/svc_demo/src/下新建server.cpp:

#include"rclcpp/rclcpp.hpp"#include"example_interfaces/srv/add_two_ints.hpp"// 回调函数:收到请求时执行,计算a+bvoidhandle(conststd::shared_ptr<example_interfaces::srv::AddTwoInts::Request>req,std::shared_ptr<example_interfaces::srv::AddTwoInts::Response>resp){resp->sum=req->a+req->b;RCLCPP_INFO(rclcpp::get_logger("server"),"%ld + %ld = %ld",req->a,req->b,resp->sum);}intmain(intargc,char**argv){rclcpp::init(argc,argv);autonode=rclcpp::Node::make_shared("server");// 创建服务,服务名"add_two_ints"autosrv=node->create_service<example_interfaces::srv::AddTwoInts>("add_two_ints",handle);RCLCPP_INFO(rclcpp::get_logger("server"),"服务已启动");rclcpp::spin(node);// 阻塞等待请求rclcpp::shutdown();return0;}

4.4 客户端client.cpp

在src/svc_demo/src/下新建client.cpp:

#include"rclcpp/rclcpp.hpp"#include"example_interfaces/srv/add_two_ints.hpp"intmain(intargc,char**argv){rclcpp::init(argc,argv);autonode=rclcpp::Node::make_shared("client");// 创建客户端,连接"add_two_ints"服务autoclient=node->create_client<example_interfaces::srv::AddTwoInts>("add_two_ints");// 构造请求autoreq=std::make_shared<example_interfaces::srv::AddTwoInts::Request>();req->a=3;req->b=7;// 等服务端启动while(!client->wait_for_service(std::chrono::seconds(1))){RCLCPP_INFO(rclcpp::get_logger("client"),"等服务端...");}// 发请求并等待结果autoresult=client->async_send_request(req);if(rclcpp::spin_until_future_complete(node,result)==rclcpp::FutureReturnCode::SUCCESS){RCLCPP_INFO(rclcpp::get_logger("client"),"结果: %ld",result.get()->sum);}rclcpp::shutdown();return0;}

4.5 修改CMakeLists.txt

在src/svc_demo/CMakeLists.txt末尾添加:

add_executable(server src/server.cpp) ament_target_dependencies(server rclcpp example_interfaces) add_executable(client src/client.cpp) ament_target_dependencies(client rclcpp example_interfaces) install(TARGETS server client DESTINATION lib/${PROJECT_NAME} ) ament_package()

4.6 编译运行

cd~/ros2_ws colcon build --packages-select svc_demosourceinstall/setup.bash

先跑服务端,再跑客户端:

# 终端1ros2 run svc_demo server# 终端2ros2 run svc_demo client

服务端打印3 + 7 = 10,客户端打印结果: 10,通了。


五、总结

类型模式逻辑适用场景
话题发布/订阅发布端一直发,订阅端一直收传感器数据、状态广播
服务请求/响应客户端问,服务端答,一问一答计算、查询、开关控制

两套通信搞明白,ROS2就算入门了。


常见问题

  1. colcon build 报错:确认执行了source install/setup.bash
  2. ros2 run 找不到节点:确认编译成功,包名和节点名正确
  3. 客户端等服务超时:确认服务名一致,服务端先启动

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询