ROS三种通信方式之服务通信

一、服务通信的理论模型

服务通信也是ROS中一种极其常用的通信模式,服务通信是基于请求响应模式的,是一种应答机制。也即: 一个节点A向另一个节点B发送请求,B接收处理请求并产生响应结果返回给A。就像是服务器与客户端,客户端发出请求,服务器给出响应。

在该模型中存在三个角色,管理者Master,客户端Client,服务端Server

在这里插入图片描述

Talker其实也是一个服务器,他为客户端的请求做出响应。

二、服务通信自定义srv

服务通信中,数据分成两部分,请求与响应,在 srv 文件中请求和响应使用---分割,具体实现如下:

功能包下新建 srv 目录,添加 addNums.srv 文件,内容:

# 客户端请求时发送的两个数字
int32 num1
int32 num2
---
# 服务器响应发送的数据
int32 sum

package.xml中添加编译依赖与执行依赖

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

CMakeLists.txt编辑 srv 相关配置

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)

add_service_files(
  FILES
  addNums.srv
)

generate_messages(
  DEPENDENCIES
  std_msgs
)

我们编译一下发现可以编译成功那基本代表着配置成功了

三、C++编码实现

3.1、实现服务端

#include "ros/ros.h"
#include "Server_Client_test/addNum.h"

bool doReq (Server_Client_test::addNum::Request& req,Server_Client_test::addNum::Response& res) {
    res.sum = req.num1 + req.num2;
    return true;
}

int main(int argc, char *argv[]) {

    setlocale(LC_ALL,"");
    // 2.初始化 ROS 节点
    ros::init(argc,argv,"addNum_Server");
    // 3.创建 ROS 句柄
    ros::NodeHandle nh;
    // 4.创建 服务 对象
    ros::ServiceServer server = nh.advertiseService("addNum",doReq);
    // 5.回调函数处理请求并产生响应
    // 6.由于请求有多个,需要调用 ros::spin()
    ros::spin();
    return 0;
}

3.2、实现客户端

#include "ros/ros.h"
#include "Server_Client_test/addNum.h"

int main(int argc, char *argv[]) {
    ros::init(argc,argv,"Client_test");
    ros::NodeHandle nh;
    ros::ServiceClient c = nh.serviceClient<Server_Client_test::addNum>("addNum");
    Server_Client_test::addNum addNum;
    addNum.request.num1 = 1;
    addNum.request.num2 = 2;
    bool flah = c.call(addNum);
    if (flah) {ROS_INFO("答案是%d\n",addNum.response.sum);}
    else {ROS_ERROR("无法解析答案");}
    return 0;
}

3.3、运行服务器

# 编译,这里我们需要配置配置文件,配置文件之前我们已经多次配置,这里不在重复
catkin_make

# 运行服务端
rosrun Server_Client_test Server_test
# 运行客户端
rosrun Server_Client_test Client_test

四、服务通信相关命令rosservice && rossrv

rosservice args    打印服务参数
rosservice call    使用提供的参数调用服务
rosservice find    按照服务类型查找服务
rosservice info    打印有关服务的信息
rosservice list    列出所有活动的服务
rosservice type    打印服务类型
rosservice uri     打印服务的 ROSRPC uri

rossrv show        显示服务消息详情
rossrv info        显示服务消息相关信息
rossrv list        列出所有服务信息
rossrv md5         显示 md5 加密后的服务消息
rossrv package     显示某个包下所有服务消息
rossrv packages    显示包含服务消息的所有包

4.1、rosservice list

列出所有活动的 service

4.2、osservice args

打印服务参数

rosservice args /spawn
x y theta name

4.3、rosservice call

调用服务

为小乌龟的案例生成一只新的乌龟

rosservice call /spawn "x: 1.0
y: 2.0
theta: 0.0
name: 'xxx'"
name: "xxx"

//生成一只叫 xxx 的乌龟

4.4、rossrv list

会列出当前 ROS 中的所有 srv 消息

4.5、rossrv packages

列出包含服务消息的所有包

4.6、rossrv package

列出某个包下的所有msg

//rossrv package 包名 
rossrv package turtlesim

4.7、rossrv show

显示消息描述

//rossrv show 消息名称
rossrv show turtlesim/Spawn

float32 x
float32 y
float32 theta
string name
---
string name

五、控制小乌龟实例

编码实现向 turtlesim 发送请求,在乌龟显示节点的窗体指定位置生成一乌龟,这是一个服务请求操作。

获取话题:/spawn

rosservice list
Copy

**获取消息类型:**turtlesim/Spawn

rosservice type /spawn
Copy

获取消息格式:

rossrv info turtlesim/Spawn
Copy

响应结果:

float32 x
float32 y
float32 theta
string name
---
string name

编写cpp文件

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


int main(int argc, char *argv[]) {
    setlocale(LC_ALL,"");
    // 2.初始化 ros 节点
    ros::init(argc,argv,"Test_turtle_creat");
    // 3.创建 ros 句柄
    ros::NodeHandle nh;
    // 4.创建 service 客户端
    ros::ServiceClient client = nh.serviceClient<turtlesim::Spawn>("/spawn");
    // 5.等待服务启动
    // client.waitForExistence();
    ros::service::waitForService("/spawn");
    // 6.发送请求
    turtlesim::Spawn spawn;
    spawn.request.x = 1.0;
    spawn.request.y = 1.0;
    spawn.request.theta = 1.57;
    spawn.request.name = "my_turtle";
    bool flag = client.call(spawn);
    // 7.处理响应结果
    if (flag) {
        ROS_INFO("新的乌龟生成,名字:%s",spawn.response.name.c_str());
    } else {
        ROS_INFO("乌龟生成失败!!!");
    }
    return 0;
}

编译后执行,这里我们需要注意一点就是,我们这个功能包需要添加turtlesim这个包的依赖,否则我们无法获取消息格式。

# 运行乌龟节点
rosrun turtlesim turtlesim_node

# 运行生成乌龟的节点
rosrun Server_Client_test Test_turtle_creat
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LyaJpunov

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值