ROS service in roscpp

简介: topic是ROS中的一种单向的异步通信方式。Service是一种请求-反馈的通信机制。请求的一方通常被称为客户端,提供服务的一方叫做服 务器端。Service机制相比于Topic的不同之处在于:1. 消息的传输是双向的,有反馈的,而不是单一的流向。 2. 消息往往不会以固定频率传输,不连续,而是在需要时才会向服务器发起请求。

1、service通信简介

topic是ROS中的一种单向的异步通信方式。Service是一种请求-反馈的通信机制。请求的一方通常被称为客户端,提供服务的一方叫做服 务器端。
Service机制相比于Topic的不同之处在于:

  1. 消息的传输是双向的,有反馈的,而不是单一的流向。
  2. 消息往往不会以固定频率传输,不连续,而是在需要时才会向服务器发起请求。

service包括两部分,一部分是请求方(Clinet),另 一部分是应答方/服务提供方(Server)。这时请求方(Client)就会发送一个request,要等 待server处理,反馈回一个reply,这样通过类似“请求-应答”的机制完成整个服务通信。

这种通信方式的示意图如下:
Node B是server(应答方),提供了一个服务的接口,叫做 /Service ,我们一般都会用 string类型来指定service的名称,类似于topic。Node A向Node B发起了请求,经过处理后得 到了反馈。
在这里插入图片描述
过程

Service是同步通信方式,所谓同步就是说,此时Node A发布请求后会在原地等待reply,直到 Node B处理完了请求并且完成了reply,Node A才会继续执行。Node A等待过程中,是处于 阻塞状态的成通信。这样的通信模型没有频繁的消息传递,没有冲突与高系统资源的占用, 只有接受请求才执行服务,简单而且高效。

2、service demo 实例

(1)创建service_demo package

进入工作空间的src文件夹

$ catkin_create_pkg service_demo_jone roscpp rospy std_msgs
# catkin_create_pkg 是创建package的命令
#service_demo_jone 是package的名称
#roscpp rospy std_msgs 依赖项

此时会在src文件夹下生成service_demo_jone文件夹
下面会有自动生成的相应文件
在这里插入图片描述

(2)创建.srv文件

在service_demo_jone文件夹下创建srv文件夹,用于存放.srv文件。
创建一个文件Greeting.srv文件。
里面写入

string name       #短横线上边部分是服务请求的数据   即客户端发给服务器的数据
int32 age
---               #短横线下面是服务回传的内容。     即服务器回传给客户端的数据
string feedback

然后编译生成cpp可以include的.h文件
在 CMakeLissts.txt 中加入


find_package(catkin REQUIRED COMPONENTS  #需要找个整个函数添加相应的依赖
  roscpp
  rospy
  std_msgs
  message_generation  # 需要添加的地方  
)


add_service_files(
   FILES    
   Greeting.srv    #自己定义的.srv文件 
   )

 generate_messages(
   DEPENDENCIES
   std_msgs           #由于定义的文件中用到了string、int32 关节字 所以必须要引入该依赖项
 )

在package.xml文件中加入

  <build_depend>message_generation</build_depend>     <!-- #generate new msg must add-->
  <exec_depend>message_runtime</exec_depend>          <!-- #generate new msg must add-->

然后回到工作空间 进行 编译

$ catkin_make

编译完成后
会在在图片路径下生成如下文件
在这里插入图片描述
新生成的Greeting类型的服务,其结构体的风格更为明显,可以这么理解,一个Greeting服务 结构体中嵌套了两个结构体,分别是请求和响应:

struct    Greeting
 {                
    struct    Request            
      {                                
         string    name;                                
         int    age;                
      }request;                
       struct    Response                
      {                                
       string    feedback;                
    }response; 
 }

(3)创建服务 提供节点 server.cpp

#include <ros/ros.h>
#include <service_demo_jone/Greeting.h>


//服务的处理函数
bool handle_function(service_demo_jone::Greeting::Request &req,service_demo_jone::Greeting::Response &res){  //用到service的参数的固定写法
      
      //从中可以拿到请求的数据 ,req.name  req.age
    ROS_INFO("Request from %s with age %d",req.name.c_str(),req.age );        //显示请求信息
 
    //赋值返回 变量
   res.feedback = "Hi!"+req.name+". I'm server!";//处理请求,结果写入response

    return true;    //返回true,正确处理了请求
}



int main(int argc, char** argv){ //主函数

    ros::init(argc, argv, "greeting_server");  //声明节点名称 greeting_server
    
    ros::NodeHandle nd;      //创建句柄,实例化node

    ros::ServiceServer service=nd.advertiseService("greeting",handle_function);      //写明服务的处理函数 handle_function  greeting是service的名称
  
    ros::spin();  //轮询 查询请求 有请求时 调用 服务的处理函数 handle_function

    return  0;
}

在以上代码中,服务的处理操作都写在 handle_function() 中,它的输入参数就是Greeting的 Request和Response两部分,而非整个Greeting对象。通常在处理函数中,我们对Requst数 据进行需要的操作,将结果写入到Response中。在roscpp中,处理函数返回值是bool型,也 就是服务是否成功执行。

(4)创建服务请求节点(client.cpp)


#include "ros/ros.h"
#include "service_demo_jone/Greeting.h"


int main(int argc, char **argv)
{
   ros::init(argc, argv, "greeting_client");//声明节点名称 greeting_client

   ros::NodeHandle nh;//创建句柄,实例化node

   ros::ServiceClient client = nh.serviceClient<service_demo_jone::Greeting>("greeting");    //    定义service客户端,service名字为“greeting”
   
     //    实例化srv,设置其request消息的内容,这里request包含两个变量,name和age,见Greeting.srv
   service_demo_jone::Greeting srv;
   srv.request.name="jone";
   srv.request.age=27;

   if(client.call(srv))//调用服务。
   {    
   //    注意我们的response部分中的内容只包含一个变量feedback,另,注意将其转变成字符串
      ROS_INFO("Response from server : %s",srv.response.feedback.c_str());
   }
   else 
   {
         ROS_INFO("Failed to call service Service_demo_jone");
         return 1;
   }
    return 0;
}

(5)修改CMakeList.txt

add_executable(greeting_server src/server.cpp )
#必须添加add_dependencies,否则找不到自定义的msg产生的头文件
add_dependencies(greeting_server ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(greeting_server ${catkin_LIBRARIES})

add_executable(greeting_client src/client.cpp )
add_dependencies(greeting_client ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(greeting_client ${catkin_LIBRARIES})

(6)编译

回到工作空间

$ catkin_make

3、测试

启动ros

$ roscore

检测是否生成package

$ rospack list

在列表里有刚做的package
在这里插入图片描述
运行greeting_server节点

$ rosrun service_demo_jone greeting_server

运行greeting_client节点

$ rosrun service_demo_jone greeting_client

当运行greeting_client节点时
收到并打印服务器反馈的信息
在这里插入图片描述
同时greeting_server节点打印 服务器此时的信息
在这里插入图片描述
此时说明在ros中创建service服务成功。

查看此时服务列表

$ rosservice list

在这里插入图片描述
在这里插入图片描述
有在代码中创建的服务

查看该服务信息

$ rosservice info /greeting

在这里插入图片描述

相关实践学习
使用ROS创建VPC和VSwitch
本场景主要介绍如何利用阿里云资源编排服务,定义资源编排模板,实现自动化创建阿里云专有网络和交换机。
ROS入门实践
本课程将基于基础设施即代码 IaC 的理念,介绍阿里云自动化编排服务ROS的概念、功能和使用方式,并通过实际应用场景介绍如何借助ROS实现云资源的自动化部署,使得云上资源部署和运维工作更为高效。
相关文章
|
传感器 机器人
[ROS2] --- service
[ROS2] --- service
396 0
|
API
ROS Service 相关API接口与命令行介绍
ROS Service 相关API接口与命令行介绍
424 0
|
4月前
|
传感器 机器人 开发者
ROS服务(Service)通信中的模型与实际应用: 初识Hello World并予以扩展
总而言之,ROS服务提供的是一种可靠而灵活的通信方式。每一次服务的请求和应答都会阻塞,直至应答完成。这意味着在调用服务之后,你可以确保你的请求被正确处理。这也是它在机器人系统中如此重要的原因,因为在许多情况下,我们需要获取实时、准确的结果,例如控制机器人执行精确的运动。
165 1
|
机器人
ROS2教程 05 服务Service
本文是关于ROS2(机器人操作系统2)中服务(Service)机制的教程,介绍了服务与话题(Topic)的区别、ROS2服务的相关命令,包括列出服务、查找服务、获取服务类型和调用服务,并通过示例代码展示了如何创建服务端(Server)和客户端(Client),以及如何测试服务调用过程。
623 0
ROS2教程 05 服务Service
|
传感器 机器人 定位技术
ROS Topic in roscpp 通信
Topic是ROS里一种异步通信的模型,,一般是节点间分工明确,有的只负责发送,有的只负责 接收处理。对于绝大多数的机器人应用场景,比如传感器数据收发,速度控制指令的收发, Topic模型是最适合的通信方式。
ROS Topic in roscpp 通信
ROS学习-写一个简单的Service 和 Client
ROS学习-写一个简单的Service 和 Client
255 0
|
C++ Python
ROS入门笔记(十一):编写与测试简单的Service和Client (Python)
ROS入门笔记(十一):编写与测试简单的Service和Client (Python)
658 0
ROS入门笔记(十一):编写与测试简单的Service和Client (Python)
|
Ubuntu 机器人 Linux
|
传感器 人工智能 算法
ROS机器人操作系统
ROS机器人操作系统
411 1
|
11月前
|
自动驾驶 安全 机器人
ROS2:从初识到深入,探索机器人操作系统的进化之路
前言 最近开始接触到基于DDS的这个系统,是在稚晖君的机器人项目中了解和认识到。于是便开始自己买书学习起来,感觉挺有意思的,但是只是单纯的看书籍,总会显得枯燥无味,于是自己又开始在网上找了一些视频教程结合书籍一起来看,便让我对ROS系统有了更深的认识和理解。 ROS的发展历程 ROS诞生于2007年的斯坦福大学,这是早期PR2机器人的原型,这个项目很快被一家商业公司Willow Garage看中,类似现在的风险投资一样,他们投了一大笔钱给这群年轻人,PR2机器人在资本的助推下成功诞生。 2010年,随着PR2机器人的发布,其中的软件正式确定了名称,就叫做机器人操作系统,Robot Op
387 14

推荐镜像

更多
  • ros