【ラズパイ】raspberry pi zero でロボットを作製中(続1)
2017/01/28
前の状態から以下のハードウェアを追加
- 5年くらい前のwebカメラ
- 11acに対応したWLANドングル
やったこと
- node.jsを使ってGPIOをweb画面上から操作(これでラジコンみたいになった)
- 同じくweb画面にmjpgを使ってwebカメラの画像を表示
- web画面からオート操縦させる(前はpythonのコードを使ってHC-SR04 を制御していたが、今回はnode.jsのr-pi-usonicというライブラリを使った)
node.js ライブラリ
- express → nodeフレームワーク使用するため
- async → オート操縦を非同期で行うため
- sleep → オート操縦時の処理待ち時間設定のため
- r-pi-usonic → HC−SR04を使用するため
- onoff → GPIOを使用するため
web操作盤画面スクショ
表示された画面をタップすると小さくなる
動作の動画
ソースコード
var express= require('express');
var router = express.Router();
var async = require('async');
var sleep = require('sleep');
var usonic = require('r-pi-usonic');
var sensor = null;
usonic.init(function (error) {
if (!error) {
sensor = usonic.createSensor(23, 17, 500);
}
});
var GPIO = require('onoff').Gpio;
var onePlus = new GPIO(19, 'out');
var oneMinus = new GPIO(20, 'out');
var twoPlus = new GPIO(21, 'out');
var twoMinus = new GPIO(26, 'out');
var FORWARD = 'forward';
var BACKWARD = 'backward';
var LEFT = 'left';
var RIGHT = 'right'
var LEFT_TURN = 'left_turn';
var RIGHT_TURN = 'right_turn';
var STOP = 'stop';
var AUTO = 'auto';
/* GET users listing. */
router.get('/', function(req, res, next) {
// console.log(req.query);
var action = req.query.action;
var msg = '';
res.header("Content-Type", "application/json; charset=utf-8");
if (sensor == null) {
msg = '超音波センサーが認識されていません!';
}
switch (action) {
case FORWARD :
forward();
msg = '前進';// + (sensor != null ? 'Distance: ' + sensor().toFixed(2) + ' cm' : '');
break;
case BACKWARD :
backward();
msg = '後退';
break;
case LEFT :
onePlus.write(0);
oneMinus.write(1);
twoPlus.write(1);
twoMinus.write(0);
msg = '左折';
break;
case RIGHT :
onePlus.write(1);
oneMinus.write(0);
twoPlus.write(0);
twoMinus.write(1);
msg = '右折';
break;
case LEFT_TURN :
leftTurn();
msg = '方向転換(左)';
break;
case RIGHT_TURN :
rightTurn();
msg = '方向転換(右)';
break;
case STOP :
stop();
msg = '停止';
break;
case AUTO :
msg = "オート操縦";
if (sensor != null) {
var turnCount = 0;
var allCount = 0 ;
forward();
async.whilst(function test(){
return allCount < 10;
}, function func(callback) {
if (sensor().toFixed(2) < 6) {
turnCount++;
} else {
turnCount--;
if (turnCount < 0) {
turnCount = 0;
}
}
if (3 < turnCount) {
backward();
sleep.usleep(600000);
leftTurn();
sleep.usleep(1000000);
forward();
turnCount = 0;
allCount++;
}
sleep.usleep(1000);
callback();
}, function result(err){
if (err) {
console.error(err);
} else {
sleep.sleep(2);
stop();
console.log('finished');
}
});
} else {
msg += "不能";
}
}
res.send(msg);
});
function leftTurn(){
onePlus.write(0);
oneMinus.write(1);
twoPlus.write(1);
twoMinus.write(0);
}
function rightTurn(){
onePlus.write(1);
oneMinus.write(0);
twoPlus.write(0);
twoMinus.write(1);
}
function forward(){
onePlus.write(0);
twoPlus.write(0);
oneMinus.write(1);
twoMinus.write(1);
}
function backward(){
oneMinus.write(0);
twoMinus.write(0);
onePlus.write(1);
twoPlus.write(1);
}
function stop(){
onePlus.write(0);
oneMinus.write(0);
twoPlus.write(0);
twoMinus.write(0);
}
module.exports = router;
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,user-scalable=no" >
<title>操作盤</title>
<link rel="stylesheet" href="/stylesheets/style.css" type="text/css" />
<script type="text/javascript" src="/javascripts/jquery-2.2.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var isAuto = false;
var isW = false;
$("button").on("touchstart", function(){
var id = $(this).attr("id");
if (id != 'auto') {
$("#response").load("/users?action="+id);
} else {
isAuto = !isAuto;
if (isAuto) {
$("#response").load("/users?action="+id);
$(this).css("background-color","#FF3333");
$("#forwad #left #right #backward").attr("disable",true);
} else {
$("#response").load("/users?action=stop");
$(this).css("background-color","#248");
$("#forwad #left #right #backward").attr("disable",false);
}
}
});
$("button").on("touchend", function(){
var id = $(this).attr("id");
if (id != 'auto') {
$("#response").load("/users?action=stop");
}
});
$("#webcam img").click(function(){
if (!isW) { isW=true;$(this).css("width","20%"); } else { isW=false;$(this).css("width","100%"); }
});
});
</script>
</head>
<body ontouchmove="event.preventDefault()" >
<div id="webcam" style="text-align:center;"><img style='width:100%;' src="http://192.168.0.152:9000/?action=stream" /></div>
<div style="margin-bottom: -3px;"><button style='width:100%;' id='forward'>⬆️</button></div>
<div>
<button style='width:49.89%;' id='left'>⬅️</button>
<button style='width:49.89%;float:right;' id='right'>➡️</button>
</div>
<div style='clear:both;'></div>
<div style="margin-top: -3px;margin-bottom: -3px;"><button style='width:100%;' id='backward'>⬇️</button></div>
<div style="margin-top: 10px;margin-bottom: -3px;text-align:left;"><button style='width:30%;' id='auto'>🔁</button></div>
<!-- <div>
<button style='width:49.89%;' id='left_turn'>↪️</button>
<button style='width:49.89%;float:right;' id='right_turn'>↩️</button>
</div> -->
<div style='clear:both;'></div>
<div id="response"></div>
</body>
</html>
次のステップ
外部公開して遠隔から家の中見るとかガードロボにするとかかな..?


