我的ROS学习笔记(三)


前言

成功编写第一个程序无疑是一个学习者最激动的时刻。接下来会以最简单的Hello ROS!程序为例,详细地讲解一下如何编译ROS程序。

一、创建工作区和功能包

1.创建工作区

我们所创建的包,应该全部放到一个叫做工作区的目录中 。可以用任何你喜欢的名字命名你的工作区,并且把目录存储在你账号中的任何位置。

1.使用标准的mkdir命令行去创建一个目录,我们将把这个新的目录称作你的工作区目录。
2.在工作区目录中创建一个叫做 src 的子目录,这个子目录将用于存放功能包的源代码

2.创建功能包

创建一个新ROS功能包的命令应该在你工作区中的src目录下运行,

catkin_create_pkg package-name

OK了

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

二、编写程序

1.编写C++程序

在你的功能包目录中创建 src 目录来存放 C ++源文件, hello.cpp 的源文件也存放在 功能包的src下(别弄混了src)

代码如下(示例):

// This is a ROS version of the standard "hello , world"
2 // program.
3
4 // This header defines the standard ROS classes .
5 #include <ros / ros.h>
6
7 int main ( int argc , char ** argv ) {
8 // Initialize the ROS system .
9 ros::init ( argc , argv , " hello _ros " ) ;
10
11 // Establ ish this program as a ROS node .
12 ros::NodeHandle nh ;
13
14 // Send some output as a log message .
15 ROS_INFO_STREAM( " Hello , ␣ ROS! " ) ;
16 }

ros::init函数初始化ROS客户端库。在你程序的起始处调用一次该函数 。函数最后的参数是一个包含节点默认名的字符串。(这个默认名可以通过启动文件或者通过rosrun 命令行参数覆盖。)

**ros::NodeHandle(节点句柄)**对象是你的程序用于和ROS系统交互的主要机制 。创建此对象会将你的程序注册为ROS节点管理器的节点。最简单的方法就是在整个程序中只创建一个NodeHandle对象。

(在内部,NodeHandle 类维护一个引用计数,仅仅在第一个NodeHandle 对象创建时才会在节点管理器注册新的节点。同样,只有当所有的 NodeHandle 对象都销毁后,节点才会
注销。这一细节有两个影响:首先,如果愿意,你可以为一个节点创建很多 NodeHandle 对象。这样做只有在一些特殊的应用中才有意义。其次,这意味着,在一个程序中使用标准的 roscpp 接口来运行多个节点是不可能的。)

ROS_INFO_STREAM 宏将生成一条消息,且这一消息被发送到不同的位置,包括控制台窗口。

2.编译 Hello 程序

(1)声明依赖库

声明依赖库
首先,我们需要声明程序所依赖的其他功能包。对于 c++程序而言,此步骤是必要的,以确保 catkin 能够向 c++编译器提供合适的标记来定位编译功能包所需的头文件和链接库。
为了给出依赖库,编辑包目录下的 CMakeLists.txt 文件。该文件的默认版本含有如下行:
find_package(catkin REQUIRED)
所依赖的其他 catkin 包可以添加到这一行的 COMPONENTS 关键字后面,如下所示:

find_package(catkin REQUIRED COMPONENTS package-names)

我们同样需要在包的package.xml 文件中列出依赖库,通过使用build_depend (编译依赖)和 run_depend(运行依赖)两个关键字实现:
<build_depend>package-name</build_depend>
<run_depend>package-name</run_depend>

对于 hello 例程,我们需要添加名为 roscpp 的依赖库,它提供了 ROS 的 C++客户端库。并且hello 程序在编译时和运行时都需要 roscpp 库,因此,修改后的 find_package 行如下所示:
find_package(catkin REQUIRED COMPONENTS roscpp)
清单文件需要包括:
<build_depend>roscpp</build_depend>
<run_depend>roscpp</run_depend>

然而,在清单文件中声明的依赖库并没有在编译过程中用到;如果你在此处忽略它们,你可能不会看到任何错误消息,直到发布你的包给其他人,他们可能在没有安装所需包的情况下编译你发布的包而导致报错。

(2)声明可执行文件

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

add_executable(executable-name source-files)
target_link_libraries(executable-name ${catkin_LIBRARIES})

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

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

(3)编译工作区

使用下面的命令来编译所有包中的所有可执行文件:

catkin_make

因为被设计成编译你的工作区中的所有包,这个命令必须从你的工作区目录运行。它将会完成一些配置步骤(尤其是你第一次运行此命令时),并且在你的工作区中创建 devel 和 build 两个
子目录。这两个新目录用于存放和编译相关的文件,例如自动生成的编译脚本、目标代码和可执行文件。

(4)Sourcing setup.bash

最后一步是是执行名为 setup.bash 的脚本文件,它是 catkin_make 在你工作区的 devel 子目录下生成的。

source devel/setup.bash

这个自动生成的脚本文件设置了若干环境变量,从而使 ROS 能够找到你创建的功能包和新生成的可执行文件。它类似于全局 setup.bash,但是是专门为你的工作区量身定做的。

三. 执行 hello 程序

rosrun agitr hello

rosrun package-name executable-name
rosrun 命令有两个参数,其中第一个参数是功能包的名称,;第二个参数是该软件包中的可执行文件的名称。
(别忘了roscore!)

这个 rosrun 命令,可能会产生如下所示的错误:
[rospack] Error: stack/package package-name not found
此错误的两个可能的原因是:
(1)错误地拼写了功能包名;
(2)没有成功运行你的工作区中的 setup.bash。


总结

到这就成功了,继续探索神奇的ROS吧!
参考书籍:《a gentle introduction to ROS》

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值