ros学习10--Creating Msg And Srv (创建ROS消息和服务)

本文系统配置ubuntu20.04+ros1,是初学者按照ros官网初级教程学习记录,仅作个人学习记录,如有问题可联系本文作者。

附上ros1官网学习教程链接Documentation - ROS Wikihttps://wiki.ros.org/ros2官网学习教程链接Project Governance — ROS 2 Documentation: Rolling documentationhttps://docs.ros.org/en/rolling/The-ROS2-Project/Governance.html

一、msg和srv介绍

  • msg(消息):msg文件就是文本文件,用于描述ROS消息的字段。它们用于为不同编程语言编写的消息生成源代码。

  • srv(服务):一个srv文件描述一个服务。它由两部分组成:请求(request)和响应(response)。

msg文件存放在软件包的msg目录下,srv文件则存放在srv目录下。

msg文件就是简单的文本文件,每行都有一个字段类型和字段名称。可以使用的类型为:

  • int8, int16, int32, int64 (以及 uint*)
  • float32, float64
  • string
  • time, duration
  • 其他msg文件
  • variable-length array[] 和 fixed-length array[C]

ROS中还有一个特殊的数据类型:Header,它含有时间戳和ROS中广泛使用的坐标帧信息。在msg文件的第一行经常可以看到Header header。

下面是一个使用了Header、字符串原语和其他两个消息的示例: 下面是一个msg文件的样例,它使用了Header,string,和其他另外两个消息的类型:

  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是响应。

二、使用msg

2.1创建msg

下面,我们将在之前创建的软件包里定义一个新的消息。

$ roscd 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>
  <exec_depend>message_runtime</exec_depend>

 

注意,在构建时,其实只需要message_generation,而在运行时,我们只需要message_runtime。

打开CMakeLists.txt文件(注意,要找到你所在工作空间的该文件),在CMakeLists.txt文件中,为已经存在里面的find_package调用添加message_generation依赖项,这样就能生成消息了。直接将message_generation添加到COMPONENTS列表中即可,如下所示:

# 不要直接复制这一大段,只需将message_generation加在括号闭合前即可
find_package(catkin REQUIRED COMPONENTS
   roscpp
   rospy
   std_msgs
   message_generation
)

添加前:

 添加后:

 

你可能注意到了,有时即使没有使用全部依赖项调用find_package,项目也可以构建。这是因为catkin把你所有的项目整合在了一起,因此如果之前的项目调用了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知道何时需要重新配置项目。

现在必须确保generate_messages()函数被调用:

在ROS Hydro及更新版本中,你需要取消下面几行的注释:

# generate_messages(
#   DEPENDENCIES
#   std_msgs
# )

 

现在,你可以从msg文件定义中生成源代码文件了。

2.2使用rosmsg

以上就是创建消息的所有步骤。让我们通过rosmsg show命令看看ROS能否识别它。

用法:

$ rosmsg show [message type]

示例:

$ rosmsg show beginner_tutorials/Num

 

在上面的例子中,消息类型包含两部分:

  • beginner_tutorials -- 定义消息的软件包

  • Num -- 消息的名称Num

如果不记得msg在哪个包中,也可以省略包名称。尝试:

$ rosmsg show Num

三、使用srv

3.1创建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

 

 

还有关键的一步:我们要确保msg文件能被转换为C++、Python和其他语言的源代码。

如果没做过上面的教程,请先打开package.xml,确保它包含以下两行且没有被注释。如果没有,添加进去:

  <build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>

如前所述,在构建时,其实只需要message_generation,而在运行时,我们只需要message_runtime。

如果没做过上面的教程,在CMakeLists.txt文件中,为已经存在里面的find_package调用添加message_generation依赖项,这样就能生成消息了。直接将message_generation添加到COMPONENTS列表中即可,如下所示:

# 不要直接复制这一大段,只需将message_generation加在括号闭合前即可
find_package(catkin REQUIRED COMPONENTS
   roscpp
   rospy
   std_msgs
   message_generation
)

(别被名字迷惑,message_generation对msg和srv都适用)

此外,你也需要像之前对消息那样在package.xml中修改服务字段,因此请看上面描述的所需附加依赖项。

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

删除#符号来取消注释,然后将Service*.srv替换为你的.srv文件名,就像下边这样:

add_service_files(
  FILES
  AddTwoInts.srv
)

现在,你可以从srv文件定义中生成源代码文件了。

3.2使用rossrv

以上就是创建服务的所有步骤。让我们通过rossrv show命令看看ROS能否识别它。

用法:

$ rossrv show <service type>

示例:

$ rossrv show beginner_tutorials/AddTwoInts

 

跟rosmsg类似, 你也可以在不指定包名的情况下找到这样的服务:

$ rossrv show AddTwoInts

 

这里显示了两个服务。第一个是刚刚在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
)

现在我们已经创建了一些新消息,所以需要重新make一下软件包:

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

user@user-Lenovo-V310-14ISK:~/catkin_ws/src/beginner_tutorials$ roscd beginner_tutorials
user@user-Lenovo-V310-14ISK:~/catkin_ws/src/beginner_tutorials$ cd ../..
user@user-Lenovo-V310-14ISK:~/catkin_ws$ catkin_make
Base path: /home/user/catkin_ws
Source space: /home/user/catkin_ws/src
Build space: /home/user/catkin_ws/build
Devel space: /home/user/catkin_ws/devel
Install space: /home/user/catkin_ws/install
####
#### Running command: "make cmake_check_build_system" in "/home/user/catkin_ws/build"
####
-- Using CATKIN_DEVEL_PREFIX: /home/user/catkin_ws/devel
-- Using CMAKE_PREFIX_PATH: /home/user/catkin_ws/devel;/opt/ros/noetic
-- This workspace overlays: /home/user/catkin_ws/devel;/opt/ros/noetic
-- Found PythonInterp: /usr/bin/python3 (found suitable version "3.8.10", minimum required is "3")
-- Using PYTHON_EXECUTABLE: /usr/bin/python3
-- Using Debian Python package layout
-- Using empy: /usr/lib/python3/dist-packages/em.py
-- Using CATKIN_ENABLE_TESTING: ON
-- Call enable_testing()
-- Using CATKIN_TEST_RESULTS_DIR: /home/user/catkin_ws/build/test_results
-- Forcing gtest/gmock from source, though one was otherwise available.
-- Found gtest sources under '/usr/src/googletest': gtests will be built
-- Found gmock sources under '/usr/src/googletest': gmock will be built
-- Found PythonInterp: /usr/bin/python3 (found version "3.8.10")
-- Using Python nosetests: /usr/bin/nosetests3
-- catkin 0.8.10
-- BUILD_SHARED_LIBS is on
-- BUILD_SHARED_LIBS is on
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~  traversing 1 packages in topological order:
-- ~~  - beginner_tutorials
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- +++ processing catkin package: 'beginner_tutorials'
-- ==> add_subdirectory(beginner_tutorials)
-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy
-- beginner_tutorials: 1 messages, 1 services
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/catkin_ws/build
####
#### Running command: "make -j4 -l4" in "/home/user/catkin_ws/build"
####
Scanning dependencies of target std_msgs_generate_messages_cpp
Scanning dependencies of target _beginner_tutorials_generate_messages_check_deps_Num
Scanning dependencies of target std_msgs_generate_messages_py
Scanning dependencies of target _beginner_tutorials_generate_messages_check_deps_AddTwoInts
[  0%] Built target std_msgs_generate_messages_cpp
[  0%] Built target std_msgs_generate_messages_py
Scanning dependencies of target std_msgs_generate_messages_nodejs
Scanning dependencies of target std_msgs_generate_messages_lisp
[  0%] Built target std_msgs_generate_messages_lisp
[  0%] Built target std_msgs_generate_messages_nodejs
Scanning dependencies of target std_msgs_generate_messages_eus
[  0%] Built target std_msgs_generate_messages_eus
[  0%] Built target _beginner_tutorials_generate_messages_check_deps_Num
[  0%] Built target _beginner_tutorials_generate_messages_check_deps_AddTwoInts
Scanning dependencies of target beginner_tutorials_generate_messages_cpp
Scanning dependencies of target beginner_tutorials_generate_messages_nodejs
Scanning dependencies of target beginner_tutorials_generate_messages_lisp
Scanning dependencies of target beginner_tutorials_generate_messages_py
[ 15%] Generating Lisp code from beginner_tutorials/Num.msg
[ 15%] Generating Javascript code from beginner_tutorials/Num.msg
[ 23%] Generating Python from MSG beginner_tutorials/Num
[ 30%] Generating C++ code from beginner_tutorials/Num.msg
[ 38%] Generating Javascript code from beginner_tutorials/AddTwoInts.srv
[ 46%] Generating Lisp code from beginner_tutorials/AddTwoInts.srv
[ 46%] Built target beginner_tutorials_generate_messages_nodejs
Scanning dependencies of target beginner_tutorials_generate_messages_eus
[ 53%] Generating EusLisp code from beginner_tutorials/Num.msg
[ 53%] Built target beginner_tutorials_generate_messages_lisp
[ 61%] Generating Python code from SRV beginner_tutorials/AddTwoInts
[ 69%] Generating C++ code from beginner_tutorials/AddTwoInts.srv
[ 76%] Generating EusLisp code from beginner_tutorials/AddTwoInts.srv
[ 84%] Generating EusLisp manifest code for beginner_tutorials
[ 92%] Generating Python msg __init__.py for beginner_tutorials
[100%] Generating Python srv __init__.py for beginner_tutorials
[100%] Built target beginner_tutorials_generate_messages_cpp
[100%] Built target beginner_tutorials_generate_messages_py
[100%] Built target beginner_tutorials_generate_messages_eus
Scanning dependencies of target beginner_tutorials_generate_messages
[100%] Built target beginner_tutorials_generate_messages
user@user-Lenovo-V310-14ISK:~/catkin_ws$ cd -
/home/user/catkin_ws/src/beginner_tutorials
user@user-Lenovo-V310-14ISK:~/catkin_ws/src/beginner_tutorials$

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++,头文件将生成在消息的头文件的同一目录中。对于Python和Lisp,会在msg目录旁边的srv目录中。

消息格式的完整规范在消息描述语言中。

如果你正在构建使用新消息的C++节点,则还需要声明节点和消息之间的依赖关系,参见catkin消息和服务构建文档

五、获取帮助

我们已经接触到不少ROS工具了。有时候很难记住每个命令所需要的参数。好在大多数ROS工具都提供了自己的帮助。

尝试:

$ rosmsg -h
  • 你可以看到一系列的rosmsg子命令。

     

     

同样也可以获得子命令的帮助:

$ rosmsg show -h
  • 这会显示rosmsg show所需的参数:

小结

到目前为止我们接触过的一些命令:

  • rospack = ros+pack(age) : provides information related to ROS packages
  • roscd = ros+cd : changes directory to a ROS package or stack

  • rosls = ros+ls : lists files in a ROS package

  • roscp = ros+cp : copies files from/to a ROS package

  • rosmsg = ros+msg : provides information related to ROS message definitions
  • rossrv = ros+srv : provides information related to ROS service definitions
  • catkin_make : makes (compiles) a ROS package
  • rosmake = ros+make : makes (compiles) a ROS package (if you're not using a catkin workspace)

现在已经学习了如何创建ROS消息和服务,接下来就可以继续学习如何编写简单的发布者和订阅者(Python)(C++)

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值