编写第一个ROS(创建工作空间workspace和功能包package)
原文网址:http://www.cnblogs.com/liuamin/p/5704281.html
刚接触ROS,学着写了第一个程序,怕以后忘记,就将其步骤记录下来。。
首先你必须保证你电脑已安装配置好ROS。
1.创建工作空间(workspace)
我们所创建功能包package,应该全部放到一个叫做工作空间(workspace)的目录中 。你可以把目录存储在你账号的任何位置例如,我所创建的工作空间的是路径/home,同时你可以用任何你喜欢的名字命名你的工作空间,我的工作空间名为 test,现在请使用标准的mkdir命令行去创建一个工作空间。我首先建立一个工作空间,名字为test,
此处创建的工作空间还需要在工作区目录中创建一个叫做 src 的子目录。这个子目录将用于存放功能包的源代码。而 代码中的 “-p” ,这时mkdir命令会自动创建所有不存在的目录。
在终端命令中键入(打开终端的快捷键为“Ctrl+Alt+T”)
mkdir -p ~/test/src
运行后你会发现你名为test的工作空间中已经有了一个src 的子目录。这样你的工作空间建立已经完成。
2.创建功能包(package)
创建一个新ROS功能包的命令应该在你工作空间中的src目录下运 行:catkin_create_pkg package-name,package-name指的是你功能包的名字,我所创建的功能包名为amin,注意是在你工作空间中的src目录下运行 (cd命令可以进入你要进入的目录)继续在终端中键入
cd ~/test/src
进入src目录下运行
catkin_create_pkg amin
其实,这个功能包创建命令没有做太多工作,它只不过创建了一个存放这个功能包的目录(也就是我所创建的功能包amin),并在amin那个目录下生成了两个配置文件。
第一个配置文件,叫做 package.xml,称为清单文件。
第二个文件,叫做 CMakeLists.txt,是一个 Cmake 的脚本文件,Cmake 是一个符合工业标准的跨平台编译系统。这个文件包含了一系列的编译指令,包括应该生成哪种可执行文件,需要哪些源文件,以及在哪里可以找到所需的头文件和 链接库。当然,这个文件表明 catkin 在内部使用了 Cmake。
注意:ROS 包的命名遵循一个命名规范,只允许使用小写字母、数字和下划线,而且首字符必须是一个小写字母。一些 ROS工具,包括 catkin,不支持那些不遵循此命名规范的包。
可以不看此处:编 辑清单文件 创建包后,你可能希望编辑其 package.xml 文件,其中包含一些描述这个包的元数据。通过 catkin_create_pkg 创建的功能包默认含有很丰富的注释,对于读者在很大程度上是不言自明的。然而,请注意,无论是在编译时还是在运行时,其中的大部分信息 ROS 并没有使用,这些信息只有在你公开发布代码时才变得重要。本着保持文档与实际功能同步的精神,至少填写description 和 maintainer 两部分可能是比较合理的。
3.编写ROS程序
我编写一个简单的 hello,ros!的程序,命名为hello.cpp。这个名为 hello.cpp 的源文件 也 存 放 在 你 的 功 能 包 amin文 件 夹 中 , 挨 着 package.xml 和CMakeLists.txt。
注意:一些在线教程建议在你的功能包目录中创建 src 目录来存放 C ++源文件。这个附加的组织结构可能是有益的,特别是对于那些含有多种类型文件的较大的功能包,但它不是严格必要的。
#include <ros/ros.h> int main ( int argc , char ** argv ) { ros::init ( argc , argv , "hello" ) ; ros::NodeHandle nh ; ROS_INFO_STREAM( " Hello , ROS! " ) ; }
4.编译 Hello 程序
我们该如何编译和运行这个程序呢?这些交给ROS的catkin编译系统来处理。
第一步:声明依赖库
首先,我们需要声明程序所依赖的其他功能包。对于 c++程序而言,此步骤是必要的,以确保 catkin 能够向 c++编译器提供合适的标记来定位编译功能包所需的头文件和链接库。为了给出依赖库,
编辑包目录下的 CMakeLists.txt 文件。
该文件的默认版本含有如下行:find_package(catkin REQUIRED)
所依赖的其他 catkin 包可以添加到这一行的 COMPONENTS 关键字后面,如下所示:find_package(catkin REQUIRED COMPONENTS package-names)
对于 hello 例程,我们需要添加名为 roscpp 的依赖库,它提供了 ROS 的 C++客户端库。因此,修改后的 find_package 行如下:
find_package(catkin REQUIRED COMPONENTS roscpp)
我们同样需要在包的清单文件package.xml 中列出依赖库,通过使用build_depend (编译依赖)和 run_depend(运行依赖)两个关键字实现:格式如下:
<build_depend>package-name</build_depend>
<run_depend>package-name</run_depend>
在hello 程序在编译时和运行时都需要 roscpp 库,因此清单文件package.xml加入:
<build_depend>roscpp</build_depend> <run_depend>roscpp</run_depend>
package.xml的打开方式用gedit打开如图:
注意:然而,在清单文件中声明的依赖库并没有在编译过程中用到;如果你在此处忽略它们,你可能不会看到任何错误消息,直到发布你的包给其他人,他们可能在没有安装所需包的情况下编译你发布的包而导致报错。
第二步:声明可执行文件
接下来,我们需要在 CMakeLists.txt 中添加两行,来声明我们需要创建的可执行文件。
其一般形式是:add_executable(executable-name source-files) 此处executable-name为执行文件的名字(hello),source-files为源文件的名字(hello.cpp)
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})
第三步:编译工作区
利用catkin_make这个命令进行编译,注意必须从你的工作空间目录运行,此命令时是进入你的工作空间目录。
cd ~/test
catkin_make这个命令它将会完成一些配置步骤(尤其是你第一次运行此命令时),并且在你的工作区中创建 devel 和 build 两个子目录。这两个新目录用于存放和编译相关的文件,例如自动生成的编译脚本、目标代码和可执行文件。如果你喜欢,当完成功能包的相关工作后(译者注:即 完成了编写、调试、测试等一系列工作后,此时代码基本定型),可以放心地删除 devel 和 build两个子目录。
catkin_make
运行完后你的工作空间目录里多了devel 和 build 两个子目录。如图为运行出来结果。
当然,有可能如 果 你 看 到 来 自 catkin_make 的编译 错 误 , 提 示 无 法 找 到ros/ros.h 头文件,或者 ros::init 等 ROS 函数未定义的错误,你会在执行此步骤时看见它们。最大的可能性是你的 CMakeLists.txt 没有正确声明对 roscpp的依赖。
在更正它们以后,你可以重新运行 catkin_make 来完成编译工作。
5.执行hello程序
首先要启动 roscore:这个程序是一个节点,节点需要一个节点管理器才可以正常运行。启动节点管理器的命令:
roscore
启动完节点管理器后,执行名为 setup.bash 的脚本文件,它是 catkin_make 在你工作区的 devel 子目录下生成的。
这个自动生成的脚本文件设置了若干环境变量,从而使 ROS 能够找到你创建的功能包和新生成的可执行文件。(也就是将程序注册)
注意:除非目录结构发生变化,否则你只需要在每个终端执行此命令一次,即使你修改了代码并且用 catkin_make 执行了重编译。
注意:此命令必须在你的工作空间目录运行,进入你的工作空间目录的命令上文提到过“cd ~/test”,否则会出现“没有那个文件或目录”
source devel/setup.bash
最后一步,运行节点,用命令:使用格式为"rosrun package-name executable-name" package-name 为功能包名称, executable-name为可执行文件名称
rosrun amin hello
运行结果如图:
这样一个简单的ROS程序就完成了。。