ROS2 筆記匯總(2) 通信接口

ROS 系統中,通信接口(Interface) 是節點之間傳遞信息的標準“語言協議”,確保了不同功能節點之間可以正確理解和使用彼此傳送的數據內容。我們可以將其理解為“數據結構+格式定義”,貫穿于話題(Topic)、服務(Service)、動作(Action)等通信機制中。

在軟件開發中,“接口”是一種連接關系,它規定了數據如何進出,模塊如何對接,只有兩邊的格式和要求一致,系統才能正常“搭伙做事”。

為了讓每個 ROS 節點可以用不同的語言編寫,比如一個節點用 C++ 控制硬件,另一個節點用 Python 實現上層邏輯,ROS 把通信接口設計成與編程語言無關的格式

int32 表示 32 位整型

int64 表示 64 位長整型

bool 表示布爾值

還支持數組(如 int32[])、嵌套結構體等復合數據類型

這些接口定義寫在 .msg(消息)或 .srv(服務)文件中。
編譯時,ROS 會自動生成對應語言(如 C++ 或 Python)里的數據結構文件,供節點直接使用,開發者不需要自己去寫解析邏輯。

無論你用什么語言編寫節點,只要遵循統一接口,數據就能準確傳輸、協同工作。

ROS 2 三種通信機制(話題、服務、動作)在接口定義上的格式差異。

在 ROS 2 系統中,通信接口的定義格式因通信機制而異,但都遵循統一的、語言無關的描述方式。

話題(Topic)通信

使用 .msg 文件定義,屬于單向異步通信
只需定義每一幀數據的內容格式,如:

int32 x
int32 y
表示消息中包含兩個 32 位整型數據,可用于發送二維坐標等。

服務(Service)通信

使用 .srv 文件定義,屬于請求-應答式的同步通信
定義由請求部分應答部分組成,中間用 --- 分隔,例如:

int64 a
int64 b
---
int64 sum
客戶端發起請求,包含 ab,服務器處理后返回 sum

動作(Action)通信

使用 .action 文件定義,適合描述持續一段時間的過程性任務,如移動、旋轉、導航等。

定義包含三部分:

# 目標
bool enable
---
# 結果
bool finish
---
# 反饋
int32 state

目標(Goal):開始任務,如開始轉動

結果(Result):任務最終是否完成

反饋(Feedback):周期性返回進度,如當前已轉動角度

通信機制接口文件特點數據方向
話題.msg異步、廣播單向
服務.srv同步請求客戶端 ? 服務端
動作.action可反饋過程客戶端 ? 服務端 + 反饋

服務接口的定義與使用

在本案例中,我們以一個獲取目標位置的服務為例,全面了解 ROS 2 中服務接口的定義方法及實際應用方式。

learning_interface/srv/GetObjectPosition.srv

bool get ? ? # 請求:是否獲取目標位置
---
int32 x ? ? ?# 響應:目標X坐標
int32 y ? ? ?# 響應:目標Y坐標

bool get:客戶端請求參數,true 表示請求當前目標位置。

---:分隔請求與響應。

int32 x, y:服務端反饋的目標坐標。

import rclpy                                            # ROS2 Python接口庫
from rclpy.node   import Node                           # ROS2 節點類
from learning_interface.srv import GetObjectPosition    # 自定義的服務接口class objectClient(Node):def __init__(self, name):super().__init__(name)                          # ROS2節點父類初始化self.client = self.create_client(GetObjectPosition, 'get_target_position')while not self.client.wait_for_service(timeout_sec=1.0):self.get_logger().info('service not available, waiting again...')self.request = GetObjectPosition.Request()def send_request(self):self.request.get = Trueself.future = self.client.call_async(self.request)def main(args=None):rclpy.init(args=args)                             # ROS2 Python接口初始化node = objectClient("service_object_client")      # 創建ROS2節點對象并進行初始化node.send_request()while rclpy.ok():rclpy.spin_once(node)if node.future.done():try:response = node.future.result()except Exception as e:node.get_logger().info('Service call failed %r' % (e,))else:node.get_logger().info('Result of object position:\n x: %d y: %d' %(response.x, response.y))breaknode.destroy_node()                              # 銷毀節點對象rclpy.shutdown()                                 # 關閉ROS2 Python接口import rclpy                                           # ROS2 Python接口庫
from rclpy.node import Node                            # ROS2 節點類
from sensor_msgs.msg import Image                      # 圖像消息類型
import numpy as np                                     # Python數值計算庫
from cv_bridge import CvBridge                         # ROS與OpenCV圖像轉換類
import cv2                                             # Opencv圖像處理庫
from learning_interface.srv import GetObjectPosition   # 自定義的服務接口lower_red = np.array([0, 90, 128])     # 紅色的HSV閾值下限
upper_red = np.array([180, 255, 255])  # 紅色的HSV閾值上限class ImageSubscriber(Node):def __init__(self, name):super().__init__(name)                              # ROS2節點父類初始化self.sub = self.create_subscription(Image, 'image_raw', self.listener_callback, 10) # 創建訂閱者對象(消息類型、話題名、訂閱者回調函數、隊列長度)self.cv_bridge = CvBridge()                         # 創建一個圖像轉換對象,用于OpenCV圖像與ROS的圖像消息的互相轉換self.srv = self.create_service(GetObjectPosition,   # 創建服務器對象(接口類型、服務名、服務器回調函數)'get_target_position',self.object_position_callback)    self.objectX = 0self.objectY = 0                              def object_detect(self, image):hsv_img = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)      # 圖像從BGR顏色模型轉換為HSV模型mask_red = cv2.inRange(hsv_img, lower_red, upper_red) # 圖像二值化contours, hierarchy = cv2.findContours(mask_red, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)   # 圖像中輪廓檢測for cnt in contours:                                  # 去除一些輪廓面積太小的噪聲if cnt.shape[0] < 150:continue(x, y, w, h) = cv2.boundingRect(cnt)              # 得到蘋果所在輪廓的左上角xy像素坐標及輪廓范圍的寬和高cv2.drawContours(image, [cnt], -1, (0, 255, 0), 2)# 將蘋果的輪廓勾勒出來cv2.circle(image, (int(x+w/2), int(y+h/2)), 5,(0, 255, 0), -1)                       # 將蘋果的圖像中心點畫出來self.objectX = int(x+w/2)self.objectY = int(y+h/2)cv2.imshow("object", image)                            # 使用OpenCV顯示處理后的圖像效果cv2.waitKey(50)def listener_callback(self, data):self.get_logger().info('Receiving video frame')        # 輸出日志信息,提示已進入回調函數image = self.cv_bridge.imgmsg_to_cv2(data, 'bgr8')     # 將ROS的圖像消息轉化成OpenCV圖像self.object_detect(image)                              # 蘋果檢測def object_position_callback(self, request, response):     # 創建回調函數,執行收到請求后對數據的處理if request.get == True:response.x = self.objectX                          # 目標物體的XY坐標response.y = self.objectYself.get_logger().info('Object position\nx: %d y: %d' %(response.x, response.y))   # 輸出日志信息,提示已經反饋else:response.x = 0response.y = 0self.get_logger().info('Invalid command')          # 輸出日志信息,提示已經反饋return responsedef main(args=None):                                 # ROS2節點主入口main函數rclpy.init(args=args)                            # ROS2 Python接口初始化node = ImageSubscriber("service_object_server")  # 創建ROS2節點對象并進行初始化rclpy.spin(node)                                 # 循環等待ROS2退出node.destroy_node()                              # 銷毀節點對象rclpy.shutdown()                                 # 關閉ROS2 Python接口

這是一個通過圖像識別紅色目標物體并通過ROS服務機制獲取其當前坐標的系統。

服務器端(服務提供方):接收圖像并處理,檢測紅色物體位置,一旦客戶端請求,就返回該位置。

客戶端(服務調用方):主動發起“請告訴我目標位置”的請求,獲取最新坐標。

在 ROS2 中,通信接口(Interface) 是一種標準格式的“數據結構定義”,用于描述節點間如何傳遞數據。

對于 服務通信(Service) 來說,接口包括兩部分:

請求部分(Request):客戶端發送給服務端的數據。

響應部分(Response):服務端返回給客戶端的結果。

接口使用 .srv 文件定義,例如你定義的:

定義通信接口文件 .srv

bool get
---
int32 x
int32 y

在服務端創建服務對象,綁定回調

self.srv = self.create_service(
? ? GetObjectPosition, ? ? ? ? ? ? ? ? ? # 使用定義好的接口
? ? 'get_target_position', ? ? ? ? ? ? ?# 服務名
? ? self.object_position_callback ? ? ? # 處理函數
)

在客戶端創建服務請求并發送

self.client = self.create_client(GetObjectPosition, 'get_target_position')
self.request = GetObjectPosition.Request()
self.request.get = True
self.future = self.client.call_async(self.request)

服務端處理請求并返回響應

def object_position_callback(self, request, response):
? ? if request.get:
? ? ? ? response.x = self.objectX
? ? ? ? response.y = self.objectY
? ? return response

再次說明,# 文件:learning_interface/srv/GetObjectPosition.srv
bool get
---
int32 x
int32 y

系統會自動生成:

一個 GetObjectPosition.Request 類(含 get 字段)

一個 GetObjectPosition.Response 類(含 xy 字段)

所以,你在代碼中哪里寫了 .get.x.y,就說明用了通信接口定義的字段!

通信接口 .srv 文件是怎么關聯上的?

在代碼中,首先導入:# 文件:learning_interface/srv/GetObjectPosition.srv

from learning_interface.srv import GetObjectPosition

意思是:你定義的服務接口 GetObjectPosition.srv,位于 ROS功能包 learning_interfacesrv/ 文件夾里

你就可以在你項目的工作空間中查找該文件:cd ~/ros2_ws/src/learning_interface/srv
ls
# 應該能看到 GetObjectPosition.srv

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

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

相關文章

微信小程序:將搜索框和表格封裝成組件,頁面調用組件

一、實現效果 實現搜索框,表格和翻頁效果 二、組件實現 1、創建表格組件頁面 (1)創建文件 在文件根目錄(與pages同級)直接創建components文件夾,并創建表格的頁面common-table/index (2)視圖層 a、寫入表頭 循環由主頁面傳遞的columns,數據為字段名label,寬度為設置…

基于貝葉斯學習方法的塊稀疏信號壓縮感知算法

基于貝葉斯學習方法的塊稀疏信號壓縮感知算法 BSBL-FM-master/BSBL_BO.m , 15593 BSBL-FM-master/BSBL_FM.m , 12854 BSBL-FM-master/Phi.mat , 131256 BSBL-FM-master/README.md , 3954 BSBL-FM-master/demo.mat , 1610 BSBL-FM-master/demo_fecg.m , 1481 BSBL-FM-master/de…

【Python爬蟲】requests知識點講解

目錄 前言1. requests庫基礎1.1 安裝requests1.2 基本導入 2. HTTP請求方法2.1 GET請求2.2 POST請求2.3 其他HTTP方法 3. 請求頭設置3.1 User-Agent設置3.2 常用請求頭 4. 響應處理4.1 響應內容獲取4.2 響應狀態碼4.3 響應頭信息 5. 會話管理5.1 Session對象5.2 Cookie處理 6. …

服務器上安裝配置vsftpd

目錄 1. 安裝vsftpd服務 2、修改配置文件 3. 修改用戶白名單 4. 通過ftp客戶端命令登錄ftp服務器 5. 參考資料 1. 安裝vsftpd服務 執行命令安裝vsftp服務、和ftp客戶端 yum install vsftpd yum install ftp 2、修改配置文件 在服務器上先創建一個系統用戶&#xff0c;待…

C#實現圖片文字識別

這幾年的AI的發展&#xff0c;使得文字識別難度大大降低、精度大大的提高。百度飛漿就是一個非常好的AI框架&#xff0c;而且是開源的。 我們利用百度飛漿就能快速簡單的實現文字識別功能&#xff0c;幾行代碼就可以集成。 其中百度飛漿的PaddleOCR&#xff0c;就是專門針對文…

Android Framework 調用棧

在Android Framework開發中&#xff0c;添加調用棧&#xff08;Call Stack&#xff09;是調試復雜問題&#xff08;如崩潰、死鎖或流程追蹤&#xff09;的核心手段。 一、Java層調用棧添加 適用于Activity、Service等組件或Framework中的Java代碼。 基礎方法&#xff1a; 使用…

Ollama安裝非系統盤操作方法(2025年6月測試通過)

Ollama是當前部署大模型比較便利的工具&#xff0c;但是默認會將軟件和模型都安裝到C盤下&#xff0c;導致系統盤爆表&#xff0c;建議將軟件和模型都放置在非系統盤。 1. 軟件安裝在非系統盤 &#xff08;1&#xff09;在D盤下手動創建ollama目錄 &#xff08;2&#xff09…

《HTTP權威指南》 第1-2章 HTTP和URL基礎

HTTP請求基礎 格式化數據塊稱為HTTP報文 請求報文&#xff1a;從客戶端發往服務器的HTTP報文&#xff0c;只有請求起始行請求首部&#xff0c;沒有請求主體 響應報文&#xff1a;從服務器發往客戶端的報文&#xff0c;包含響應起始行響應首部響應主體 HTTP報文通過傳輸控制…

9. TypeScript 泛型

TypeScript 中的泛型使開發者能夠編寫靈活、可重用的代碼&#xff0c;同時保持類型安全。它們允許動態定義類型&#xff0c;確保函數、類和接口可以適用于任何數據類型。這有助于避免重復&#xff0c;提高代碼的模塊化&#xff0c;使其既類型安全又具備適應性。 一、認識泛型 …

Apache Iceberg與Hive集成:分區表篇

一、Iceberg分區表核心概念與Hive集成原理 1.1 分區表在大數據場景的價值 在大規模數據分析中&#xff0c;分區表通過將數據按特定維度&#xff08;如時間、地域、業務類型&#xff09;劃分存儲&#xff0c;可顯著提升查詢效率。Apache Iceberg的分區表設計融合了Hive的分區理…

SAST + IAST + DAST 全鏈路防護體系構建方案

&#x1f525;「炎碼工坊」技術彈藥已裝填&#xff01; 點擊關注 → 解鎖工業級干貨【工具實測|項目避坑|源碼燃燒指南】 1. 生命周期分層嵌入&#xff08;防御縱深&#xff09; 階段工具防護重點集成觸發點編碼階段SAST源碼漏洞&#xff08;硬編碼密鑰、SQL注入模式&#x…

pnpm link如何不踩坑

前提一&#xff1a;我有一個source-project源碼庫&#xff0c;有一個develop-project項目庫。想使用pnpm link對source-project進行本地調試。 前提二&#xff1a;source-project源碼庫已打包 本地調試詳細步驟如下&#xff1a; 1、檢查是否配置了系統環境變量&#xff0c;P…

vue3 javascript 多字段求和技巧

在 Vue 3 中&#xff0c;如果你需要在一個組件中處理多個字段的求和&#xff0c;你可以通過計算屬性&#xff08;computed properties&#xff09;或者方法&#xff08;methods&#xff09;來實現。這里我將展示兩種主要的方法&#xff1a; 方法 1&#xff1a;使用計算屬性&am…

【LeetCode】每日一題 —— No.3405

LeetCode 3405 統計恰好有 K 個相等相鄰元素的數組數目&#xff08;DP 構造型&#xff09; 題目概述 我們需要統計長度為 n 的數組 arr 滿足如下條件的方案數&#xff1a; 每個元素在區間 [1, m] 之間恰好存在 k 個位置 i (1 ≤ i < n) 滿足 arr[i] arr[i - 1] 也就是說…

Elsa Workflows: .NET 的開源工作流引擎簡介

文章目錄 Elsa Workflows&#xff1a; .NET 的開源工作流引擎核心定位與理念關鍵特性與優勢當前 (Elsa 3) 的已知限制/待完善項總結 Elsa Workflows&#xff1a; .NET 的開源工作流引擎 Elsa Workflows 是一個開源的、模塊化的 .NET 庫集合&#xff0c;旨在為 .NET 應用程序提…

linux虛擬機yum命令報錯解決方案

問題 假如出現了這樣的問題&#xff0c;可能是虛擬機yum庫存在問題 解決方法 1、打開cmd&#xff0c;輸入ssh root地址&#xff0c;比如ssh root192.168.222..111&#xff0c;選yes&#xff0c;輸入虛擬機密碼 2、使用yum repolist,查看倉庫狀態&#xff0c;status下面如果是…

C++ 第一階段 基本語法 - 第一節:變量與數據類型詳解

目錄 一、變量與數據類型概述 1.1 什么是變量&#xff1f; 1.2 數據類型分類 二、基本數據類型詳解 2.1 整型&#xff08;int, short, long&#xff09; 2.1.1 常見整型類型 2.1.2 代碼示例 2.1.3 注意事項 2.2 浮點型&#xff08;float, double&#xff09; 2.2.1 浮…

CppCon 2017 學習:CNL: A Compositional Numeric Library

你說的這段關于浮點數的問題總結得很精準&#xff0c;我幫你整理一下&#xff0c;讓理解更清晰&#xff1a; The Problem with Floating-Point&#xff08;浮點數的問題&#xff09; 復雜的表示結構 浮點數由符號位 &#xff0c;有效數&#xff08;significand/mantissa&…

linux基礎重定向及組合重定向

一、基礎重定向操作符 ?類別? ?操作符? ?含義? ?示例? ?備注? ?標準輸出? > 覆蓋寫入 stdout 到文件 ls > file.txt 文件不存在則創建&#xff0c;存在則清空內容 >> 追加 stdout 到文件末尾 date >> log.txt 保留原有內容 ?標準…

佰力博科技與您探討鐵電分析儀適用場景

鐵電分析儀是一種用于測試和研究鐵電材料性能的精密儀器&#xff0c;其適用場景非常廣泛&#xff0c;涵蓋了材料科學、物理學、電子工程等多個領域。 1、材料科學與工程 鐵電分析儀廣泛應用于鐵電材料的研究&#xff0c;包括薄膜、厚膜、塊體材料以及電子陶瓷等。它能夠測試材料…