【ROS入门】使用 ROS 服务(Service)机制实现同步请求与答复

news2024/12/24 0:12:34

文章结构

  • 任务要求
  • 话题模型
  • 实现步骤
    • 自定义srv
      • 定义srv文件
      • 编辑配置文件
      • 编译
    • 自定义srv调用
      • vscode配置
      • 编写服务端实现
      • 编写客户端实现
    • 执行
      • 启动roscore
      • 编译
      • 启动客户端和服务端
        • 编译
        • 启动roscore
        • 启动节点

任务要求

编写代码实现 ROS 中的服务请求与答复:

  • 创建服务端,注册 Service
  • 当服务端收到客户端 Service 请求(携带整型参数 a,b)后服务端返回 a,b 的和给客户端
  • 客户端输出结果。

话题模型

在这里插入图片描述
ROS Master 负责保管 Server 和 Client 注册的信息,并匹配话题相同的 Server 与 Client ,帮助 Server 与 Client 建立连接,连接建立后,Client 发送请求信息,Server 返回响应信息。

实现步骤

自定义srv

在服务通信中,客户端提交两个整数至服务端,服务端求和并响应结果到客户端。因此,需要创建服务器与客户端通信的数据载体。

  1. 按照固定格式创建srv文件

  2. 编辑配置文件

  3. 编译生成中间文件

定义srv文件

进入工作空间,在src文件夹下创建新的功能包:

在这里插入图片描述

在新的功能包中创建名为srv的文件夹,并在该文件夹中创建srv文件,这里将其命名为addInts.srv:

在这里插入图片描述

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

# 客户端请求时发送的两个数字
int32 a
int32 b
---
# 服务器响应发送的数据
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
)
# 需要加入 message_generation,必须有 std_msgs

在这里插入图片描述

add_service_files(
  FILES
  addInt.srv
)

由于在srv文件内使用的数据类型都是基于标准消息的,即依赖于standard_messages,故有了下面的修改:

generate_messages(
  DEPENDENCIES
  std_msgs
)

在这里插入图片描述
前面的find_package是指创建的功能包所依赖的包,而catkin_package是指find_package所依赖的包:

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES service_demo
 CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
#  DEPENDS system_lib
)

在这里插入图片描述

编译

命令行中:

$ catkin_make

或者在vscode中:ctrl+shift+B:

在这里插入图片描述

自定义srv调用

编写服务通信,客户端提交两个整数至服务端,服务端求和并响应结果到客户端。

vscode配置

找到devel/include的路径
在这里插入图片描述
在.vscode中的c_cpp_properties.json中修改

{
    "configurations": [
        {
            "browse": {
                "databaseFilename": "",
                "limitSymbolsToIncludedHeaders": true
            },
            "includePath": [
                "/opt/ros/noetic/include/**",
                "/usr/include/**",
                "/xxx/yyy工作空间/devel/include/**" //配置 head 文件的路径 
            ],
            "name": "ROS",
            "intelliSenseMode": "gcc-x64",
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "c11",
            "cppStandard": "c++17"
        }
    ],
    "version": 4
}

在这里插入图片描述

编写服务端实现

编写两个节点实现服务通信,客户端节点需要提交两个整数到服务器。服务器需要解析客户端提交的数据,相加后,将结果响应回客户端,客户端再解析。

//1.头文件
#include "ros/ros.h"
#include "service_demo/addInt.h"    //该头文件名字和srv文件一致

//5.处理请求并产生响应
bool doNums(service_demo::addInt::Request &request,
            service_demo::addInt::Response &response)   //请求对象和响应对象以参数的方式传入
{
    //1.处理请求
    int a = request.a;
    int b = request.b;
    ROS_INFO("收到的请求数据:a = %d, b = %d",a,b);

    //2.组织响应
    int sum = a+b;
    response.sum = sum;
    ROS_INFO("求和结果: sum = %d",sum);
    return true;
}
int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");
    //2.初始化ROS节点
    ros::init(argc,argv,"addInt_Server");   //节点名称需要保持唯一

    //3.创建ROS句柄
    ros::NodeHandle n;
    
    //4.创建服务对象
    //参数1为话题名称/主题名称,用于将服务端和客户端关联在一起
    //参数2是一个回调函数,用于处理请求,返回值为布尔类型
    ros::ServiceServer server = n.advertiseService("addInt",doNums);   

    //6.多请求,需要调用ros::spin()
    ros::spin();
    return 0;
}


随后在CMakeLists进行编译设置修改:

在这里插入图片描述

编写客户端实现

实现参数的动态提交:

  1. 格式:rosrun xxxx xxxx 12 34
  2. 节点执行时,需要获取命令中的参数,并组织进request
// 1.包含头文件
// 1.包含头文件
#include "ros/ros.h"
#include "service_demo/addInt.h"

int main(int argc, char *argv[])
{
    //如果输入的参数个数不对,会进行提示。argc为传入参数的个数。argv[]为参数的数组
    if(argc != 3)
    {
        ROS_INFO("提交的参数个数不对");
        return 1;
    }

    setlocale(LC_ALL,"");

    // 2.初始化 ROS 节点
    ros::init(argc,argv,"addInt_Client");

    // 3.创建 ROS 句柄
    ros::NodeHandle n;

    // 4.创建 客户端 对象
    ros::ServiceClient client = n.serviceClient<service_demo::addInt>("addInt");

    // 5.组织请求数据
    service_demo::addInt ai;

    //5-1.组织请求
    //从argv数组中提取参数,将字符串类型转为整形
    ai.request.a = atoi(argv[1]);
    ai.request.b = atoi(argv[2]);

    //5-2.处理响应
    //调用判断服务器状态的函数,用于等待服务
    //函数1
    client.waitForExistence();
    //函数2
    // ros::service::waitForService("addInt");
    //客户端请求服务器
    bool flag = client.call(ai);
    if (flag)
    {
        ROS_INFO("响应成功");
        //获取结果
        ROS_INFO("响应结果 = %d",ai.response.sum);
    }
    else
    {
        ROS_ERROR("请求处理失败....");
        return 1;
    }

    return 0;
}


随后在CMakeLists文件中修改配置:

在这里插入图片描述

执行

启动roscore

$ roscore

在这里插入图片描述

编译

命令行中:

$ catkin_make

或者在vscode中:ctrl+shift+B:

在这里插入图片描述

启动客户端和服务端

编译
$ catkin_make

在这里插入图片描述

启动roscore
$ roscore
启动节点
$ source ./devel/setup.bash
$ service_demo service_demo_server_c

再开一个终端

$ source ./devel/setup.bash
$ rosrun rosrun service_demo service_demo_client_c 10 10

效果如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1041214.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue中使用富文本编辑器,@tinymce/tinymce-vue

富文本就是在后台管理系统中常见的录入带格式的内容&#xff0c;如&#xff1a;表格&#xff0c;字体加粗&#xff0c;斜体&#xff0c;文字颜色等等&#xff0c;就像一个word一样。类似于这样的效果&#xff1a; 我们使用通用在线编辑器tinymce。支持vue和react。 1. 安装 np…

opencv形态学-腐蚀

opencv形态学-腐蚀 腐蚀就是取每一个位置结构元领域内最小值作为该位置的输出灰度值&#xff1b; 结构元有很多&#xff0c;一般采用矩形&#xff0c;圆 解析 下图左测是原始图片的灰阶&#xff0c;右边是经过3X3矩形腐蚀后的结果&#xff0c;我们拿19,44,99进行分析&#…

Flink CDC MySQL同步MySQL错误记录

1、启动 Flink SQL [appuserwhtpjfscpt01 flink-1.17.1]$ bin/sql-client.sh2、新建源表 问题1&#xff1a;Encountered “(” 处理方法&#xff1a;去掉int(11)&#xff0c;改为int Flink SQL> CREATE TABLE t_user ( > uid int(11) NOT NULL AUTO_INCREMENT COMME…

关于DDR协议的一些操作的理解4

address 1.DDR中的地址&#xff0c;下表中的*4/ *8/ *16表示的是颗粒位宽。不同位宽的颗粒的行列地址的分步是不一样的。图中的page size表示的就是一行所存储的内容&#xff0c;以64MB*16格式为例&#xff0c;一行一共有10列&#xff0c;每一列存储16bit&#xff0c;也就是2B…

每日一题 146. LRU 缓存

难度&#xff1a;中等 由于周日没做&#xff0c;今天又是困难题&#xff0c;所以假装今天是周日 思路&#xff1a; 在字典结构的基础之上完成三个要求显然题目要求构建一个有序字典&#xff08;当然不使用OrderedDict&#xff09;&#xff0c;由于 key 是唯一的&#xff0c;…

TLS/SSL(六) 非对称密码应用 PKI 证书体系

一 PKI 证书体系 概念&#xff1a; PKI、CA、数字证书、证书链、数字签名之前讲解的公钥不同于https站点所获取的证书,公钥只是数字证书的一部分信息说明&#xff1a; 以下内容仅作为个人笔记 华为云证书管理服务 CCM ① 基础 PKI目前有一系列标准规范定义,主要包括: ② …

lv5 嵌入式开发-6 线程的取消和互斥

目录 1 线程通信 – 互斥 2 互斥锁初始化 – pthread_mutex_init 3 互斥锁销毁 pthread_mutex_destroy 4 申请锁 – pthread_mutex_lock 5 释放锁 – pthread_mutex_unlock 6 读写锁 7 死锁的避免 8 条件变量&#xff08;信号量&#xff09; 9 线程池概念和实现 9.1 …

全栈工程师必须要掌握的前端JavaScript技能

作为一名全栈工程师&#xff0c;在日常的工作中&#xff0c;可能更侧重于后端开发&#xff0c;如&#xff1a;C#&#xff0c;Java&#xff0c;SQL &#xff0c;Python等&#xff0c;对前端的知识则不太精通。在一些比较完善的公司或者项目中&#xff0c;一般会搭配前端工程师&a…

暗月中秋靶场活动writeup

前言 暗月在中秋节搞了个靶场活动&#xff0c;一共有4个flag&#xff0c;本着增长经验的想法参加了本次活动&#xff0c;最终在活动结束的时候拿到了3个flag&#xff0c;后面看了其他人的wp也复现拿到第四个flag。过程比较曲折&#xff0c;所以记录一下。 靶场地址 103.108.…

【sgUploadTileImage】自定义组件:浏览器端生成瓦片图,并转换为File文件序列上传瓦片图

特性&#xff1a; 支持自定义瓦片图尺寸支持显示预览最小尺寸100x100像素大小&#xff0c;切换为实际切割尺寸支持获取切割后的文件Files数组 sgUploadTileImage源码 <template><div :class"$options.name"><div class"sg-ctrl"><di…

使用datax将数据从InfluxDB抽取到TDengine过程记录

1. 编写InfluxDB数据查询语句 select time as ts,device as tbname, ip,device as district_code from "L2_CS" limit 1000 2. 创建TDengine表 create database if not exists sensor; create stable if not exists sensor.water(ts timestamp, ip varchar(50), …

App Inventor 2 模拟sleep函数

App Inventor 2 原生没有 sleep 及相关函数&#xff0c;需要模拟实现&#xff0c;经过测试这里给出一个既简单又相对高效率的实现方案&#xff1a; 需要用到计时器组件&#xff1a; 实现代码如下&#xff1a; 代码原理非常简单&#xff0c;就是计算好要 sleep 到的时刻&#x…

MySQL - 关于约束类型和作用的介绍

约束的概念&#xff1a;约束是作用于表中字段上的规则&#xff0c;用于限制存储在表中的数据。 约束的作用&#xff1a;用于保证数据库中数据的正确性、完整性和一致性。 约束分类&#xff1a; 约束类型作用关键字非空约束限制该字段的数据不能为nullnot null唯一约束保证该…

UE5 ChaosVehicles载具研究

一、基本组成 载具Actor类名称&#xff1a;WheeledVehiclePawn Actor最原始的结构 官方增加了两个摇臂相机&#xff0c;可以像驾驶游戏那样切换多机位、旋转观察 选择骨骼网格体、动画蓝图类、开启物理模拟 二、SportsCar_Pawn 角阻尼&#xff1a;物体旋转的阻力。数值越大…

C# OpenCvSharp 基于直线检测的文本图像倾斜校正

效果 项目 代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using OpenCvSharp;namespace OpenCvSharp_基于直线检测的文…

.balckhoues-V-XXXXXXX勒索病毒数据怎么处理|数据解密恢复

引言&#xff1a; 随着网络犯罪的不断演进&#xff0c;勒索病毒已成为当前数字时代的威胁之一&#xff0c;其中包括.balckhoues-V-XXXXXXX勒索病毒。本文将深入介绍.balckhoues-V-XXXXXXX勒索病毒的特点、数据恢复方法以及预防措施&#xff0c;以帮助您更好地理解和应对这一威…

【区块链 | DID】白话数字身份

《十四五数字经济发展规划》提出建立健全政务数据共享协调机制&#xff0c;加快数字身份统一认证和电子证照、电子签章、电子公文等互信互任&#xff0c;推进发票电子化改革&#xff0c;促进政务数据共享、流程优化和业务协同。在数字经济逐渐成形的背景下&#xff0c;推进数字…

【RabbitMQ实战】05 RabbitMQ后台管理

一、多租户与权限 1.1 vhost的概念 每一个 RabbitMQ服务器都能创建虚拟的消息服务器&#xff0c;我们称之为虚拟主机(virtual host),简称为 vhost。每一个 vhost本质上是一个独立的小型RabbitMQ服务器&#xff0c;拥有自己独立的队列、交换器及绑定关系等&#xff0c;并且它拥…

高级时钟项目(2)Json文件解析学习---C语言版本

笔者来介绍一下json文件解析 1、背景介绍 笔者在获取天气数据的时候&#xff0c;是通过MCU的WIFI去获取&#xff0c;但是获取到的数据json数据&#xff0c;需要解析&#xff0c;C语言没那么解析库&#xff0c;所以就需要找一些开源的解析库。 笔者找到cjson这个适用于C语言…

洗衣行业在线预约小程序系统源码搭建 支持直播功能+在线预约下单+上门取件

目前&#xff0c;人们对生活品质的追求不断提高&#xff0c;但生活节奏却也不断加快。对品质的追求遇到了忙碌的生活节奏&#xff0c;人们更渴望以最简单、便捷的方式达到追求品质的目的。同时&#xff0c;由于线上支付的普及&#xff0c;大家更希望足不出户就可以解决自己生活…