Help us understand the problem. What is going on with this article?

ROSのWebインタフェースを作る

More than 3 years have passed since last update.

 ロボットをWebブラウザから色々操作できれば,便利なわけです.
 個人的にも,人の入力を待つみたいな非同期イベントは,ロボット制御のループからは離しておきたいので,そういう意味でも非同期入力が得意なWebブラウザにお任せしておくのは良さそうだと思っています.

Webサーバを立ち上げる

 なんとびっくりなんですが,ROSのパッケージの中に,簡単なWebサーバを実現するものがありました!roswww
 こいつをインストールすれば,最低限の機能は実現できそうです.

apt
sudo apt-get install ros-indigo-roswww

 実際に起動してみましょう.

roswww.launch
roslaunch roswww roswww.launch

 この状態で, http://localhost:8085/ にアクセスすると,インストール済みパッケージのリストを表示するページが開きます.また, http://localhost:8085/roswww/ にアクセスすると,「roswww, sup?」とだけ書かれたテストページが開きます.
 roswwwは, rosインストール先/share/各パッケージ/www/ のフォルダを参照するので,自作のパッケージにも www フォルダを作って, share 下にインストールすれば, http://localhost:8085/自作パッケージ名/ というURLでアクセスできるようになります.

JavaScriptでTopicをPub/Subする

 さて,静的なページだけだと,やはりつまらない.Webページ上からTopicを投げる方法がないかros-jpのメーリングリストで質問したら,roslibjsという,javascriptから直接ROS TopicのPub/SubやActionの発行など,ROSの緒機能にアクセスできるパッケージを紹介してもらいました!このパッケージは,rosbridgeで提供されるROSのwebsocketの口を利用するようです.
 さっそくインストール.

apt
sudo apt-get install ros-indigo-rosbridge-server

(もしかしたら,roswwwの依存関係で,もう入ってるかも)

 んで,roswwwのlaunchフォルダに以下のようなlaunchファイルを書いて,

chat.launch
<launch>
  <include file="$(find rosbridge_server)/launch/rosbridge_websocket.launch" />
  <include file="$(find roswww)/launch/roswww.launch" />
</launch>

同じくroswwwのwwwフォルダに以下のようなhtmlファイルを入れます.

chat.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
        <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
        <style type="text/css">
        <!--
            *{ padding:0px; margin:0px;}
        -->
        </style>
        <title>Sample Chat</title>
        <script src="http://cdn.robotwebtools.org/EventEmitter2/current/eventemitter2.js"></script>
        <script src="http://cdn.robotwebtools.org/roslibjs/current/roslib.js"></script> </head>
    <body>
        <script type="text/javascript">
        <!--
if(!Chat){
    var Chat = {
        ros : null,
        name : "",
        init : function(){
            this.ros = new ROSLIB.Ros();
            this.ros.on('error', function(error) {
                document.getElementById('state').innerHTML = "Error";
                document.getElementById("btn").disabled = true;
            });
            this.ros.on('connection', function(error) {
                document.getElementById('state').innerHTML = "Connect";
                document.getElementById("btn").disabled = false;
            });
            this.ros.on('close', function(error) {
                document.getElementById('state').innerHTML = "Close";
                document.getElementById("btn").disabled = true;
            });
            this.ros.connect('ws://localhost:9090');

            var sub = new ROSLIB.Topic({
                ros : this.ros,
                name : '/chat',
                messageType : 'std_msgs/String'
            });
            sub.subscribe(function(message) {
                var res = message.data;
                var date = res.substring(1, res.indexOf("]"));
                res = res.substring(res.indexOf("]")+1, res.length);
                var name = res.substring(0, res.indexOf(":"));
                res = res.substring(res.indexOf(":")+1, res.length);
                var el = document.createElement("p");
                el.innerHTML = "[" + date + "] <b>" + name + " :</b> " + res;
                //document.getElementById("talk").appendChild(el);
                document.getElementById("talk").insertBefore(el, document.getElementById("talk").childNodes[0]);

                document.getElementById("btn").disabled = false;
                document.getElementById("state").innerHTML = "received";
            });
        },
        send : function(){
            if(document.getElementById("comment").value.length == 0) return;

            document.getElementById("btn").disabled = true;
            document.getElementById("state").innerHTML = "sending";

            var now = new Date();
            var str_date = (now.getMonth()<10?"0":"") + (now.getMonth()+1) + "/";
            str_date += (now.getDate()<10?"0":"") + now.getDate() + "/";
            str_date += now.getFullYear() + " ";
            str_date += (now.getHours()<10?"0":"") + now.getHours() + ":";
            str_date += (now.getMinutes()<10?"0":"") + now.getMinutes() + ":";
            str_date += (now.getSeconds()<10?"0":"") + now.getSeconds(); 

            var comment = document.getElementById("comment").value;
            var pub = new ROSLIB.Topic({
                ros : this.ros,
                name : '/chat',
                messageType : 'std_msgs/String'
            });

            var str = new ROSLIB.Message({data : "[" + str_date + "]" + this.name + ":" + comment});
            pub.publish(str);
            document.getElementById("comment").value = "";
        }
    }
    Chat.init();

    window.onload = function(){
        Chat.name = window.prompt("What's your name?", "Jane Doe");
        document.getElementById("name").innerHTML = Chat.name;
    };
    window.onunload = function(){
        Chat.ros.close();
    };
}
        //-->
        </script>
<p>Connection status: <label id="state">Disconnect</label></p>
<p>Your name: <label id="name"></label></p>
<form action="javascript:Chat.send();" id="ui">
<label>Comment: </label>
<input type="text" id="comment" size="20" />
<input type="submit" value="send" id="btn" /><br/>
</form>
<div id="talk"><p></p></div>

    </body>
</html>

 それでは,いつものようにインストール.私はros_make_isolatedを愛用してます.ros_makeでも,たぶん同じ.

catkin_make
catkin_make_isolated --install --pkg roswww

そして,以下のコマンドで起動します.

launch_roswww
roslaunch roswww chat.launch

 ここまでできたら,ブラウザで http://localhost:8085/roswww/chat.html にアクセスしてください.名前の入力を促すダイアログが現れるので,適当に入力してください.
 次に,さらにもう1つ別のウィンドウで同じページにアクセスしてください.この状態で,片方のウィンドウからコメントを送ると,rostopicを介して,もう片方のウィンドウにも表示されます!

ROSでChat

 プロジェクトの全文はGitHubにも置いてあるので,参考にしてくださいー.

 以上,WebブラウザをROSのインタフェースにするお話しでしたっ!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away