Rospy入门
ROS(Robot Operating System)是一个专为机器人开发设计的开源中间件框架,旨在简化机器人系统开发。其核心包括:roscore(通信中枢)、节点(功能单元)、功能包(代码组织)、话题(异步通信)、服务(同步通信)等组件。ROS采用模块化设计,支持跨语言、跨设备交互,提供传感器驱动、路径规划等常用功能封装。开发流程通常从启动roscore开始,通过rosrun或roslaunch
一、先明确 ROS 的本质
ROS(Robot Operating System)不是传统操作系统,而是一套为机器人开发设计的开源中间件 / 软件框架,核心目标是:
- 把机器人的复杂功能拆成独立模块(解耦);
- 提供统一的通信方式,让模块间能跨语言、跨设备高效交互;
- 封装常用功能(传感器驱动、路径规划、仿真),降低开发门槛。
类比:ROS 就像 “机器人的操作系统内核 + 应用商店”,内核负责模块通信,应用商店提供现成的功能包。
二、ROS 核心概念(按优先级排序)
1. ROS 核心(roscore)—— 机器人的 “总控中心”
- 核心定义:
roscore是 ROS 网络的 “大脑”,启动 ROS 应用的第一步,本质是多个后台进程的集合(节点管理器、参数服务器、话题 / 服务路由)。 - 生活化比喻:像公司的 “前台 + 服务器机房”,负责记录所有员工(节点)的信息,转发员工间的消息(话题 / 服务),存储公司的公共配置(参数)。
- 核心作用:
- 节点注册表:记录所有运行的节点,确保节点名全局唯一;
- 消息路由:转发话题 / 服务消息,让节点间不用直接连,通过
roscore中转; - 参数服务器:存储全局配置参数(如机器人速度阈值、传感器校准值)。
- 实操关联:
- 启动命令:
roscore; - 关闭
roscore会导致所有节点强制退出; roslaunch会自动检查并启动roscore,无需手动执行。
- 启动命令:
2. 节点(Node)—— 机器人的 “功能员工”
- 核心定义:ROS 程序的最小独立运行单元,一个可执行文件(Python/C++ 脚本)运行起来就是一个节点,每个节点只负责一个具体功能。
- 生活化比喻:像公司里的 “单个员工”,比如 “激光雷达数据读取员”“路径规划员”“电机控制员”,每个员工只做一件事,通过前台(roscore)和其他员工沟通。
- 核心特点:
- 单一职责:一个节点只做一件事(如读取激光雷达、控制电机),解耦易维护;
- 分布式:节点可跑在不同设备上(如电脑跑路径规划,机器人跑电机控制);
- 唯一标识:节点名全局唯一,重复启动同名节点会失败(可加
anonymous=True自动加后缀)。
- 实操关联:
- 启动节点:
rosrun 功能包名 节点脚本名; - 查看节点:
rosnode list; - 终止节点:
rosnode kill /节点名或 Ctrl+C。
- 启动节点:
3. 功能包(Package)—— 机器人的 “功能部门”
- 核心定义:ROS 中组织代码的基本单元,是节点、配置文件、依赖的集合,一个功能包对应一个 “完整的小功能”(如激光 SLAM、导航、摄像头驱动)。
- 生活化比喻:像公司里的 “部门”,比如 “导航部” 包含 “路径规划员、定位员、指令发送员”(多个节点),还有部门的 “规章制度”(配置文件)。
- 核心组成:
scripts/:Python 节点脚本;src/:C++ 节点源码;launch/:启动文件(一键启动多个节点);package.xml:功能包依赖(如依赖rospy、actionlib);CMakeLists.txt:编译规则(C++ 节点需要)。
- 实操关联:
- 创建功能包:
catkin_create_pkg 包名 依赖1 依赖2(如catkin_create_pkg my_nav rospy actionlib); - 编译功能包:
catkin_make(在工作空间根目录执行)。
- 创建功能包:
4. 话题(Topic)—— 机器人的 “实时广播频道”
- 核心定义:节点间异步、单向、实时传递数据的通信方式,一个节点(发布者)往话题发消息,所有订阅该话题的节点(订阅者)都能收到。
- 生活化比喻:像公司的 “广播频道”,比如 “激光雷达数据频道”,数据读取员(发布者)持续往频道里播数据,路径规划员、避障员(订阅者)都能听,发布者不管谁在听,订阅者也不用回应。
- 核心特点:
- 单向通信:发布者只发不收,订阅者只收不发;
- 异步实时:按固定频率发数据(如 10Hz),适合传感器数据、控制指令等持续传输场景;
- 强类型:每个话题有固定的消息类型(如
std_msgs/String、sensor_msgs/LaserScan),类型不匹配无法通信。
- 实操关联:
- 查看话题:
rostopic list; - 查看话题消息:
rostopic echo /话题名; - 手动发消息:
rostopic pub /话题名 消息类型 消息内容。
- 查看话题:
5. 消息(Message)—— 机器人的 “通信语言”
- 核心定义:话题 / 服务 / 动作传输数据的 “格式规范”,定义了数据的类型和结构(如字符串、整数、激光点云坐标)。
- 生活化比喻:像广播频道的 “语言规范”,比如 “激光雷达频道” 必须用 “坐标 + 距离” 的格式说话,所有听众都按这个格式理解。
- 常见类型:
- 基础类型:
std_msgs/String(字符串)、std_msgs/Int32(整数); - 传感器类型:
sensor_msgs/LaserScan(激光雷达数据)、sensor_msgs/Image(图像数据); - 自定义类型:可自己定义
.msg文件(如MyPose.msg,包含 x、y、z 坐标)。
- 基础类型:
- 实操关联:
- 查看消息类型:
rostopic info /话题名; - 查看消息结构:
rosmsg show 消息类型(如rosmsg show sensor_msgs/LaserScan)。
- 查看消息类型:
6. 服务(Service)—— 机器人的 “一对一请求 - 响应”
- 核心定义:节点间同步、双向、一次性的通信方式,一个节点(客户端)向另一个节点(服务端)发请求,服务端处理后返回响应。
- 生活化比喻:像员工间的 “一对一咨询”,比如路径规划员(客户端)问定位员(服务端)“当前位置是多少?”,定位员必须明确回复,路径规划员要等回复后才能继续工作。
- 核心特点:
- 同步阻塞:客户端发请求后会等待服务端响应,直到超时 / 收到回复;
- 双向通信:请求→响应,适合短时间、一次性的操作(如查询位置、设置参数);
- 强类型:服务有固定的请求 / 响应类型(
.srv文件定义)。
- 实操关联:
- 查看服务:
rosservice list; - 调用服务:
rosservice call /服务名 请求参数(如rosservice call /clear_costmaps ""); - 自定义服务:创建
.srv文件,定义请求(Request)和响应(Response)结构。
- 查看服务:
7. 动作(Action)—— 机器人的 “带反馈的长任务请求”
- 核心定义:基于话题 / 服务扩展的通信方式,支持 “目标发送→过程反馈→结果返回”,适合长时间运行的任务(如导航、机械臂运动)。
- 生活化比喻:像员工间的 “复杂协作”,比如路径规划员(客户端)让电机控制员(服务端)“把机器人开到 A 点”,电机控制员实时反馈 “已走 50%”“已到 80%”,最终回复 “到达 / 失败”。
- 核心特点:
- 异步非阻塞:客户端发目标后可继续做其他事,不用一直等;
- 带反馈:能实时获取任务进度(如导航剩余距离);
- 可取消:任务执行中可取消(如导航到一半取消目标);
- 强类型:动作有固定的目标(Goal)、反馈(Feedback)、结果(Result)类型(
.action文件定义)。
- 实操关联:
- 常用动作服务器:
move_base(导航核心); - 查看动作:
rostopic list | grep action(动作底层基于话题实现); - 核心类:
actionlib.SimpleActionClient(客户端)、actionlib.SimpleActionServer(服务端)。
- 常用动作服务器:
8. 参数服务器(Parameter Server)—— 机器人的 “公共配置表”
- 核心定义:
roscore内置的键值对存储系统,用于保存全局配置参数(所有节点都能读写)。 - 生活化比喻:像公司的 “公共公告板”,比如 “机器人最大速度 = 0.5m/s”“激光雷达校准值 = 1.2”,所有员工都能看、能改。
- 核心特点:
- 全局共享:所有节点可读写同一参数;
- 数据类型:支持字符串、整数、浮点数、列表等;
- 临时存储:
roscore关闭后参数会丢失(可保存为.yaml文件持久化)。
- 实操关联:
- 设置参数:
rosparam set /参数名 值(如rosparam set /speed_limit 0.5); - 获取参数:
rosparam get /参数名; - 保存参数:
rosparam dump 文件名.yaml; - 加载参数:
rosparam load 文件名.yaml。
- 设置参数:
9. 启动文件(Launch)—— 机器人的 “一键启动脚本”
- 核心定义:XML 格式的配置文件,可一键启动多个节点、设置参数、配置命名空间,解决复杂应用需手动启动多个节点的问题。
- 生活化比喻:像公司的 “早会流程表”,一键启动 “激光雷达员、定位员、路径规划员”,并设置好每个人的 “初始配置”(参数)。
- 核心功能:
- 自动启动
roscore; - 同时启动多个节点;
- 设置节点参数、命名空间;
- 启动可视化工具(如 Rviz、Gazebo)。
- 自动启动
- 实操关联:
- 启动命令:
roslaunch 功能包名 启动文件名.launch; -
<launch> <node name="talker" pkg="my_pkg" type="talker.py" output="screen"/> <param name="/speed_limit" value="0.5" type="double"/> </launch>
- 启动命令:
10. 命名空间(Namespace)—— 机器人的 “部门隔离”
- 核心定义:给节点 / 话题 / 服务加 “前缀”,实现同名资源的隔离(如多个机器人同时运行时,避免话题冲突)。
- 生活化比喻:像公司的 “分公司前缀”,比如 “北京分公司 - 激光雷达频道”“上海分公司 - 激光雷达频道”,同名频道但属于不同分公司,互不干扰。
- 实操关联:
- 在 launch 文件中设置:
<node name="talker" pkg="my_pkg" type="talker.py" ns="/beijing"/>; - 最终话题名:
/beijing/chatter(而非/chatter)。
- 在 launch 文件中设置:
补充:
1、Ros简介
ROS(Robot Operating System)不是传统意义上的操作系统(如 Windows、Linux),而是一套为机器人开发设计的开源软件框架 / 中间件,核心目标是 “降低机器人开发的复杂度”。
SLAM(同步定位与地图构建)是 “让机器人在未知环境中,一边确定自己的位置,一边构建环境地图” 的核心算法,而 ROS 是实现 SLAM 的最佳载体,二者是 “框架” 与 “算法” 的紧密结合关系。
2、Ros生命周期
- ROS 整体生命周期以
roscore为核心:roscore启动则网络活,roscore关闭则网络死,是跨脚本 / 跨设备共享的全局生命周期; - 单个节点的生命周期:
init_node注册 → 运行 → shutdown 注销,独立于其他节点,但依赖roscore存活; - 单个节点按 Ctrl+C 只会终止该节点自身,ROS 核心(roscore)和其他节点不受影响;
- 被终止的节点会向 roscore 注销,其对应的话题 / 服务会停止,但 roscore 的核心功能仍正常;
- 只有直接终止 roscore 进程,才会导致整个 ROS 网络终止,所有节点被迫退出。
3、ROS 应用完整运行流程
步骤 1:启动 ROS 核心(roscore)—— 必选第一步
ROS 核心是所有节点的 “通信中转站”,没有它,节点无法互相通信。
- 操作:打开终端,执行命令:
roscore - 核心作用:
- 初始化参数服务器(存储全局配置);
- 建立节点注册表(管理所有节点);
- 搭建话题 / 服务的消息路由通道。
- 运行成功标志:终端输出
started core service [/rosout],且无报错。
步骤 2:运行单个节点(基础方式)
适用于简单应用(如单个发布者 / 订阅者),用 rosrun 启动节点。
- 操作:新开终端(保留
roscore终端),执行命令:# 格式:rosrun 功能包名 节点脚本名 rosrun my_ros_pkg talker.py - 关键逻辑:
rosrun会自动定位功能包路径,加载 ROS 环境;- 脚本执行
rospy.init_node()向roscore注册节点; - 节点进入运行状态,开始发布 / 订阅话题、提供 / 调用服务。
步骤 3:运行多个节点(高效方式:launch 文件)
复杂应用(如 SLAM、导航)需要同时启动多个节点(传感器驱动、SLAM 算法、可视化),手动逐个启动效率低,用 launch 文件一键启动。
- 创建 launch 文件:在功能包的
launch/目录下新建my_app.launch,内容示例:xml
<launch> <!-- 启动发布者节点 --> <node name="talker_node" pkg="my_ros_pkg" type="talker.py" output="screen"/> <!-- 启动订阅者节点 --> <node name="listener_node" pkg="my_ros_pkg" type="listener.py" output="screen"/> <!-- 启动可视化工具Rviz --> <node name="rviz_node" pkg="rviz" type="rviz" output="screen"/> </launch> - 运行 launch 文件:新开终端,执行命令:
# 格式:roslaunch 功能包名 launch文件名 roslaunch my_ros_pkg my_app.launch
- 核心优势:
- 自动检查并启动
roscore(无需手动先启动); - 一键启动多个节点,按配置顺序加载;
- 可设置节点参数、命名空间、输出日志等。
- 自动检查并启动
步骤 4:调试与监控(运行中)
运行过程中需查看节点状态、话题数据,常用调试命令:
| 命令 | 作用 |
|---|---|
rosnode list |
查看当前运行的所有节点 |
rosnode info /节点名 |
查看单个节点的详细信息(发布 / 订阅的话题) |
rostopic list |
查看所有活跃话题 |
rostopic echo /话题名 |
实时打印话题的消息内容 |
rviz |
启动可视化工具,查看机器人 / 地图 / 传感器数据 |
rqt_graph |
可视化节点与话题的通信关系(直观看到数据流向) |
步骤 5:终止应用(按需)
- 终止单个节点:在运行节点的终端按
Ctrl+C,节点会向roscore注销,正常退出; - 终止所有节点(launch 启动):在运行
roslaunch的终端按Ctrl+C,所有通过该 launch 文件启动的节点都会终止; - 终止整个 ROS 应用:关闭
roscore终端(或按Ctrl+C),所有节点会因失去通信核心而强制退出; - 强制终止(异常情况):若节点卡死,用命令杀死进程:
# 杀死指定节点进程 rosnode kill /节点名 # 杀死所有ROS节点 killall -9 rosout rosmaster rosmaster
4、init_node() 的核心作用(4 个关键)
1. 向 ROS 核心(roscore)“注册节点”
这是最核心的作用。roscore 作为 ROS 网络的 “总控中心”,需要知道所有节点的存在才能管理通信。
- 执行
init_node('节点名')时,脚本会向roscore发送 “注册请求”,上报自己的节点名、运行地址、通信端口等信息; roscore会把这个节点加入 “全局节点注册表”,后续其他节点才能找到它(比如向它发布 / 订阅话题);- 如果注册失败(比如节点名重复),
init_node()会直接抛错,脚本无法继续运行。
2. 初始化节点的通信链路
ROS 节点间的所有通信(话题、服务、参数)都需要基于特定的网络链路,init_node() 会完成:
- 建立节点与
roscore之间的 TCP/UDP 连接; - 初始化话题 / 服务的消息收发队列;
- 加载 ROS 环境变量(如命名空间、通信协议),保证消息格式统一。简单说:这一步是给节点 “打通网络”,没有它,后续
Publisher/Subscriber都会失效。
3. 初始化节点的基础运行环境
- 设定节点的日志输出规则(比如日志级别、输出位置),你用的
rospy.loginfo()能正常打印,就是靠这一步初始化; - 绑定节点的 shutdown 信号(比如 Ctrl+C 终止时的清理逻辑);
- 初始化时间 / 定时器模块(
rospy.get_time()、rospy.Rate()等功能依赖)。
4. 可选:通过参数控制节点唯一性(anonymous=True)
如之前聊到的,init_node('节点名', anonymous=True) 会自动给节点名加随机后缀,避免同一时间同名节点注册冲突,本质也是在注册阶段完成的。
5、为什么用 anonymous(匿名)这个单词表示 “保证节点名唯一”?
首先明确:ROS 里 anonymous=True 的命名确实有点 “反直觉”,但本质是从 “节点名不可预测” 的角度体现 “匿名” 的含义,而非 “完全隐藏节点名”。
拆解逻辑:
- 字面含义 vs 实际作用:
anonymous本意是 “匿名的、无名的”,但 ROS 并没有让节点 “无名”,而是让节点名变成 “不可预测的唯一名称”—— 你只指定了基础名(比如string_subscriber),但最终的节点名是系统自动加随机后缀的(比如string_subscriber_1689001234),相当于 “你不知道它最终叫什么名字”,这就是 ROS 设计时用anonymous这个词的原因。
- 类比理解:就像你去咖啡店点单,说 “我要一杯拿铁,不用写我的名字,随便标个号就行”—— 店员会给你的杯子贴一个随机号码(比如 88 号),你不是 “无名”,而是用一个 “随机、不可预测的标识” 代替了你的真实名字,这在 ROS 设计语境里就被称作 “anonymous(匿名化)”。
- 补充:如果严格按 “匿名” 的本意,ROS 其实没有 “完全匿名的节点”,所有节点都必须有唯一名称才能被
roscore管理,anonymous=True只是 “伪匿名”—— 通过随机后缀让节点名不可预测,从而保证唯一。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)