ROS学习笔记(十二)- 创建一个ROS msg 和 srv

1 介绍msg和srv

  • msg:描述ROS message的简单文本,用来生成不同语言的消息源代码。
  • srv:一个srv描述一个service。它有请求和回复两部分组成。
    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,一个字符串和两条其他msg。
  Header header
  string child_frame_id
  geometry_msgs/PoseWithCovariance pose
  geometry_msgs/TwistWithCovariance twist

srv跟msg差不多,不过它包含两部分,一部分是请求,一部分是应答,用"-----"分隔开:

int64 A
int64 B
---
int64 Sum

2 使用msg

2.1 建立一个msg

在之前的包里面建立一个新的msg.

$ roscd beginner_tutorials
$ mkdir msg
$ echo "int64 num" > msg/Num.msg

进不去就输入:
export ROS_PACKAGE_PATH=~/catkin_ws/src:$ROS_PACKAGE_PATH

source ~/catkin_ws/devel/setup.bash
现在msg就有一行了,我们可以写的更复杂一些,一个占一行:

string first_name
string last_name
uint8 age
uint32 score

还有一步,这一步确保其可以转成C++,Python或者其他语言:
打开package.xml,确保里面有以下两行:

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

我们现在要编译,所以我们需要message_generation,运行的时候需要message_runtime。
打开 CMakeLists.txt,在find_package 里面加入*message_generation *:

# 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
)

其实即使你没有配置,有时候也能正常编译,这是因为catkin会自动用以前的项目的配置,不过如果隔离编译就不行了。
确保运行时出口的依赖关系:

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES beginner_tutorials
  CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
#  DEPENDS system_lib
)

找到下列代码:

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

去掉注释,改成:

add_message_files(
   FILES
   Num.msg
 )

现在我们需要确保CMake知道我们添加了.msg文件。
找到下面的代码:

# generate_messages(
#   DEPENDENCIES
#   std_msgs
# )

去掉“#”号。
后面要做的内容下个教程再说。

3 使用rosmsg:

使用rosmsg show确保ROS能够看见它。
用法:
$ rosmsg show [message type]
例如:
$ rosmsg show beginner_tutorials/Num
我们将会看到:
int64 num
在前面的例子里,消息由两部分构成:

  • beginner_tutorials -- 消息定义的地方
  • Num--消息的名称
    如果你忘了包里有什么msg:
    $ rosmsg show Num
    你可以看到:
[beginner_tutorials/Num]:
int64 num

4 使用srv

4.1 创建一个srv

使用刚刚创建的package创建一个srv

$ roscd beginner_tutorials
$ mkdir srv

我们将会从另一个package里面拷一个而不是完全的手工创建,使用roscp指令。
用法:
$ roscp [package_name] [file_to_copy_path] [copy_path]
现在我们从小海龟那里拷一个:
$ roscp rospy_tutorials AddTwoInts.srv srv/AddTwoInts.srv
接下来一步,我们要确保把srv文件转化成C++源代码或者其他程序源码。
打开CMakeLists.txt,去除以下程序的井号:

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

然后替换成自己的srv文件:

add_service_files(
  FILES
  AddTwoInts.srv
)

现在,就做好了从我们服务定义生成源文件的准备。具体的做法在后面的教程里有。

4.2 使用rossrv

使用rossrv show确保ROS能够看到它。
用法:
$ rossrv show <service type>
例如:
$ rossrv show beginner_tutorials/AddTwoInts
你会看到:

int64 a
int64 b
---
int64 sum

其实可以不写包名,它会自动显示所以此名称的srv.

5 msg和srv的共同步骤

这一节和上一节都省略了一些前面做过的内容,如果需要查看可以参考官网。官网本节链接
首先,改变CMakelists.txt的内容:

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

解除注释,添加包含着你依赖的.msg文件的包:

generate_messages(
  DEPENDENCIES
  std_msgs
)

现在我们的包里已经有了一些新消息,我们需要重新make我们的包:

# In your catkin workspace
$ roscd beginner_tutorials
$ cd ../..
$ catkin_make install
$ cd -

.msg生成的不同语言的源码存放位置如下,懒得翻译了:
Any .msg file in the msg directory will generate code for use in all supported languages. The C++ message header file will be generated in *~/catkin_ws/devel/include/beginner_tutorials/. *The Python script will be created in ~/catkin_ws/devel/lib/python2.7/dist-packages/beginner_tutorials/msg. The lisp file appears in ~/catkin_ws/devel/share/common-lisp/ros/beginner_tutorials/msg/.
与此相似的是,.srv文件的源码,C++就在和message相同的文件夹,别的在在msg文件夹旁边的srv文件夹。
message的完整设计说明 Message Description Language .

如果你变异的C++node要用你的新消息, 你需要声明一个新的依赖 catkin msg/srv build documentation.

6 获取帮助

我们很难记住每个命令的使用要求,我们可以使用帮助功能来获知,即在命令后面加上-h即可。

7 复习

我们现在列举一些我们用过的命令:

  • rospack=ros+pack:提供有关ROS package的信息。
  • roscd=ros+cd:changes directory 改变路径到一个ROS package或stack
  • rosls=ros+ls:lists 列举ROS package中的文件
  • roscp=ros+cp:copies 从一个ROS package复制文件到另一个
  • rosmsg=ros+msg:提供关于ROS message定义的信息
  • rossrv=ros+srv:提供关于ROS service定义的信息
  • catskin_make:makes(compiles)一个ROS package
  • rosmake=ros+make:在没有使用一个catkin工作空间的情况下makes(compiles)一个ROS package

推荐阅读更多精彩内容