Milkcocoaを使ってセンサー情報をウェブサイトで表示
Milkcocoaを利用すると、センサー情報をクラウドに上げてウェブサイト等で利用するといった、IoTチックなことが超簡単にできてしまいます。
僕も、自宅にあるRaspberry Piに接続した温湿度センサとPIRセンサの値をMilkcocoaにアップロードして、僕のウェブサイトのトップページの右下あたりに表示しています。
センサー情報の取得の仕方やMilkcocoaへの送信方法については、PIRセンサ(SB00412A-1)とMilkcocoaで簡易見守りシステムを構築 - Yura YuLife の記事を参考にしてください。
JavaScriptでMilkcocoaのデータストアにアクセス
こんな感じで書くだけです。
HTML部分
<p> 現在の温度: <span id="temperature"></span>度 </p>
JavaScript部分
<script src="https://code.jquery.com/jquery-1.12.1.min.js"></script> <script src="http://cdn.mlkcca.com/v2.0.0/milkcocoa.js"></script> <script> // Milkcocoaに接続 var milkcocoa = new MilkCocoa('アプリID.mlkcca.com'); // データストアを取得 var ds = milkcocoa.dataStore('データストア名'); ds.stream().next(function(err, msgs){ // データストアの最新メッセージ var last_msg = msgs[msgs.length - 1]; // 例えばメッセージが{"temperature": 20.0}みたいな形式とする var temperature = last_msg.value.temperature; // spanに温度を表示 $('#temperature').text(temperature); }); </script>
めちゃくちゃ簡単ですね!
なお、好き勝手にセンサー値を悪用されないよう、設定画面で許可Originの設定はちゃんと行いましょう。
参考URL
PIRセンサ(SB00412A-1)とMilkcocoaで簡易見守りシステムを構築
見守りシステムで家の中に監視カメラを置くなんて話がありますが、さすがに部屋をずっと撮影されているといい気持ちはしないと思います。そこで、前の記事で紹介したaitendoの人感センサ(SB00412A-1)のデータをRaspberry PiからMilkcocoaにアップロードして、簡単な見守りシステムを構築します。
PIRセンサならば見られてる感もないですし、留守じゃないのに全く反応がなければ何かがおかしいはずなので、簡易的な見守りセンサーとしては役割を果たせるのかもしれません。
必要なもの
- Raspberry Pi
- PIRセンサ(SB00412A-1)
- ブレッドボード
- ジャンパーワイヤ 4〜6本
- 1kオームの抵抗 3個
配線
Raspberry Piで人感センサ(SB00412A-1)を5Vで利用する方法 - Yura YuLifeの記事を参考に配線してください。
Pythonからセンサー情報を取得してMilkcocoaへ送信
下準備
Raspberry Pi上でMilkcocoaのPython SDKをインストールしておきます。
$ git clone https://github.com/milk-cocoa/python_sdk.git $ cd python_sdk/ $ sudo python setup.py install
また、Milkcocoaのウェブサイトでアプリを作成して、API Key とAPI Secretを作成しておきます。
センサー情報をMilkcocoaに送信
以下のスクリプトを保存し、PIRセンサを接続したGPIOのピン番号、MilkcocoaのアプリID、API Key、API Secret、データストア名を記入します。
後は$ nohup ./pir_to_milkcocoa.py &
で動かしておけば、30秒毎にMilkcocoaにJSONデータが送信されます。
アプリの管理画面から、確かにデータが送信されていることが確認できます。
データの可視化
Milkcocoaのfreeboardを利用して、データを可視化します。
画面右上のDatasourcesにデータストアを追加します。DATASTOREにデータストア名を記入、API
はpush
を選択します。
続いてADD PANE
からPANEを追加します。TYPEはSparkline
、VALUEにはdatasources["データストア名"]["value"]["count"]
と記入します。
下図のように30秒ごとの検知回数がグラフ化されます。
コレを使えば、不在のはずなのに0以外の値が頻繁に返ってきたり、在宅のはずなのに0ばかりの場合は何かおかしなことが起きている、くらいのことが分かりますね。
参考URL
Raspberry Piで人感センサ(SB00412A-1)を5Vで利用する方法
aitendoで購入したPIRセンサ(SB00412A-1)ですが、Raspberry Piで3.3Vで利用すると誤検知を繰り返し動作が不安定なので、5Vで利用する方法をまとめました。
必要なもの
- Raspberry Pi2 Model B
- 低電圧極小PIRセンサー SB00412A-1
- 1kΩ以上の同じ種類の抵抗 3個
- ブレッドボード
- ジャンパーワイヤ 4〜6本
配線
配線は下図のとおりです。
抵抗3つを利用して、VOUTの5Vの電圧の2/3(=3.3V)を取り出しています。
Raspberry PiのGPIOは5Vに対応していないため、直接VOUTを接続するとRaspberry Pi自体が壊れる恐れがあるので、間違えないよう注意して接続します。
動作用のPythonスクリプトは以前の記事(人感センサ(SB00412A-1)検知時にLEDを光らせる - Yura YuLife)を参照してください。
動作の違い
3.3Vで動作させた場合
人の有無にかかわらず、約7秒間HIGH → 約1秒間LOWを繰り返す。覆いなどをかぶせても同様。
5.0Vで動作させた場合
覆いをかぶせると常にLOWを返し、人が近づいたり動いたりするとHIGHに切り替わる。人が去ると約10秒程度でLOWに切り替わる。
参考URL
ROSのPointCloud2で独自のフィールドを定義
ROSのpclパッケージで独自のフィールドを定義したPointCloud2
のトピックをpublish, subscribeする方法です。
環境
- Ubuntu 14.04
- ROS Indigo
スクリプト例(Publisher)
rvizで確認
上記のスクリプトを動かし、rvizでPointCloud2
型の/custom_point_cloud
トピックを表示すると、下図のように生成した3つの点が色付きで表示されることが確認できます。
$ rosrun some_package publish_custom_point_cloud.py
フィールドの定義
上記スクリプトではFIELDS
の部分で独自のフィールドを定義しています。
FIELDS = [ # x, y, zやrgbなどはよく使われるフィールド名 PointField(name='x', offset=0, datatype=PointField.FLOAT32, count=1), PointField(name='y', offset=4, datatype=PointField.FLOAT32, count=1), ... # 以下が独自のフィールド PointField(name='my_field1', offset=16, datatype=PointField.FLOAT32, count=1), ]
よく使われるフィールドについては pcl/Overview - ROS Wiki の 1.3 Common PointCloud2 field names の項目で列挙されています。
PointFieldの各引数は以下のように定義されています。
string name # Name of field
uint32 offset # Offset from start of point struct
uint8 datatype # Datatype enumeration, see above
uint32 count # How many elements in the field
name
とdatatype
は見ての通り、フィールド名とデータ型です。
offset
はPointCloud2の各点を表す構造体の中で、何バイトのところからがそのフィールドを表しているかを定義するようです。
例えばx
座標のフィールドのFloat32
は4バイトなので、後続するy
座標のフィールドはoffset=4
となっています。
また、count
は当該フィールドのデータ数を表しています。通常は1で良いと思います。
ポイントの生成
POINTS = [ # FIELDSで定義したフィールドを列挙 # [x, y, z, rgb, my_field1, my_field2] [0.3, 0.0, 0.0, 0xff0000, 0.5, 1.2], [0.0, 0.3, 0.0, 0x00ff00, 1.8, 0.0], [0.0, 0.0, 0.3, 0x0000ff, 0.9, 0.4], ]
create_cloud
の3番目の引数には点のリストであるPOINTS
を渡しています。
POINTS
の各要素はそれぞれがポイントに対応しており、各ポイントもリスト型になっていて、FIELDS
で定義したフィールドの順に値が並んでいます。
例えば、count=1
のフィールドが3個の場合は長さ3のリストに、count=1
のフィールドが3個とcount=3
のフィールドが1個の場合は長さ6にリストになります。
スクリプト例(Subscriber)
このスクリプトを動かすと以下のような出力が表示されます。
$ rosrun some_package subscribe_custom_point_cloud.py [WARN] [WallTime: 1456466400.492649] x, y, z: 0.3, 0.0, 0.0 [WARN] [WallTime: 1456466400.492909] my field 1: 0.500000 [WARN] [WallTime: 1456466400.493283] my field 2: 1.200000 [WARN] [WallTime: 1456466400.493446] x, y, z: 0.0, 0.3, 0.0 [WARN] [WallTime: 1456466400.493641] my field 1: 1.800000 [WARN] [WallTime: 1456466400.493788] my field 2: 0.000000 [WARN] [WallTime: 1456466400.493930] x, y, z: 0.0, 0.0, 0.3 [WARN] [WallTime: 1456466400.494073] my field 1: 0.900000 [WARN] [WallTime: 1456466400.494212] my field 2: 0.400000
各ポイントを使うときはread_points
関数を利用すると、publisherのPOINTS
と同じ形式で点群を取得できます。
参考URL
Python, OpenCVでRGBとHSVを相互変換
動作環境
- OpenCV 2.4.8
OpenCVでRGBとHSVを相互変換
画像のRGBとHSVをまるごと変換するにはcv2.cvtColor
をそのまま使えばよいのですが、こちらはRGBとHSVの値を1ピクセルだけ変換するためのラッパー関数です。
import numpy as np import cv2 def hsv_to_rgb(h, s, v): bgr = cv2.cvtColor(np.array([[[h, s, v]]], dtype=np.uint8), cv2.COLOR_HSV2BGR)[0][0] return (bgr[2], bgr[1], bgr[0]) def rgb_to_hsv(r, g, b): hsv = cv2.cvtColor(np.array([[[b, g, r]]], dtype=np.uint8), cv2.COLOR_BGR2HSV)[0][0] return (hsv[0], hsv[1], hsv[2])
>>> hsv_to_rgb(0, 255, 255) (255, 0, 0) >>> hsv_to_rgb(60, 255, 255) (0, 255, 0) >>> hsv_to_rgb(120, 255, 255) (0, 0, 255) >>> rgb_to_hsv(255, 0, 0) (0, 255, 255) >>> rgb_to_hsv(0, 255, 0) (60, 255, 255) >>> rgb_to_hsv(0, 0, 255) (120, 255, 255)