ROS 1.0 学习笔记(7)msg和srv使用

由于ROS1 的 kinetic版本不支持了,现在改用melodic版本的ROS1,两者目前我没发现太大的区别,用法好像都是一致的,这里声明一下。

官方教程

首先奉上官方教程,点击这里。

1 新建msg 消息

一般都会在工作空间下,新建一个专门用于存放各种消息的功能包,我这里就新建了一个与autoware消息对接的ROS1功能包,这里就举个例子,然后就新建一个test_msgs的功能包,由于我分别安装了ROS1和ROS2,分别的工作空间目录为 ~/Documents/ros1_melodic 和 ~/Documents/ros2_dashing ,所以以下都是按照我的工作空间来描述的,首先进入工作空间的src文件夹下,新建一个test_msgs功能包。

cd ~/Documents/ros1_melodic/src
catkin_create_pkg test_msgs  std_msgs roscpp rospy

然后,新建自定义的msg文件,要养成一个良好的习惯,msg文件要放在msgs文件夹下面。 msg文件每一行定义一个变量,更确切的来说就是一个变量类型加上一个变量名,msg中可以使用的变量类型有:

  • int8, int16, int32, int64 (plus uint*)
  • float32, float64
  • string
  • time, duration
  • variable-length array[] and fixed-length array[C]
  • other msg files

个人认为msg文件最大的方便之处在于,可以依赖于其他的msg而生成个人需要的msg消息格式,这里举个栗子说明一下。ROS1中的std_msgs/Header.msg中的内容如下:

# Standard metadata for higher-level stamped data types.
# This is generally used to communicate timestamped data 
# in a particular coordinate frame.
# 
# sequence ID: consecutively increasing ID 
uint32 seq
#Two-integer timestamp that is expressed as:
# * stamp.sec: seconds (stamp_secs) since epoch (in Python the variable is called 'secs')
# * stamp.nsec: nanoseconds since stamp_secs (in Python the variable is called 'nsecs')
# time-handling sugar is provided by the client library
time stamp
#Frame this data is associated with
# 0: no frame
# 1: global frame
string frame_id

简单解释一下,seq表示消息的滚动计数,stamp表示消息的时间戳,frame_id表示此消息中的数据是所基于坐标系的名称。
而ROS1中的自带的另一个消息geometry_msgs/PoseStamped.msg中的内容如下:

std_msgs/Header header
geometry_msgs/Pose pose

可以从中看到,PoseStamped.msg中就直接调用了std_msgs/Header格式的消息。这种使用方式,是很方便的,而且实际使用的大多数消息,都是第一行就是std_msgs/Header header ,这里就不多赘述了,一些ROS1常用的消息,在这里附上链接,方便后续查阅 std_msgs,common_msgs。
基本的概念就这样吧,下面继续新建msg文件,建立一个msg文件夹,放msg文件,并新建test.msg文件:

cd test_msgs/
mkdir msg
cd msg/
touch test.msg

其中test.msg中的内容如下,

std_msgs/Header header
string child_frame_id
float32[] data
geometry_msgs/Pose pose

2 新建srv消息

由于srv这一块用的不是很多,就把自己理解的部分码上来,如有错误,小伙伴看到了麻烦批评指出。
首先,srv消息主要用于,需要经常调用这个服务的功能,因此,service多数都是在后台开启的,client在需要实现service功能的时候,向service发送需要处理的数据,然后再由client接收service返回的值,具体可以直接看ROS1官方的代码。
继续新建srv消息,首先在功能包test_msgs中新建一个srv文件夹,然后新建一个 AddTwoInts.srv 文件。

cd ..
mkdir srv
cd srv
touch AddTwoInts.srv

具体的 AddTwoInts.srv 内容如下,

int64 a
int64 b
---
int64 sum

其中,a和b为 request,sum为service处理完后,返回的值,注意中间的 — 符号,符号上面的为 request,下面为 return 。

配置 package.xml 文件

打开 test_msgs 文件夹下的文件 package.xml,确保其有下面两条代码:

 message_generation
  message_runtime

message_generation 为把 .msg 和 .srv文件生成对应的 C++ 或者 Python 代码的工具包,此外由于新建的 test.msg 文件中,使用了 geometry_msgs ,这样就需要另外加上两行代码,
声明自定义消息的依赖,

geometry_msgs
 geometry_msgs

如果还有其他的功能包依赖,则一样需要添加进去,这里没有了,所以就这么多。

配置 CMakeList.txt 文件

CMakeList.txt 确定了编译环境的配置

  1. 调用 find_package 查找所依赖的包,必须的一般都有 roscpp(c++语言支持) rospy(Python语言支持)
    message_generation(消息生成),其他的有 geometry_msgs ,因为自定义的消息,使用了
    geometry_msgs/Pose pose ,所以自定义的消息依赖于 geometry_msgs 功能包,其他的依赖,类推即可。
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  geometry_msgs
  message_generation
)
  1. 然后是,通过 add_message_files 指定对应的msg 文件
add_message_files(
  FILES
  test.msg
)
  1. 通过 add_service_files 指定对应的 srv 文件
 add_service_files(
  FILES
  AddTwoInts.srv
)
  1. 配置 generate_messages ,指定生成消息的依赖项, test.msg 使用了 geometry_msgs ,此时就要加进去
generate_messages(
  DEPENDENCIES
  std_msgs
  geometry_msgs
)
  1. 进入工作空间下,我的就是 ~/Documents/ros1_melodic/ , 进行编译
catkin_make

编译完成后,运行

rosmsg show test_msgs/test

如果显示
ROS 1.0 学习笔记(7)msg和srv使用_第1张图片
表示 msg 已经生成。
运行

rossrv show test_msgs/AddTwoInts

显示
在这里插入图片描述
则说明 srv 消息也生成成功。

其他功能包调用自定义的 msg 消息

另外在 ~/Documents/ros1_melodic/src/ 下新建一个功能包 test

catkin_create_pkg test std_msgs roscpp rospy

进入该功能包的src文件夹下,新建文件 test.cpp,内容为,

#include "ros/ros.h"
#include 
#include "test_msgs/test.h"

int main(int argc, char **argv)
{
    ros::init(argc, argv, "test");
    ros::NodeHandle node;
    ros::Publisher test_pub = node.advertise<test_msgs::test>("test_msg",1000);
    ros::Rate loop_rate(10);

    ROS_INFO("Test Init !!!");

    while (ros::ok())
    {
        test_msgs::test msg;
        std::cout << "msg.data.size=" << msg.data.size() << std::endl;

        msg.header.frame_id = " Test ";

        test_pub.publish(msg);

        ros::spinOnce();
        loop_rate.sleep();
    }
    
    return 0;
}

对应的 CMakeList.txt 文件中,需要在 find_package 中加入 test_msgs,catkin_package下的CATKIN_DEPENDS 同样需要加入 test_msgs,如下

cmake_minimum_required(VERSION 2.8.3)
project(test)

add_compile_options(-std=c++11)

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  test_msgs
)

catkin_package(
  INCLUDE_DIRS include
  LIBRARIES test
  CATKIN_DEPENDS roscpp rospy std_msgs test_msgs
  DEPENDS system_lib
)

include_directories(
 include
 ${catkin_INCLUDE_DIRS}
)

add_executable(test_node src/test.cpp)

target_link_libraries(test_node
  ${catkin_LIBRARIES}
)

package.xml 文件中,需要加入

test_msgs
test_msgs

至于 srv 的参考,这里奉上官方的连接,可以参考,大致和 msg 的调用一致,只是用法有些不同而已。

你可能感兴趣的:(ROS,学习笔记)