本教程将带你从零开始,动手编写、编译并运行第一个 ROS 程序——经典的'Hello World',用两种主流语言(C++和 Python)分别实现。
一、ROS 开发:两种语言,一套流程
ROS 程序主要使用 C++ 和 Python 实现,两者在 ROS 中地位相当:
- C++:运行效率高,常用于对性能要求高的模块(如传感器处理、核心控制)。
- Python:开发效率高,语法简洁,常用于算法原型验证、工具脚本等。
无论使用哪种语言,编写一个 ROS 程序的核心流程都是固定的,就像一套标准化的'建房子'工序:
- 打地基 -> 创建工作空间(Workspace)并初始化
- 划区域 -> 创建功能包(Package)
- 砌砖块 -> 编写源代码(.cpp 或 .py)
- 画图纸 -> 配置编译规则(CMakeLists.txt 或 package.xml)
- 盖房子 -> 编译并运行
接下来,我们就严格按照这五步,完成我们的第一个 ROS 程序。本文将以 C++ 实现为例,详解每一步,并在最后对比给出 Python 的实现差异。
二、五步搭建:C++版'Hello ROS'
第 1 步:创建工作空间并初始化
工作空间(Workspace)是你存放所有 ROS 代码项目的'项目总文件夹'。 打开终端(Ctrl+Alt+T),执行以下命令创建并进入一个名为 demo01_ws 的工作空间:
mkdir -p ~/demo01_ws/src
cd ~/demo01_ws/
mkdir -p 命令会递归创建目录。src 目录是存放所有功能包源代码的必备子文件夹。
在工作空间根目录(demo01_ws/)下,使用 ROS 内置命令初始化工作空间:
catkin_make
这个命令会自动在 demo01_ws 下创建 build 和 devel 两个文件夹,并生成一系列配置文件。看到大量编译日志并以 100% 结束,即表示初始化成功。
此时你的工作空间结构如下:
demo01_ws/
├── build/ # 编译中间文件,无需关心
├── devel/ # 生成的目标文件和环境设置脚本
└── src/ # 【核心】你的所有功能包源码都放这里
第 2 步:创建功能包
功能包(Package)是 ROS 中软件组织的基本单元,可以理解为你的一个'具体项目'或'功能模块'。 进入 src 目录:
cd src
使用 catkin_create_pkg 命令创建功能包:
catkin_create_pkg helloworld roscpp rospy std_msgs
- helloworld:你的功能包名称。
- roscpp rospy std_msgs:此功能包所依赖的其他 ROS 包。
roscpp:C++ 客户端库,用 C++ 写 ROS 程序必须。rospy:Python 客户端库,用 Python 写 ROS 程序必须。std_msgs:标准消息库,定义了常见的数据类型(如 Int32,String)。
创建成功后,src 目录下会生成一个以你的功能包名命名的文件夹(helloworld/),里面包含了默认的文件结构。
第 3 步:编写 C++ 源代码
现在我们来创建并编写真正的'Hello World'程序。 进入功能包的 src 目录(注意:是功能包下的 src,不是工作空间的 src):
cd ~/demo01_ws/src/helloworld/src
创建并编辑 C++ 源文件,例如命名为 helloworld_c.cpp:
gedit helloworld_c.cpp &
将以下代码复制进去:
// 1. 包含 ROS 的头文件
#include "ros/ros.h"
// 2. 主函数
int main(int argc, char* argv[]) {
// 3. 初始化 ROS 节点,节点名称为 "hello_node"
// 节点名称在运行时必须是唯一的。
ros::init(argc, argv, "hello_node");
// 4. 在 ROS 中输出日志信息 "hello world!"
ROS_INFO("hello world!");
return 0;
}
#include "ros/ros.h":包含 ROS C++ API 的核心头文件,必不可少。ros::init(...):初始化 ROS 节点。可以理解为给你的程序在 ROS 网络中'上户口'。ROS_INFO(...):ROS 中打印信息级别日志的宏,相当于 C++ 的 cout 或 C 的 printf,但功能更强大。
第 4 步:配置编译规则(CMakeLists.txt)
ROS 使用 CMake 构建系统。我们需要告诉 CMake:编译哪个源文件?生成的可执行文件叫什么?需要链接哪些库? 打开功能包根目录下的 CMakeLists.txt 文件(与 src 文件夹同级):
gedit ~/demo01_ws/src/helloworld/CMakeLists.txt
找到文件中的 add_executable 和 target_link_libraries 部分(通常在文件后半部分),取消注释并修改:
修改一:定义可执行文件 找到类似下面的行:
#add_executable(${PROJECT_NAME}_node src/helloworld_node.cpp)
修改为(将 _node 前的部分替换为你的项目名,并指向你的源文件):
add_executable(haha src/helloworld_c.cpp)
- haha:这是你为生成的可执行文件起的名字,后续运行命令会用到。
src/helloworld_c.cpp:源文件的路径。
修改二:链接 ROS 库 找到紧接着的 target_link_libraries 行:
#target_link_libraries(${PROJECT_NAME}_node ${catkin_LIBRARIES})
修改为:
target_link_libraries(haha ${catkin_LIBRARIES})
这里的 haha 必须和上面 add_executable 里定义的名字完全一致。
第 5 步:编译与执行
房子盖好了,让我们启动它!
编译: 回到工作空间根目录(~/demo01_ws/),执行编译:
cd ~/demo01_ws
catkin_make
看到 100% 的进度提示,即表示编译成功。
执行:
- 启动 ROS 核心(必须):新开一个终端(Ctrl+Alt+T),运行:
这是 ROS 的'总机',所有程序运行前都必须先启动它。roscore - 设置环境变量:回到你编译的终端(运行 catkin_make 的那个),或在新的终端中,先切换到工作空间根目录,然后执行:
这条命令的作用是将你刚刚编译生成的功能包路径添加到当前终端的 ROS 环境变量中,这样 ROS 才能找到你的 helloworld 包。注意:此设置只对当前终端有效。source devel/setup.bash - 运行你的程序:在同一个设置了环境变量的终端中,使用 rosrun 命令启动节点:
rosrun helloworld haha- helloworld:你的功能包名。
- haha:在 CMakeLists.txt 中 add_executable 定义的可执行文件名。
如果一切顺利,你将在这个终端中看到输出的 [ INFO] [时间戳]: hello world!。
三、触类旁通:Python 版'Hello ROS'
Python 版本的流程在第 1、2、5 步完全一致。差异仅在第 3、4 步,因为 Python 是解释型语言,无需编译。
第 3 步差异:编写 Python 源代码
在功能包下创建一个 scripts 文件夹(通常用于存放 Python 脚本):
mkdir -p ~/demo01_ws/src/helloworld/scripts
cd ~/demo01_ws/src/helloworld/scripts
创建并编辑 Python 文件,例如 helloworld_p.py:
gedit helloworld_p.py &
写入以下代码:
#!/usr/bin/env python3
# 1. 导入 rospy 模块
import rospy
# 2. 主程序入口
if __name__ == "__main__":
# 3. 初始化 ROS 节点,节点名称为 "hello_node_py"
rospy.init_node("hello_node_py")
# 4. 在 ROS 中输出日志信息 "hello world! (Python)"
rospy.loginfo("hello world! (Python)")
#!/usr/bin/env python3:指定解释器为 python3。import rospy:导入 ROS 的 Python 客户端库。rospy.init_node("hello_node_py"):初始化 ROS 节点。rospy.loginfo():等同于 C++ 的 ROS_INFO()。
重要:为 Python 脚本添加可执行权限:
chmod +x helloworld_p.py
输入 ll 查看是否有可执行权限。
第 4 步差异:配置安装规则(package.xml 和 CMakeLists.txt)
Python 脚本需要被'安装'到正确的位置(主要是 devel 或 install 目录下的 lib 中),ROS 才能找到它。通常有简单方法和标准方法。
推荐简单方法:修改 package.xml,确保 <exec_depend> 标签包含 rospy。然后,你可以直接通过完整路径运行,或者用下面的标准方法配置。
标准配置方法: 在 CMakeLists.txt 中,找到 catkin_install_python 部分,取消注释并修改:
catkin_install_python(PROGRAMS scripts/helloworld_p.py DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
第 5 步执行:Python 版
- 新开一个终端,确保 roscore 在运行。
- 再打开一个终端,进入工作空间,输入:
catkin_make - 设置环境变量(同 C++ 步骤):
source devel/setup.bash - 运行 Python 节点:
注意,这里直接写脚本名 helloworld_p.py。rosrun helloworld helloworld_p.py
四、常见问题
- rosrun 找不到包/节点:
- 确保在工作空间根目录执行了
source devel/setup.bash。 - 检查功能包名、可执行文件名(C++)或脚本名(Python)是否拼写正确。
- 确保在工作空间根目录执行了
- Python 脚本执行权限错误: 确保对 .py 文件执行了
chmod +x 脚本名.py。 - roscore 未运行: 任何 ROS 节点运行前都必须先启动 roscore。

