ROS是現在應為最為廣泛的機器人操作系統,為了將ROS與Web端的應用結合起來,ROS Web Tools社區開發了很多Web功能包,利用這些工具,我們能夠在Web端實現對機器人的監測與控制。

工具的准備
首先介紹以下所需要的工具包:rosbridge_suite功能包,roslibjs,ros2djs,ros3djs。
● rosbridge_suite:實現Web瀏覽器與ROS之間的數據交互;
● roslibjs:實現了ROS中的部分功能,如Topic,Service,URDF等;
● ros2djs:提供了二維可視化的管理工具,可以用來在Web瀏覽器中顯示二維地圖;
● ros3djs:提供了三維可視化的管理工具,可以在Web端顯示三維模型。
在這幾個功能包中,rosbridge_suite是最重要的,它是Web和ROS溝通的橋梁,roslibjs也是必須的,它能實現ROS中最基本的功能,下面的例程就是用它來實現的,至於ros2djs和ros3djs是后期開發所需要的,對於新手來說可以暫時不用下載。它們的下載安裝方法如下,在終端中分別輸入以下指令:
$ sudo apt-get install ros-kinetic-rosbridge-suite$ git clone https://github.com/RobotWebTools/roslibjs.git$ git clone https://github.com/RobotWebTools/ros2djs$ git clone https://github.com/RobotWebTools/ros3djs
在使用ROS Web的時候,我們首先要運行一個launch文件,便於Web端能夠連接到ROS主機上,在終端中運行:
$ roslaunch rosbridge_server rosbridge_websocket.launch
在運行了這個launch文件后,我們只需要在瀏覽器中打開我們設計的html文件就能夠實現Web端與ROS的交互了。下面來看一個簡單的example.html的例子。
例程代碼及解釋
<html><head><meta charset="utf-8" /><script type="text/javascript" src="http://static.robotwebtools.org/EventEmitter2/current/eventemitter2.min.js"></script><script type="text/javascript" src="http://static.robotwebtools.org/roslibjs/current/roslib.min.js"></script><script type="text/javascript" type="text/javascript">// Connecting to ROSvar ros = new ROSLIB.Ros({url : 'ws://localhost:9090'});//判斷是否連接成功並輸出相應的提示消息到web控制台ros.on('connection', function() {console.log('Connected to websocket server.');});ros.on('error', function(error) {console.log('Error connecting to websocket server: ', error);});ros.on('close', function() {console.log('Connection to websocket server closed.');});// Publishing a Topicvar cmdVel = new ROSLIB.Topic({ros : ros,name : '/cmd_vel',messageType : 'geometry_msgs/Twist'});//創建一個topic,它的名字是'/cmd_vel',,消息類型是'geometry_msgs/Twist'var twist = new ROSLIB.Message({linear : {x : 0.1,y : 0.2,z : 0.3},angular : {x : -0.1,y : -0.2,z : -0.3}});//創建一個messagefunction func()//在點擊”Publish”按鈕后發布消息,並對消息進行更改{cmdVel.publish(twist);//發布twist消息twist.linear.x = twist.linear.x + 0.1;twist.linear.y = twist.linear.y + 0.1;twist.linear.z = twist.linear.z + 0.1;twist.angular.x = twist.angular.x + 0.1;twist.angular.y = twist.angular.y + 0.1;twist.angular.z = twist.angular.z + 0.1;}// Subscribing to a Topicvar listener = new ROSLIB.Topic({ros : ros,name : '/chatter',messageType : 'std_msgs/String'});//創建一個topic,它的名字是'/chatter',,消息類型是'std_msgs/String'function subscribe()//在點擊”Subscribe”按鈕后訂閱'/chatter'的消息,並將其顯示到網頁中{listener.subscribe(function(message) {document.getElementById("output").innerHTML = ('Received message on ' + listener.name + ': ' + message.data);});}function unsubscribe()//在點擊”Unsubscribe”按鈕后取消訂閱'/chatter'的消息{listener.unsubscribe();}</script></head><body><h1>Simple roslib Example</h1><p>Check your Web Console for output.</p><p id = "output"></p><button onclick = "func()">Publish</button><button onclick = "subscribe()">Subscribe</button><button onclick = "unsubscribe()">Unsubscribe</button><br /></body></html>
關於html文件的具體語法和內容,在此處就不做過多的介紹了,我主要說明一下幾個與ROS相關的配置。
var ros = new ROSLIB.Ros({url : 'ws://localhost:9090'});
這個代碼段的作用是創建一個ROSLIB.ros對象,用於連接rosbridge服務器,如果rosbridge服務器位於本機,url的設置中可用localhost代表IP地址,否則需要修改為rosbridge服務器對應的IP地址。
var cmdVel = new ROSLIB.Topic({ros : ros,name : '/cmd_vel',messageType : 'geometry_msgs/Twist'});
這個代碼段的作用是創建一個ROSLIB.Topic對象,用於在這個話題上發布或者訂閱消息。
具體實現過程
首先,在新終端中運行:
$roslaunch rosbridge_server rosbridge_websocket.launch
將出現以下界面:

接着,在新終端中運行:
$rosrun roscpp_tutorials talker
將出現以下界面:

這一操作的目的是為了通過talker節點發布話題‘/chatter’的消息,便於在Web端進行該話題的訂閱操作。
然后在瀏覽器中打開example.html文件,並打開Web控制台,將出現以下界面:

在控制台中,可以看到“Connected to websocket server”的提示信息,說明Web端與ROS端成功連接了起來。
在新終端中運行:
$rostopic echo /cmd_vel
這一操作的目的是為了監控‘/cmd_vel’話題的消息。
點擊幾次網頁中的Publish按鈕,會看到此終端中出現如下的界面:

這說明Web端成功地發布了‘/cmd_vel’話題的消息。
在網頁中點擊Subscribe按鈕,將會在網頁中看到如下界面:

這說明Web端成功地訂閱了talker節點發布的消息,然后點擊Unsubscribe按鈕,結束對於該話題的訂閱操作。
我們也可以在新終端中運行rqt_graph命令,得到當前ROS系統中的計算圖,類似於下圖:

從該圖中我們可以看出,rosbridge_websocket節點訂閱了名為‘/chatter’的topic,發布了名為‘/cmd_vel’的topic。
以上就是整個example.html文件實現過程,該例程只實現了topic的訂閱與發布,具體的實際應用將會涉及到更加復雜的情景,還需要我們去做更多的摸索。
拓展延伸:如何在其他移動的Web端實現與ROS的交互?
上面舉的例子是ROS的master與Web端處於同一個主機的情形,那么如何使用更多移動端實現Web與ROS的交互也成了我們非常關心的問題,下面提供一種解決思路,目前該方法只能用於ios端,具體方法如下:
1.確保移動的Web端設備與ROS的master處在同一個局域網中,最簡單的方法就是ROS master所在的電腦與Web的移動端連接同一個WIFI。
2.對html文件中的ROSLIB.ros對象進行初始化時,將localhost改為所在局域網中的IP地址,用點分十進制來表示。
3.打開終端並運行roslaunch bridge_server bridge_socket.launch,再在移動的Web端打開html文件,就能夠實現移動的Web端與ROS的交互。
采用上述的方法將大大地擴展了ROS Web的使用范圍,這也更有利於對於機器人狀態的監測和調試,當然,此方法在andriod端還存在問題,需要進一步地完善,也希望和大家多多交流。
