2019年7月2日火曜日

ランドセルチェッカー その2

前回は家庭用で使えるRFIDデバイスを作りたい!ということでランドセルチェッカーを作ってみました。これ製品化するためには Androidのタブレットが必要で、しかも常設なのでできればACアダプタで電源供給できて、しかも同時にUSBホストでRFIDリーダを接続できないといけないなど制約が多く、しかも安いのじゃないとダメなのでそういうの無いかなーといろいろ探してたんですが結局見つからず… そんなの探せばいくらでもあるでしょーと思ってたんですが意外と無いものですねー。

というわけで止まっていたんですが、その間に Google Nest Hub とか Amazon Echo Show とか出てきていて、あー、これいーなー、こんなのが欲しかったんだけどなー、待てよ、というかこれで動かせばいいんじゃね?ということでこの辺のデバイスからRFIDリーダに接続できないかちょっと調べたところこの手のデバイスの通信はZigbeeを使ってると。Zigbeeねー、でもそれ用モジュール作ったりスマートディスプレイ側のアプリ組んだりとかなんか大変そうやなーということでまた立ち止まるなど。

あ、でもチェックしてOKかどうかわかればいいんだからディスプレー要らなくね?ということは Amazon Echo とかで音声だけでもいいじゃん。ということで設定などはWebサイトでやっておいて、チェックだけAmazon Echoからできるように作ってみました。


デバイスはラズパイちゃんを使います。IoTっぽく Windows10 IoT Core で動かして、Azureにつないで操作できるようにします。操作といってもRFIDのスキャンをして結果を送信するだけです。RFIDリーダは前回同様免許なしで使える250mWのSTIXを使います。

問題はレスポンス時間で、Amazon Echo でチェックを開始指示→Azureに指示→Azureから該当のデバイスに指示→デバイス側でRFIDスキャン→結果をAzureに戻す→Azureで忘れ物がないか確認→結果をEcho側に返す→Echoで結果をしゃべる とまぁ、それぞれやってることは大したことないんですが経路が長いのでこれがどのくらいのレスポンスで返せるのかが気になっていました。


Webの設定画面がこちら。デザインは全く入れてませんのでいたってシンプルです。ここで時間割の設定をします。この画面でもチェックボタンを押せば、リーダがタグを読み取って足りないものを表示してくれます。

さーて、Amazon Echo側のスキルも作成し、いよいよレスポンスを試します。

こちらが教科書に貼ったタグ。


リーダの上に空のランドセルを載せます。


自宅の Amazon Echo ちゃん


「アレクサ、ランドセルを開いてチェックして。」

・・・

Alexa「こくご、さんすうが足りません。」

おー、5秒くらいかな?これならオッケーオッケー
ということで国語と算数の教科書を入れてもう一度

「アレクサ、ランドセルを開いてチェックして。」

・・・

Alexa「OKです。すべて揃っています。」

よっしゃー、かなり使えそう。しばらく使ってみることにします。


2019年6月3日月曜日

MANICAモバイル導入事例:株式会社アンドユー様

ドレスやアクセサリのレンタルサービスを展開されている株式会社アンドユー様における、MANICAモバイル導入事例の紹介記事が公開されました。

http://www.hayato.info/home/jirei_andu.htm



2019年5月28日火曜日

ItemSenseサーバをセットアップしてみた

Impinj社のItemSenseサーバをセットアップしてみました。公式ドキュメント通り進めるだけですが、備忘録を兼ねてメモしておきます。

今回使ったもの

  • Windows 10 Pro
  • Hyper-V
  • Ubuntu 16.04
  • itemsense-2.0.3+34-setup.run

Hyper-Vの有効化

PCのOSがWindows 10 Pro以上だと、Hyper-Vが使用可能です。Hyper-Vの有効化はここにやり方が書いてあります。

Ubuntuのセットアップ

ItemSenseの動作環境がUbuntu 16.04かCentOS 7となっています。今回は筆者の好みの問題でUbuntu 16.04にしました。公式サイトからisoファイルをダウンロードしてください。今回、"64-bit PC (AMD64) desktop image"を使用しましたが、"64-bit PC (AMD64) server install image"の方がよかったかもしれません。

次に仮想マシンを新規作成します。今回は第2世代を使いました。その際、「セキュアブートを有効にする」のチェックを外す必要があるそうです。あとはダウンロードしたisoを指定して、起動するだけです。Ubuntu自体のセットアップは割愛。キーボードレイアウトの設定くらいでほとんど設定項目ありませんでした。

前提条件となるソフトウェア

セットアップ後、追加で下記をインストールしました。
  • ssh 1:7.2p2-4ubuntu2.8
  • curl 7.47.0-1ubuntu2.13
  • docker.io 18.09.2-0ubuntu1~16.04.1
  • docker-compose 1.24.0
docker-composeのみ、リポジトリのバージョンが古かったので、公式サイトからダウンロードしました。
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose 
hash -r 

いざ、ItemSenseインストール

あとはスクリプトを動かすだけです。

sudo ./itemsense-2.0.3+34-setup.run install

お使いのブラウザからubuntu 16.04環境のIPアドレス:3010にアクセスすると、初回はInstance IDの入力を求められるので、入力します。すると、今度はusername / passwordを求められますので、admin / admindefault を入力してください。ログインできます。


とりあえず、ここまで。



2019年5月22日水曜日

タグの読みすぎ問題を考える

RFIDを使っていると、タグの読みすぎ問題というのが発生します。タグは読むためにあんだろーが!読めないより読めたほうがいいに決まってんじゃねーか!というのは御尤もなわけですが、特にハンディリーダなど使っていると読みたくないタグまで読んでしまっていやーなんやこれ想定外やなこれは聞いてないでー、という状況が発生します。

例えば


こういうところで、ダンボールにはタグが付いていて、出庫処理をするのに手前の3個のダンボールだけ読みたいとするじゃないですか。しかし後ろにもダンボールがあってこっちにもタグが貼ってあるわけですね。


この状態でハンディリーダを使って読み取りすると、読みたくない方のタグまで漏れなく読んでくれるわけです。これがタグの読みすぎ問題と言われるものです。もちろん読みたくないタグが近くに無いような状況を作ればいいのですがそういう状況を作れない(場所がない)場合が多いと思います。

この問題を解決するのに2つのアプローチがあります。1つは電波強度を落とすという方法、もう1つはタグの電波受信強度(RSSIと呼ばれるもの)を利用するという方法になります。(実はもう1つあって、読みたいタグが最初からわかってる場合はそれだけ読むようにするというのもありますがこちらは運用とかも絡んでくるので今回は外します)

電波強度を落とす方法は、リーダから出す電波の強度を落として遠くのタグを読みにくくすることで近くのタグだけ読ませようというやり方、受信強度を利用する方法はリーダからの出力は最大にしておいて、タグからの受信電波強度を見て、あるしきい値以下の強度だったら読まなかったことにするということでこちらも近くのタグだけ選別しようというやり方です。

で、果たしてどちらの方法が人にやさしいというか人間の感覚にフィットするのかというのが気になりましたので試してみました。

利用したのはこちらのリーダ


AT-S100ちゃんです。今流行りのスレッド型になります。出力は1Wでアンテナは円偏波です。

1番上のダンボールの写真のアングルから、ダンボールから50cm、1m、1.5m離れた場所でリーダを普通に1振りしてどんなもんかを計測します。読みたいダンボールは3個、後ろの読みたくないダンボールは3個、合計6個のタグを読み取りします。

まずは電波強度を変えるやり方、MAXの30dBmから3dBmずつ落として読み取ります。電波強度を変える方は単純に遠くのタグを読めなくする方法なので、読み取りできた枚数が3枚になるポイントを探ります(もちろんその3枚が手前のダンボールのタグである必要があります)。

結果がこちら(数値は読み取ったタグの個数です)

出力\距離 0.5m 1m 1.5m
30dBm 6 6 6
27dBm 6 5 5
24dBm 6 5 5
21dBm 6 5 5
18dBm 4 4 4
15dBm 3 3 3
12dBm 3 1 0

今回のパターンでは、15dBmにすると読みたいタグだけ読んでくれてることがわかります。

次に受信強度(RSSI)を見るやり方、こちらはリーダの出力は最大の30dBmにしておいて、手前のタグたちのRSSIと後ろのタグたちのRSSIを見てしきい値を設けられるかがポイントになります。手前3個でのRSSI値の最小値と、後ろ3個のRSSI値の最大値に差があればあるほどしきい値を設けやすくなります。

距離\RSSI 手前3個で最小のRSSI 後ろ3個で最大のRSSI
0.5m -52.3 -63.0
1m -58.3 -66.8
1.5m -61.8 -67.9
単位:dB

0.5mのときはRSSI値に結構差がありますので、-58あたりをしきい値にしていれば概ね大丈夫のようです。距離が離れていくと差が縮んでいくので、1.5mのときは一応しきい値-64くらいでやれそうですがちょっと危ないかなーという感じですね。

結果としては読み取りたいタグとリーダの距離が近い場合は受信強度を見る方法もありですが、必ずこの距離で読んでくださいねーとかそれを制限するのもちょっと難しそうなのでやはり出力を調整する方法が現実的のようです。


2019年5月13日月曜日

AR と RFID

ARのライブラリもかなりよくなってきたのではないだろうかとふと思い立ち、ちょっと試してみることにしました。以前は ARToolkit を使って車両認識をARマーカを使ってやってみよう!みたいなことをやってましたが、今回は RFID と組み合わせてみます。

RFID のハンディリーダは便利なのですが、当然のことながらタグは読めてもタグの位置まではわかりません。GPS と連動すれば位置はわかりますが、どの棚の何段目みたいのはわかりません。そこでこれを AR を使ってうまいことできないだろうかということでやってみました。

利用するライブラリはスマホでも使えるように Google の ARCore を使用しました。ついでに開発を端折るためにサンプルプログラムの augmented_image を改修して試してみることにします。

ARCore は平面の検出などかなり高度なことができるライブラリで、その中でもマーカを認識する機能と、スマホの動きをトラッキングするモーショントラッキングの機能を使います。これを使うことで、マーカの認識と、マーカーとスマホの相対位置がわかるようになります。

マーカを柱など固定されたところに貼っておいて、そのマーカとの相対位置でタグの位置を識別することで、マーカから見てどの辺りにタグがあるのかがわかるようになります。マーカは移動しない固定された位置(壁など)に貼りますから、そこからの相対位置が分かればタグの絶対位置がわかるだろうというそういう都合のいい理論です。

利用するハンディはこちらです。


ブラスターにハンディのアタッチメントを付けたものです。画像認識にスマホのカメラを使いますので、必然的にこういうリーダしか使えないというのがこれにした理由でもあります。

仮想的な倉庫としてこんな感じ


一番左にマーカ、ダンボールの中にタグが入っていて、わかりやすいように 0001~0004の4桁をエンコードしてあります。

実際に動かしてみたのがこちら。ちなみにデモ用にリーダの出力はかなり抑えてあります。


ちょっとわかりづらいですが、タグを読み取ったところでIDの看板みたいのを表示しています。


これでマーカとの相対位置はわかりますのでタグの位置管理的なことが可能になりますね。

2019年4月12日金曜日

MANICAモバイル貸出返却時にGoogle Homeに喋らせる


■環境
Android
 MANICAモバイルをインストールします。
 https://play.google.com/store/apps/details?id=info.hayato.manicamobile
Google Home
PC(Windows10)
 Node.js、google-home-notifier等をインストールします。
※Google HomeとPCは同一LAN上に設置します。

■処理の流れ

①MANICAモバイルで貸出返却時にIFTTTのWebhooksにWebリクエストを投げます。
②IFTTTのWebhooksでngrokにWebリクエストを投げます。
③ngrokへのWebリクエストをPC上のNode.jsで受け取ります。
④google-home-notifierでGoogleHomeに喋らせます。
⑤MANICAモバイルから直接ngrokにWebリクエストを投げると404が返ってきてしまうので、IFTTTを噛ますようにしました。

■環境構築
1.PC
・Node.jsをインストール  
下記サイトより8.12.0をダウンロードしてインストールします。 

 https://nodejs.org/ja/

Node.jsはJavaScriptで動作するプラットフォームで、サーバサイドプログラムをJavaScriptで記述することができます。シングルスレッドで非同期処理を行い高いスケーラビリティを持ち、リアルタイム性が必要で小規模なWebアプリケーションなどに用いられます。

・Python2.7をインストール
下記サイトより2.7.15をインストールします。

 https://www.python.org/downloads/

・コマンドプロンプトを管理者権限で起動し、作業用のフォルダを作成します。
C:\>mkdir mmbot
C:\>cd mmbot
・windows-build-toolsをインストールします。
npmを使用し、下記コマンドでインストールします。
C:\mmbot>npm install –g windows-build-tools

npmはNode Package Managerの略で、Node.jsのパッケージを管理するツールです。npmではパッケージをインストールする方法が、グローバルインストールとローカルインストールの2種類存在します。
グローバルインストールは「-g」をつけてインストールし、全てのプロジェクトで使用することができます。
ローカルインストールはプロジェクトのルート配下にあるnode_moduleフォルダにパッケージがインストールされ、対象のプロジェクトのみで使用することができます。
  
Windows-build-toolsはWindows環境でnode-gypを使用するのに必要になります。

・node-gypをインストールします。
C:\mmbot>npm install –g node-gyp
node-gypはNode.jsで書かれたクロスプラットフォームのコマンドラインツールで、Node.jsのネイティブアドオンモジュールをビルドするツールです。

・Bonjour SDK、Bonjour Print Serviceをインストールします。

https://developer.apple.com/download/more/?=Bonjour SDK for Windows

https://support.apple.com/kb/DL999?locale=ja_JP

Bonjourはgoogle-home-notifierのインストールに必要になります。

・google-home-notifierをインストールします。
C:\mmbot>npm install google-home-notifier
作業フォルダ配下にnode_modulesフォルダが作成され、各種パッケージが作成されます。
google-home-notifierはNode.jsで動作するGoogle Homeに喋らせることができるモジュールです。
google-home-notifierをインストールすると、ngrokも一緒にインストールされます。
ngrokは. ローカルPC上で稼働しているWebサーバを外部公開できるサービスです。

・example.jsをテキストエディタで編集します。
google-home-notifierをインストールすると、node_modules\google-home-notifierフォルダにexample.jsファイルが作成されるので、テキストエディタで編集します。
下記赤字部分で、GoogleHomeに喋らせる言語を日本語に設定しています。
var express = require('express');
var googlehome = require('./google-home-notifier');
var ngrok = require('ngrok');
var bodyParser = require('body-parser');
var app = express();
const serverPort = 8080; 
const deviceName = 'Google Home';
const language = 'ja';

googlehome.device(deviceName, language);
googlehome.accent(language);

var urlencodedParser = bodyParser.urlencoded({ extended: false });

app.post('/google-home-notifier', urlencodedParser, function (req, res) {
  if (!req.body) return res.sendStatus(400)
  console.log(req.body);
  var text = req.body.text;
  if (text){
    try {
      googlehome.notify(text, function(notifyRes) {
        console.log(notifyRes);
        res.send(deviceName + ' will say: ' + text + '\n');
      });
    } catch(err) {
      console.log(err);
      res.sendStatus(500);
      res.send(err);
    }
  }else{
    res.send('Please POST "text=Hello Google Home"');
  }
})

app.listen(serverPort, function () {
  ngrok.connect(serverPort, function (err, url) {
    console.log('POST "text=Hello Google Home" to:');
    console.log('    http://localhost:' + serverPort + '/google-home-notifier');
    console.log('    ' +url + '/google-home-notifier');
    console.log('example:');
    console.log('curl -X POST -d "text=Hello Google Home" ' + url + '/google-home-notifier');
  });
})


・example.jsを起動します。
コマンドプロンプトで「node example.js」を入力して起動します。
ngrokからURLが発行されます。

c:\mmbot\node_modules\google-home-notifier>node example.js
POST "text=Hello Google Home" to:
    http://localhost:8080/google-home-notifier
    https://xxxxxxxx.ngrok.io/google-home-notifier
example:
curl -X POST -d "text=Hello Google Home" https://xxxxxxxx.ngrok.io/google-home-notifier

別のコマンドプロンプトを開き、上記の赤字の部分をコピペして実行すると、Google Homeが「Hello Google Home」と喋ります。
発行されたURLは後で使用します。
※「xxxxxxxx」の部分はexample.jsを起動する度に変わります。また、8時間でURLは失効しますが、ngrokの無料アカウント登録をすることでトークンを貰えるので、それをexample.jsに加えると失効しなくなります。
アカウント登録をしてもexample.jsを止めて再度起動すると新しいURLになってしまいます。

2.IFTTT(イフト)
IFTTTのMy Applets→New AppletからAppletを新規作成します。
「this」をクリックします。



トリガとしてWebhooksを選択します。
 「Receive a web request」を選択します。Webリクエストを受け取った時に実行されるトリガーになります。
 Event Nameに適当な文言を設定します。この文言がURLの一部になります。
例では「manicamobile」と設定しています。

 次にアクションを設定します。「that」をクリックします。
 同様にWebhooksを選択します。
 「Make a web request」を選択します。Webリクエストを投げるというアクションになります。
 URLにexample.jsを起動した時にngrokから発行されたURLを記入します。
Methodは「POST」を選択します。
Bodyに「text=」と入力し「Add ingredient」から「Value1」を選択します。
「Value1」の箇所にはトリガー(MANICAモバイルからのWebリクエスト)からもらうパラメータが入ります。実際にGooogle Homeに喋らせたい文言が入ります。


3.MANICAモバイル

MANICAモバイルで店舗設定ページを開くと、貸出時/返却時のWebリクエストを設定することができるので、先程登録したIFTTTのWebhooks宛てのリクエストを登録します。


https://manica-mobile.appspot.com/

WebリクエストURL
https://maker.ifttt.com/trigger/{EventName}/with/key/{Key}?value1={Message}

{EventName}…トリガーで設定したEventNameの「manicamobile」を指定します。
{key}…Webhooksで与えられるKeyを指定します。
(IFTTTのMyApplets→Services→Webhooks→Documentationで確認できます。)
{Message}…Google Homeに喋らせる文言を指定します。
例では「MANICAモバイルで貸し出ししました」「MANICAモバイルで返却しました」が設定されています。


例)
https://maker.ifttt.com/trigger/manicamobile/with/key/xxxxxxxxxx?value1=MANICAモバイルで貸し出ししました。


以上の設定を終えAndroidアプリのMANICAモバイルで貸出/返却をすると、Google Homeがしゃべります。