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 ROS
var 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 Topic
var 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
}
});//創建一個message
function 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 Topic
var 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端還存在問題,需要進一步地完善,也希望和大家多多交流。