LoginSignup
19
16

More than 5 years have passed since last update.

roslibjsの基本的な使い方

Last updated at Posted at 2018-08-11

はじめに

roslibjsを使って開発している中で、日本語の情報がまとまっておらず不便だったためまとめてみました。
基本的にはROS Wiki に記載されている内容ですが、サービスについては追加しています。
paramについては利用していないので記載していません。

他の使い方も、勉強し次第追記しようと思います。
間違い等あれば指摘していただけると幸いです。

環境

  • Ubuntu16.04
  • ROS kinetic
    • rosbridge-serverパッケージをインストール
  • node
    • roslibをインストール

ウェブページ等で動かす場合にはnodeのインストールは不要です。

roslibjsのインポート

NodeJSを利用する場合

const ROSLIB = require("roslib");

ウェブページ等で利用する場合 (html内に)


<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>

rosとの接続の確立

接続するurlやrosbridge-websocketを介してrosと接続したとき、接続でエラーが起きたとき、接続が閉じられた時などに行う処理を記載します。

この際、url内のホスト名はrosbridge-websocketを起動するPCのホスト名であり、roscoreが起動しているROS_MASTER_URIのホスト名とは異なるため注意します。

const ros =  new ROSLIB.Ros({
    url: 'ws://localhost:9090'
});

ros.on('connection', () => {
    console.log('Connected to websocket server');
});

ros.on('error', error =>{
    console.log('Error connecting to websocket server: ', error);
});

ros.on('close', () => {
    console.log("Connection to websocket server was closed");
});

Publish

トピックの宣言、メッセージの宣言等は以下のように行います。

const cmdVel = new ROSLIB.Topic({
    ros : ros,
    name : '/cmd_vel',
    messageType : 'geometry_msgs/Twist'
});

const twist = new ROSLIB.Message({
    linear : {
     x : 0.1,
     y : 0.2,
     z : 0.3
    },
    angular : {
     x : -0.1,
     y : -0.2,
     z : -0.3
    }
});

宣言したcmdVelトピックのメッセージとしてtwistをpublishする場合は以下のようにします。

cmdVel.publish(twist);

Subscribe

まずは、publish時と同様に、subscribeしたいトピックを宣言します。

const listener = new ROSLIB.Topic({
   ros : ros,
   name : '/listener',
   messageType : 'std_msgs/String'
});

そして、そのトピックを受け取った際に行う関数を登録します。

listener.subscribe(message => {
    console.log('Received message on ' + listener.name + ': ' + message.data);
});

以上の方法でトピックを受け取ることができます。
これ以上受け取る必要がない場合には、以下のようにunsubscribe()を実行しましょう。

listener.unsubscribe();

Service

ROS Wikiには、サービスコールについてのみしか記載されていないため、roslibjsのリポジトリを見て理解したことをまとめます。

サービスの宣言

nameにはサービスの名前を,serviceTypeにはサービスタイプを記載します。rosbridge_websocketを起動するPC上でsrvファイルを作成し、catkin_makeしておくか、ROSの基本パッケージで定義されたサービスタイプを利用しましょう。
ここでは、ROS Wikiで使用されているrospy_tutorials/AddTwoIntsを使用しています。必要な場合はros-kinetic-rospy-tutorialsをインストールしましょう。

const addTwoIntsClient = new ROSLIB.Service({
    ros: ros,
    name: '/add_two_ints',
    serviceType: 'rospy_tutorials/AddTwoInts',
});

サービスコール

宣言したサービスへのリクエストの内容を宣言し、サービス.callService()の引数としてリクエストの内容と、レスポンスがあった際の処理を記載することでサービスコールを行うことができます。

let request = new ROSLIB.ServiceRequest({
   a : 1,
   b : 2
});

addTwoIntsClient.callService(request, result => {
   console.log('Result for service call on '
     + addTwoIntsClient.name
     + ': '
     + result.sum);
});

サービスの実行

宣言したサービスを、js上で実行する方法です。
上で宣言したサービスをそのまま使ってもいいのですが、名前がClientなのに違和感があるので新たに宣言します。

const addTwoIntsServer = new ROSLIB.Service({
    ros: ros,
    name: '/add_two_ints_server',
    serviceType: 'rospy_tutorials/AddTwoInts',
});

そして、リクエストへの処理をコールバックとして記述し、以下のようにサービス.advertise()の引数に与えることでサービスを実行できます。

addTwoIntsServer.advertise((req, res) => {
    res.sum = req.a + req.b
    return;
}

この際、rosbridge_websocketを実行したままの状態で、ページの再読込等によって同じサービスの宣言が複数回行われてしまうと、初回のサービスコールが失敗する場合があるため注意してください。

サービスの停止

一度実行したサービスを停止したい場合には、以下のようにサービス.unadvertiseを実行します。

addTwoIntsServer.unadvertise();

おまけ

pythonやC++で開発を行う際に、別のノードで実行されているサービスへサービスコールを行う場合には,waitForService()等を利用するかと思います。
roslibjsには同様の関数はありませんが、

ros.getServices(services => {
    if(services.indexOf('/add_two_ints') != -1){
        ...(中略)...
});

以上のようにgetServices()メソッドで、サービスの一覧をリストで取得できるため、使用したいサービスが格納されているindexを探すと、サービスが実行されているかが分かります。
もっと良い使い方があれば教えてください。

19
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
16