開發(fā)ROS android 端遇到的問題 之 java 反射規(guī)則不符合校驗(yàn)要求失敗的問題
當(dāng)我們嘗試與ros service 通訊時(shí),通訊失敗凿滤,收到的提示。以前在項(xiàng)目中都是使用ros node 進(jìn)行topic 通訊庶近,第一次和同事在app 實(shí)現(xiàn)rosservice. 費(fèi)了很大的勁翁脆,搭建起開發(fā)環(huán)境開始做技術(shù)嘗試,這幾篇文章記錄這個(gè)項(xiàng)目遇到的相關(guān)問題鼻种。并簡要說明我們采用的解決方案反番。
2019-12-20?17:46:08.192?26580-26807/com.anzer.robot.navigation?E/AndroidRuntime:?FATAL?EXCEPTION:?pool-1-thread-96????Process:?com.anzer.robot.navigation,?PID:?26580????org.ros.exception.RosRuntimeException:?client?wants?service?/add_two_ints?to?have?md5sum?6ba90081e934800663a867fb3cb76f5a,?but?it?has?e3aba31982a34e28270141afefced002.?Dropping?connection.????????at?org.ros.internal.node.service.DefaultServiceClient.connect(DefaultServiceClient.java:140)????????at?org.ros.internal.node.service.ServiceFactory.newClient(ServiceFactory.java:146)????????at?org.ros.internal.node.DefaultNode.newServiceClient(DefaultNode.java:378)????????at?org.ros.internal.node.DefaultNode.newServiceClient(DefaultNode.java:385)????????at?com.anzer.robot.navigation.AddTwoIntService.add(AddTwoIntService.java:29)????????at?com.anzer.robot.navigation.AddTwoIntService.onStart(AddTwoIntService.java:69)????????at?org.ros.internal.node.DefaultNode$5.run(DefaultNode.java:520)????????at?org.ros.internal.node.DefaultNode$5.run(DefaultNode.java:517)????????at?org.ros.concurrent.EventDispatcher.loop(EventDispatcher.java:43)????????at?org.ros.concurrent.CancellableLoop.run(CancellableLoop.java:56)????????at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)????????at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)????????at?java.lang.Thread.run(Thread.java:776)
app 取到這個(gè)日志,在ros service 后臺(tái)也取到log
client wants service /add_two_ints to have md5sum 6ba90081e934800663a867fb3cb76f5a, but it has e3aba31982a34e28270141afefced002. Dropping connection.
拿到這個(gè)粒度的日志叉钥,首先分析日志罢缸。在這個(gè)過程中,client 端是app 發(fā)起的請(qǐng)求沼侣,它對(duì)應(yīng)的md5 是 6ba90081e934800663a867fb3cb76f5a祖能,不過server 端對(duì)應(yīng)的是 e3aba31982a34e28270141afefced002,不匹配蛾洛,所以切斷連接。
通過不斷嘗試雁芙,對(duì)照相關(guān)網(wǎng)絡(luò)上的資料轧膘,后來才理解。
原來ROS service 端會(huì)把 AddTwoInts.srv中的文本內(nèi)容計(jì)算 md5 的指紋和app 端的定義的message 類型兔甘。如果這兩個(gè)md5不匹配就返回上述的異常信息谎碍。
app 端的服務(wù)定義如下:
package cloud_msgs;
import org.ros.internal.message.Message;
public interface AddTwoIntsextends Message {
String_TYPE ="cloud_msgs/AddTwoInts";
? ? String_DEFINITION ="int64 a\nint64 b\n---\nint64 sum\n";
}
在不清楚rosjava 創(chuàng)建services 的流程,約束條件洞焙。解決問題的思路是找一個(gè)邏輯接近的場景蟆淀,可以運(yùn)行起來的程序拯啦,想起以前學(xué)習(xí)ros service 時(shí),對(duì)兩個(gè)數(shù)值求和的例子熔任。
1. 只有一個(gè)基本數(shù)據(jù)類型的情況
2. 如果弄清楚轉(zhuǎn)換規(guī)則褒链,再添加一個(gè)參數(shù)
3. 逐步把我們需要的參數(shù)都添加進(jìn)去,構(gòu)成項(xiàng)目中的自定義數(shù)據(jù)類型
多次試驗(yàn)得知:
+ 通過_TYPE反射生成對(duì)象疑苔,把“/” 替換為“.”,生成包路徑為 cloud_msgs.AddTwoInts 的對(duì)象
+ 根據(jù) _DEFINITION 反射生成 request 和response 接口
+ 剛開始我把 _DEFINITION 理解為注釋甫匹,就遇到到各種不同的md5 校驗(yàn)失敗的日志,參考別的msgs,如果要當(dāng)做注釋惦费,需要表達(dá)為 _DEFINITION="# comment"
c++??????????????????????????? java
int32??????????????????????? int
float32??????????????????? float
bool??????????????????????? boolean
int32[]??????????????????? int[]
string???????????????????? String/List
映射為這種關(guān)系兵迅,一步一步測試通過即可。