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!,说明程序已经正常执行了,按照我们的设计程序正常打印后会自动结束。

posted @ 2020-07-03 19:54  喵哥解说  阅读(2333)  评论(0编辑  收藏  举报