建設(shè)網(wǎng)站申請(qǐng)空間需要多少錢怎么創(chuàng)建網(wǎng)址
0. 簡介
在前幾講我們講了Matlab中的Message以及Topic的相關(guān)知識(shí)。而ROS主要支持的通信機(jī)制還有服務(wù)這一類。服務(wù)通過允許請(qǐng)求以及響應(yīng)的通信方式,來給整個(gè)系統(tǒng)完成更緊密的耦合。服務(wù)客戶端向服務(wù)服務(wù)器發(fā)送請(qǐng)求消息并等待響應(yīng)。服務(wù)器將使用請(qǐng)求中的數(shù)據(jù)構(gòu)造響應(yīng)消息并將其發(fā)送回客戶端。每個(gè)服務(wù)都有一個(gè)類型,該類型決定請(qǐng)求和響應(yīng)消息的結(jié)構(gòu)。
1. ROS1的服務(wù)端和客戶端
1.1 創(chuàng)建服務(wù)端
在ROS1當(dāng)中,如果希望創(chuàng)建一個(gè)簡單的服務(wù)服務(wù)器,并在調(diào)用服務(wù)時(shí)能夠顯示“A service client is calling”。使用rosssvcserver命令創(chuàng)建服務(wù)。從而指定服務(wù)名稱和服務(wù)消息類型。然后還要將回調(diào)函數(shù)定義為exampleHelperROSEmptyCallback。
為了獲得更快的性能,一般我們?cè)谠O(shè)置rossvcsrve時(shí)候帶上結(jié)構(gòu)格式消息類型。
testserver = rossvcserver("/test","std_srvs/Empty",@exampleHelperROSEmptyCallback,"DataFormat","struct")
testserver =
ServiceServer with properties:
ServiceType: ‘std_srvs/Empty’
ServiceName: ‘/test’
NewRequestFcn: @exampleHelperROSEmptyCallback
DataFormat: ‘struct’
當(dāng)列出ROS網(wǎng)絡(luò)中的所有服務(wù)時(shí),可以看到新服務(wù)/test。
rosservice list
/add
/matlab_global_node_55791/get_loggers
/matlab_global_node_55791/set_logger_level
/node_1/get_loggers
/node_1/set_logger_level
/node_2/get_loggers
/node_2/set_logger_level
/node_3/get_loggers
/node_3/set_logger_level
/reply
/test
此外還可以使用rosservice info獲取有關(guān)您的服務(wù)的更多信息。
rosservice info /test
Node: /matlab_global_node_55791
URI: rosrpc://ah-csalzber:51639
Type: std_srvs/Empty
Args: MessageType
1.2 創(chuàng)建客戶端
使用服務(wù)客戶機(jī)從ROS服務(wù)服務(wù)器請(qǐng)求信息。要?jiǎng)?chuàng)建客戶端,請(qǐng)使用帶有服務(wù)名稱的rossvcclient作為參數(shù)。
為我們剛剛創(chuàng)建的/test服務(wù)創(chuàng)建一個(gè)服務(wù)客戶機(jī)。
testclient = rossvcclient("/test","DataFormat","struct")
testclient =
ServiceClient with properties:
ServiceType: ‘std_srvs/Empty’
ServiceName: ‘/test’
DataFormat: ‘struct’
為服務(wù)創(chuàng)建一個(gè)空請(qǐng)求消息。使用rosmessage函數(shù)并將客戶端作為第一個(gè)參數(shù)傳遞。這將創(chuàng)建一個(gè)具有服務(wù)指定的消息類型和格式的服務(wù)請(qǐng)求函數(shù)。
testreq = rosmessage(testclient)
testreq = struct with fields:
MessageType: ‘std_srvs/EmptyRequest’
確保服務(wù)已連接到客戶端,并在必要時(shí)等待客戶端連接。
waitForServer(testclient,"Timeout",3)
當(dāng)您希望從服務(wù)器獲得響應(yīng)時(shí),請(qǐng)使用call函數(shù),該函數(shù)將調(diào)用服務(wù)服務(wù)器并返回響應(yīng)。您之前創(chuàng)建的服務(wù)服務(wù)器將返回一個(gè)空響應(yīng)。此外,它將調(diào)用exampleHelperROSEmptyCallback函數(shù)并顯示字符串“A service client is calling”。您還可以定義一個(gè)Timeout參數(shù),該參數(shù)指示客戶機(jī)應(yīng)該等待響應(yīng)的時(shí)間。
testresp = call(testclient,testreq,"Timeout",3);
如果上面的調(diào)用函數(shù)失敗,就會(huì)出錯(cuò)。如果希望使用條件對(duì)調(diào)用失敗做出反應(yīng),則可以從調(diào)用函數(shù)返回狀態(tài)和statustext輸出,而不是錯(cuò)誤。狀態(tài)輸出指示調(diào)用是否成功,而statustext提供其他信息。waitForServer也可以返回類似的輸出。
numCallFailures = 0;
[testresp,status,statustext] = call(testclient,testreq,"Timeout",3);
if ~statusnumCallFailures = numCallFailues + 1;fprintf("Call failure number %d. Error cause: %s\n",numCallFailures,statustext)
elsedisp(testresp)
end
MessageType: 'std_srvs/EmptyResponse'
1.3 兩數(shù)之和
如果說我們想要完成兩數(shù)求和這樣的功能,我們可以先將現(xiàn)有的服務(wù)類型roscpp_tutorials/TwoInts用于此任務(wù)。您可以通過調(diào)用rosmsg show來檢查請(qǐng)求和響應(yīng)消息的結(jié)構(gòu)。請(qǐng)求包含兩個(gè)整數(shù)A和B,響應(yīng)包含它們?cè)赟um中的加法。
rosmsg show roscpp_tutorials/TwoIntsRequest
int64 A
int64 B
rosmsg show roscpp_tutorials/TwoIntsResponse
int64 Sum
使用此消息類型創(chuàng)建服務(wù)服務(wù)器和計(jì)算加法的回調(diào)函數(shù)。為了方便起見,exampleHelperROSSumCallback函數(shù)已經(jīng)實(shí)現(xiàn)了這個(gè)計(jì)算。將函數(shù)指定為回調(diào)函數(shù)。
sumserver = rossvcserver("/sum","roscpp_tutorials/TwoInts",@exampleHelperROSSumCallback,"DataFormat","struct")
sumserver =
ServiceServer with properties:
ServiceType: ‘roscpp_tutorials/TwoInts’
ServiceName: ‘/sum’
NewRequestFcn: @exampleHelperROSSumCallback
DataFormat: ‘struct’
要調(diào)用服務(wù)服務(wù)器,必須創(chuàng)建一個(gè)服務(wù)客戶機(jī)。注意,這個(gè)客戶端可以在ROS網(wǎng)絡(luò)中的任何地方創(chuàng)建。為了本例的目的,我們將在MATLAB中為/sum服務(wù)創(chuàng)建一個(gè)客戶端。
sumclient = rossvcclient("/sum","DataFormat","struct")
sumreq = rosmessage(sumclient);
sumreq.A = int64(2);
sumreq.B = int64(1)
if isServerAvailable(sumclient)sumresp = call(sumclient,sumreq,"Timeout",3)
elseerror("Service server not available on network")
end
sumresp = struct with fields:
MessageType: ‘roscpp_tutorials/TwoIntsResponse’
Sum: 3