
Halo,這里是Ppeua。平時(shí)主要更新C語(yǔ)言,C++,數(shù)據(jù)結(jié)構(gòu)算法…感興趣就關(guān)注我吧!你定不會(huì)失望。
本章將介紹如何通過(guò)服務(wù)通信的方式實(shí)現(xiàn)節(jié)點(diǎn)數(shù)據(jù)交換以及ROS相關(guān)指令
0.服務(wù)通信概念
在ros中,一個(gè)節(jié)點(diǎn)想要獲取某種服務(wù)(例如:一個(gè)節(jié)點(diǎn)想要獲取此時(shí)的相機(jī)數(shù)據(jù),節(jié)點(diǎn)就需要向相機(jī)發(fā)送一個(gè)請(qǐng)求,而相機(jī)接收到請(qǐng)求后可以根據(jù)消息類(lèi)型將數(shù)據(jù)類(lèi)型返回),這就是基本的服務(wù)通信使用場(chǎng)景。
以請(qǐng)求響應(yīng)的方式實(shí)現(xiàn)不同節(jié)點(diǎn)間的數(shù)據(jù)交互
我們現(xiàn)階段也不需要了解具體這代表什么意思,只需要知道:
client客戶(hù)端/server服務(wù)端先后在rosmaster中注冊(cè)本身信息,然后通過(guò)相同話題匹配.
- server 與 client 的啟動(dòng)無(wú)先后順序要求
- server 與 client 都可以有多個(gè)
- server 與 client 連接后不再需要rosmaster,也就是說(shuō)僅在嘗試連接的時(shí)候需要rosmaster
1.自定義srv消息
srv消息是服務(wù)端與客戶(hù)端之間通信的一個(gè)數(shù)據(jù)載體,可用數(shù)據(jù)類(lèi)型與std_msgs里的數(shù)據(jù)類(lèi)型一致,但需要自己定義.
步驟大概為以下幾步:
- 根據(jù)需要定義srv格式消息
- 修改配置文件
- 編譯生成中間文件并引用
1.1定義srv格式消息
這是一個(gè)自己定義的srv的消息格式
因?yàn)橐獙?shí)現(xiàn)的是兩個(gè)數(shù)相加,所以這樣定義。
其中—上方為client客戶(hù)端發(fā)送的消息格式,下方為服務(wù)端響應(yīng)的消息格式。
# 客戶(hù)端請(qǐng)求
int32 num1
int32 num2
---
# 服務(wù)端響應(yīng)
int32 ans
1.2修改配置文件
- 和定義msg類(lèi)似,也要先修改功能包目錄下的package.xml,
其中54行的message_generation是編譯時(shí)的消息軟件包
而59行message_runtime是運(yùn)行時(shí)的消息軟件包 -
在CMakeList中找到這些地方并修改
# 1.編譯時(shí)的依賴(lài)包 find_package(catkin REQUIRED COMPONENTS rospy std_msgs message_generation ) # 2.加入自己定義的srv文件名字 add_service_files( FILES Addints.srv ) # 3.編譯包時(shí)的消息依賴(lài) generate_messages( DEPENDENCIES std_msgs ) # 4.加入message_runtime,但官網(wǎng)沒(méi)有這一步似乎也可以. catkin_package(**chmod +x py文件** CATKIN_DEPENDS rospy std_msgs message_runtime )
-
編譯一下,可以在這個(gè)路徑中找到剛剛編譯完的中間件
之后調(diào)用的方法如下:
至于為什么要import * 我們可以先來(lái)看看編譯完產(chǎn)生的文件是什么樣的:# from packagename.srv import *
其產(chǎn)生了一個(gè)srv的中間件,出現(xiàn)了三個(gè)類(lèi),我們之后這三個(gè)類(lèi)都需要使用到,所以一般都是直接import*
2.自定義srv服務(wù)通信客戶(hù)端python實(shí)現(xiàn):
先來(lái)分析下作為一個(gè)客戶(hù)端我們需要做什么事:
- 初始化ros節(jié)點(diǎn)
- 創(chuàng)建請(qǐng)求對(duì)象,設(shè)置通信話題
- 請(qǐng)求響應(yīng),獲得響應(yīng)結(jié)果
import rospy
import lesson3_srv.srv import *
rospy.init_node("sum_client")
client=rospy.ServiceProxy("sum2",Addints)
if(len(sys.argv)!=3):
rospy.logerr("參數(shù)不對(duì)")
sys.exit(1)
num=int(sys.argv[1])
num2=int(sys.argv[2])
response=client.call(num,num2)
rospy.loginfo("%d",response.ans)
這里先導(dǎo)入了rospy的包以及消息類(lèi)型,初始化了節(jié)點(diǎn)信息與話題。
創(chuàng)建了請(qǐng)求服務(wù)的對(duì)象,serviceprovy(話題,srv消息)
對(duì)傳入的參數(shù)進(jìn)行了一個(gè)處理
clint.call返回類(lèi)型為自定義消息類(lèi)型的格式,call(srv中的參數(shù))最后處理返回的消息
這就是客戶(hù)端實(shí)現(xiàn),當(dāng)然還有一些優(yōu)化內(nèi)容,等服務(wù)端實(shí)現(xiàn)完在提
3.自定義srv服務(wù)通信服務(wù)端python實(shí)現(xiàn):
先來(lái)分析下作為一個(gè)服務(wù)端我們需要做什么事:
- 初始化節(jié)點(diǎn)
- 設(shè)置訂閱話題
- 設(shè)置處理消息的回調(diào)函數(shù)
import rospy
from lesson3_srv.srv import *
def doNum(request):
num1=request.num1
num2=request.num2
sum=num1+num2
response=AddintsResponse()
response.ans=sum
rospy.loginfo("%d %d %d",request.num1,request.num2,response.ans)
return response
rospy.init_node("sum")
server=rospy.Service("sum2",Addints,doNum)
rospy.spin()
這里先導(dǎo)包
然后通過(guò)service(話題名稱(chēng),srv消息類(lèi)型,回調(diào)函數(shù))創(chuàng)建服務(wù)對(duì)象
剛剛客戶(hù)端傳入的數(shù)據(jù),會(huì)作為回調(diào)函數(shù)的參數(shù)
先將其取出,之后通過(guò)AddintsResponse的方法創(chuàng)建一個(gè)返回對(duì)象,改變ans后返回此時(shí)的返回值是給了客戶(hù)端
4.優(yōu)化客戶(hù)端
這里的客戶(hù)端有個(gè)很小的問(wèn)題,僅能在服務(wù)器啟動(dòng)后進(jìn)行通信,若服務(wù)器沒(méi)有啟動(dòng),而先啟動(dòng)了客戶(hù)端就會(huì)出錯(cuò),ros官方提供了兩個(gè)解決方法,二者選其一即可
# rospy.wait_for_service(話題名稱(chēng))
# client.wait_for_service()
所以改進(jìn)的客戶(hù)端代碼如下:
import rospy
import sys
from lesson3_srv.srv import *
rospy.init_node("sum_client")
client=rospy.ServiceProxy("sum2",Addints)
if(len(sys.argv)!=3):
rospy.logerr("參數(shù)不對(duì)")
sys.exit(1)
num=int(sys.argv[1])
num2=int(sys.argv[2])
#client.wait_for_service()
rospy.wait_for_service("sum2")
response=client.call(num,num2)
rospy.loginfo("%d",response.ans)
5.啟動(dòng)運(yùn)行
- 先添加可執(zhí)行權(quán)限 chmod +x py文件
-
之后配置一下CMakeList.txt
catkin_install_python( PROGRAMS scripts/demo01_server.py scripts/demo01_client.py DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} )
-
rosrun lesson3_srv demo01_client.py rosrun lesson3_srv demo01_server.py
運(yùn)行效果:傳入2 3 返回值為 5文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-436639.html
至此服務(wù)通信內(nèi)容結(jié)束文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-436639.html
到了這里,關(guān)于【ROS】如何讓ROS中節(jié)點(diǎn)實(shí)現(xiàn)數(shù)據(jù)交換Ⅱ --服務(wù)通信的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!