ROS入门笔记(九):编写ROS的第一个程序hello world(重点)
ROS入门笔记(九):编写ROS的第一个程序hello world(重点)
1 Catkin工作空间
-
工作空间(workspace)是一个存放工程开发相关文件的文件夹。
src:代码空间(Source Space) build:编译空间(Build Space) devel:开发空间(Development Space) install:安装空间(Install Space)
-
Catkin工作空间是创建、修改、编译catkin软件包的目录。catkin的工作空间,直观的形容就是一个仓库,里面装载着ROS的各种项目工程,便于系统组织管理调用。在可视化图形界面里是一个文件夹。
-
我们自己写的ROS代码通常就放在工作空间中,本节就来介绍catkin工作空间的结构。
1.1 创建catkin工作空间
创建一个 catkin 工作空间:
$ mkdir -p ~/catkin_ws/src # 创建了第二层级的文件夹src,这是放ROS软件包的地方
$ cd ~/catkin_ws/src # 进入工作空间,catkin_make必须在工作空间这个路径上执行
$ catkin_init_workspace # 初始化src目录,生成的CMakeLists.txt为功能包编译配置
1.2 编译工作空间
$ cd ~/catkin_ws # 回到工作空间,catkin_make必须在工作空间下执行;
$ catkin_make # 开始编译,调用系统自动完成编译和链接过程,构建生成目标文件
注意: catkin编译之前需要回到工作空间目录,catkin_make
在其他路径下编译不会成功。
编译完成后,如果有新的目标文件产生(原来没有),那么一般紧跟着要source刷新环境,使得系统能够找到刚才编译生成的ROS可执行文件。这个细节比较容易遗漏,致使后面出现可执行文件无法打开等错误。
catkin_make
命令也有一些可选参数,例如:
catkin_make [args]
-h, --help 帮助信息
-C DIRECTORY, --directory DIRECTORY
工作空间的路径 (默认为 '.')
--source SOURCE src的路径 (默认为'workspace_base/src')
--build BUILD build的路径 (默认为'workspace_base/build')
--use-ninja 用ninja取代make
--use-nmake 用nmake取'make
--force-cmake 强制cmake,即使已经cmake过
--no-color 禁止彩色输出(只对catkin_make和CMake生效)
--pkg PKG [PKG ...] 只对某个PKG进行make
--only-pkg-with-deps ONLY_PKG_WITH_DEPS [ONLY_PKG_WITH_DEPS ...]
将指定的package列入白名单CATKIN_WHITELIST_PACKAGES,
之编译白名单里的package。该环境变量存在于CMakeCache.txt。
--cmake-args [CMAKE_ARGS [CMAKE_ARGS ...]]
传给CMake的参数
--make-args [MAKE_ARGS [MAKE_ARGS ...]]
传给Make的参数
--override-build-tool-check
用来覆盖由于不同编译工具产生的错误
注意, 对于 Python 3 用户,在一个空的 catkin 工作空间中第一次运行 catkin_make的命令应为:
$ catkin_make -DPYTHON_EXECUTABLE=/usr/bin/python3
这将会配置 catkin_make 使用 Python 3.你可以在随后的构建中只使用 catkin_make
。
1.3 设置环境变量
另外,如果你查看一下当前目录应该能看到 'build' 和 'devel' 这两个文件夹。在 'devel' 文件夹里面你可以看到几个 setup.*sh
文件。source
这些文件中的任何一个都可以将当前工作空间设置在ROS工作环境的最顶层。接下来首先 source
一下新生成的 setup.*sh
文件:
$ source devel/setup.bash # 刷新坏境
1.4 检查环境变量
要想保证工作空间已配置正确,需确保ROS_PACKAGE_PATH
环境变量包含你的工作空间目录,采用以下命令查看:
$ echo $ROS_PACKAGE_PATH
# 出现 /home/<youruser>/catkin_ws/src:/opt/ros/kinetic/share
到此你的工作环境已经搭建完成。
创建好了一个ROS的工作空间了,接下来就是在catkin_ws工作空间下的src目录下新建功能包并进行功能包程序。
2 创建功能包
同一个工作空间下,不允许存在同名功能包不同工作空间下,允许存在同名功能包
$ catkin_create_pkg <package_name>[depend1] [depend2] [depend3] # 创建功能包,和依赖项
#在catkin_ws/src/下创建取名为hello_world的功能包
# ROS功能包命名规范:只允许使用小写字母、数字和下划线,
# 且首字符必须为一个小写字母。
$ cd ~/catkin_ws/src
$ catkin_create_pkg hello_world
3 编写功能包的源代码
以c++代码作为示范,一些在线教程建议在你的功能包目录中创建src目录用来存放c++源文件,这个附加的组织结构是很有益处的,特别是对含有很多种类型文件的大型功能包,不过不是严格必要的。出于编程规范,我建议把c++源文件放在功能包中的src目录下。
第一步,在hello_world目录下新建src目录;
第二步,再在新建的src目录下新建一个my_hello_world_node.cpp文件;
第三步,文本编辑器gedit打开my_hello_world_node.cpp文件,并输入如下内容;
//包含头文件ros/ros.h,ROS提供的C++客户端库,在后面的编译配置中要添加相应的依赖库roscpp
#include "ros/ros.h"
int main(int argc,char **argv)
{
ros::init(argc,argv,"hello_node"); //初始化ros节点;并指明节点的名称为 hello_node
ros::NodeHandle n; //声明一个ros节点的句柄;
//调用了roscpp库提供的方法ROS_INFO_STREAM来打印信息。这里打印字符串"hello world!"。
ROS_INFO_STREAM("hello world!");
}
4 功能包的编译配置
4.1 在package.xml中添加功能包依赖
在package.xml中添加roscpp依赖库;
用文本编辑器gedit打开功能包目录下的package.xml文件,找到这样一句话<buildtool_depend>catkin</buildtool_depend>,在这句话的下面添加如下内容:
<build_depend>roscpp</build_depend>
<build_export_depend>roscpp</build_export_depend>
<exec_depend>roscpp</exec_depend>
4.2 在CMakeLists.txt添加编译选项
4.2.1 声明依赖库
对于我们的my_hello_world_node.cpp程序来说,我们包含了<ros/ros.h>这个库,因此我们需要添加名为roscpp的依赖库。
第一步,在CMakeLists.txt中添加roscpp依赖库;
用文本编辑器gedit打开功能包目录下的CMakeLists.txt文件,在find_package(catkin REQUIRED ...)字段中添加roscpp,添加后的字段如下:
find_package(catkin REQUIRED COMPONENTS roscpp)
第二步,在CMakeLists.txt中找到include_directories(...)字段,去掉${catkin_INCLUDE_DIRS}前面的注释,如下:
include_directories(
# include
${catkin_INCLUDE_DIRS}
)
4.2.2 声明可执行文件
在CMakeLists.txt中添加两句,来声明我们需要创建的可执行文件;一般在文件最后一行添加。
add_executable(my_hello_world_node src/my_hello_world_node.cpp)
target_link_libraries(my_hello_world_node ${catkin_LIBRARIES})
第一行声明了我们想要的可执行文件的文件名,以及生成此可执行文件所需的源文件列表。如果你有多个源文件,把它们列在此处,并用空格将其区分开。
第二行告诉 Cmake 当链接此可执行文件时需要链接哪些库(在上面的 find_package 中定义)。如果你的包中包含多个可执行文件,为每一个可执行文件复制和修改上述两行代码。
5 编译功能包
两种编译方式,一种是编译工作空间内的所有功能包,另一种是编译工作空间内的指定功能包;
5.1 方法一
编译工作空间内的所有功能包:
$ cd ~/catkin_ws # 回到工作空间,catkin_make必须在工作空间下执行;
$ catkin_make # 开始编译,调用系统自动完成编译和链接过程,构建生成目标文件
$ source ~/catkin_ws/devel/setup.bash # 刷新环境
编译完成后,如果有新的目标文件产生(原来没有),那么一般紧跟着要source刷新环境,使得系统能够找到刚才编译生成的ROS可执行文件。
5.2 方法二
编译工作空间内的指定功能包:
其实就是加入参数 -DCATKIN_WHITELIST_PACKAGES=” ”
,在双引号中填入需要编译的功能包名字,用空格分割。
$ cd ~/catkin_ws
$ catkin_make -DCATKIN_WHITELIST_PACKAGES="hello_world"
$ source ~/catkin_ws/devel/setup.bash # 激活catkin_ws工作空间
6 启动功能包
第一步,打开命令行终端,输入命令:
用roscore命令来启动ROS节点管理器,ROS节点管理器是所有节点运行的基础。
$ roscore # 启动ROS节点管理器
第二步,再打开一个命令行终端,输入如下命令:
用rosrun <package_name> <node_name>
启动功能包中的节点;
$ source ~/catkin_ws/devel/setup.bash # 激活catkin_ws工作空间
$ rosrun hello_world my_hello_world_node # 启动功能包中的节点
第三步,看到输出hello world!,说明程序已经正常执行了,按照我们的设计程序正常打印后会自动结束。