2011年5月15日日曜日

javascriptによるROS rosbridgeとrosjs

javascriptからROSに簡単に接続するライブラリがあります。
rosbridgeパッケージとrosjsです。

http://www.ros.org/wiki/rosbridge

まずはrosbridgeですが、
JSONというデータでソケット通信できるものならROSのAPIを使えます。

なのでjavascriptだけでなく、さまざまなものから利用できるようになっているようです。
だから名前がrosbridgeなんですね。

ようするにJSON形式でソケット通信するとそれをROSのAPIに変換してくれます。

例えば、以下のデータをrosbridgeに送信すると、

{"receiver":"/topic","msg":{},"type":"package/Type"}
/topicというトピックに対してpackage/Type型で、中身が空のメッセージをpublishすることになります。

例えば、よく使う速度を表すTwistだと以下のようになります。
{"receiver":"/cmd_vel","msg":{"linear":{"x":0,"y":0,"z":0},"angular":{"x":0,"y":0,"z":0}},"type":"geometry_msgs/Twist"}

サービスも同様です。
{"receiver":"/service","msg":[]}

rosbridgeは以下のようにして起動します。
$ rosrun rosbridge rosbridge.py



で、次にrosjsですが、この形式の通信をjavascriptから利用しやすくしたクライアントです。
つまり、以下のような接続になります。ユーザはrosjsを使ってROS通信を行うことができます。
 ROS Server <-> rosbridge <-> rosjs

rosjsのドキュメントは以下のチュートリアルが詳しいです。

接続を確立するには以下のように書きます。
<html>
      <head>
        <script type="text/javascript" src="http://brown-ros-pkg.googlecode.com/svn/tags/brown-ros-pkg/rosjs/ros.min.js"></script>
        <script type="text/javascript">
        </script>
      </head>
    <body onload="main()">
    function main() {
      var x = 0;
      var z = 0;
      var connection = new connection.Connection("ws://hostname:9090");
      connection.setOnClose(function (e) {
        document.write('connection closed<br/>');
      });
      connection.setOnError(function (e) {
        document.write('error!<br/>');
      });
      connection.setOnOpen(function (e) {
        document.write('connected to ROS<br/>');
      });
    </body>
    </html>
hostnameにはrosbridgeが動いているマシン、9090はrosbridgeのデフォルトのポート番号です。基本的にsetOnOpenにやりたいことを書けばいいみたいです。

publishは非常に簡単で
function pub() {
      connection.publish('/cmd_vel', 'geometry_msgs/Twist', '{"linear":{"x":' + x + ',"y":0,"z":0}, "angular":{"x":0,"y":0,"z":' + z + '}}');
    }
と書けばよいです。

subscribeはちょっと面倒で、以下のように2つのメソッドを使います。
connection.addHandler('/sensorPacket',function(msg) {
        if (msg.bumpLeft || msg.bumpRight) {
            alert('bump');    
        }
    });
    connection.callService('/rosjs/subscribe','["/sensorPacket",0]',function(rsp) {
        alert('subscribed to /sensorPacket');
    });
addHandlerでトピックに対するハンドラ(コールバック)を登録します。
で、実際にsubscribeをはじめるにはrosbridgeの/rosjs/subscribeというサービスを呼び出します。
これにより指定したトピックが発行されたときに登録したハンドラが呼び出されるようになります。

serviceはすでに出てきましたが、以下のように書けばOK。3つ目の引数はserviceのresponseが入っています。
connection.callService('/soundOf','["tree falling in woods"],function(){});

これでjavascriptからROSが使えますね。
興味を持った方はリンク先を参照ください。
RoombaをTwistメッセージで動かす例があります。

今回はこれくらいにします。

0 件のコメント:

コメントを投稿