前言:本教程介绍了如何创建和构建 msg 和 srv 文件,并介绍了 rosmsg,rossrv 和 roscp 命令行工具。
####1.Introduction to msg and srv
msg:msg 文件是简单的文本文件,它描述了 ROS 消息的属性。这些文件被用来生成消息在不同语言下的源码。
srv:srv 文件描述了服务。它由 2 部分组成:请求和响应。
msg 文件保存在包的 msg 字典中。srv 文件保存在 srv 字典中。
msg 文件是简单的文本文件,它的每一行包含一个属性类型和属性名字。下面是属性的类型:
int8, int16, int32, int64 (plus uint*)
float32, float64
string
time, duration
other msg files
variable-length array[] and fixed-length array[C]
ROS 中有一种特殊的类型:Header。Header 包含一个邮戳和 ROS 中普遍使用的坐标帧信息。你将频繁的看到 msg 文件的第一行是 Header header。
这里给出一个使用 msg 的例子,它用到了 Header,string,两个其他的 msg:
Header header
string child_frame_id
geometry_msgs/PoseWithCovariance pose
geometry_msgs/TwistWithCovariance twist
srv 和 msg 很类似,区别在于他们包含的两部分:请求和响应。两个部分之间通过单独的‘---’一行区分。这里给出一个 srv 的例子:
int64 A
int64 B
---
int64 Sum
上面的例子中 A 和 B 是请求,Sum 是响应。
####2.Using msg
#####2.1Creating a msg
让我们在之前创建的包中定义一个新的 msg。
$ cd ~/catkin_ws/src/beginner_tutorials
$ mkdir msg
$ echo "int64 num" > msg/Num.msg
示例中的.msg 文件只包含了一行。当然也可以通过一行添加一个复杂的元素来创建更复杂的文件,就像下面的那样:
string first_name
string last_name
uint8 age
uint32 score
接下来,我们需要确定这个 msg 文件要转换为那种源码,是 C++,Python,还是别的什么语言:
打开 package.xml 文件,确保下面的几行是在文件中,并且取消注释:
<build_depend>message_generation</build_depend>
<run_depend>message_generation</run_depend>
<run_depend>message_runtime</run_depend>
文件中注明在构建的时候,需要"message_generation",运行的时候需要"message_runtime".
打开 CMakeList.txt 文件,在文件中添加 message_generation 依赖到已有的 find_package 标签中。你可以简单的添加 message_generation 到 COMPONENTS 列表中,添加之后为:
# Do not just add this to your CMakeLists.txt, modify the existing text to add message_generation before the closing parenthesis
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
你可能已经注意到很多时候就算你不调用 find_package 添加所有依赖,你的工程也可以构建成功。这是因为 catkin 联合了你的所有工程到一个工程里面,所以如果之前的工程里面调用了 find_package,之后的工程也使用同样的配置。但是忘记调用 find_package 在单独的构建工程的时候非常容易失败。
同样的也需要确定导出运行时依赖的消息。
catkin_package(
...
CATKIN_DEPENDS message_runtime ...
...)
找到下面部分的代码:
# add_message_files(
# FILES
# Message1.msg
# Message2.msg
# )
通过删除#符号取消注释,然后替换 Message×.msg 文件为你的.msg 文件,完成之后看起来像:
add_message_files(
FILES
Num.msg
)
通过手动的添加.msg 文件,我们可以确定 CMake 知道在你添加了其他的.msg 文件之后需要重新配置工程。
现在我们需要确定 generate_messages()方法被调用了。
对于 ROS Hydro 及其之后的版本, 取消注释下面的几行:
# generate_messages(
# DEPENDENCIES
# std_msgs
# )
修改之后为:
generate_messages(
DEPENDENCIES
std_msgs
)
在更早的版本,只需要取消注释下面这一行:
generate_messages()
现在我们已经准备好了根据 msg 的定义生成源文件.如果你想立马开始做,忽略接下来的部分,直接跳到 Common step for msg and srv。
####3.Using rosmsg
这就是创建一个 msg 所有需要做的。让我们来确保这个 msg 对于 ROS 是可见的,使用 rosmsg show 即可。
用法:
$ rosmsg show [message type]
例如:
$ rosmsg show beginner_tutorials/Num
将看到:
int64 num
在之前的例子中,消息的类型由 2 部分组成:
beginner_tutorials -- 消息定义在哪个包
Num -- Num 是消息的名称.
如果你不记得是 msg 是在具体哪个包里面,你可以不指定包名。尝试:
$ rosmsg show Num
可以看到:
[beginner_tutorials/Num]:
int64 num
####4.Using srv
#####4.1Creating a srv
首先进入我们之前创建的包去创建一个 srv:
$ roscd beginner_tutorials
$ mkdir srv
这次我们不手动的创建一个新的 srv 定义,而是从别的包中拷贝一个现有的。
为了达成我们的目的,roscp 是一个非常有用的命令行工具,它可以用来从一个包中拷贝文件到另一个包。
方法:
$ roscp [package_name] [file_to_copy_path] [copy_path]
现在我们从 rospy_tutorials 包中拷贝一个服务:
Now we can copy a service from the rospy_tutorials package:
$ roscp rospy_tutorials AddTwoInts.srv srv/AddTwoInts.srv
接下来,我们需要确定这个 srv 文件要转换为那种源码,是 C++,Python,还是别的什么语言:
除非你已经做好了,不然打开 package.xml 文件,然后确保下面两行没有被注释掉:
<build_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>
像之前那样,在构建的时候需要 message_generation,而在运行的时候,需要 message_runtime。
除非在之前已经在创建新的 msg 的时候做好了,不然接下来需要在 CMakeList.txt 文件中添加 message_generation 依赖:
# 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 做之前在创建 msg 的时候同样的事情,所以我们向上看看额外需要的依赖:
删除#取消对下面几行的注释:
# add_service_files(
# FILES
# Service1.srv
# Service2.srv
# )
然后把 Service*.srv 这几个文件改成你的文件:
add_service_files(
FILES
AddTwoInts.srv
)
现在我们已经准备好了根据服务的定义生成源码了。如果你想立马做的话,跳到 Common step for msg and srv。
#####4.2.Using rossrv
这就是创建一个 srv 需要做的全部事情。让我们通过 rossrv 来确定 ROS 可见我们刚才创建的 srv。
用法:
$ rossrv show <service type>
例如:
$ rossrv show beginner_tutorials/AddTwoInts
你将看到:
int64 a
int64 b
---
int64 sum
跟 rosmsg 类似, 可以找到需要的 srv 文件,而不需要指定包名:
$ rossrv show AddTwoInts
[beginner_tutorials/AddTwoInts]:
int64 a
int64 b
---
int64 sum
[rospy_tutorials/AddTwoInts]:
int64 a
int64 b
---
int64 sum
####5.Common step for msg and srv
确定 CMakeLists.txt 文件中下面的几行没有被注释 :
# generate_messages(
# DEPENDENCIES
# # std_msgs # Or other packages containing msgs
# )
取消注释,然后添加使用 msg 需要依赖的任何.msg 文件,完成之后看起来像下面的样子:
generate_messages(
DEPENDENCIES
std_msgs
)
现在已经在包中添加了一些新的 msg,重新 make 包:
# In your catkin workspace
$ 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/common-lisp/ros/beginner_tutorials/msg/。
类似的,任何 srv 目录中的.srv 文件也能生成被支持的语言的源码。对于 C++,生成在 msg 的头文件相同的目录中。对于 Python 和 Lisp,生成在 msg 目录里的 srv 目录。
所有消息格式的描述参考:http://wiki.ros.org/ROS/Message_Description_Language.
如果你使用新的 msg 构建 c++ 节点,你需要在 node 和 message 之间声明依赖,参考:http://docs.ros.org/hydro/api/catkin/html/howto/format2/building_msgs.html。
####6.Getting Help
如今已经有了很多的新 ROS 工具。很难去记得每一个命令需要什么参数,幸运的是,大多数的 ROS 工具提供了他们自己的帮助。
运行:
$ rosmsg -h
你可以看到不同的 rosmsg 子命令.
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于