[ROS](10)ROS通信 —— 服务(Service)通信

17 篇文章 12 订阅

  文章只是个人学习过程中学习笔记,主要参考ROS教程1


1、概念

  服务(Services):是节点之间通讯的另一种方式。服务允许节点发送一个请求(request)并获得一个响应(response)。
service概念图.png

图1-1 服务(Services)、服务客户端(Client)和服务服务器(Server)的概念图

2、 服务通信机制

  服务通信 是也是ROS通信中最常用的一种基于 请求和响应 模型的通信方式。用于临时性、非周期性、有一定逻辑处理的数据传输场景。

   服务通信 通过允许请求-响应通信来实现更紧密的耦合。服务客户端向服务服务器发送请求消息并等待响应(客户端将阻塞,直到收到响应)。服务器将使用请求中的数据构造响应消息并将其发送回客户端。每个服务都有一个类型,它决定了请求和响应消息的结构。服务也有在一个网络中唯一的名称。

  ROS Node想通过service方式来传递消息: 首先Server节点和Client节点都要到ROS Master(节点管理器)中进行注册节点名称、服务(Sevice)名称、消息类型、URI地址和端口;然后, ROS Master会根据注册表中的信息匹配Server Client,并向Client发送 Server 的 TCP 地址信息;其次,Client 根据Server的信息,使用TCP与Server 建立连接,并请求发送消息;最后, Server 接收、解析请求的数据,并产生响应结果返回给 Client

sevice通信架构.png

图2-1 服务(Services)通信模型

1.客户端请求被处理时,需要保证服务器已经启动;
2.服务端和客户端都可以存在多个;

3、服务命令rosservice

rosservice 2 可以很容易地通过服务附加到ROS客户端/服务器框架上。

命令功能
rosservice argc输出服务的参数
rosservice call用给定的参数调用服务
rosservice find按服务的类型查找服务
rosservice info输出服务的信息
rosservice list输出活跃的服务
rosservice type输出服务的类型
rosservice uri输出服务的ROSRPC uri

Tips:使用rosservice <command> -h 帮助选项获取更详细的用法。

4、服务通信实操 – 在乌龟模拟器的指定位置孵化一个小乌龟

  通过ROS内置的乌龟模拟器turtlesim)来进行服务通信的实操,在乌龟模拟器的指定位置孵化一个小乌龟。
  实现的步骤如下:
  步骤1:在新终端中启动roscore

roscore

  步骤2:在新终端中启动乌龟模拟器节点turtlesim_node

rosrun turtlesim turtlesim_node

  步骤3:通过调试工具rqt_service_caller和编程的方式在乌龟模拟器的指定位置孵化一个小乌龟。

4.1 调试工具实现

  通过rqt_service_caller工具模拟服务请求:

  • 启动rqt_service_caller工具
rosrun rqt_service_caller rqt_service_caller
  • 通过图形化配置参数,如果所示,选择孵化服务 /spawn,在Request中配置孵化位置、角度、乌龟名字请求参数,然后点击右上角call 发送请求,如果乌龟模拟器响应成功,会在Response中显示结果,并在乌龟模拟器turtlesim中孵化出一个小乌龟。

service rqt_service_caller.png

图4-1 使用rqt_service_caller工具模拟服务请求

4.2 编程实现(C++)

  在beginner_tutorials软件包的src目录下创建服务客户端源文件:

roscd beginner_tutorials
cd src
touch turtle_spawn_client.cpp

4.2.1 服务客户端程序(turtle_spawn_client.cpp)

#include "ros/ros.h"
#include "turtlesim/Spawn.h"

int main(int argc, char **argv)
{
    setlocale(LC_ALL,"");

    /* 初始化ROS节点 */
    ros::init(argc,argv,"turtle_spawn_client");
    /* 为这个节点创建句柄 */
    ros::NodeHandle nh;
    /* 创建service client 指定服务类型为turtlesim::Spawn */
    ros::ServiceClient client = nh.serviceClient<turtlesim::Spawn>("/spawn");

    /* 等待服务器启动 */
    ros::service::waitForService("/spawn");
    
    /* 实例化服务数据类型,并给成员request赋值 */
    turtlesim::Spawn spawn;
    spawn.request.x = 2;
    spawn.request.y = 8;
    spawn.request.theta = 1.8;
    spawn.request.name = "new_turtle1";

    /* 服务调用 */
    if(client.call(spawn))
    {
        ROS_INFO("小乌龟[%s]已孵化", spawn.response.name.c_str());
    }
    else
    {
        ROS_INFO("小乌龟孵化失败!");
    }

    return 0;
}

4.2.2 配置CMakeLists.txt

  只需将这几行添加到CMakeLists.txt文件的底部:

add_executable(turtle_spawn_client src/turtle_spawn_client.cpp)
target_link_libraries(turtle_spawn_client ${catkin_LIBRARIES})
add_dependencies(turtle_spawn_client ${PROJECT_NAME}_gencpp)

4.2.3 编译、运行

在你的工作空间下执行catkin_make编译,将turtle_spawn_client.cpp编译成可执行文件turtle_spawn_client。编译后,在终端中执行过程如下所示。
sevice turtlesim spawn.png

图4-2 运行服务客户端 turtle_spawn_client,孵化小乌龟(左上)

4.3 编程实现(Python)

  在beginner_tutorials软件包的scripts目录下创建服务客户端源文件:

roscd beginner_tutorials
cd scripts
touch turtle_client.py
chmod +x turtle_client.py

4.3.1 服务客户端程序(turtle_spawn_client.py)

#!/usr/bin/env python
# encoding: utf-8

import rospy
from turtlesim.srv import Spawn,SpawnRequest

def turtle_spawn_client():
    # 初始化ROS节点
    rospy.init_node("turtle_spawn_client")
    # 创建sevice client
    spawn_client = rospy.ServiceProxy('/spawn',Spawn)

    # 等待服务开启
    spawn_client.wait_for_service()

    # 创建请求数据
    spawn_req = SpawnRequest()
    spawn_req.x = 8.0
    spawn_req.y = 8.0
    spawn_req.theta = 0.8
    spawn_req.name = "new_turtle2"

    try:     
        # 调用服务并获取相应结果
        spawn_res = spawn_client.call(spawn_req)    
        rospy.loginfo("小乌龟[%s]龟已孵化", spawn_res.name)
    except rospy.ServiceException as e:
        rospy.loginfo("小乌龟孵化失败!")    

if __name__ == '__main__':
    turtle_spawn_client()

4.2.2 配置CMakeLists.txt

  只需catkin_install_python中添加 scripts/turtle_spawn_client.py即可:

# 安装python可执行脚本
catkin_install_python(PROGRAMS
  scripts/turtle_spawn_client.py
  ... 
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
  )

4.2.3 编译、运行

  其实这个例子很简单,不需要编译,直接执行python文件就行。但是我们还是养成习惯吧,每次创建和修改代码后,就catkin_make编译一下,即使是Python节点也必须使用它。这是为了确保能为创建的消息和服务自动生成Python代码。
sevice turtlesim spawn 2.png

图4-3 运行服务客户端 turtle_spawn_client.py,孵化小乌龟(右上)

5、服务命令实操

  ROS提供了一些命令行工具帮助我们查看Service的信息。通过小乌龟模拟器(turtlesim)来实操服务命令。

5.1 rosservice list

   rosservice list 输出活跃(当前正在运行)服务的信息。

rosservice list.png

   list命令显示有两个与rosout节点有关的服务:/rosout/get_loggers和/rosout/set_logger_level。其余的都是turtlesim节点提供了9个服务。

5.2 rosservice argc

   rosservice argc[service] 输出服务的所有参数。

rosservice argc.png

5.3 rosservice type

   rosservice type [service] 输出服务的类型。

rosservice type.png

5.4 rosservice find

   rosservice call [service] 按服务的类型查找服务。
rosservice find

5.5 rosservice uri

   rosservice uri 输出服务的ROSRPC uri。

在这里插入图片描述

5.6 rosservice info

   rosservice info [service] 输出服务的信息。
rosservice info

5.7 rosservice call

   rosservice call [service] [args] 用给定的参数调用服务。

# 调用服务 /spawn ,给定参数:位置(8.0,2.0)、角度为1.8、名字为new_turtle3,然后孵化小乌龟。
rosservice call /spawn  8.0 2.0 1.8 "new_turtle3"

rosservice call

图4-3 运行 rosservice call 命令,孵化小乌龟(右下)

  1. ROS.otg. ROS教程[EB/OL]. 2020-12-22[2022-7-5].
    http://wiki.ros.org/cn/ROS/Tutorials. ↩︎

  2. ROS.otg. rosservice[EB/OL]. 2020-12-22[2022-7-5].
    https://wiki.ros.org/rosservice. ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值