はじめに
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とのコネクションをするだけのコードです.今後記載するサンプルのベースプログラムとなります.
<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するサンプルプログラムです。
<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されます
3.Subscriber
次はSubscriberのサンプルプログラムです。
<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
にデータを送るとブラウザに表示されます
4.Service Client
Service Clientのサンプルです。
<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を実行するとサービスのコールを確認できます。標準では入っていないと思うので別途インストールしてください。
4.最後に
vueでroslibjsを使ってrosと通信することができました.
5.参考
- スマホアプリでROSのUIを作る場合はFlutterがおすすめらしい(ロボットにスマホ乗せる場合とか良さそう)
- roslib JavaScriptでの使用方法