在编写第一个ROS节点程序之前需要创建工作空间(workspace)和功能包(package)。

一、创建工作空间(workspace)

创建一个catkin_ws:

#注意:如果使用sudo一次性创建多个目录,则这多个目录属主都为root,若是非root用户创建的ROS,则无法在root目录创建工作空间
sudo mkdir -p ~/dev/catkin_ws/src
cd ~/dev/catkin_ws/src
catkin_init_workspace

当我们创建工作空间文件夹后,里面并没有功能包,只有CMakeList.txt。下一步是编译工作空间,使用下面命令:

cd ~/dev/catkin_ws
catkin_make

现在,如果你输入ls -l命令,可以看到上面命令创建的新文件夹,分别是“build”和一个“devel”文件夹:

zlkj@ubuntu:~/dev/catkin_ws$ ls -l
total 12
drwxrwxr-x 7 zlkj zlkj 4096 Mar 19 12:10 build
drwxrwxr-x 3 zlkj zlkj 4096 Mar 19 12:10 devel
drwxrwxr-x 2 zlkj zlkj 4096 Mar 19 11:23 src zlkj@ubuntu:~/dev/catkin_ws/build$ ls -l
total 64
drwxrwxr-x 3 zlkj zlkj 4096 Mar 19 12:10 catkin
drwxrwxr-x 4 zlkj zlkj 4096 Mar 19 12:10 catkin_generated
-rw-rw-r-- 1 zlkj zlkj 0 Mar 19 12:10 CATKIN_IGNORE
-rw-rw-r-- 1 zlkj zlkj 125 Mar 19 12:10 catkin_make.cache
-rw-rw-r-- 1 zlkj zlkj 16071 Mar 19 12:10 CMakeCache.txt
drwxrwxr-x 9 zlkj zlkj 4096 Mar 19 12:10 CMakeFiles
-rw-rw-r-- 1 zlkj zlkj 7365 Mar 19 12:10 cmake_install.cmake
-rw-rw-r-- 1 zlkj zlkj 284 Mar 19 12:10 CTestTestfile.cmake
drwxrwxr-x 3 zlkj zlkj 4096 Mar 19 12:10 gtest
-rw-rw-r-- 1 zlkj zlkj 8578 Mar 19 12:10 Makefile
drwxrwxr-x 2 zlkj zlkj 4096 Mar 19 12:10 test_results zlkj@ubuntu:~/dev/catkin_ws/devel$ ls -l
total 36
-rwxr-xr-x 1 zlkj zlkj 506 Mar 19 12:10 env.sh
drwxrwxr-x 2 zlkj zlkj 4096 Mar 19 12:10 lib
-rw-r--r-- 1 zlkj zlkj 260 Mar 19 12:10 setup.bash
-rw-r--r-- 1 zlkj zlkj 2542 Mar 19 12:10 setup.sh
-rwxr-xr-x 1 zlkj zlkj 12378 Mar 19 12:10 _setup_util.py
-rw-r--r-- 1 zlkj zlkj 270 Mar 19 12:10 setup.zsh

可以看到在devel目录下,有很多setup.*sh文件,读取这些文件中的任何一个都会将当前工作空间的环境变量置于所有环境变量的最上层。如果我们打开这些文件会发现,最终都是要读取setup.bash文件,这个文件中定义了catkin_ws空间所需要的环境变量。

读取setup.bash文件:

source devel/setup.bash

确认已经加载好catkin工作空间环境变量:

echo $ROS_PACKAGE_PATH

//显示出:
/home/zlkj/catkin_ws/src:/opt/ros/indigo/share:/opt/ros/indigo/stacks

这时ROS的工作空间已经创建好了。

总结:

初始化ROS的catkin工作空间:catkin_init_workspace

编译ROS的catkin工作空间:catkin_make

读取当前catkin工作空间的环境变量:source devel/setup.bash

验证ROS工作空间的环境变量加载成功:echo $ROS_PACKAGE_PATH

二、创建功能包(package)

使用catkin_create_pkg命令行工具在之前创建的工作空间创建新的功能包:

cd ~/dev/catkin_ws/src
catkin_create_pkg amin std_msgs roscpp

其实,这个功能包创建命令没有做太多工作,它只不过创建了一个存放这个功能包的目录(也就是我所创建的功能包amin),并在amin那个目录下生成了两个配置文件。

  • 第一个配置文件,叫做 package.xml,称为清单文件。
  • 第二个文件,叫做 CMakeLists.txt,是一个 Cmake 的脚本文件,Cmake 是一个符合工业标准的跨平台编译系统。这个文件包含了一系列的编译指令,包括应该生成哪种可执行文件,需要哪些源文件,以及在哪里可以找到所需的头文件和链接库。当然,这个文件表明 catkin 在内部使用了 Cmake。

catkin_create_pkg命令的格式包括功能包的名称和依赖项。在上面示例中,依赖项为std_msgs和roscpp。如以下命令行所示:

catkin_create_pkg [package_name] [depend1] [depend2] [depend3]

这些依赖项包括:

  • std_msgs 包含了常见消息类型,表示基本数据类型和其他基本的消息构造,如多维数组。
  • roscpp 使用C++实现ROS的各种功能。它提供了一个客户端库,让C++程序员能够调用这些接口快速完成与ROS的主题、服务和参数相关的开发工作。

注意:ROS 功能包的命名遵循一个命名规范,只允许使用小写字母、数字和下划线,而且首字符必须是一个小写字母。一些 ROS工具,包括 catkin,不支持那些不遵循此命名规范的功能包。

三、编写ROS节点程序

编写一个简单的ros节点程序,命名为hello.cpp。这个名为 hello.cpp 的源文件也存放在你的功能包 amin文件夹中 , 挨着 package.xml 和 CMakeLists.txt。

注意:一些在线教程建议在你的功能包目录中创建 src 目录来存放 C ++源文件。这个附加的组织结构可能是有益的,特别是对于那些含有多种类型文件的较大的功能包,但它不是严格必要的。

ROS节点程序如下:

#include <ros/ros.h>

int main (int argc, char **argv)
{
ros::init(argc, argv, "hello") ;
ros::NodeHandle nh;
ROS_INFO_STREAM("Hello, ROS!") ;
}

四、编译Hello.cpp程序

我们该如何编译和运行这个程序呢?这些交给ROS的catkin编译系统来处理。

第一步:声明依赖库

首先,我们需要声明程序所依赖的其他功能包。对于 c++程序而言,此步骤是必要的,以确保 catkin 能够向 c++编译器提供合适的标记来定位编译功能包所需的头文件和链接库。

为了给出依赖库,需要编辑功能目录下的 CMakeLists.txt 与 package.xml 文件,通过使用build_depend (编译依赖)和 run_depend(运行依赖)两个关键字实现,格式如下:

<build_depend>package-name</build_depend>
<run_depend>package-name</run_depend>

不过这一步可以省略,因为在创建功能包说明依赖项的同时,系统自动声明了依赖库,除非创建时未说明依赖项。

使用rospack depend1 amin可以查看直接功能包的直接依赖。在很多情况下,我们会遇到依赖的依赖,即间接依赖。例如amin的依赖文件roscpp也有其他依赖。如果我们使用rospack depends amin,则会列出amin功能包的所有依赖文件。

第二步:声明可执行文件

接下来,我们需要在 CMakeLists.txt 中添加两行,来声明我们需要创建的可执行文件。其一般形式是:

add_executable(executable-name source-files)
target_link_libraries(executable-name ${catkin_LIBRARIES})
  • 第一行声明了我们想要的可执行文件的文件名,以及生成此可执行文件所需的源文件列表。如果你有多个源文件,把它们列在此处,并用空格将其区分开。
  • 第二行告诉 Cmake 当链接此可执行文件时需要链接哪些库(在上面的 find_package 中定义)。如果你的包中包括多个可执行文件,为每一个可执行文件复制和修改上述两行代码。

在本例程中,我们需要一个名为 hello 的可执行文件,它通过名为 hello.cpp 的源文件编译而来。所以我们需要添加如下两行代码到 CMakeLists.txt 文件中 include_directories(include ${catkin_INCLUDE_DIRS}) 之后:

add_executable(hello hello.cpp)
target_link_libraries(hello ${catkin_LIBRARIES})

第三步:编译工作区

利用catkin_make这个命令进行编译,注意必须在你的工作空间目录运行。

cd ~/dev/catkin_ws
catkin_make

运行完后会在 ~/dev/catkin_ws/devel/amin 目录下生产 hello 这个可执行文件。下图为运行的结果。

五、执行hello程序

首先要启动 roscore:这个程序是一个节点,节点需要一个节点管理器才可以正常运行。启动节点管理器的命令:

roscore

启动完节点管理器后,执行名为 setup.bash 的脚本文件,它是 catkin_make 在你工作区的 devel 子目录下生成的。这个自动生成的脚本文件设置了若干环境变量,从而使 ROS 能够找到你创建的功能包和新生成的可执行文件。(也就是将程序注册)

source devel/setup.bash

最后一步,运行节点,用命令:使用格式为"rosrun package-name executable-name" ,package-name 为功能包名称, executable-name为可执行文件名称。

rosrun amin hello

运行结果如图:

这样一个简单的ROS程序就完成了。

ROS学习笔记三:编写第一个ROS节点程序的更多相关文章

  1. Android:日常学习笔记(2)——分析第一个Android应用程序

    Android:日常学习笔记(2)——分析第一个Android应用程序 Android项目结构 整体目录结构分析 说明: 除了APP目录外,其他目录都是自动生成的.APP目录的下的内容才是我们的工作重 ...

  2. ROS学习笔记三(理解ROS节点)

    要求已经在Linux系统中安装一个学习用的ros软件包例子: sudo apt-get install ros-indigo-ros-tutorials ROS图形概念概述 nodes:节点,一个节点 ...

  3. Apache Ignite 学习笔记(三): Ignite Server和Client节点介绍

    在前两篇文章中,我们把Ignite集群当做一个黑盒子,用二进制包自带的脚本启动Ignite节点后,我们用不同的客户端连接上Ignite进行操作,展示了Ignite作为一个分布式内存缓存,内存数据库的基 ...

  4. ROS学习笔记(三)

    机器人建模与仿真URDF(Unified Robot Descrption Format,统一机器人描述格式),ROS提供了URDF的c++解析器.安装语法检查工具sudo apt-get insta ...

  5. Ajax学习笔记1之第一个Ajax应用程序

    代码 <head> <title>An Ajax demo</title> <script src="../js/jquery-1.4.1.js&q ...

  6. ROS学习手记 - 8 编写ROS的Publisher and Subscriber

    上一节我们完成了 message & srv 文件的创建和加入编译,这次我们要玩简单的Publisher 和 Subscriber 要玩 Publisher 和 Subscriber, 需要具 ...

  7. Learning ROS for Robotics Programming Second Edition学习笔记(三) 补充 hector_slam

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  8. Learning ROS for Robotics Programming Second Edition学习笔记(三) indigo rplidar rviz slam

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  9. ROS学习笔记七:在ROS中使用USB摄像头

    下面是一些USB摄像头的驱动(大多数摄像头都支持uvc标准): 1 使用软件库里的uvc-camera功能包 1.1 检查摄像头 lsusb ----------------------------- ...

随机推荐

  1. NodeJS+MongoDB+AngularJS+Bootstrap书店示例

    目录 一.Bootstrap 1.1.添加引用 1.2.在页面中使用BootStrap 1.3.可视化布局 二.使用MongoDB创建数据库 2.1.启动MongoDB数据库 2.2.启动数据库GUI ...

  2. 【APUE】vim常用命令

    转自:http://coolshell.cn/articles/5426.html 基本命令: i → Insert 模式,按 ESC 回到 Normal 模式. x → 删当前光标所在的一个字符. ...

  3. html5摇一摇代码优化

    首先对DeviceMotionEvent进行优化: 去除没用的代码,又一次封装DeviceMotionEven if(window.DeviceMotionEvent) { var speed = 2 ...

  4. ScrollView阻尼效果

    activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...

  5. WEKA简单介绍与资源汇总

    简单介绍 Weka是一个开源的数据挖掘软件,里面集成了很多经典的机器学习算法,在高校和科研机构中受到了广泛的应用. 具体的简单介绍和简单的使用请參考文档:<使用Weka进行数据挖掘>. 学 ...

  6. Android NDK编程浅入深出之--Android.mk

        Android.mk Android.mk是一个向Android NDK构建系统描写叙述NDK项目的GUN Makefile片段.它是每个NDK项目的必备组件. 构建系统希望它出如今jni子文 ...

  7. NPOI解析Excel

    园子的文章: http://www.cnblogs.com/csqb-511612371/category/654604.html 关键就是如何解析Excel表头,特别是合并单元格的..还有对应NPO ...

  8. CXF Spring 使用

    <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...

  9. Android应用基础学习记录

    01_前言 前言,了解了Android的情况.这里也介绍一下本文.本文是记录学习Android应用程序开发过程,视频中使用的Android2.2版本号,我以4.2版本号为基础,找出当中的差异并记录下来 ...

  10. jackson实体为NULL或者为空不显示

    1.实体上 @JsonInclude(JsonInclude.Include.NON_NULL) 将该注解放在属性上,如果该属性为null则不参与序列化: 如果放在类上边,那对这个类的全部属性起作用 ...