首页 > 其他分享 >ROS笔记Day04----服务通信(实现排序--xxb第二次作业)

ROS笔记Day04----服务通信(实现排序--xxb第二次作业)

时间:2024-04-09 17:59:09浏览次数:15  
标签:sort int32 int Day04 ---- xxb num client ros

一、服务通信简介

请添加图片描述

服务通信是基于请求响应模式的,是一种应答机制。

一个节点A向另一个节点B发送请求,B接收处理请求并产生响应结果返回给A。

服务通信适用于实时性要求比较高的场景,例如设计一款自动搭讪机器人,每当摄像头检测到有搭讪目标出现,则摄像头这个节点就会向底盘发送请求,让机器人运动起来.

与话题通信的对比:
Ⅰ.话题通信适用于不断更新的数据传输的场景,而服务通信适用于即时应答,无需不断更新.

客户端请求被处理时,需要保证服务器已经启动
同时服务端在完成需求后,需要将结果返回给客户端
(类比实际生活中的客户-服务模型)

二、实现流程

功能需求:客户端发送5个-100~100之间的数给服务端,服务端完成排序后返回给客户端

  1. 首先要定义服务的请求和响应的数据结构(定义srv文件)

意思是:客户端与服务端需要相互发布消息,这个发布的消息是需要我们自己定义的

举个例子:
如果我们要让客户端发布两个整数,服务端实现这两个整数的和并返回回去,这时候就需要我们在srv文件中定义能够实现这个功能的消息类型(类似结构体)

//供客户端使用
int num1;
int num2;
//供服务端使用
int sum;

srv文件就是专门用来自定义消息的地方

具体流程:
功能包下新建 srv 目录,添加 xxx.srv 文件,内容:(不需要分号结尾!!)
必须用 “- - -” 隔开

# 客户端请求时发送的五个数字
int32 num1
int32 num2
int32 num3
int32 num4
int32 num5
---
# 服务器响应发送的数据
int32 num1
int32 num2
int32 num3
int32 num4
int32 num5

图片里有误 我发现如果用数组会报错 那就不用了
在这里插入图片描述

接着编辑配置文件(具体可参考Day03中自定义消息类型)

防止大家不会我们再操作一遍:
①修改package.xml文件
在这里插入图片描述
②修改cmakelist文件
在这里插入图片描述

虚拟机崩溃了n次

在这里插入图片描述
在这里插入图片描述
最后修改:
在这里插入图片描述
需要用 不要用vscode自带的编译器编译!!!
ros编译用的是catkin_make!!!
编译:在工作空间下的devel文件下的 include文件中会生成.h文件 这就是我们上述做的一系列最终的结果:
在这里插入图片描述
我们在定义srv文件的时候用- - - 隔开了两部分对吧 所以在这里就生成了两部分的消息,一个是request.h 另一个是response.h 这就是我们在服务过程中的消息应答载体.

最后的最后 把生成文件的路径包含进去,不然一会引用头文件会报错:
在这里插入图片描述
一定 一定要注意!! 这里添加的路径之前是没有逗号的 我们需要加一个逗号!!!
这里报错我找了好久

  1. 编写客户端发布五个数
#include "ros/ros.h"
#include "service_client/sort.h"

int main(int argc, char *argv[])
{
    ros::init(argc, argv,"client");
    ros::NodeHandle nh;
    ros::ServiceClient client;

    client = nh.serviceClient<service_client::sort>("sort");
    ros::service::waitForService("sort");
    service_client::sort num;
    int numbers[5];
    for(int i = 0; i < 5; i++)
    {
        int input;
        ROS_INFO("please input number%d:",i);
        std::cin >> input;
        if(input > -100 && input < 100)
        {
            numbers[i] = input;
        }
        else
        {
            ROS_INFO("wrong number!");
            std::cin.clear();
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            --i; // 保持索引不变,以便重新输入
            continue;
        }
        numbers[i] = input;
    }
    num.request.num1 = numbers[0];
    num.request.num2 = numbers[1];
    num.request.num3 = numbers[2];
    num.request.num4 = numbers[3];
    num.request.num5 = numbers[4];
    bool flag;
    flag = client.call(num);
    if(flag)
    {
        ROS_INFO("sort successful");
        ROS_INFO("results: %d %d %d %d %d",num.response.num1, num.response.num2, num.response.num3, num.response.num4, num.response.num5);
    }
    return 0;
}


服务端代码:

#include "ros/ros.h"
#include "service_client/sort.h"

bool do_sort(service_client::sort::Request& req,service_client::sort::Response& resp)
{
    int num[5];
    num[0] = req.num1;
    num[1] = req.num2;
    num[2] = req.num3;
    num[3] = req.num4;
    num[4] = req.num5;
    int k;
    for(int i = 0; i < 4; i++)
    {
        for(int j = 0; j < 4-i; j++)
        {
            if(num[j] > num[j+1])
            {
                k = num[j];
                num[j] = num[j+1];
                num[j+1] = k;
            }
        }
    }
    resp.num1 = num[0];
    resp.num2 = num[1];
    resp.num3 = num[2];
    resp.num4 = num[3];
    resp.num5 = num[4];
    return true;
}
int main(int argc, char *argv[])
{
    ros::init(argc, argv, "server");
    ros::NodeHandle nh;
    ros::ServiceServer server = nh.advertiseService("sort",do_sort);

    ros::spin();
    return 0;
}

运行结果:
在这里插入图片描述
实现了检测是否不在-100 到 100 同时完成了排序
win

三、代码讲解

缺陷:
服务消息不知道怎么定义为数组,导致代码冗余

今天就到这里了,明天见.

标签:sort,int32,int,Day04,----,xxb,num,client,ros
From: https://blog.csdn.net/chenmoxuexi/article/details/137549542

相关文章

  • 半导体的一些表征方法(论文学习)
    半导体的一些表征方法一、扫描隧道显微镜(STM)扫描隧道显微镜是一种扫描探针显微术工具,扫描隧道显微镜可以让科学家观察和定位单个原子,它具有比它的同类原子力显微镜更加高的分辨率。此外,扫描隧道显微镜在低温下(4K)可以利用探针尖端精确操纵原子,因此它在纳米科技既是重要......
  • NKCTF-login_system
    无壳程序,所以我们直接进行反编译正常的加密,username是直接通过z3可以直接算出来的,我们看看源码_BOOL8__fastcallsub_1229(char*a1){returna1[2]+a1[1]+*a1+a1[3]==447&&101*a1[2]+*a1+9*a1[1]+8*a1[3]==12265&&5*a1[2]+3*......
  • 跨框架探索:React Redux 和 Vuex 对比分析快速掌握React Redux
    ReactRedux和Vuex都是前端状态管理库,分别用于React和Vue.js框架。它们都提供了一套规范的状态管理机制,帮助开发者更好地组织和管理应用状态。下面是它们的一些异同点:相同点:中心化状态管理:两者都提供了一个全局的存储中心,使得组件间状态共享变得简单。响应式:状......
  • 数据同步练习-1
    一、    数据结构分析:(1)京津冀三省的2015年度的科技成果数据原始表,为Access数据库,; (2)要求将三省的科技成果数据汇总到同一表中(要求结果表为MySql数据表);(3)三个原始数据表结构不一致,要求结果表中包括所有的字段,表达意思相同或相似的字段要进行合并,不允许丢失字段(若只有本表独......
  • go语言面经
    目录=和:=的区别?答案:=声明+赋值=仅赋值```govarfooint```如何在Markdown中插入代码块?在Markdown中插入代码块,您可以使用三个反引号(```)来包围代码内容,如下所示:defhello_world():print("Hello,World!")上面的Markdown代码将会......
  • js把数组中的某一项移动到第一位
    在JavaScript中,如果你要将数组中的某一项移动到第一位,你可以使用以下几种方法。假设我们有一个数组arr,并且想要将位于索引index的项移动到数组的第一个位置:letarr=[1,2,3,4,5];letindex=2;//假设我们想将3(即索引2的项)移动到第一位方法一:使用splice和unshif......
  • 三、 分支和循环
    目录1.if语句2.关系操作符3.条件操作符4.逻辑操作符5.switch语句6.while循环7.for循环8.do-while循环9.break和continue语句10.循环的嵌套11.goto语句1.if语句在C语言中,"if"语句的基本结构也是类似的,但是没有像Python那样的缩进来表示代码块的......
  • 目的NAT-4.9
    目的NAT:一般情况不允许外部网络主动访问内部网络但是有时也需要外部网络访问内部网络。例如公司将内部资料给客户或出差员工访问动态目的NAT转换前后的地址不存在固定的映射关系。例如移动终端访问无线网络。拓扑图:第一步:配置接口ip第二步:配置安全区域第三步:配置安全策略......
  • 台式电脑开机一点没反应检查步骤
    如果有滴滴的报警声就在百度上搜搜就行了,一般是内存条没插紧之类的问题一、检查电源1.拔下电源主板24pin供电,就是插在主板上面最粗最大的那坨线(记得按卡扣)。2.短接电源。将24pin卡扣侧面向自己,将(镊子/铁丝/回形针)两端分别插入左数第3根黑线+第4根绿线内,连接电源线。(网上教程......
  • 对类中std::vector私有成员进行更改
    本文是对 C++关于vector做返回值的引用细节 的延申问题一:使用vector作为函数返回值时,加&与不加&有什么区别在C++中,当函数返回一个vector时,可以选择在返回类型中使用引用(&)或者不使用引用的方式。这两种方式有一些区别,主要涉及到拷贝构造和性能。1.使用引用(&):std::vector<i......