ROS 服务Server

1背景知识

1.1 服务是什么

  ROS程序由多个功能组成;一个功能由多个节点完成;各节点的功能独立,节点与节点间通过不同的通信方式,实现数据的传输,完成功能。即总功能由分功能组成,各分功能由节点的子功能及节点间的通信完成。
  服务是一种节点与节点间进行一对一双向传输的数据通信方式,数据通过服务的请求与响应实现传送。

1.2 服务的通信机制

  参与节点及节点功能:

  1. 服务端节点Server:提供服务。
  2. 客户端节点Client: 请求服务。
  3. 节点管理器ROS Master:保管节点注册信息,匹配话题的订阅者和发布者,并帮助服务端和客户端的建立连接。
    在这里插入图片描述

  五步骤如下:

步骤步骤内容类比
1.服务端Server注册向节点管理器ROS Master注册相关信息,包括:节点信息、提供的服务在婚姻介绍所登记信息
2.客户端Client注册向节点管理器ROS Master注册相关信息,包括:节点信息、请求的服务在婚姻介绍所登记信息
3.节点管理器进行话题匹配保管注册信息,匹配服务相同的Server和Client,通过RPC向Client发送Server的TCP地址婚姻介绍所匹配信息,推荐相亲对象
4.客户端请求服务Client通过TCP,与Server建立网络连接,发送请求数据看对眼了,加微信
5.服务端提供服务Server 接收、解析请求的数据,并产生响应结果返回给 Client通过好友请求,开始聊天

1.3 服务通信的特点

  服务实现一对一,双向的通信,客户端请求服务,服务端响应服务,处理得到的反馈,并将反馈返回给请求服务的客户端。通信通过反馈实现数据的双向流通。
  服务是一种同步通信方式,客户端请求服务,服务端立即响应服务,在服务端未处理完请求前,客户端将等待,直到服务端反馈请求的数据,客户端才会继续执行程序。

1.4 验证

打开一终端,运行roscore

$ roscore

打开另一终端,运行turtlesim_node节点

$ rosrun turtlesim turtlesim_node 
[ INFO] [1681894353.864916325]: Starting turtlesim with node name /turtlesim
[ INFO] [1681894353.871969072]: Spawning turtle [turtle1] at x=[5.544445], y=[5.544445], theta=[0.000000]

再启另一终端,查看/turtlesim 节点提供的服务,并请求/spawn服务

$ rosnode info /turtlesim 
--------------------------------------------------------------------------------
Node [/turtlesim]
Publications: 
 * /rosout [rosgraph_msgs/Log]
 * /turtle1/color_sensor [turtlesim/Color]
 * /turtle1/pose [turtlesim/Pose]

Subscriptions: 
 * /turtle1/cmd_vel [unknown type]

Services: 
 * /clear
 * /kill
 * /reset
 * /spawn
 * /turtle1/set_pen
 * /turtle1/teleport_absolute
 * /turtle1/teleport_relative
 * /turtlesim/get_loggers
 * /turtlesim/set_logger_level


contacting node http://ubuntu:39225/ ...
Pid: 20104
Connections:
 * topic: /rosout
    * to: /rosout
    * direction: outbound (41501 - 127.0.0.1:34348) [24]
    * transport: TCPROS

$ rosservice info /spawn 
Node: /turtlesim
URI: rosrpc://ubuntu:37257
Type: turtlesim/Spawn
Args: x y theta name

$ rosservice call /spawn 3 6 7.8 "hello"
name: "hello"

在这里插入图片描述
  上述过程中, /turtlesim 节点提供了服务/spawn,服务/spawn能够生成新的乌龟,并返回新乌龟的名字,表明请求服务成功。

  服务通过请求与响应实现数据传递,例如:查看服务/spawn传递的数据:

$ rossrv show turtlesim/Spawn 
float32 x
float32 y
float32 theta
string name
---
string name




前提ROS 创建工作空间和软件包
  当前所处软件包为beginner_tutorials,该软件包的文件系统结构如下图:
在这里插入图片描述

2 自定义服务Server

  服务消息的数据结构:由两组数据构成 ; 两组由仅包含三个破折号的一行为界, - - -上为请求,- - -下为响应。例如:请求"两数相加的和"服务中,其AddTwoNumber.srv文件如下:

int32 a
int32 b
- - -
int32 sum

  自定义服务的文件的后缀为.srv。

2.1 创建srv文件夹 ,并编辑.srv文件**

  创建srv文件夹和两数相加之和的.srv文件

$ roscd beginner_tutorials          //进入软件包
$ mkdir srv                        //新建msg 目录  放置消息
$ touch AddTwoNumber.srv

  编辑AddTwoNum.srv文件,内容如下:

int32 a
int32 b
---
int32 sum
2.2 添加srv的依赖

  编辑package.xml文件(修改后部分)

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

  编辑CMakeLists.txt 文件(修改后部分)

//需添加部分1
find_package(catkin REQUIRED COMPONENTS
   roscpp
   rospy
   std_msgs
   message_generation
)

//需添加部分2:添加运行时的依赖关系
catkin_package(
  ...
  CATKIN_DEPENDS message_runtime ...
  ...)
  
//需修改部分3:     
			 1)删除前面的# 符号 
			 2)替换Service1.srv为AddTwoNumber.srv
add_message_files(
	FILES
 	AddTwoNumber.srv
)

  查看服务是否创建成功

$ rossrv show beginner_tutorials/AddTwoNumber 
int64 a
int64 b
---
int64 sum  

$ rossrv show AddTwoNumber
[beginner_tutorials/AddTwoNumber:
int64 a
int64 b
---
int64 sum
2.3 编译,使.srv文件能被转换为C++、Python和其他语言的使用的源代码

  要使用自定义服务,需将.srv文件编译为 .h 文件,再引入到程序中 。

$ roscd beginner_tutorials
$ cd ~/.catkin_ws
$ catkin_make

  编译后,将在/devel/include/beginner_tutorials/下出现三个与srv相关的头文件。

  1. AddTwoNumberRequest.h :请求头文件
  2. AddTwoNumberResponse.h:响应头文件
  3. AddTwoNumber.h :#include 响应和请求头文件的头文件


3 服务的客户端

  1. 初始化节点
  2. 创建句柄
  3. 创建客户端对象,请求的服务,请求服务的数据
  4. 请求服务,接收服务的响应
3.1 编辑add_two_number_client.cpp
$ touch add_two_number_client.cpp

  编辑add_two_number_client.cpp文件

#include "ros/ros.h"
#include "beginner_tutorials/AddTwoNumber.h"
#include <cstdlib>

int main(int argc, char **argv)
{
        ros::init(argc, argv, "add_two_ints_client");
        if (argc != 3)
        {
                ROS_INFO("usage: add_two_ints_client X Y");
                return 1;
        }

        ros::NodeHandle n;
        ros::ServiceClient client = n.serviceClient<beginner_tutorials::AddTwoNumber>("add_two_ints");
        beginner_tutorials::AddTwoNumber srv;
        srv.request.a = atoll(argv[1]);
        srv.request.b = atoll(argv[2]);
        if (client.call(srv))
        {
                ROS_INFO("Sum: %ld", (long int)srv.response.sum);
        }
        else
        {
                ROS_ERROR("Failed to call service add_two_ints");
                return 1;
        }

        return 0;
 }
3.2 编译,生成可执行文件
add_executable(add_two_ints_client src/add_two_number_client.cpp.cpp)
target_link_libraries(add_two_ints_client ${catkin_LIBRARIES})
add_dependencies(add_two_ints_client beginner_tutorials_gencpp)

  在工作空间下编译,生成可执行文件。

$ cd catkin_ws
$ catkin_make
$ source ./devel/setup.bash

  可执行文件放置于:devel/lib/beginner_tutorials


4 服务的服务器

  1. 初始化节点
  2. 创建句柄
  3. 创建服务对象,处理服务的回调函数
  4. 回调函数处理请求,并产生响应
4.1 编辑add_two_number_server.cpp
touch add_two_number_server.cpp

  编辑add_two_number_server.cpp

#include "ros/ros.h"
#include "beginner_tutorials/AddTwoNumber.h"

//服务的回调函数
bool add(beginner_tutorials::AddTwoNumber::Request  &req,
         beginner_tutorials::AddTwoNumber::Response &res)
{
        res.sum = req.a + req.b;
        ROS_INFO("request: the x number =%ld, the y number =%ld", (long int)req.a, (long int)req.b);
        ROS_INFO("sending back response: [%ld]", (long int)res.sum);
        return true;
}

int main(int argc, char **argv)
{
        ros::init(argc, argv, "add_two_ints_server");
        //初始化节点
        ros::NodeHandle n;
        //初始化句柄

        ros::ServiceServer service = n.advertiseService("add_two_ints", add);
        //服务对象,处理的服务,服务的回调函数
        
        ROS_INFO("Ready to add two ints.");
        ros::spin();

        return 0;
}
4.2 编译,生成可执行文件
add_executable(add_two_ints_server src/add_two_number_server.cpp)
target_link_libraries(add_two_ints_server ${catkin_LIBRARIES})
add_dependencies(add_two_ints_server beginner_tutorials_gencpp)

  在工作空间下编译, 生成可执行文件。

$ cd catkin_ws
$ catkin_make
$ source ./devel/setup.bash

  可执行文件放置于:devel/lib/beginner_tutorials。


5 验证

  打开终端,运行roscore

$ roscore

  另起终端,先运行服务器节点add_two_ints_server节点

$ rosrun beginner_tutorials add_two_ints_server

  再另起终端,运行add_two_ints_client节点

$ rosrun beginner_tutorials add_two_ints_client 23 67

  结果:

在这里插入图片描述

当前软件包的文件系统结构:(红框为当前教程新增)
在这里插入图片描述

6 总结

  ros指令:

rosserver show <package_name> :查看当前活跃的服务

rossrv show <package_name>/ :查看服务的消息格式

  核心函数:
在这里插入图片描述

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值