5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ROSAdvent Calendar 2021

Day 5

vueでroslibjs使ってみた

Last updated at Posted at 2021-12-04

はじめに

vueでroslibjsを使ってrosと通信する方法を記載します.

使用環境は以下の通りです.

Ubuntu 20.04
ROS noetic
Vue 3.0

準備

まずはvuecliをインストールし,vueプロジェクトを作成します.

vueプロジェクトを作成したら,まずROSとの通信に使用するroslibをインストールします

npm install roslib

あとはsrc/App.vueを以降の記事内用に記載しているサンプルに置き換えます.
また,roslaunch rosbridge_server rosbridge_websocket.launchも同時に実行します.

サンプル

1.ベースプログラム

rosbridgeとのコネクションをするだけのコードです.今後記載するサンプルのベースプログラムとなります.

src/App.vue
<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <HelloWorld msg="Welcome to Your Vue.js App"/>
</template>

<script>
import ROSLIB from "roslib" // 追加
import HelloWorld from './components/HelloWorld.vue'

// *** 追加 ここから *** //
const ros =  new ROSLIB.Ros({
    url: 'ws://localhost:9090'
});
// *** 追加 ここまで *** //

export default {
  name: 'App',
  components: {
    HelloWorld
  },

  // *** 追加 ここから *** //
  mounted() {
    this.init();
  },
  methods: {
    init: function () {
      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.");
      });
    },
    // *** 追加 ここまで *** //
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

2.Publisher

ブラウザからPublishするサンプルプログラムです。

src/App.vue
<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <HelloWorld msg="Welcome to Your Vue.js App"/>
  <p><button v-on:click="publish()">publish</button></p> <!-- 追加 -->
</template>

<script>
import ROSLIB from "roslib"
import HelloWorld from './components/HelloWorld.vue'

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

// *** 追加 ここから *** //
var cmdVel = new ROSLIB.Topic({
    ros : ros,
    name : '/cmd_vel',
    messageType : '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
    }
});
// *** 追加 ここまで *** //

export default {
  name: 'App',
  components: {
    HelloWorld
  },

  mounted() {
    this.init();
  },
  methods: {
    init: function () {
      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.");
      });
    },
    // *** 追加 ここから *** //
    publish: function () {
      cmdVel.publish(twist);  
    },
    // *** 追加 ここまで *** //
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

実行の結果以下のようになり、ブラウザのボタンを押すと,/cmd_velがpublishされます

vue-ros-sample1.gif

3.Subscriber

次はSubscriberのサンプルプログラムです。

src/App.vue
<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <HelloWorld msg="Welcome to Your Vue.js App"/>
  <p>sub msg: {{ msg }} </p> <!-- 追加 -->
</template>

<script>
import ROSLIB from "roslib"
import HelloWorld from './components/HelloWorld.vue'

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

// *** 追加 ここから *** //
var sub = new ROSLIB.Topic({
  ros: ros,
  name: "/listener",
  messageType: "std_msgs/String"
});
// *** 追加 ここまで *** //

export default {
  name: 'App',
  components: {
    HelloWorld
  },
  // *** 追加 ここから *** //
  data: function () {
    return {
      msg: "",
    };
  },
  // *** 追加 ここまで *** //
  mounted() {
    this.init();
  },
  methods: {
    init: function () {
      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.");
      });

      // *** 追加 ここから *** //
      var self = this;

      sub.subscribe(function(message) {
        //console.log("callback",message);
        self.msg = message;
      });
      // *** 追加 ここまで *** //
    },
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

実行の結果以下のようになり、/listenerにデータを送るとブラウザに表示されます

vue-ros-sample2.gif

4.Service Client

Service Clientのサンプルです。

src/Add.vue
<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <HelloWorld msg="Welcome to Your Vue.js App"/>
  <p><button v-on:click="call()">service call</button></p> <!-- 追加 -->
</template>

<script>
import ROSLIB from "roslib"
import HelloWorld from './components/HelloWorld.vue'

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

// *** 追加 ここから *** //
var addTwoIntsClient = new ROSLIB.Service({
    ros : ros,
    name : '/add_two_ints',
    serviceType : 'rospy_tutorials/AddTwoInts'
});

var request = new ROSLIB.ServiceRequest({
    a : 1,
    b : 2
});
// *** 追加 ここまで *** //

export default {
  name: 'App',
  components: {
    HelloWorld
  },
  mounted() {
    this.init();
  },
  methods: {
    init: function () {
      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.");
      });
    },
    // *** 追加 ここから *** //
    call: function () {
      addTwoIntsClient.callService(request, function(result) {
        console.log('Result for service call on ' + addTwoIntsClient.name + ': ' + result.sum);
      });
   },
    // *** 追加 ここまで *** //
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

rospy_tutorialsのadd_two_serverを実行するとサービスのコールを確認できます。標準では入っていないと思うので別途インストールしてください。

vue-ros-sample3.gif

4.最後に

vueでroslibjsを使ってrosと通信することができました.

5.参考

  • スマホアプリでROSのUIを作る場合はFlutterがおすすめらしい(ロボットにスマホ乗せる場合とか良さそう)

  • roslib JavaScriptでの使用方法

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?