ログインしたあなたが操る[リアル]クリスマスツリー(後編)


やったこと

『これ↓の作り方を紹介する』の後編です。前編はこちら → 前編

実装したことと実装手段

実装した機能と実装手段を紹介します。今回は、③④の実装手順を紹介します。(①②については、前編を参照ください → 前編

参考


では作っていきます。

回るツリーを実装しよう

写真下部にある赤い四角の物体がモーターです。これを使ってツリーを回します。

ツリーの土台とモーターを繋げるためにLEGOを使います(LEGOテクニックという種類を使いました)

土台の底にLEGOをビニールテープでくっつけます。ツリーはガラス製なので、外れないようビニールテープでぐるぐる巻きにします。

モーターの制御は、obnizを使います。obnizはクラウド経由で操作できるIoTデバイスです。電子工作に苦手な人でも簡単にLEDやモーターなどをobnizを使って制御できます。obnizを操作するスクリプトはhtmlファイルで書くことができます。

最初に、obnizに関するモジュールを読み込みます。

<script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
<script src="https://unpkg.com/[email protected]/obniz.js" crossorigin="anonymous"></script>

次にボタンを作ります。

<button class="btn btn-primary btn-lg active" id="forward">回転</button><BR />
<button class="btn btn-primary btn-block" id="reverse">逆回転</button><BR />
<button class="btn btn-success btn-block " id="powerup">荒ぶる</button><BR />
<button class="btn btn-success btn-block" id="powerdown">通常</button><BR />
<button class="btn btn-secondary btn-block" id="stop">止まる</button>

モーター動作のJavaScriptを書きます。1行目のObniz_IDには、お持ちのobnizのIDを設定します。

var obniz = new Obniz("Obniz_ID"); // 持っているobnizのIDを設定
obniz.onconnect = async function () {      
    var motor2 = obniz.wired("DCMotor", {forward:10, back:11});
    obniz.display.clear();
    obniz.display.print("Hello World");

    $('#forward').click(function () {
    motor2.reverse();
    obniz.display.clear();
    obniz.display.print("forward");
    });

    $('#reverse').click(function () {
    motor2.forward();
    obniz.display.clear();
    obniz.display.print("reverse");
    });

    $('#powerup').click(function () {
    motor2.power(100);
    obniz.display.clear();
    obniz.display.print("powerup");
    });

    $('#powerdown').click(function () {
    motor2.power(30);
    obniz.display.clear();
    obniz.display.print("powerdown");
    });

    $('#stop').click(function () {
    motor2.stop();
    obniz.display.clear();
    obniz.display.print("stop");
    });
};

回るツリーを配信しよう

ラズベリーパイ(Raspberry Pi 4 Model B)に MJPG-streamerをインストールし、ストリーミングサーバーにします。それをツリーの前に設置します。

MJPG-streamerをインストールします。

$ sudo apt-get install build-essential libjpeg8-dev imagemagick libv4l-dev cmake -y
$ git clone https://github.com/jacksonliam/mjpg-streamer.git
$ cd mjpg-streamer/mjpg-streamer-experimental

makeコマンドでエラーが発生しないように、CMakeLists.txtを編集します。
以下の行の先頭に#を追加してコメントアウトします。

#add_subdirectory(plugins/input_opencv)

準備が整ったのでインストールを開始します。

$ make
$ sudo make install

※なんかよくわからないのですが、↓ のようにするといいらしいです。

$ ~/mjpg-streamer/mjpg-streamer-experimental
$ cp input_raspicam.so ../

これでインストールが完了しました。ではストリーミングを開始します。

# ストリーミング起動
$ /usr/local/bin/mjpg_streamer -i "input_raspicam.so -x 640 -y 480 -fps 15 -q 80" -o "output_http.so -p 8090 -w /usr/local/share/mjpg-streamer/www" 

ブラウザでストリーミングサイトのURL(http://{{raspberrypi-IP}}:8090/)開くと、このようなサイトが開きます。

URLを変更することで、装飾なしの静止画や映像を表示することもできます。

URL 概要
http://{{raspberrypi-IP}}:8090?action=snapshot ブラウザ開いた時の静止画
http://{{raspberrypi-IP}}:8090?action=stream ストリーミング

自作サイトにストリーミング配信を実装しよう

JavaScriptのストリーミングサイト(http://{{raspberrypi-IP}}:8090/?action=stream)のhtmlソースが参考になります。
以外だったのがimgタグが使われていました。しかも、srcには静止画のURLが設定されています。なぜストリーミングという動画系を配信するサイトにimgタグを使うのか?、なぜ静止画のURLを使うのか?これでは静止画が表示されそうですが、実際には動画が表示されます。不思議でしたがソースを読むとわかってきました。

javascript.html
<img src="./?action=snapshot" width="512px" height="384px" />

スクリプト部分に、このような関数が定義されています。どうやらパラパラ漫画のように、画像ファイルを頻繁に更新して動画のように見せているようです。ほぉー

function createImageLayer() {
    var img = new Image();
    img.style.position = "absolute";
    img.style.zIndex = -1;
    img.onload = imageOnload;
    img.onclick = imageOnclick;
    img.width = 512;
    img.height = 384;
    img.src = "./?action=snapshot&n=" + (++imageNr);
    var webcam = document.getElementById("webcam");
    window.info = document.getElementById('info').firstChild;
    window.ravgFps = document.getElementById('ravgfps').firstChild;
    window.ravgMs = document.getElementById('ravgms').firstChild;
    webcam.insertBefore(img, webcam.firstChild);
    document.getElementById('fN').firstChild.nodeValue = fN;
}

動画系の描画はvideoタグと思っていたのですが、videoタグはChromeで表示されないなどある (*1) ので、videoタグよりimgタグを使った方が閲覧できるブラウザが多そうです。
ということで、この仕組みはありがたく利用させていただきました。

(*1) video.js でChromeでも描画できます。詳細はこちらに書きました → ラズパイ4とGStreamerでストリーミングサーバーを作ろう