【写一个简单的service and client(C++)例子——services】

文章目录

  • 1、概要
  • 2、引言
  • 3、服务开始的地方及步骤
    • 3.1 创建工作空间
    • 3.2 创建功能包
    • 3.3 更新package.xml
    • 3.4 编写service 节点
      • 3.4.1 添加可执行文件
      • 3.4.2 添加 install(TARGETS…) 部分
    • 3.5 编写client 节点
      • 3.5.1 添加可执行文件
    • 3.6 编译运行
    • 3.7 运行结果

1、概要

目标:使用 C++ 创建和运行service 和 client 节点。

当节点使用服务进行通信时,发送数据请求的节点称为client节点,响应请求的节点称为service节点。请求和响应的结构由 .srv 文件确定。

2、引言

服务是ROS图中节点的另一种通信方式。服务基于呼叫和响应模型,而不是主题的发布者-订阅者模型。虽然主题允许节点订阅数据流并获取持续更新,但服务仅在客户端专门调用它们时提供数据。

请添加图片描述
请添加图片描述
这里使用的示例是一个简单的整数加法系统;一个节点请求两个整数的总和,另一个节点响应结果。

3、服务开始的地方及步骤

3.1 创建工作空间

如已经创建了工作空间可以不用创建

mkdir -p ~/ros2_ws/src
cd  ~/ros2_ws/src

3.2 创建功能包

  1. 进入ros2_ws/src的目录下,创建一个新的功能包cpp_srvcli
ros2 pkg create --build-type ament_cmake --license Apache-2.0 cpp_srvcli --dependencies rclcpp example_interfaces
  • 终端将返回一条消息,验证包cpp_srvcli及其所有必要文件和文件夹的创建。
  • --dependencies 参数将自动向package.xmlCMakeLists.txt 添加必要的依赖项行。
  • example_interfaces是包含构建请求和响应所需的 .srv 文件的包:

在这里插入图片描述
cpp_srvcli包的文件结构如下
cpp_srvcli/
├── CMakeLists.txt
├── include
├── LICENSE
├── package.xml
└── src

2 directories, 3 files


  1. 创建example_interfaces功能包
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_cmake exapmle_interfaces
cd exapmle_interfaces
mkdir msg srv

在这里插入图片描述

  1. 在example_interfaces/srv下,新建一个AddTwoInts.srv文件
touch AddTwoInts.srv
gedit AddTwoInts.srv

添加以下代码

int64 a
int64 b
---
int64 sum

前两行是请求的参数,短划线下面是响应。

3.3 更新package.xml

由于在包创建过程中使用了 --dependencies 选项,因此无需手动将依赖项添加到package.xmlCMakeLists.txt

但是,需要确保将描述、维护者电子邮件和名称以及许可证信息添加到package.xml

在这里插入图片描述

3.4 编写service 节点

cd ~/ros2_ws/src/cpp_srvcli/src
touch add_two_ints_server.cpp

add_two_ints_server.cpp代码

#include "rclcpp/rclcpp.hpp"
#include "example_interfaces/srv/add_two_ints.hpp"#include<memory>//add 函数从请求中添加两个整数,并为响应提供总和,同时使用日志通知控制台其状态。
void add(const std::shared_ptr<example_interfaces::srv::AddTwoInts::Request> request,std::shared_ptr<example_interfaces::srv::AddTwoInts::Response>     response)
{response->sum = request->a + request->b;RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"Incoming request\na: %ld" "b: %ld",request->a,request->b);RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"sending back response:[%ld]",(long int)response->sum);
}int main(int argc,char* argv[])
{rclcpp::init(argc,argv);  //初始化 ROS 2 C++ 客户端库//创建名为 add_two_ints_server 的节点:std::shared_ptr<rclcpp::Node> node = rclcpp::Node::make_shared("add_two_inits_server");//为该节点创建名为 add_two_ints 的服务,并使用 &add 方法在网络中自动发该服务:rclcpp::Service<example_interfaces::srv::AddTwoInts>::SharedPtr service = node->create_service<example_interfaces::srv::AddTwoInts>("add_two_ints",&add);//准备就绪时打印日志消息:RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"Ready to add two ints.");rclcpp::spin(node);  //spin节点,使服务可用。rclcpp::shutdown();return 0;
}

3.4.1 添加可执行文件

add_executable(server src/add_two_ints_server.cpp)
ament_target_dependencies(server rclcpp example_interfaces)

3.4.2 添加 install(TARGETS…) 部分

添加 install(TARGETS…) 部分,以便 ros2 run 可以找到可执行文件:

install(TARGETSserverDESTINATION lib/${PROJECT_NAME})

在这里插入图片描述

3.5 编写client 节点

cd ~/ros2_ws/src/cpp_srvcli/src
touch add_two_ints_client.cpp

add_two_ints_client.cpp代码

#include"rclcpp/rclcpp.hpp"
#include"example_interfaces/srv/add_two_ints.hpp"#include<chrono>
#include<cstdlib>
#include<memory>using namespace std::chrono_literals;int main(int argc,char**argv)
{rclcpp::init(argc,argv);if(argc!=3){RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"usage: add_two_ints_client X Y");return 1;}//创建节点,然后为该节点创建客户端:std::shared_ptr<rclcpp::Node> node = rclcpp::Node::make_shared("add_two_ints_client");rclcpp::Client<example_interfaces::srv::AddTwoInts>::SharedPtr client = node->create_client<example_interfaces::srv::AddTwoInts>("add_two_ints");//创建请求,其结构由在 AddTwoInts.srv 文件定义。auto request = std::make_shared<example_interfaces::srv::AddTwoInts::Request>();request->a = atoll(argv[1]);request->b = atoll(argv[2]);while(!client->wait_for_service(1s)){if(!rclcpp::ok()){//如果客户端被取消(例如,通过在终端中输入 Ctrl+C),它将返回一条错误日志消息,指出它已中断。RCLCPP_ERROR(rclcpp::get_logger("rclcpp"),"Interrupted while waiting for the service . exiting.");return 0;}//while 循环为客户端提供 1 秒钟的时间来搜索网络中的服务节点。如果它找不到任何,它将继续等待。RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"service not available,waiting again...");}auto result = client->async_send_request(request);if(rclcpp::spin_until_future_complete(node,result)==rclcpp::FutureReturnCode::SUCCESS){RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"Sum: %ld",result.get()->sum);}else{RCLCPP_ERROR(rclcpp::get_logger("rclcpp"),"Failed to call service add_two_ints");}rclcpp::shutdown();return 0;}

3.5.1 添加可执行文件

add_executable(client src/add_two_ints_client.cpp)
ament_target_dependencies(client rclcpp example_interfaces)install(TARGETSserverclientDESTINATION lib/${PROJECT_NAME})

在这里插入图片描述

3.6 编译运行

  1. 导航回工作区的根目录,ros2_ws,并生成新包:
colcon build --packages-select cpp_srvcli

在这里插入图片描述

3.7 运行结果

  1. 打开一个新终端,导航到ros2_ws,并获取安装文件:
. install/setup.bash
ros2 run cpp_srvcli server

在这里插入图片描述
2. 打开另一个终端,再次从内部获取ros2_ws设置文件。启动客户机节点,后跟用空格分隔的任意两个整数:

. install/setup.bash
ros2 run cpp_srvcli client 2 3

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

高端制造企业生产设备文件管理,怎样保证好用不丢失文件?

高端制造业在市场经济中占据重要角色&#xff0c;在高端制造业企业内部&#xff0c;生产设备又是最关键的一环环&#xff0c;它们不仅负责完成生产任务&#xff0c;同时也会产生大量的文件。这些数据反映了设备的运行状态、生产效率、能源消耗以及产品质量等多个方面&#xff0…

网络协议安全:OSI七层模型分层及作用,数据封装与解封过程,数据传输过程。

「作者简介」&#xff1a;2022年北京冬奥会中国代表队&#xff0c;CSDN Top100&#xff0c;学习更多干货&#xff0c;请关注专栏《网络安全自学教程》 这一章节我们需要知道OSI分哪七层&#xff0c;每层的作用&#xff0c;知道数据在七层模型中是怎样传输的&#xff0c;封包和解…

C/C++ 入门(7)vector类(STL)

个人主页&#xff1a;仍有未知等待探索-CSDN博客 专题分栏&#xff1a;C 请多多指教&#xff01; 目录 一、标准库中的vector 1、了解 2、vector常用接口 二、vector的实现 1、框架 2、构造、析构函数 3、操作函数 三 、问题 1、由于赋值而引起的浅拷贝 2、因为类没…

岭回归(概念+实例)

目录 前言 一、基本概念 1. 引言 2. 岭回归的原理 3. 数学表达式 4. 岭回归的优点 5. 岭回归的局限性 6. 实际应用 二、具体实例 前言 “岭回归”这个词源于英文“Ridge Regression”&#xff0c;是一种用于处理回归分析中多重共线性&#xff08;multicollinearity&am…

Linux-软件安装--jdk安装

jdk安装 前言1、软件安装方式二进制发布包安装rpm安装yum安装源码编译安装 2、安装jdk2.1、使用finalShell自带的上传工具将jdk的二进制发布包上传到Linux2.2、解压安装包2.3、配置环境变量![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/61ba9750e2e34638a39575c5…

电脑自带dll修复在哪里打开?教你如何快速修复dll丢失问题

MSVCP140.dll文件作为Windows操作系统中不可或缺的一环&#xff0c;对众多基于C编译的应用程序的正常运行起着关键作用。在我深入研究和处理与该文件相关问题的过程中&#xff0c;积累了丰富的认知和实践经验。以下是我对MSVCP140.dll文件的总体介绍以及针对其丢失问题的解决方…

C++ 验证一下,你对递归是不是一知半解

公众号:编程驿站 公众号:编程驿站 1. 前言 无递归,不算法。无论怎样强调递归的重要性,都不为过。受限于计算机的思维能力,计算机的计算找答案的过程就是在不停试错、纠正错误的过程,类似于爱迪生发明灯炮。递归能帮助我们在不知道计算边界的情形下试错。 多函数求解过…

echarts树图-实现拓扑图效果

使用echarts树图来实现拓扑图效果&#xff0c;其效果如下&#xff1a; 代码如下&#xff1a; const data {name: XXX公司,children: [{name: 网络主机,children: [{name: 普通路由器,children: [{name: 智能网关},{name: 192.168.1.0/24}]}]},{name: 企业路由器},{name: 三…

MySQL-----多表查询(一)

目录 一.多表关系&#xff1a; 1.1 一对多(多对一)&#xff1a; 1.2 多对多: 1.3 一对一: 二.多表查询概述&#xff1a; 三.连接查询&#xff1a; 3.1内连接&#xff1a; 3.2外连接&#xff1a; 3.3自连接查询&#xff1a; 3.4联合查询&#xff1a; 一.多表关系&…

Vast+产品展厅 | Vastbase G100数据库是什么架构?(1)

Vastbase G100是海量数据融合了多年对各行业应用场景的深入理解&#xff0c;基于openGauss内核开发的企业级关系型数据库。 了解Vastbase G100的架构&#xff0c;可以帮助您确保数据库系统的高效、可靠和安全运行。 “Vast产品展厅”将分两期&#xff0c;为您详细讲解Vastbas…

划分数据集2,详细说明

看完了这个之后划分数据集&#xff0c;训练自己的数据集。-CSDN博客 我再详细说一下自己标注的文件放在什么位置 我发的文件里有这几个文件 在dataset里面有 自己的数据集分为&#xff0c;图片部分和标注文件部分 打开VOCdevkit文件夹 里面有三个文件夹 自己的图片的话&…

(C++) 内类生成智能指针shared_from_this介绍

文章目录 &#x1f601;介绍&#x1f914;类外操作&#x1f605;错误操作&#x1f602;正确操作 &#x1f914;类内操作&#x1f62e;std::enable_shared_from_this<>&#x1f62e;奇异递归模板 CRTP&#xff08;Curiously Recurring Template Pattern&#xff09;&#…

carrier开利触摸屏ICVC控制面板维修CEPL130445

开利离心机19XR空调ICVC显示面板维修CEPL130445-03-R/04-R/02-R 人机界面触摸维修故障有&#xff1a;花屏、白屏、按触摸屏无反应或反应慢(触摸不好)、内容错乱、无背光、背光暗、有背光无字符、不能通信、按键无反应等&#xff08;可更换液晶屏&#xff09;黑屏、对触摸屏触摸…

QML 中的状态

Qt hello – 专注于Qt的技术分享平台 状态描述了当前用户界面样子&#xff0c;QML中一个状态定义了一组属性的改变&#xff0c;并且会在一定条件下被触发。 假设有这么一个场景&#xff0c;红黄绿三个灯&#xff0c;用一个按钮&#xff0c;点击后依次切换三个灯亮起。使用QWi…

js如何获取对象的属性值

获取对象的属性值&#xff0c;有两种方式。 方式一&#xff1a; 对象.属性名 let obj {name:张三,age:23 }; console.log(obj.name); //张三方式二&#xff1a; 对象[属性名] let obj {name:张三,age:23 }; console.log(obj[name]); //张三 两种方式有什么不同&am…

AWR报告采集

一、windows下采集 自动负载信息库&#xff08;Automatic Workload Repository&#xff0c;AWR&#xff09;是在Oracle 10g中被引入的&#xff0c;缺省地被安装到Oracle10g数据库中&#xff0c;用于收集关于该特定数据库的操作统计信息和其他统计信息。AWR的采样工作由后台进程…

Linux-线程互斥和死锁

目录 一.线程互斥 1.1 进程线程间的互斥相关背景概念 1.2 互斥量mutex 二.互斥量的接口 2.1 初始化互斥量 2.2 销毁互斥量 2.3 互斥量加锁和解锁 2.4 改进后售票代码 三.死锁 3.1.什么是死锁&#xff1f; 3.2.死锁四个必要条件 3.3 避免死锁 一.线程互斥 1.1 进程…

吴恩达2022机器学习专项课程(一) 6.1 动机第三周课后实验:Lab1使用逻辑回归进行分类

问题预览/关键词 什么是逻辑回归&#xff1f;什么是二分类问题&#xff1f;二分类问题案例如何表达二分类的结果&#xff1f;逻辑回归通常用哪种表达形式&#xff1f;什么是正样本和负样本&#xff1f;什么是阈值&#xff1f;可视化线性回归解决二分类线性回归面对二分类产生的…

jmeter之跨线程关联

1&#xff09;_setproperty函数&#xff1a;将值保存成jmeter属性 2&#xff09;_property函数&#xff1a;在其他线程组中使用property函数读取属性 一、跨线程接口引用变量 1. 法一&#xff1a;jmeter自带函数_setProperty和_property 1. 1线程组 01 创建登录的【HTTP请求】…

1、k8s问题pod从service中剔除

一、起因 redis原来由两服务器的集群变为三服务器的集群&#xff0c;通过statefulset扩展了两节点&#xff0c;并把redis-app-0和redis-app-3从集群中去除&#xff0c;但是由于service路由后端不变&#xff0c;导致程序连接后端仍然可能到redis-app-0和redis-app-3 二、处理 …