標籤:systems roi 機械 publish 接收 平台 blank mes 環境
安卓與ROS通訊的現狀
因為ROS官方支援的語音綁定只有C++和Python,所以目前安卓想與ROS通訊,必須藉助半官方的rosjava包,而Rosjava太重了,因為它跟C++/Python一樣,是一個全功能的ROS綁定,意即你可以在Java(android)平台上建立Master Node,然後其他Node(C++/Python)可以連上這個Master,進行分布式通訊!這對於案頭Java或許還能接受,但對於android實在是過於複雜了。
另外,rosjava的gradle指令碼太複雜,需要很深的gradle知識才能將其整合到自己的android工程,很多公司(比如我們-_-!)嫌麻煩直接匯入rosjava的demo工程,然後將自己的代碼添加進去,團隊裡如果有新人加入,則還要重新搭建一個rosjava環境,太麻煩了
rosbridge協議
很多人都覺得移動平台or嵌入式系統要實現跟ROS進行分布式通訊成本太高昂,大家尋思用C/S架構可能更符合移動平台的需求,於是提出了rosbridge協議,該協議的基本思想是將節點間的分布式通訊,改成client節點與一個代理節點進行C/S通訊,然後代理節點再將請求轉寄給server節點,這樣移動端就不需要實現整個ROS平台,只需要跟代理節點通訊即可。
這是一篇比較rosjava跟rosbridge優劣的pdf,簡單來說,就是移動平台以犧牲做server節點的代價,換來了輕量級ROS互動的能力。不過特殊情況下rosjava還是有用的,比如機器人的底盤調用機械臂的service,如果機械臂只支援rosbridge,則調用不可行——不過這種情況通過pub/sub應該也能解決。
ROSBridgeClient庫
要讓android能收發rosbridge訊息,首先要支援WebSocket這種特殊的傳輸通道才能實現android接收ROS端publish(推送)過來的訊息,目前實現WebSocket的大部分集中在案頭Java,比如Jetty、Netty等,其中Jetty因為用到了某些Dalvik VM不支援的java類而導致不能在android上使用。另外android自身的webview對WebSocket的支援較晚,不能保證全機型覆蓋,所以Java-WebSocket這個用java.nio包裡的類實現的WebSocket就脫穎而出。
有了傳輸通道,剩下的就是怎麼組包發送了,這個庫不僅要將發送的Java類型轉換成語言無關的ROS訊息類型(反之亦然),還要將ROS操作(訂閱、發布、調用service、廣播topic等)轉換成rosbridge裡規定的json串,在評估了java_rosbridge庫和ROSBridgeClient庫後,我選擇了後者,因為前者雖然更小巧,但是用的jetty來實現WebSocket通訊,沒法跑在android上
添加std_msgs包裡的訊息類型
在試用ROSBridgeClient庫的過程中,我發現作者連std_msgs裡的訊息類型——例如String——都沒有實現,卻而代之的,是一個精巧的註解加反射機制實現的meta message類型,要擴充很簡單,見我fork出來的repo
在摸索std_msgs的過程中,我弄明白一個機制:ROS的內建類型其實並不是實際存在的,它必須對應到具體語言的內建類型,所以為了跨語言通訊,所有Message只能使用Wrapper類型,這就解釋了為什麼std_msgs包裡一堆wrapper了,因為每個msg檔案裡的內建類型(比如string),都是不存在的,必須對應到Java的String,或Python的str、或C++的std::string,唯獨不能對應ROS的string,因為ROS不是一門語言。
[轉]使用rosbridge協議實現安卓跟ros的解耦