ROS学习笔记三:编写第一个ROS节点程序
在编写第一个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节点程序的更多相关文章
- Android:日常学习笔记(2)——分析第一个Android应用程序
Android:日常学习笔记(2)——分析第一个Android应用程序 Android项目结构 整体目录结构分析 说明: 除了APP目录外,其他目录都是自动生成的.APP目录的下的内容才是我们的工作重 ...
- ROS学习笔记三(理解ROS节点)
要求已经在Linux系统中安装一个学习用的ros软件包例子: sudo apt-get install ros-indigo-ros-tutorials ROS图形概念概述 nodes:节点,一个节点 ...
- Apache Ignite 学习笔记(三): Ignite Server和Client节点介绍
在前两篇文章中,我们把Ignite集群当做一个黑盒子,用二进制包自带的脚本启动Ignite节点后,我们用不同的客户端连接上Ignite进行操作,展示了Ignite作为一个分布式内存缓存,内存数据库的基 ...
- ROS学习笔记(三)
机器人建模与仿真URDF(Unified Robot Descrption Format,统一机器人描述格式),ROS提供了URDF的c++解析器.安装语法检查工具sudo apt-get insta ...
- Ajax学习笔记1之第一个Ajax应用程序
代码 <head> <title>An Ajax demo</title> <script src="../js/jquery-1.4.1.js&q ...
- ROS学习手记 - 8 编写ROS的Publisher and Subscriber
上一节我们完成了 message & srv 文件的创建和加入编译,这次我们要玩简单的Publisher 和 Subscriber 要玩 Publisher 和 Subscriber, 需要具 ...
- Learning ROS for Robotics Programming Second Edition学习笔记(三) 补充 hector_slam
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...
- Learning ROS for Robotics Programming Second Edition学习笔记(三) indigo rplidar rviz slam
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...
- ROS学习笔记七:在ROS中使用USB摄像头
下面是一些USB摄像头的驱动(大多数摄像头都支持uvc标准): 1 使用软件库里的uvc-camera功能包 1.1 检查摄像头 lsusb ----------------------------- ...
随机推荐
- OpenGL蓝宝书第七章:立体天空和纹理折射、双纹理(下)
对照了蓝宝书,才知道红宝书的长处. reflect函数的原理在红宝书中有说明,仅仅有对照了红宝书,才知道红宝书的定位:高级工具书. 蓝宝书作为入门级书籍,以较快的速度让读者敲到代码去思考,总遗留了须要 ...
- react-container-query
1.媒体查询 响应式组件 2.使用方法 (1)引入 import { ContainerQuery } from 'react-container-query'; (2)规定屏幕尺寸 /** * 媒体 ...
- hdu 1879 继续畅通project
本题链接:pid=1879http://">点击打开链接 本题大意: 输入n行数据.每行数据前两个表示该条路连通的两个村庄的编号,第三个表示修该条路的成本.最后的0或1表示该路未修或已 ...
- 一个bug在redmine中的诞生到终结
1.測试员測试出bug,跟踪状态为支持,状态为新建,指派给产品经理. 2.产品经理鉴定确觉得bug.改动跟踪状态为bug.指派给技术经理: 3.技术经理收到bug,指派给开发者: 4.开发者收到bug ...
- [办公自动化]chrome浏览器的书签在哪里存放
最近换电脑了. 硬盘直接挂在了新电脑上.忘记导出Chrome的浏览器的书签了. 对于书签,Windows XP和Windows 7的路径都是: C:\Documents and Settings\** ...
- PyTorch 60 分钟入门教程:PyTorch 深度学习官方入门中文教程
什么是 PyTorch? PyTorch 是一个基于 Python 的科学计算包,主要定位两类人群: NumPy 的替代品,可以利用 GPU 的性能进行计算. 深度学习研究平台拥有足够的灵活性和速度 ...
- slf4j的总结
参考文章 log4j2使用总结 slf4j介绍以及实现原理窥探 使用Slf4j集成Log4j2构建项目日志系统的完美解决方案 slf4j(全称是Simple Loging Facade For Jav ...
- C# 敏感词过滤
public class BadWordFilter { #region 变量 private HashSet<string> hash = new HashSet<string&g ...
- is id() == 从内存的最小化占用角度解释 我是孕育者,我也应该这样设计 变,必然伴随着加法 一个list是否可以执行set()
def f(a, b): print(a is b, b is a, a == b, a.__eq__(b), id(a), id(b)) f(2, 2) f([2], [2]) f('2', '2' ...
- android编程取消标题栏方法(appcompat_v7、Theme.NoTitleBar)
方式一:编码方式 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstance ...