ドローンで分度器を作る
この記事はプロコンゼミ(SPC同好会) その2 Advent Calendar 2018 6日目の記事です.
その1はこちらより.
こんにちは.@car4ryuです.AdventCalendar,6日目担当だとすっかり忘れてバイトにレポートに没頭していました.ごめんなさいホント.きっと私は今ハワイにいるんです.ハワイ時間ではセーフです.えへへ.(殴)
この記事では私が数年前に購入して以来ほとんど使っていなかったParrot社製 Bebop Droneを分度器として使う方法について解説します.
はじめに
ドローン,飛ばす機会が無くて自宅の棚の肥やしになってませんか.私はなってます.
ドローンを有効活用したい
折角こんなセンサーのてんこ盛りなドローンですから,飛ばすことをせずとも,せめて有効活用したいわけであります.
いくつか思い立つアイデアとしては,
- 高度計測ソナーを使って定規を作る
- ビデオカメラにする
- GPS使って速度計にする
- モーターを逆回転して扇風機にする
と言ったところですが,今回は
- 加速度センサーで分度器を作る
を実装することにしました.
技術的解説
ドローンの加速度センサーにアクセスし,roll方向の情報をよしなに受け取り,何等か表示する形で実装します.
このドローンを扱うためには,ドローン本体が立てているWiFi APに接続し192.168.42.1
に立っている制御用サーバーにアクセスします.
が,自分で実装は面倒なのでNode.jsとnode-bebopを使っていきます(大変使いやすくて感謝)
また,表示をうまい具合にするためにexpressと,テンプレートエンジンにejsも併用します.
適当なディレクトリで
npm init
をし,質問に答えた後に
npm install node-bebop
npm install express
npm install ejs
をしてインストール,app.js
の記述をしていきます.
var drone = require('node-bebop');
var express = require("express");
var bebop = drone.createClient();
var app = express();
var data = 0;
var server = app.listen(3000, function() {
console.log("Node.js is listening on port 3000.");
});
app.set('view engine', 'ejs');
app.get("/roll", function(req, res, next) {
res.set('Content-Type', 'text/html');
res.send('the angle is ' + data);
console.log('data is ' + data);
});
app.get("/", function(req, res, next) {
res.render("index", {});
});
bebop.connect(function() {
bebop.on('ready', function() {
bebop.Piloting.flatTrim();
bebop.on('AttitudeChanged', function(attitude) {
data = Math.round(attitude.roll * 57.2958);
if(data == -0) data = 0;
});
});
});
記事を書く当日になって間に合わせで書いたコードなのでコメントがないですが・・・一先ず載せておきます(あとから修正します)
必要最低限の機能のみを実装しているので,このコードが行うのはルーティングとドローンとの通信のみです.
ルーティングは以下のように実装しました.
url | function |
---|---|
/ | htmlのrender |
/roll | ドローンからのデータ受信 |
node-bebopでrollの角度を受け取るとradianで返ってくるので,57.2958を掛けた上で四捨五入し,整数値にしています.正確性が担保できる仕様ではありませんが,今回は問題ないでしょう.
次に,プロジェクト内にviews
ディレクトリを作成しindex.ejs
を記述します.
<html>
<body>
<p id="angle"></p>
</body>
</html>
<script type="text/javascript">
window.onload=function() {
var data = document.getElementById("angle");
const xhr = new XMLHttpRequest();
var POLLING_TIME = 100;
console.log('loaded');
polling();
function polling() {
getText();
window.setTimeout(polling, POLLING_TIME);
}
function getText() {
xhr.open("GET", '/roll');
xhr.addEventListener("load", (event) => {
data.innerHTML = "<p>"+event.target.responseText+"</p>";
});
xhr.send();
}
}
</script>
html部分は極めてシンプルです.idがangleのp要素を一つ置いただけです.(AdventCalendar用にダッシュで書いたので・・・お許しを)
あまりいい実装とは言えないかもわかりませんが,一先ず/roll
へGETを投げる動作を,ポーリングさせることで実装しました.ポーリング間隔は100ミリ秒,0.1秒ですが,こちらも正確性の担保される数値ではありません.が,こちらも支障ないでしょう.
記述したコードは以上です.
さて,
node app.js
をし,ブラウザから
localhost:3000
にアクセスしてみると・・・.
と,割とちゃんと角度が取れているようです.
以上,ドローンを分度器にする方法でした.
さいごに
今回私が猛ダッシュで書いた拙いコードは,
https://github.com/car4ryu/bebop_ruler
から自由に閲覧・クローン出来ます.私がこの数時間で焦りまくってコミットしていった恥ずかしい履歴が閲覧できます.
ドローンあるけど退屈している方,よろしければどうぞ.
ちなみにどうしてリポジトリ名がrulerかって言うと,本来ソナー使って定規のほうを実装したかったからなんですが,いい感じに動いてくれなくてタイムリミットが迫ってきたので分度器にしました(えぇ)
次のプロコンゼミ(SPC同好会) Advent Calendarの担当は,こちらおよび,「くろむ」さんの記事になります.
(あれ・・・?なんで6日目の記事の最後に7日目の記事のリンクが張れるんだろう・・・???)