了解了通信接口的概念,接下來(lái)我們?cè)購(gòu)拇a實(shí)現(xiàn)的角度,研究下如何定義以及使用一個(gè)接口。
在之前服務(wù)概念講解的課程中,我們編寫(xiě)了這樣一個(gè)例程,我們?cè)賮?lái)回顧下。
有三個(gè)節(jié)點(diǎn):
第一個(gè)驅(qū)動(dòng)相機(jī)發(fā)布圖像話(huà)題;
第二個(gè)是機(jī)器視覺(jué)識(shí)別節(jié)點(diǎn),封裝了一個(gè)服務(wù)的服務(wù)端對(duì)象,提供目標(biāo)識(shí)別位置的查詢(xún)服務(wù);
第三個(gè)節(jié)點(diǎn)在需要目標(biāo)位置的時(shí)候,就可以發(fā)送請(qǐng)求,收到位置進(jìn)行使用了。
接口定義
在這個(gè)例程中,我們使用GetObjectPosition.srv定義了服務(wù)通信的接口:
learning_interface/srv/GetObjectPosition.srv
bool get # 獲取目標(biāo)位置的指令---int32 x # 目標(biāo)的X坐標(biāo)int32 y # 目標(biāo)的Y坐標(biāo)
定義中有兩個(gè)部分,上邊是獲取目標(biāo)位置的指令,get為true的話(huà),就表示我們需要一次位置,服務(wù)端就會(huì)反饋這個(gè)x、y坐標(biāo)了。
完成定義后,還需要在功能包的CMakeLists.txt中配置編譯選項(xiàng),讓編譯器在編譯過(guò)程中,根據(jù)接口定義,自動(dòng)生成不同語(yǔ)言的代碼:
...find_package(rosidl_default_generators REQUIRED)rosidl_generate_interfaces(${PROJECT_NAME} "srv/GetObjectPosition.srv")...
功能包的package.xml文件中也需要添加代碼生成的功能依賴(lài):
... < build_depend >rosidl_default_generators< /build_depend > < exec_depend >rosidl_default_runtime< /exec_depend > < member_of_group >rosidl_interface_packages< /member_of_group > ...
程序調(diào)用
我們?cè)诖a中再來(lái)重點(diǎn)看下接口的使用方法。
客戶(hù)端接口調(diào)用
learning_service/service_object_client.py
#!/usr/bin/env python3# -*- coding: utf-8 -*-"""@作者: 古月居@說(shuō)明: ROS2服務(wù)示例-請(qǐng)求目標(biāo)識(shí)別,等待目標(biāo)位置應(yīng)答"""import rclpy # ROS2 Python接口庫(kù)from rclpy.node import Node # ROS2 節(jié)點(diǎn)類(lèi)from learning_interface.srv import GetObjectPosition # 自定義的服務(wù)接口class objectClient(Node): def __init__(self, name): super().__init__(name) # ROS2節(jié)點(diǎn)父類(lèi)初始化 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 = True self.future = self.client.call_async(self.request)def main(args=None): rclpy.init(args=args) # ROS2 Python接口初始化 node = objectClient("service_object_client") # 創(chuàng)建ROS2節(jié)點(diǎn)對(duì)象并進(jìn)行初始化 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)) break node.destroy_node() # 銷(xiāo)毀節(jié)點(diǎn)對(duì)象 rclpy.shutdown() # 關(guān)閉ROS2 Python接口
服務(wù)端接口調(diào)用
learning_service/service_object_server.py
#!/usr/bin/env python3# -*- coding: utf-8 -*-"""@作者: 古月居(www.guyuehome.
-
通信接口
+關(guān)注
關(guān)注
3文章
240瀏覽量
31074 -
服務(wù)端
+關(guān)注
關(guān)注
0文章
66瀏覽量
7066 -
ROS
+關(guān)注
關(guān)注
1文章
281瀏覽量
17126
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論