.msg文件是描述ROS消息的字段的文件,其本质上是简单的.txt格式的文件,其目的是用来生成基于不同编程语言的承载消息的源代码。

.srv文件描述了一种服务,它由两个部分组成:分别是请求和应答(或者响应)

.msg格式的文件是存储在名为msg的目录下,而.srv格式的文件存储在名为srv的目录下。

消息文件中的每一行包含两个字段,分别是字段类型和字段名。

可用的字段类型有:

int8
int16
int32
int64
float32
float64
string
time
duration
other msg files
可变长度的数组array[]和固定长度的数组array[C]

当然了,也有ROS中的特殊类型:Header,头包含了ROS中常用的时间戳和坐标系信息,你将会经常看到一个.msg文件的第一行有Header header

下面是一个具体的.msg文件的例子:

  Header header
  string child_frame_id
  geometry_msgs/PoseWithCovariance pose
  geometry_msgs/TwistWithCovariance twist

说完了.msg文件,现在,我们来讲一讲.srv文件,.srv文件很像.msg文件,只是.srv文件包含两个部分:请求部分和响应部分,这两部分之间由'---'三条破折线隔开。

下面是.srv文件的一个具体的例子:

int64 A
int64 B
---
int64 Sum

讲完了.msg文件和.srv文件的基本功能之后,我们来试着使用它们。

创建一个.msg文件:

cd catkin_ws
source devel/setup.bash
roscd beginner_tutorials
mkdir msg
echo "int64 num" > msg/Num.msg

上面的例子中,我们仅仅加入了一行,当然了,你也可以添加个元素,每行一个元素来创建一个复杂的消息文件。

就像这样的:

string first_name
string last_name
uint8 age
uint32 score

你以为这样就可以了吗?不急,我们还有一个关键的步骤需要做,否则是无法实现我们的功能的。因为我们需要确保我们上面创建的消息文件被准确地翻译成了基于比如C++、Python或者其他编程语言的源代码。

为了达到这个目的,我们需要做如下的工作:

首先,我们需要打开beginner_tutorials功能包的package.xml文件,然后用鼠标把滚动条拉到最底下,最后是添加如下的两行标签:

<build_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>

注意:我们在构建功能包的时候,需要message_generation,而当我们运行功能包的节点的时候,需要message_runtime

修改了package.xml文件,我们是不是还需要修改CMakeLists.txt文件呢?想想我们的所有的功能包的构建和运行,是不是都是通过package.xml和CMakeLists.txt文件进行配置和管理的?是的,我们还需要修改CMakeLists.txt文件!

你可以用你最喜欢的纯文本编辑器打开CMakeLists.txt文件并进行如下的编辑:

在CMakeLists.txt文件的find_package项添加message_generation依赖包,这样你就可以在构建的时候生成消息。

具体的添加方法如下:

find_package(catkin REQUIRED COMPONENTS
   roscpp
   rospy
   std_msgs
   message_generation
)

注意:或许,有时候,你会发现即使你的CMakeLists.txt文件里面没有调用find_package()里面的所有依赖项,这是因为catkin会把你所有的项目结合在一起,所以如果你之前的一个项目里面调用了find_package(),那么你当前的项目也会使用和前一个项目相同的值进行配置,也就是说,catkin具有配置项记忆功能。但是,如果你忘记了调用find_package()意味着你的项目很容易崩溃,特别是当你的项目构建过程是不连续的时候。

当然了,你还需要确保导出消息运行时依赖项:

catkin_package(
	CATKIN_DEPENDS message_runtime 
)

当然了,我们还需要将如下的内容:

# add_message_files(
#   FILES
#   Message1.msg
#   Message2.msg
# )

修改成:

add_message_files(
  FILES
  Num.msg
)

通过手动添加Num.msg文件,我们还确保了让Cmake知道什么时候它需要重新配置当前这个项目,当你还添加了其他的.msg文件的时候。

最后,我们还需要确保generate_messages()函数被调用了。

为此,我们需要取消掉如下的注释:

# generate_messages(
#   DEPENDENCIES
#   std_msgs
# )

使其变成:

generate_messages(
   DEPENDENCIES
   std_msgs
)

好了,现在你已经为.msg文件生成源文件准备好了准备。

使用rosmsg

我们可以通过rosmsg show命令来查看消息的内容,以确保ROS能够看到它。

该命令的调用格式如下:

rosmsg show [message type]

例如:

rosmsg show beginner_tutorials/Num

输出的结果为:

liuqiang@liuqiang-pc:~$ rosmsg show beginner_tutorials/Num
int64 num

从上面的例子可以看出,消息类型名是由两部分组成的:

1、beginner_tutorials是定义了消息的功能包的名称

2、Num是消息文件的名称Num

如果你不记得具体是那个功能包里面包含了Num消息,可以使用如下的方法:

rosmsg show Num

输出的结果为;

liuqiang@liuqiang-pc:~$ rosmsg show Num
[beginner_tutorials/Num]:
int64 num

使用rossrv

创建一个srv

roscd beginner_tutorials
mkdir srv

这里,我们不准备直接创建一个.srv文件,我们准备直接从另一个功能包里面复制过来:

roscp [package_name] [file_to_copy_path] [copy_path]

现在,我们准备从rospy_tutorials功能包里面复制service:

roscp rospy_tutorials AddTwoInts.srv srv/AddTwoInts.srv

同样的,我们需要在package.xml里面添加如下的内容,如果之前添加过,那么就不需要添加了:

<buid_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>

在CMakeLists.txt文件里面更改和添加如下的内容:

find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)

将如下的内容:

# add_service_files(
#   FILES
#   Service1.srv
#   Service2.srv
# )

修改成:

add_service_files(
FILES
AddTwoInts.srv
)

使用rossrv

我们可以使用rossrv show来查看服务文件的内容:

liuqiang@liuqiang-pc:~$ rossrv show beginner_tutorials/AddTwoInts
int64 a
int64 b
---
int64 sum

同样的,我们也可以使用下面的方法来实现上面的功能,而不需要给出功能包的名称:

rossrv show AddTwoInts

输出的结果为:

liuqiang@liuqiang-pc:~$ rossrv show AddTwoInts
[beginner_tutorials/AddTwoInts]:
int64 a
int64 b
---
int64 sum

[rospy_tutorials/AddTwoInts]:
int64 a
int64 b
---
int64 sum

除非你前面已经做过了如下的内容,否则需要修改功能包的CMakeLists.txt文件。

我们需要将下面的内容:

# generate_messages(
#   DEPENDENCIES
# #  std_msgs  # Or other packages containing msgs
# )

去掉注释:

generate_messages(
  DEPENDENCIES
  std_msgs
)

现在,我们可以通过如下的命令进行功能包的编译了:

roscd beginner_tutorials
cd ../.. # 即进入父目录的父目录
catkin_make

注意:任何msg目录下的.msg文件将会为用户生成以所有支持的编程语言的代码。C++的消息头文件将在~/catkin_ws/devel/include/beginner_tutorials/生成,而Python的脚本将在如下的目录下生成:

~/catkin_ws/devel/lib/python2.7/dist-packages/beginner_tutorials/msg

同样的,任何srv目录下的.srv文件将会为用户生成以所有支持的编程语言的代码。对于C++,服务的头文件跟消息的头文件存储在同一个目录下,对于Python来说,msg目录的旁边会生成一个srv目录,而Python的脚本就在里面。

获取有关rosmsg的帮助:

rosmsg -h

输出结果为:

liuqiang@liuqiang-pc:~$ rosmsg -h
rosmsg is a command-line tool for displaying information about ROS Message types.

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

Type rosmsg <command> -h for more detailed usage

根据输出的提示,我们还可以使用如下的命令获取更加详细的提示:

rosmsg show -h

输出结果为:

liuqiang@liuqiang-pc:~$ rosmsg show -h
Usage: rosmsg show [options] <message type>

Options:
  -h, --help            show this help message and exit
  -r, --raw             show raw message text, including comments
  -b BAGFILE, --bag=BAGFILE
                        show message from .bag file