[ROS2] --- service

1 service介紹

1.1 service概念

話題通信是基于訂閱/發布機制的,無論有沒有訂閱者,發布者都會周期發布數據,這種模式適合持續數據的收發,比如傳感器數據。機器人系統中還有另外一些配置性質的數據,并不需要周期處理,此時就要用到另外一種ROS通信方式——服務(Service)。服務是基于客戶端/服務器模型的通信機制,服務器端只在接收到客戶端請求時才會提供反饋數據。

1.2 service特點

  • 同一個服務(名稱相同)有且只能有一個節點來提供
    在這里插入圖片描述

  • 同一個服務可以被多個客戶端調用(可以一對一也可一對多)
    在這里插入圖片描述

  • 同步通信
    這個過程一般要求越快越好,假設服務器半天沒有反應,你的瀏覽器一直轉圈圈,那有可能是服務器宕機了,或者是網絡不好,所以相比話題通信,在服務通信中,客戶端可以通過接收到的應答信息,判斷服務器端的狀態,我們也稱之為同步通信。

2 自定義通信接口

和話題通信類似,服務通信的核心還是要傳遞數據,數據變成了兩個部分,一個請求的數據,比如請求蘋果位置的命令,還有一個反饋的數據,比如反饋蘋果坐標位置的數據,這些數據和話題消息一樣,在ROS中也是要標準定義的,話題使用.msg文件定義,服務使用的是.srv文件定義。

2.1 新建工作空間

mkdir -p dev_ws/src
cd dev_ws/src
ros2 pkg create custom_interface --build-type ament_cmake

2.2 編寫srv接口文件

# 創建srv目錄
cd  dev_ws/src/custom_interface
mkdir srv
touch CapitalFullName.srv

CapitalFullName.srv

string name
string surname
---
string capitalfullname

2.3 編譯

colcon build

3 service代碼實現

上面第二步已經實現了自定義接口,并在install目錄生成了對應的頭文件,我們下面的代碼中可以直接引用這個自定義接口了。

3.1 新建工作空間

前面已經講解過,這里不再贅述
這里創建工作空間名為learning03_service

3.2 server_node_class.cpp

/*** @file service_node_class.cpp** @brief A basic ROS2 service server node with class implementation that gets two *        strings as request and answer with a capitalized full string as response.*        It's necessary to use the custom message defined in the external*        package "Custom msg and srv"*        To call the service from a terminal use on a single line:*        ros2 service call /create_cap_full_name *        custom_interface/srv/CapitalFullName "{name: x, surname: y}"** @author Antonio Mauro Galiano* Contact: https://www.linkedin.com/in/antoniomaurogaliano/**/#include "rclcpp/rclcpp.hpp"
#include "custom_interface/srv/capital_full_name.hpp"
#include <boost/algorithm/string.hpp>class MyServiceNode : public rclcpp::Node
{
private:rclcpp::Service<custom_interface::srv::CapitalFullName>::SharedPtr service_;void ComposeFullName(const std::shared_ptr<custom_interface::srv::CapitalFullName::Request> request,std::shared_ptr<custom_interface::srv::CapitalFullName::Response> response);public:MyServiceNode(std::string passedNodeName="VOID"): Node(passedNodeName){RCLCPP_INFO(this->get_logger(), "I am ready to capitalize your full name");// like the subscriber class node it's needed the boost::bind to acces the member method // with 2 placeholders to pass request and response to the callbackservice_ = this->create_service<custom_interface::srv::CapitalFullName>("create_cap_full_name", std::bind(&MyServiceNode::ComposeFullName, this, std::placeholders::_1, std::placeholders::_2 ));}};// method to handle the client request and give back a response
// the service gets the name and surname and responses with a capitalized full name
void MyServiceNode::ComposeFullName(const std::shared_ptr<custom_interface::srv::CapitalFullName::Request> request,std::shared_ptr<custom_interface::srv::CapitalFullName::Response> response)
{std::string fullName = request->name + " " + request->surname;std::string capitalFullName = boost::to_upper_copy<std::string>(fullName);response->capitalfullname = capitalFullName;    RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Incoming name: %s" "\tIncoming surname: %s",request->name.c_str(), request->surname.c_str());RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Sending back the capitalize full name: [%s]", response->capitalfullname.c_str());
}int main(int argc, char **argv)
{rclcpp::init(argc, argv);auto node = std::make_shared<MyServiceNode>("service_node");rclcpp::spin(node);   // the service starts to wait and manage requestsrclcpp::shutdown();
}

3.3 client_node_class.cpp

/*** @file client_node_class.cpp** @brief A basic ROS2 service client node with class implementation that asks the user *        to input twostrings and gets back a capitalized full string from the server service.*        It's necessary to use the custom message defined in the external *        package "custom_interface"** @author Antonio Mauro Galiano* Contact: https://www.linkedin.com/in/antoniomaurogaliano/**/#include "custom_interface/srv/capital_full_name.hpp"
#include "rclcpp/rclcpp.hpp"using namespace std::chrono_literals;class MyClientNode : public rclcpp::Node
{
private:const std::string name_;const std::string surname_;rclcpp::Client<custom_interface::srv::CapitalFullName>::SharedPtr client_;void ServerResponse();public:MyClientNode(std::string passedNodeName="VOID", std::string passedName="VOID", std::string passedSurname="VOID"): Node(passedNodeName), name_(passedName), surname_(passedSurname){client_ = this->create_client<custom_interface::srv::CapitalFullName>("create_cap_full_name");this->ServerResponse();}};void MyClientNode::ServerResponse()
{auto request =std::make_shared<custom_interface::srv::CapitalFullName::Request>();request->name = name_;request->surname = surname_;std::chrono::seconds myPause = 1s;while (!client_->wait_for_service(1s)) {if (!rclcpp::ok()) {RCLCPP_ERROR(rclcpp::get_logger("rclcpp"),"Interrupted while waiting for the service. Exiting.");}RCLCPP_INFO(rclcpp::get_logger("rclcpp"),"SERVICE NOT AVAILABLE, waiting again...");}auto result = client_->async_send_request(request);// note that for the MyClientNode object it's used the get_node_base_interface// to allow the client spinning for a server response// it returns the needed rclcpp::node_interfaces::NodeBaseInterface::SharedPtr if (rclcpp::spin_until_future_complete(this->get_node_base_interface(), result) ==rclcpp::FutureReturnCode::SUCCESS){RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Capitalized full name: %s",result.get()->capitalfullname.c_str());} else{RCLCPP_ERROR(rclcpp::get_logger("rclcpp"),"Failed to call service create_cap_full_name");}
}int main(int argc, char **argv)
{rclcpp::init(argc, argv);std::string name = "";std::string surname = "";std::cout << "Insert the name -> ";std::cin >> name;std::cout << "Insert the surname -> ";std::cin >> surname;auto node = std::make_shared<MyClientNode>("client_node", name, surname);rclcpp::shutdown();
}

3.4 CMakeLists.txt

cmake_minimum_required(VERSION 3.5)
project(learning03_service)# Default to C99
if(NOT CMAKE_C_STANDARD)set(CMAKE_C_STANDARD 99)
endif()# Default to C++14
if(NOT CMAKE_CXX_STANDARD)set(CMAKE_CXX_STANDARD 14)
endif()if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")add_compile_options(-Wall -Wextra -Wpedantic)
endif()# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(custom_interface REQUIRED)if(BUILD_TESTING)find_package(ament_lint_auto REQUIRED)# the following line skips the linter which checks for copyrights# uncomment the line when a copyright and license is not present in all source files#set(ament_cmake_copyright_FOUND TRUE)# the following line skips cpplint (only works in a git repo)# uncomment the line when this package is not in a git repo#set(ament_cmake_cpplint_FOUND TRUE)ament_lint_auto_find_test_dependencies()
endif()# add_executable(service_node src/service_node.cpp)
# ament_target_dependencies(service_node rclcpp custom_interface)# add_executable(client_node src/client_node.cpp)
# ament_target_dependencies(client_node rclcpp custom_interface)add_executable(client_node_class src/client_node_class.cpp)
ament_target_dependencies(client_node_class rclcpp custom_interface)add_executable(service_node_class src/service_node_class.cpp)
ament_target_dependencies(service_node_class rclcpp custom_interface)install(TARGETS#  service_node#  client_nodeclient_node_classservice_node_classDESTINATION lib/${PROJECT_NAME})ament_export_dependencies(rosidl_default_runtime)
ament_package()

3.5 package.xml

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3"><name>learning03_service</name><version>0.0.0</version><description>Example nodes to create service server and service client</description><maintainer email="foo@foo.foo">Antonio Mauro Galiano</maintainer><license>TODO: License declaration</license><buildtool_depend>ament_cmake</buildtool_depend><build_depend>rclcpp</build_depend><exec_depend>rclcpp</exec_depend><test_depend>ament_lint_auto</test_depend><test_depend>ament_lint_common</test_depend><depend>custom_interface</depend><export><build_type>ament_cmake</build_type></export>
</package>

4 編譯運行

# 編譯
colcon build# source環境變量
source install/setup.sh# 運行publisher
ros2 run learning03_service client_node_class# 運行subsriber
ros2 run learning03_service server_node_class

5 service常用指令

# 查看service列表
ros2 service list# 查看所有service類型
ros2 service list -t# 查看service類型
ros2 service type <service_name># 查看同一類型所有在運行的service
ros2 service find <service_type># 查看service內容
ros2 interface show <service_interface>
ros2 interface show <service_name># 調用service
ros2 service call <service_name> <service_type>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/211289.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/211289.shtml
英文地址,請注明出處:http://en.pswp.cn/news/211289.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C#,圖算法——以鄰接節點表示的圖最短路徑的迪杰斯特拉(Dijkstra)算法C#程序

1 文本格式 using System; using System.Text; using System.Linq; using System.Collections; using System.Collections.Generic; namespace Legalsoft.Truffer.Algorithm { public class Node // : IComparable<Node> { private int vertex, weigh…

第7章-使用統計方法進行變量有效性測試-7.5.4-模型評估

目錄 混淆矩陣 準確率 定義 局限性 精準率 定義 局限性

【分布式微服務專題】從單體到分布式(一、SpringCloud項目初步升級)

目錄 前言閱讀對象閱讀導航前置知識筆記正文一、單體服務介紹二、服務拆分三、分布式微服務升級前的思考3.1 關于SpringBoot/SpringCloud的思考【有點門檻】 四、SpringCloud升級整合4.1 新建父子項目 學習總結感謝 前言 從本節課開始&#xff0c;我將自己手寫一個基于SpringC…

如何輕松恢復 Windows 中刪除的文件夾

我們都曾經歷過這樣的事&#xff0c;而且我們中的大多數人可能很快就會再次這樣做。我們討論的是在 Windows 中按“Delete”或“ShiftDelete”鍵意外刪除重要文件夾的情況。 如果您剛剛按下刪除鍵且未超過 30 天&#xff0c;或者尚未清空回收站&#xff0c;則可以恢復文件夾。…

操作系統學習筆記---內存管理

目錄 概念 功能 內存空間的分配和回收 地址轉換 邏輯地址&#xff08;相對地址&#xff09; 物理地址&#xff08;絕對地址&#xff09; 內存空間的擴充 內存共享 存儲保護 方式 源程序變為可執行程序步驟 鏈接方式 裝入方式 覆蓋 交換 連續分配管理方式 單一連…

python安裝與工具PyCharm

摘要&#xff1a; 周末閑來無事學習一下python&#xff01;不是你菜雞&#xff0c;只不過是對手太強了&#xff01;所以你要不斷努力&#xff0c;去追求更高的未來&#xff01;下面先了解python與環境的安裝與工具的配置&#xff01; python安裝&#xff1a; 官網 進入官網下載…

lua腳本串口收發與CRC16校驗及使用方法

lua腳本CRC16校驗 --calculate CRC16校驗 --data : t, data to be verified --n : number of verified --return : check result function add_crc16(start, n, data)local carry_flag, a 0local result 0xfffflocal i startwhile(true)doresult result ~ data[i]for j…

git 關于分支、merge、commit提交

最近開始用git終端提交代碼&#xff0c;梳理了一些知識點 一 關于分支 關于分支&#xff0c;git的分支分為本地分支遠程分支兩種分支&#xff0c;在上傳代碼時&#xff0c;我們要確保當前本地分支連接了一個遠程分支。 我們可以通過下面代碼查看當前的本地分支&#xff1a; g…

迅為3588開發板 sudo: 無法解析主機:/DNS配置

環境申明 RK3588 ubuntu 22.04 jammy 迅為開發板 hostname 看是否有Host .&#xff0c;如果沒有&#xff0c; sudo vim /etc/hostname在里面加一行&#xff0c;我這就這一個 iTOP-RK3588hosts 修改本地hosts sudo vim /etc/hosts127.0.0.1 localhost localhost iTOP-RK3…

2.postman環境變量及接口關聯

一、環境變量以及全局變量 操作流程 1.點擊environment 2.點擊environment右側號&#xff0c;新增環境變量 3.在變量中輸入變量名以及變量值 4.回到collection頁面&#xff0c;修改變量環境 5.在collection中通過{{變量名}}調用變量 變量定義 環境變量&#xff1a;環境變量…

vue 限制在指定容器內可拖拽的div

<template><div class"container" id"container"><div class"drag-box center" v-drag v-if"isShowDrag"><div>無法拖拽出容器的div浮窗</div></div></div> </template><script&g…

P11 Linux進程編程exec族函數

前言 &#x1f3ac; 個人主頁&#xff1a;ChenPi &#x1f43b;推薦專欄1: 《Linux C應用編程&#xff08;概念類&#xff09;_ChenPi的博客-CSDN博客》??? &#x1f525; 推薦專欄2: 《C_ChenPi的博客-CSDN博客》??? &#x1f6f8;推薦專欄3: ??????《鏈表_C…

Java 簡易版 UDP 多人聊天室

服務端 import java.io.*; import java.net.*; import java.util.ArrayList; public class Server{public static ServerSocket server_socket;public static ArrayList<Socket> socketListnew ArrayList<Socket>(); public static void main(String []args){try{…

算法通關村第五關—LRU的設計與實現(黃金)

LRU的設計與實現 一、理解LRU的原理 LeetCode146:運用你所掌握的數據結構&#xff0c;設計和實現一個LRU(最近最少使用)緩存機制 實現LRUCache類&#xff1a; LRUCache(int capacity) 以正整數作為容量capacity初始化 LRU 緩存 int get(int key) 如果關鍵字key存在于緩存中&a…

數據可視化|jupyter notebook運行pyecharts,無法正常顯示“可視化圖形”,怎么解決?

前言 本文是該專欄的第39篇,后面會持續分享python數據分析的干貨知識,記得關注。 相信有些同學在本地使用jupyter notebook運行pyecharts的時候,在代碼沒有任何異常的情況下,無論是html還是notebook區域,都無法顯示“可視化圖形”,界面區域只有空白一片。遇到這種情況,…

SQL(COALESCE)

zstarling 非空值查找及替換COALESCE 非空值查找及替換COALESCE 新語法SQL COALESCE(staff_no,staff_no1,)詳解 在SQL中&#xff0c;COALESCE函數用于返回一組表達式中的第一個非NULL值。它接受兩個或多個參數&#xff0c;并按參數順序依次判斷每個參數是否為NULL&#xff0c…

如何才能保證績效考核的有效性呢?

績效管理是現代人力資源管理的核心&#xff0c;做好績效考核是做好績效管理的重要手段。但企業績效考核的設計往往缺乏針對性和科學性&#xff0c;績效考核工作也常常停留在形式上&#xff0c;最終沒能為提高組織效率提供幫助&#xff0c;還消耗員工與管理者的時間、精力。于是…

Nginx服務優化以及防盜鏈

1. 隱藏版本號 以在 CentOS 中使用命令 curl -I http://192.168.66.10 顯示響應報文首部信息。 查看版本號 curl -I http://192.168.66.10 1. 修改配置文件 vim /usr/local/nginx/conf/nginx.conf http {include mime.types;default_type application/octet-stream;…

京東數據運營(京東API接口):10月投影儀店鋪數據分析

鯨參謀監測的京東平臺10月份投影儀市場銷售數據已出爐&#xff01; 10月份&#xff0c;環同比來看&#xff0c;投影儀市場銷售均上漲。鯨參謀數據顯示&#xff0c;今年10月&#xff0c;京東平臺投影儀的銷量為16萬&#xff0c;環比增長約22%&#xff0c;同比增長約8%&#xff1…

鴻蒙應用開發ArkTS基礎組件的使用

語雀知識庫地址&#xff1a;語雀HarmonyOS知識庫 飛書知識庫地址&#xff1a;飛書HarmonyOS知識庫 本文示例代碼地址&#xff1a;Gitee 倉庫地址 嗨&#xff0c;各位好呀&#xff0c;我是小白 上一篇文章我為大家介紹了如何使用 ArkTS 開發鴻蒙應用&#xff0c;對 HarmonyOS 項…