酒呑みガジェット

〜マニアックな視点 ガジェットまとめ〜

【ラズパイ】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 ライブラリ

  1. express → nodeフレームワーク使用するため
  2. async  → オート操縦を非同期で行うため
  3. sleep  → オート操縦時の処理待ち時間設定のため
  4. r-pi-usonic → HC−SR04を使用するため
  5. onoff → GPIOを使用するため

 

web操作盤画面スクショ

操作盤1

 

操作盤2

表示された画面をタップすると小さくなる

 

動作の動画

ソースコード

スクリーンショット 2016-05-05 10.31.26

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>

 

次のステップ

外部公開して遠隔から家の中見るとかガードロボにするとかかな..?

-RaspberryPi
-, ,