在编写第一个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. Python导入模块的几种姿势

    中文翻译:http://codingpy.com/article/python-import-101/ 英文原文:http://www.blog.pythonlibrary.org/2016/03/0 ...

  2. Linux下的lds链接脚本简介(一)

    转载自:http://linux.chinaunix.net/techdoc/beginner/2009/08/12/1129972.shtml 一. 概论 每一个链接过程都由链接脚本(linker ...

  3. 转: eclipse 快捷键列表(功能清晰版本)

    转自: http://www.uml.org.cn/mobiledev/201110092.asp Eclipse 在开发中使用到的快捷键很实用噢 Ctrl+1 快速修复(最经典的快捷键,就不用多说了 ...

  4. 用"再生龙"Clonezilla 来克隆Linux系统

      上周公司买了5套高配置PC机来做测试用.上面要装好CentOS 加上一堆工具,有web的,数据库的,还有一些自己开发的工具.有些朋友肯定想,直接用kickstart不就行了,确实.kickstar ...

  5. office outlook 無法開啟 outlook 視窗

    例如[無法啟動Microsoft Office Outlook.無法開啟Outlook 視窗.] 1.啟動 Outlook 安全模式outlook.exe /safe2.清除並重新產生目前設定檔的功能 ...

  6. Android拍照、摄像方向旋转的问题 代码具体解释

    近期做了个拍照.摄像的应用.遇到了拍照.摄像的图像相对于现实.翻转了90度.原因:相机这个硬件的角度是横屏的角度,所以会出现都是横屏的. 1.照相.摄影预览图像的正确角度显 示: public sta ...

  7. Please enter a commit message to explain why this merge is necessary.

    Please enter a commit message to explain why this merge is necessary. 请输入提交消息来解释为什么这种合并是必要的 git 在pul ...

  8. 简单JS全选、反选代码

    1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org ...

  9. c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程

    c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...

  10. 2 AngularJS 1 概念浓缩

    Angular Web APP 结构图: module   --> 模块     :相当于一个容器,Angular里的所有东西都得放在模块里,才能够被引用和加载. directive  --&g ...