回顾:
1. 一些常用命令组合:
rospack = ros+pack(age): 提供与ros包相关的信息
roscd = ros+cd: 将目录更改为ros包或堆栈
rosls = ros+ls: 列出ros包中的文件
roscp = ros+cp: 从ros包中复制文件
rosmsg = ros+msg: 提供与ros消息定义相关的信息
rossrv = ros+srv:提供与ros服务定义相关的信息
catkin_make:生成(编译)一个ROS包
rosmake = ros+make:编译ros包(如果不使用catkin工作区)
2.这篇主要讲如何创建新的工作空间/mycatkin,在工作空间建立自己的ROS包/beginner_tutorials,然后在包/beginner_tutorials里定义消息msg和服务srv。
(1)创建工作空间:
$ source /opt/ros/kinetic/setup.bash //配置环境。假设已经安装catkin,并且是在kinetic中通过apt-get的形式安装的catkin
$ mkdir -p ~/mycatkin/src //这里将新创建的工作空间命名为mycatkin
$ cd ~/mycatkin/
$ catkin_make //编译工作空间,这里可能涉及到源码放在不同目录下,如my_src,如何编译,可以往上翻
//编译工作空间,自动生成build和devel目录,并在src目录中生成一个CMakelists.txt。在devel中有许多setup.*bash文件,source这些文件可以将此工作空间覆盖在环境之上。
(2)将工作空间加入ROS环境中
$ source devel/setup.bash
//在新创建的工作空间目录下执行该操作,确保安装脚本正确地覆盖该工作空间,确保ROS_PACKAGE_PATH环境变量包含 您所在的目录。(或者直接在.bashrc中写入配置路径,不用每次开一个新终端都需要手动输入)
(3)建立自己的ROS包
再啰嗦一下:ROS的软件以Package的方式组织起来。package包含节点(Node)、ROS依赖库、数据套、配置文件、第三方软件、或者任何其他逻辑构成。package的目标是提供一种易于使用的结构以便于软件的重复使用。总得来说,ROS的package遵从Goldilocks原则:短小精干。所有的ROS packages包括很多类似的文件:manifests, CMakeLists.txt, mainpage.dox, 和Makefiles.
a. 使用工具,例如roscreate-pkg(也可以使用其他工具,以后在慢慢研究)
$ roscreate-pkg [package_name]
这里直接引用官网提供的这个例子:---创建beginner_tutorials package,他依赖std_msgs, roscpp, rospy
$ roscreate-pkg beginner_tutorials std_msgs roscpp rospy
得到结果:
Created package directory /opt/ros/cturtle/ros/beginner_tutorials
Created include directory /opt/ros/cturtle/ros/beginner_tutorials/include/beginner_tutorials
Created cpp source directory /opt/ros/cturtle/ros/beginner_tutorials/src
Created package file /opt/ros/cturtle/ros/beginner_tutorials/Makefile
Created package file /opt/ros/cturtle/ros/beginner_tutorials/manifest.xml
Created package file /opt/ros/cturtle/ros/beginner_tutorials/CMakeLists.txt
Created package file /opt/ros/cturtle/ros/beginner_tutorials/mainpage.dox
Please edit beginner_tutorials/manifest.xml and mainpage.dox to finish creating your package
最后一句话是说编辑package的清单,这里我们需要仔细阅读manifest.xml。
b. 将该路径添加到ros系统中(即更新ros查找路径)
$ export ROS_PACKAGE_PATH=YOUR_BEGINNER_TUTORIALS_PATH:$ROS_PACKAGE_PATH
注意注意!!!根据ROS官方的教程创建工作空间后,进入[src]目录,在其中创建一个名为“beginner_tutorials”的新程序包,并建立了它的依赖关系。
注意:这里我的新建工作空间位于/home/chen/mycatkin/src
$ export ROS_PACKAGE_PATH=/home/chen/mycatkin/src:ROS_PACKAGE_PATH
$ rospack find beginner_tutorials
输出:/home/chen/mycatkin/src/beginner_tutorials
The solution is before to do the command:
$ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
We need to be located in : ~/catkin_ws/src
For some reason I was in ~/catkin_ws and thought it was the right place to create the Package.
之前我把beginner_tutorials包安装在了/mycatkin目录下,一直找不到,后来才发现应该在src目录下创建,上面是谷狗上的。
c. 我们可以查看package相关第一层依赖项
$ rospack depends1 beginner_tutorials ----package第一层依赖项查询
结果如下:
std_msgs
rospy
roscpp
$ rospack depends1 rospy ----package依赖项rospy的第一层依赖项查询
结果如下:
roslib
roslang
$ rospack depends beginner_tutorials ---package所有依赖项查询
genmsg_cpp
rospack
roslib
rosconsole
std_msgs
roslang
rospy
xmlrpcpp
roscpp
d. 建立和编译package
参考网址:http://www.ros.org/wiki/ROS/Tutorials/BuildingPackages
前面用roscreate-pkg建立package,这里我们根据系统关联来编译这些packages.
catkin_make是一个命令行工具,它为标准的catkin工作流增加了一些便利。您可以想象catkin_make将对cmake的调用与标准cmake工作流中的make结合起来:
# In a catkin workspace
$ catkin_make [make_targets] [-DCMAKE_VARIABLES=...]
以上命令将构建在src文件夹中找到的所有catkin项目。如果你的源代码在不同的地方,如my_src,然后你会调用catkin_make这样:
注意:如果您运行以下命令,它将无法工作,因为目录my_src不存在。
# In a catkin workspace
$ catkin_make --source my_src
$ catkin_make install --source my_src # (optionally)
e. 查看建立的package
如果您正在使用此页面构建自己的代码,请参阅后面的教程(c++)/(Python),因为您可能需要修改CMakeLists.txt。
你应该已经有了一个catkin工作空间和一个名为beginner_tutorials的新catkin包,它来自于前面的教程,创建了一个包。如果你还没有进入catkin的工作空间,请进入src文件夹:
#$ cd ~/catkin_ws/
$ cd ~/mycatkin/ //这是我自己创建的工作空间名字
$ ls src
显示:
beginner_tutorials CMakeLists.txt
(4). 在自己的ROS包中创建ROS msg 和 srv
参考网址:http://www.ros.org/wiki/ROS/Tutorials/CreatingMsgAndSrv
a. msg和srv介绍:
msg:msg文件是描述ROS 消息的描述文件,是用来为消息生成不同语言下源代码。msg文件存储在该package路径下的msg文件路径。
msg文件包括以上几种类型:
srv:srv文件是用来描述服务的,由请求和响反应两部分组成。srv文件存储在srv文件路径。
srv文件就像msg文件,另外还包括请求和响应两部分,由“----”分开,例如:
int 64 A
int 64 B
---
int64 Sum
其中,A,B是请求者,Sum是响应者。
b. 创建一个msg
在已经创建好的beginner_tutorials package上创建msg
$ roscd beginner_tutorials
$ mkdir msg
$ echo "int64 num" > msg/Num.msg
然后,
$ gedit CMakeLists.txt --打开该package的CMakeList.txt,取消“# rosbuild_genmsg()”前的“#”号。(没有找到,尴尬)
上面的示例.msg文件只包含一行。当然,您可以通过添加多个元素来创建更复杂的文件,每行一个元素,如下所示:
string first_name
string last_name
uint8 age
uint32 score
不过,还有一步。我们需要确保msg文件被转换成c++、Python和其他语言的源代码:(这里也可以在创建完服务srv后再添加也可以)
打开package.xml,并确保这两行是在它里面和未注释:
message_generation
message_runtime
注意,在构建时,我们需要“message_generation”,而在运行时,我们只需要“message_runtime”。
将message_generation依赖项添加到find_package调用中,该调用已经存在于您的CMakeLists.txt中,以便您可以生成消息。您可以通过简单地将message_generation添加到组件列表中来实现这一点,如下所示:
# Do not just add this to your CMakeLists.txt, modify the existing text to add message_generation before the closing parenthesis 不要只是将其添加到您的CMakeLists.txt中,修改现有的文本,在右括号之前添加message_generation
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
您可能会注意到,有时即使没有使用所有依赖项调用find_package,项目构建也很好。这是因为catkin将您的所有项目组合到一个项目中,所以如果前面的项目调用find_package,则您的项目将配置相同的值。但是忘记调用意味着您的项目在单独构建时很容易中断。-->啥子意思?
还要确保导出消息运行时依赖项。(没找到,尴尬)
catkin_package(
...
CATKIN_DEPENDS message_runtime ...
...)
找到以下代码块:(/beginner_tutorials/CMakelists.txt)
# add_message_files(
# FILES
# Message1.msg
# Message2.msg
# )
通过删除#符号取消注释,然后用your .msg替换Message*.msg文件,这样它看起来像这样:
add_message_files(
FILES
Num.msg
)
通过手动添加your.msg文件,我们可以确保CMake知道在您添加其他.msg文件之后何时需要重新配置项目。
现在我们必须确保调用了generate_messages()函数。
对于ROS Hydro及以后的版本,您需要取消注释这些行:
# generate_messages(
# DEPENDENCIES
# std_msgs
# )
像这样:
generate_messages(
DEPENDENCIES
std_msgs
)
现在可以从msg定义生成源文件了。
使用rosmsg
这就是创建.msg所需要做的全部工作。让我们确保ROS可以使用rosmsg show命令查看它。
$ rosmsg show [message type]
例如:
$ rosmsg show beginner_tutorials/Num
输出:
int64 num
在前面的例子中,消息类型由两部分组成:
beginner_tutorials——定义消息的包
Num——msg Num的名称。
如果您不记得.msg在哪个包中,您可以省略包名。试一试:
$ rosmsg show Num
输出:
[beginner_tutorials/Num]:
int64 num
使用 srv
让我们使用我们刚刚创建的包来创建一个srv:
$ roscd beginner_tutorials
$ mkdir srv
我们将从另一个包中复制一个现有的srv定义,而不是手工创建一个新的srv定义。
为此,roscp是一个有用的命令行工具,用于将文件从一个包复制到另一个包。
$ roscp [package_name] [file_to_copy_path] [copy_path]
现在我们可以从rospy_tutorials包复制一个服务:
$ roscp rospy_tutorials AddTwoInts.srv srv/AddTwoInts.srv
不过,还有一步。我们需要确保srv文件被转换成c++、Python和其他语言的源代码。(之前添加过不用重复添加)
除非你已经这样做了,否则打开package.xml,并确保这两行是在它和未注释:
message_generation
message_runtime
和前面一样,注意在构建时,我们需要“message_generation”,而在运行时,我们只需要“message_runtime”。
除非您已经在前面的步骤中为消息做了这样的操作,否则添加message_generation依赖项来在CMakeLists.txt中生成消息:(前面操作过就不用再重复)
# Do not just add this line to your CMakeLists.txt, modify the existing line
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
(尽管名为message_generation,但它同时适用于msg和srv。)
对于服务和消息,您需要对package.xml进行相同的更改,因此请查看上面的附加依赖项。(修正一下,这里是在CMakelists.txt中更改的)
删除#来取消以下行的注释:
# add_service_files(
# FILES
# Service1.srv
# Service2.srv
# )
现在可以从服务定义生成源文件了。如果您现在想这样做,请跳过下面的小节,转到msg和srv的常用步骤。
使用(查看) rossrv
以上完成创建srv所需要做的全部工作。让我们确保ROS可以使用rossrv show命令查看它。
$ rossrv show
例如:
$ rossrv show beginner_tutorials/AddTwoInts
输出:
int64 a
int64 b
---
int64 sum
与rosmsg类似,您可以找到这样的服务文件,而不需要指定包的名称:
$ rossrv show AddTwoInts
[beginner_tutorials/AddTwoInts]:
int64 a
int64 b
---
int64 sum
[rospy_tutorials/AddTwoInts]:
int64 a
int64 b
---
int64 sum
这里显示了两个服务。第一个是您刚刚在beginner_tutorials包中创建的,第二个是rospy_tutorials包中预先存在的。
msg和srv的常用步骤
除非您在前面的步骤中已经这样做了,否则更改CMakeLists.txt。:
# generate_messages(
# DEPENDENCIES
# # std_msgs # Or other packages containing msgs
# )
取消注释并添加您所依赖的包含消息使用的.msg文件的任何包(在本例中为std_msgs),使它看起来像这样:
generate_messages(
DEPENDENCIES
std_msgs
)
现在我们已经做了一些新的消息,我们需要再次使我们的包:
# In your catkin workspace
$ roscd beginner_tutorials
$ cd ../..
$ catkin_make install
$ cd -
msg目录中的任何.msg文件都将生成用于所有受支持语言的代码。c++消息头文件将在~/catkin_ws/devel/include/beginner_tutorials/中生成。Python脚本将在~/catkin_ws/devel/lib/python2.7/dist-packages/beginner_tutorials/msg中创建。lisp文件出现在~/catkin_ws/devel/share/ commonlisp /ros/beginner_tutorials/msg/中。
类似地,srv目录中的任何.srv文件都将以支持的语言生成代码。对于c++,这将在与消息头文件相同的目录中生成头文件。对于Python和Lisp,在“msg”文件夹旁边会有一个“srv”文件夹。
消息格式的完整规范可从消息描述语言页面获得。
如果要构建使用新消息的c++节点,还需要声明节点和消息之间的依赖关系,如catkin msg/srv构建文档中所述。
寻求帮助
我们已经看到了不少ROS工具。跟踪每个命令需要的参数可能比较困难。幸运的是,大多数ROS工具都提供了它们自己的帮助。
$ rosmsg -h
可以看到一个列表不同的rosmsg子命令
Commands:
rosmsg show Show message description
rosmsg list List all messages
rosmsg md5 Display message md5sum
rosmsg package List messages in a package
rosmsg packages List packages that contain messages
也可以从子命令中获得帮助:
$ rosmsg show -h
这显示了rosmsg show需要的参数:
Usage: rosmsg show [options]
Options:
-h, --help show this help message and exit
-r, --raw show raw message text, including comments
以上内容参考自ROS官网和他人博客,用于自己学习笔记记忆。
http://blog.sina.com.cn/s/articlelist_1712413141_7_1.html