Nordic nRF5を使ってIPv6 Globalする

NordicさんからnRF52 Dev Kitで動くIoT SDK(自分の中で通称6LoWPAN SDKと呼んでいる)が出てきたので早速使ってみることに。SDKとかはこの辺からダウンロードしてきて書き込み。

ダウンロードして展開すると、documentationに使い方が詳しく書いてあるから見れば使える。Getting Started(この辺はRaspberry PIをGWにした方法)、IoT SoftDevice(利用するSoftDevice)あたりを読めばOK。examples以下にサンプルが山ほどあるから、Keil5(を自分は使った)で書き込んで完了という簡単な流れ。

IMG_9796

ただ、RPiを使わなくてもPC(Bluetoothが付いているPC)でVMを使えば大丈夫。方法はこの辺で。一応、Win/MacともにBTが付いているPC上でVMを作って、IPv6 Gatewayにして疎通できた。

あと、これはICMPv6のサンプルコードに書いてある部分の画面キャプチャ。ボタンを押すとRAをしたり、これ便利ね。SDKダウンロードしてきて、ソースを見れば書いてあるけど。

IPv6リンクローカルなら疎通は問題なし。すぐ出来ると思われ。ただ、やっぱあれよね、Global IPv6から疎通したみたいぜ!!と思うのは自然だと思われで、やってみたらこれも問題なし。方法は次の流れで。

前提) IPv6 /64プレフィックスが使える環境
1) ルータのIPv6遮断(フィルタを切る)
2) RPiをルータに接続して、IPv6/Bluetooth Gatewayとして機能させる

前提) IPv6 /64プレフィックスが使える環境
まず前提のIPv6 /64プレフィックスが使える環境は、幸いな事に自分はAU光の回線&プロバイダを使っているおかげで、特に追加費用とか何もいらずにIPv6 /64 Globalが使えている。AU光な人はすぐ実験&IPv6できるですね。
よくIPv6の促進がどーとか聞くけど、Flet’s系のGlobal追加は知らんけど(追加費用が必要と思われ。そのままでも使えるけどGlobal抜けられないw。この辺は脈々と古くから続いているシガラミ)、AU光だとIPv6が降ってきて知らないうちに使えている人は多いような。しらないうちにIPv6が使えているってやつっすね。
ということで、この普通に宅内に引いてきているAU光を使う。

1) ルータのIPv6遮断(フィルタを切る)
これは、一応だけど超注意が必要。心配ならフィルタを切るなりした方が良い。IPv6 Globalで直接、宅内のIPv6 NWまで侵入される可能性もあるから(IPv4側は大丈夫)。ただ、設定はAterm(プロバイダから貰ったやつ)のでこの辺。自分は保護しているから、この部分は心配せずに全公開でwww

2) RPiをルータに接続して、IPv6/Bluetooth Gatewayとして機能させる
これはNordic SDKの資料のGetting Startedあたりにも書いてあるけど、radvd(IPv6のRAをするデーモン)を使ってやる。radvdとかもうヲレ的に10年前からずっと、RAをLinux上でするならradvdだよね感がする、枯れて普通に動くものですね。

RPi上でのコマンドの流れはこんな感じで、RPiを上位のAU光からの/64のGWにして、Bluetooth側に流している。本当はブリッジして…とかの方が良いのかもだけど、btXXの増減を考えるとbrを作るか、NDP Proxyでとりあえず代理応答しておくか…は考え所かなと思われ。とりあえず手軽にNDP Proxyした訳だけど、どっちもどっちだと思われ。
ちなみに、以下、プレフィックスを特に隠さず全部書いちゃっているけど、このアドレス&プレフィックスにアクセスしてもすでにアクセス不能にしているので気にしてないっす。ONUを再起動すれば変わっちゃったりするし。

# 6lowpanを有効にする
modprobe bluetooth_6lowpan
echo 1 > /sys/kernel/debug/bluetooth/6lowpan_enable

# nRF52に接続する
echo "connect 00:B9:89:15:EF:B1 1" > /sys/kernel/debug/bluetooth/6lowpan_control

# IPv6 forwarding(GW)を有効
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding

# とりあえずlink localのIPv6 pingを投げて確認
ping6 fe80::2b9:89ff:fe15:efb1 -I bt0

# bt0でRAを受けれるようにする(brさせなきゃ、別にいらない気もするけど)
echo 2 > /proc/sys/net/ipv6/conf/bt0/accept_ra 

# ICMPv6 NDP Proxyを有効(これはRPiのeth0に入ってくるRA応答用)
sysctl -w net.ipv6.conf.all.proxy_ndp=1

# 生成されるアドレス用の上位ルータ向けNDP Proxy
ip -6 neigh add proxy 240f:1:6c14:1:2b9:89ff:fe15:efb1 dev eth0

# とりあえず適当にbtにアドレスを振っておく
ifconfig bt0 add 240f:1:6c14:1::4/68

こっちはradvdの設定

cat /etc/radvd.conf 
interface bt0
{
    AdvSendAdvert on;
    # このIPv6 prefixはAU光から配布されたもの
    prefix 240f:1:6c14:1::/64
    {
        AdvOnLink off;
        AdvAutonomous on;
        AdvRouterAddr on;
    };
};

ifconfigの状態はこんなん

root@raspberrypi:~# ifconfig
bt0       Link encap:UNSPEC  HWaddr 00-19-86-FF-FE-00-00-78-00-00-00-00-00-00-00-00  
          inet6 addr: 240f:1:6c14:1:219:86ff:fe00:78/64 Scope:Global
          inet6 addr: 240f:1:6c14:1::4/68 Scope:Global
          inet6 addr: fe80::219:86ff:fe00:78/64 Scope:Link
          UP POINTOPOINT RUNNING MULTICAST  MTU:1280  Metric:1
          RX packets:65 errors:0 dropped:0 overruns:0 frame:0
          TX packets:98 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:6339 (6.1 KiB)  TX bytes:8122 (7.9 KiB)

eth0      Link encap:Ethernet  HWaddr b8:27:eb:d8:d5:d6  
          inet addr:192.168.0.3  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: 240f:1:6c14:1:d709:d6c2:f28f:a2d9/64 Scope:Global
          inet6 addr: fe80::7dec:ae50:4f54:7d90/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1147 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1164 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:123007 (120.1 KiB)  TX bytes:212157 (207.1 KiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:155 errors:0 dropped:0 overruns:0 frame:0
          TX packets:155 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:12940 (12.6 KiB)  TX bytes:12940 (12.6 KiB)

bt0はnRF52と接続しているBluetoothドングルのインタフェイス。プレフィックスが若干適当感がするけど、とりあえずOK。ここまで出来たら、radvdを起動すればBluetooth側にIPv6 Global側からping6で疎通できる。IPv6が大量に配布してくれるConoHaというクラウド(特に何の追加費用もいらずに16個もデフォでもらえる。IPv6使った簡単な疎通テストとか、IPv6使った何かをする時はめっちゃ便利と思われ)があって、そこからping6を投げて、RPi上のbt0でtcpdumpをとってみるとこんな感じ。

[Global IPv6 Server] [宅内ルータ] [RPi:BTドングル] [nRF52]

といった感じで、RPiのbt0の所でちゃんとnRF52側(240f:1:6c14:1:2b9:89ff:fe15:efb1)と行って戻ってきているのが分かるですね。NDP Proxyした方が接続したbtXに合わせて上位のrouterをGW(RPi)で選択できるし、開け閉め出来そうだから良いかなーとは思ったけど、ちゃんと据え置きGWにするならbrでも良い気もする。イメージしたのは、キャリアにIPv6を使うよう通達が出ているあれで、スマホでIPv6を/64で終端した時にスマホに接続したBTとかをGW(スマホ)を経由して流す感じの。まぁ、AndroidとかLinuxだしカーネルツリーにすでに6lowpanモジュールは入っていて、その辺は時間の問題だと思われ。
とりあえず、これは実験ってことでね。

会社でArduinoとか配布した〜IOTには実際にモノを触ってみる

社内でArduino&センサー類を無償配布した。これには少し動機があって、IoTという言葉が流行っているのもあるけど…

1. IoTはWebサービス側だけじゃなく、デバイスも関わってくる。
2. ガジェット・デバイス物の基礎を知ることは、ネット・サービス系でも重要な要素の一つ。
3. Things=モノは実際に触れて、作って理解することが大切になる。

こういう立て付けにて配布を行うことに。もちろん、結果や物が出来ても出来なくてもOKで、無償で配布した。

「IoT、IoTとかってネット・サービス側から言っても、実際にデバイスやモノを触ってみないと分からんべ」という所もある。ネット・サービス系のエンジニアでも面白いガジェットが出れば興味津々で、どんなアプリに?何に使おうか?といったモノに対する気持ちはあると思うし。
まぁ、机上でIoTやガジェット物・デバイスやらArduinoってあるよねー的に知っているより、自分でやってみる方が文字通り、百聞は一見に如かずってやつですね。

効果としては、IoTを支える基礎技術に触れることで、そこから何か新しいサービスやアプリ・ガジェットを考えたりも出来る可能性が生まれてくる。あとこういう学習を通じた会社/グループの基礎体力の向上という側面もあるし、IoTという言葉でなにを行うか?といった時、それぞれの人が各グループ会社での相談先の一人になるという事もあるかなと。

前置や建て付けは色々あるけど、化学反応的な何かが起きるかも知れないという期待は高くなったりもした。何はともあれ、まずは使いやすいArduinoを使ってという路線でやる事にした。ググれば大抵の方法は書いてあるし。流れ的にはこんな感じにて。

1. ワークショップに必要な部材を検討・予算確保・購入
2. 参加者を募集
3. 購入部材を参加者に渡す
4. ノウハウと共に使い方を説明(WP)

流れを追って書いていく。

1. ワークショップに必要な部材を検討・予算確保・購入

部材は大量に購入した。一覧は次の通り。わりと大量で型番まで書く元気が無いから、とりあえず名称/機能だけ記載しておく。

Arduino UNO(もちろん純正)
USBケーブル

- LED類
赤色LED
青色LED
黄色LED
緑色LED
赤外線LED
赤外線リモコン受光モジュール

- センサ/WiFi
フォトリフレクタ
温度センサ
照度、光センサ、Cdsセル
赤外線距離センサ(GP2Y0A21YK)
圧力センサ
音センサ、コンデンサマイク(4個入り)
6軸加速度センサ(3軸加速度・ジャイロ) MPU 6050
WiFi ESP8266
圧電スピーカ

- モータ
サーボモータ : SG90x2
サーボモータ用ブラケット
DCモータ
DCモータドライバ TP7291P

- 接続類
ブレッドボード
ジャンパーコード
ジャンパーワイヤー
ジャンパーワイヤー
小型クリップ付きコード
トグルスイッチ
基板用トグルスイッチ3P
タクトスイッチ、赤、黒、黄

- トランジスタ/IC
トランジスタ(PNP)、2SA1015L-GR
トランジスタ(NPN)、2SC1818Y
オペアンプ、LM358N
オペアンプ、LM386N

- 抵抗類
半固定抵抗、10KΩ
抵抗 10KΩ
抵抗 1KΩ
抵抗 330Ω
抵抗 220Ω
抵抗 470Ω
抵抗 1MΩ
抵抗 100KΩ
抵抗 22KΩ
抵抗 220KΩ

- コンデンサ
コンデンサ、0.1μF
コンデンサ、1μF
コンデンサ、10μF

予算は社長に内容を直訴して、IoTということ・必要性・効果について説明して確保した。理解がある会社・社長で良かった。
そして、これらは全て備品扱いで、個別に参加者に渡して自由に使って貰う事にした。変に管理するより、自由に使って貰った方が良いからね。個別に全部パックして渡して「自由に使ってOKです!!」と。

2. 参加者を募集

これは会社のSNSで呼びかけです。参加したい人は、メールかメッセを貰えたらーということで。
グループ全部で数千人(6,000人くらい)の社員さんがいるけど、クリエイター・エンジニア・非エンジニアの区別なく募集した。この辺の条件は特に無しで。全員を引き受けようとはしたけど、先着40名ということで。ただ、めっちゃ応募が来たから、フルフルに使い切って全部で50-60パックほど配布した。予算・在庫確保を先にしたというのもあるけど、全員に配れなかったのは申し訳無かった。。。

3. 購入部材を参加者に渡す

備品はこんな感じで(これは一部分ですね)、一つづつパックに入れてラベリングした。

大量に準備

これはいきなり抵抗やら電子部品を渡しても、混ぜちゃったり、これは一体なに?と思うだろうなぁ…と思い、地味にラベルを作って内職のように貼り&包み分けしまくったですね。結構根気がいる単純作業で手伝って貰ったりして。

4. ノウハウと共に使い方を説明(WP)

これは次回はなにをやるか?というのをSNSで流して参加性で、業務時間後の19時以降に毎回行った。「これを作ってやってみよう!!」「レッツ!!」といった感じで。

ワークショップだと、他にも自分の手持ちのAgICを使って静電容量センサを作ってみたり(スマートフォンの静電容量式タッチパネルの原理の基礎)、基本的な原理についても説明して進めたりした。

これは圧力センサを使ったもの。

たまに小ネタで、果物をタッチすると音が鳴るという組み合わせも.

ただ、作る人は自分で作っちゃうもんで、赤外線でエアコンをつけたりする物を自宅で作って動画をSNSにアップして見せていたり(赤外線リモコンっすね)、最近だとL3D Cubeに渡したArduinoをつけて動かしてみた人とかも。

他にも3Dプリンターやドローンも使えたり、わりと何でも作れる環境だったりする。突然、IoTワークショップをやりたいです!!と会社(GMO Internetという会社っすね)に言ってみたら、OK!!とサクサク進んで感謝です。

elastic/Kibanaでセンサーデータの可視化

これは Elasticsearch Advent Calendar 2015 の記事です。

複数のセンサーデータを取得してfluentd経由でelasticsearchに流して可視化する内容です。構成的にはこんな感じです。

これだけ見れば普通にサクッと出来そうですね。golang/fluentdとセンサー周辺の設定、データ形式やコードについてはこちらの記事を参照。elastic/kibanaは次のような感じです。

elastic : 2.0.0-rc1
kibana : 4.3.0

kibanaについてはgitにある最新版を使ってみました。これは一つにダークテーマを使いたいという、これ1点に尽きます。開発時点ではテーマの選択が出来なくて白い感じので、何となくクールでカッコイイテーマを使いたくて、4.3を使おうとしたらelasticのバージョンも上げないとダメ…という事でどちらも最新版を使ったですね。多分だけど、ダークなテーマが好きって人は多いと思われ。

んでセンサーデータの表示画面はこんな感じで。

照度(光センサーの値)が上がると、電球マークが光る。

そうですね…kibanaのUIというか表示をいじって、インタラクティブな要素を入れています。ってことで、kibanaのざっくりした構成を読み解くと。

実装: NodeJS
グラフ周り : D3
フレームワーク : AngularJS

デバックモードで起動してあげると、コードを修正すると自動でリロードがかかってdeploy&チェックできるという仕組み(その時、js周りの圧縮もかかったりも)だったり、nodejsのmoduleが山ほど入っている。ただ、このNodeJS/D3/AngularJS周りを抑えておけば、独自の改造はどーにかなると思われ。基本的にpluginの形式で、ほとんどのUI(dashboardも)が作られているからね。

んで、このダッシュボードに追加するボックスの単位はlegendという扱いになっていて、中のUIを変更するために src/ui/public/vislib/lib/legend.js にゴリゴリっと手を入れている。他にも手を入れているけど、メインはその周辺あたり。

[その他]
今回、地域毎に大量のダッシュボードを用意した。色んな地域、国にセンサーを置いていて、それ毎にダッシュボードを用意した。

このダッシュボードの追加での対応を楽にしたい!!という欲求があって、色々と試してみたらKibanaの便利機能を発見(というか、ですよねー的な)した。流れとしては、

1. visualization を基本要素(温度、湿度、照度)で作る。
2. Dashboardを作る
3. Dashbaordの”Edit dashboard Object”でクエリーを直接書いて、地域選択

という流れ。これでvisualizationで作る要素を基本要素だけにして、dashboardを用意してちょっとクエリでキーを追加してあげれば完成という流れ。これはメチャクチャ便利だと思った。基本のvisualizationだけ用意すれば、あとの表示要素はどうとでもなるから。

実際の流れは…

1. visualization を基本要素(温度、湿度、照度)で作る。
実際、3つしか作っていない。

2. Dashboardを作る
とりあえず、Dashbaordの”+ボタン”で追加する。

3. Dashbaordの”Edit dashboard Object”でクエリーを直接書いて、地域選択
dashboardの一覧画面の編集から..

んで、IDを設定して完了。

という流れ。表示要素はほぼ同じで、ダッシュボードを大量に作って区別するときは、こんな感じでVisualizationで基本要素を作っておいて、Dashboard側のちょっとした変更でとっても簡単&大量に作ることができる。

golangでセンサーデータをMQTTで受けてloggerする

Go その2 Advent Calendar 2015の記事です。

golangで複数のセンサーからのデータをMQTTで受けてfluentdを使ってロギング、elastic/kibana, splunkで可視化します。これは実際にET展のマクニカさんのMpressionによるIoTのPoC(Proof of Concept)にて展示してきた内容の詳細です。実際の展示中の内容はこちらです。会場と世界各国のマクニカさんのオフィスにセンサーを置いて頂き、色んなところからモニタリングしています。

構成
以下の図のような構成です。色んなセンサーを使っています。MQTTを使えるセンサーがあるので、MQTTサーバとしてはmosquittoを使っています。

送信データフォーマット
センサーからのデータは基本的には、温度、湿度、照度を扱っています。他にも色々取れるのですが(加速度、地磁気、音声, IR…etc)基本データとして3個を扱う事にします。MQTTで各センサーデバイスからデータを送信するのですが、その時のデータフォーマットは以下にしています。(一部抜粋です)

DeviceId   string : センサデバイスに振られているID
DeviceType string : TI/BCM/Kivo...etc センサーのタイプ
Temp       string : 温度
Lux        string : 照度
Humidity   string : 湿度

デバイスIDはシステム側で管理して、存在するものだけをloggingしたり、検索時の引き当てで入れておいた方が良いでしょう。センサーのタイプはシステム側でIDから引ければ問題無しです。温度、照度、湿度はそのままですね。

サーバ側
こちらはMQTTで受け側です。センサデータを受けたらfluentdに流しています。fluentdで直接受けて流してもOKですが、ここではgolangで受けてfluentdに投げてみましょう。fluentd, mqttのIPとか設定すれば動くです。

package main

import (
    "encoding/json"
    "flag"
    "log"
    "fmt"
    "time"

    MQTT "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git"
    "github.com/t-k/fluent-logger-golang/fluent"
)

// 受信するjsonデータ
type SensorData struct {
    DeviceId   string `json:"DeviceId"`
    DeviceType string `json:"DeviceType"`
    Temp       string `json:"Temp"`
    Lux        string `json:"Lux"`
    Humidity   string `json:"Humidity"`
}

// デフォルトハンドラ(Subscribe時にトピック毎に指定も可能)
var defaultMTTTHandler MQTT.MessageHandler = func(client *MQTT.Client, message MQTT.Message) {
    fmt.Printf("Received MQTT message on topic: %s\n", message.Topic())
    fmt.Printf("Message: %s\n", message.Payload())

    sensorData := SensorData{}
    json.Unmarshal([]byte(message.Payload()), &sensorData)

    logger, err := fluent.New(fluent.Config{FluentPort: 24224, FluentHost: "host.name"})
    if err != nil {
        fmt.Println(err)
    }
    defer logger.Close()

    tag := "sensor.data"
    t := time.Now()

    // ちょっと加工用
    data := map[string]string{
        "temperature":      sensorData.Temp,
        "lux":              sensorData.Lux,
        "humidity":         sensorData.Humidity,
        "device-type":    sensorData.DeviceType,
        "device-id": sensorData.DeviceId,
    }
    logger.PostWithTime(tag, t, data)
    log.Println("Send to fluentd")
}

func main() {
    opts := MQTT.NewClientOptions().AddBroker("tcp://host.name:1883").SetClientID("sensorlogger")
    opts.SetDefaultPublishHandler(defaultMTTTHandler)

    client := MQTT.NewClient(opts)
    if token := client.Connect(); token.Wait() && token.Error() != nil {
       panic(token.Error())
    }

    qos := flag.Int("qos", 1, "The QoS to subscribe to messages at")
    if token := client.Subscribe("/sensor/put", byte(*qos), nil); token.Wait() && token.Error() != nil {
        panic(token.Error())
    }

    for {
        time.Sleep(1 * time.Second)
    }
    client.Disconnect(250)
}

センサー側(TI/RPi2)
こちらはセンサー側のRaspberry PI、TI(nodejs)側。SensorTagとBLEで通信して、データを取得したらMQTTで投げているだけですね。

var SensorTag = require('sensortag');
var mqtt    = require('mqtt');
var request = require('request-json');
var mqttclient  = mqtt.connect('mqtt://mqtt server');

SensorTag.discoverByAddress("sensor tag BTのMacアドレス", function(tag) {
    tag.on('disconnect', function() {
        console.log('disconnected!');
        process.exit(0);
    });

    function connectAndSetUpMe() {
        console.log('connectAndSetUp');
        tag.connectAndSetUp(enableIrTempMe);
    }

    function enableIrTempMe() {
        console.log('enableSensor');
        tag.enableHumidity(notifyMe);
        tag.enableLuxometer(notifyLux);
    }

    function notifyLux() {
    }

    function notifyMe() {
        tag.notifyHumidity(listenForHumidity);

        tag.setHumidityPeriod(1000, function(error) {
            if (error != null)
                console.log(error);
        });
    }

    function listenForHumidity() {
        tag.on('humidityChange', function(temperature, humidity) {
            tag.readLuxometer(function(error, lux) {
                var data = {
                    DeviceId: "unique device id",
                    DeviceType: "TI SensorTag",
                        Temp: temperature.toFixed(1),
                         Lux: lux.toFixed(1),
                    Humidity: humidity.toFixed(1)
                };
                mqttclient.publish('/sensor/put', JSON.stringify(data, null, "\t"), {qos : 1});
            });
        });
    }
    connectAndSetUpMe();
});

結果
実際の可視化の様子はこちらです。
elastic/kibana

splunk

Pub/Subのライブラリは色々あって、なぜにGolangを使ったか?というと、とっかかり易くて便利というのもあるけど、センサーデータはストリームで恐ろしい勢いで機械的にデータが飛んできたり、IPは変えられるけどエンドポイントは固定のパスとかあったりする可能性を考えて、並列部分を簡単に書けて、endpointづつ小さいAPIでサクサク作れるgolangで良いかなと。

IoT proof of concept – realtime sensor monitoring using elastic/kibana and splunk

I had exhibit the IoT proof of concept at Embedded Technology 2015 in Macnica showcase(Thanks for Macnia all stuff!!). In this exhibit, realtime monitoring, analyzing the sensor data in cloud system by using several sensors and networking protocol.
I had some problem to be solved when I developed. The sensor has it’s original networking protocol(exp: MQTT, REST, TCP, JSON…etc.) difficult to update that all firmware, hard to use the same networking protocol. For example, if all sensors can use MQTT, this problem is piece of cake. But sensor have own original networking protocol. So I made sensor networking exchange GW in Cloud server side. This GW can manage several networking protocols quickly and easily when new sensor join the system.
And next, how to logging and aggregation the sensor data in system and can use explore, visualize, discover data. Of course logging data can be easy to process and routing in system, have to send to some analyzing system like a elastic/kibana, splunk and more analyzing system(Hadoop, Spark). For resolved this problem, I choice fluentd for this logging system. Fluentd have good performance, message routing architecture, many useful plugins, and can be processing sensor data very easily.
And this IoT PoC system scale for many sensors, have some security requirements.

Architecture Overview.

Exhibit in showcase(written in japanese).
Mpression IoT PoC(Proof of concept) held in ET/IoT 2015 – readltime visualizing the environments sensor data from the company offices around the world., Monitoring

– Sensor Devices
EH Terminal
Kibo(CP-1)
Uzuki Konashi
Broadcom WICED
TI SensorTag

Broadcom WICED and TI SensorTag communicate to the Raspberry PI2(BLE), this how to install environment and nodejs source code is here(but japanese).

– Server Side
Cloud : Konoha
OS : Ubuntu 14.04
Sensor GW : golang/mosquitto
elasticsearch 2.0.0
kibana 4.3
Fluentd (td-agent 2.2.1)
Splunk 6.3

sensor devices place in Germany, Hongkong, Shanghai, Taiwan, Dallas, Japan(ShinYokohama, Osaka, Nagoya, Matsumoto, Shibuay, in exhibit showcase)…etc, realtime visualizing sensor data(temperature, humidity, lux) in GoogleMap.

sensor data detail in elastic/kibana.

when the lux parameter become up(dark to bright), lamp image will change.

sensor data summary in splunk.

渋谷モノ系ミートアップやってみます

久々にイベントを立てた。

渋谷モノ系ミートアップ

モノ系主体のイベントとかミートアップはよくあるけど、Web、ネット側からモノ系にアプローチしてやっている所からの…といった感じで、モノ系な人とネット系な人とのミートアップになれば…と。前にやっていたSolr勉強会以来、かなり久々です。

別に渋谷が好きとか何とかじゃないけど、渋谷周辺にはアプリ、サービス、課金、ネット広告をやっている会社がゴロゴロしている。そして、システムもシステムの自動化、運用はもちろん、凄まじく膨大なデータを使った機械学習もノウハウがとってもあると思われ。(それはそうで、大量のサービスをやっている所に大量のデータが集まるというのも自然なので、データが大量にあればそれを生かす技術も発達するわけで)

自分が率直に感じているのは、IoTという言葉自体はそんなに好きじゃなく(顔文字にしか見えないw)、モノを使ったサービスの総称といった感じが。そこで、面白い、触ってみて楽しいモノというだけじゃなく、それを使ったサービスやアプリ、または課金/広告といった方法、超大規模システム、データの扱いを日常的にやっている所との繋がり、両輪が間違いなく必要になると思われ。dailyで数億のアクセスが一気に来るとか、多分モノ寄りの方は経験が無いと思われで、逆にネット寄りの方はこの端末・センサーが…とか扱う特性とかさっぱり分からないはず。

ただ、両方にちょっぴり顔を出している感じとしては…技術の下地(モノ寄り、Web寄り)が違うので、技術・サービスのミートアップでお互いが会う事がない、これに尽きる。
それぞれの技術が全く違うというのもあって、例えばネット寄りの人に「この回路でセンサーの値を取って…」とか簡単なものでも理解を得られる事がとっても少ない…(経験上)。もちろん逆もまた然りとは思ったりも。

ネット系の方は「このガジェット面白い!!」とか興味津々だったりするし、モノ寄りの方は機械学習(AI的な)とか広告、超大規模システムの作りとか興味津々かなと。例えば数億/dailyでガツンとアクセスが来るとか、モノが当たってシステムをスケール・自動化する時とかどーするか?だったりは、ネット系のノウハウが必要になると思われ。

どちらの分野でも、この人マジですげぇ!!と思う人は沢山いる中で、両輪が交わらないのは勿体なさすぎる!!という所が多分にあったりする。モノ系の方も、ネット系の方もぜひぜひ!!

現状のタイムラインはこちら。LTは絶賛募集です。

  • 場所 : 21cafe 東京都渋谷区道玄坂1-14-6 ヒューマックス渋谷ビル3F
  • 日時 : 2015/11/05(木) 18:30-(開場), 19:00-開始
  • 定員 : 80名sdf
  1. Beatrobo, Inc 浅枝大志さま
    レトロゲームをスマホ用に復活!ピコカセット
  2. フリービット株式会社 渡辺知男さま
    ドローン + IT + ウェアラブル(仮)
  3. GMOインターネット 宮尾 武裕さま
    O2O iBeaconを使ったサービスについて(仮)
  4. LT
    1. Web/ネット系からモノ系開発への関わりについて : hirotakaster
    2. レゴマインドストームのクラウド連携(Azure,AWS) : 渡辺 登 さま
    3. プログラマ向けハードウェア自動設計ツール ミルフィーユ Kou Yosinariさま

Raspberry PIとSensor Tag

Raspberry Pi2にBluetoothのドングルを指して、Broadcom WICED SenseとTI SensorTagに同時にBluetooth経由でNodeJSでアクセスする方法について、備忘録で残しておく。

– 現物
右 : Broadcom WICED Sense
左 : TI Sensor Tag

Broadcom WICED Sense
搭載されているセンサーとしては、加速度、ジャイロ、電子コンパス、気圧、温度、湿度が取れますね。BluetoothはBCM20737S。スイッチサイエンスさん、マクニカオンラインさんとかでゲットできるですね。

TI Sensor Tag
こちらは、CC2650が搭載された激しめの端末。加速度、ジャイロ、3軸磁力計(というかMPU 9250)、照度、湿度、気圧、磁気、IRサーモパイルセンサといった感じで盛り積み。

– Raspberry PI2上での作業
NodeJSとbluezを入れるだけ。

uname -a 
# nodejsとbluezのインストール
# Linux raspberrypi 4.1.7-v7+ #817 SMP PREEMPT Sat Sep 19 15:32:00 BST 2015 armv7l GNU/Linux
# RASPBIAN JESSIEを使っています。
# 
sudo wget http://node-arm.herokuapp.com/node_latest_armhf.deb
sudo dpkg -i node_latest_armhf.deb
node -v 
npm -v
sudo apt-get install bluez

– WICED Senseにつなぐ

npm install cylon
npm install cylon-ble
npm install cylon-wiced-sense

test.js

var Cylon = require('cylon');
// UUIDはhcitool lescanで見れるMacアドレス
// 00:10:18:01:4A:FA WICED Sense Kit
// こんな感じで
Cylon.robot({
  connections: {
    bluetooth: { adaptor: 'ble', uuid: '001018014afa' }
  },

  devices: [
    {name : 'wiced',  driver: 'wiced-sense' },
  ],

  display: function(err, data) {
    if (err) {
      console.log("Error:", err);
    } else {
      console.log("Data:", data);
    }
  },

  work: function(my) {
    my.wiced.getData(function(err, data) {
      if (!!err) {
        console.log("Error: ", err);
        return;
      }
      console.log("Data: ", data);
    });
  }
}).start();

結果

sudo node test.js     
2015-10-15T07:22:39.092Z : [Robot 1] - Starting connections.
2015-10-15T07:22:39.152Z : [Robot 1] - Starting connection 'bluetooth'.
2015-10-15T07:22:43.960Z : [Robot 1] - Starting devices.
2015-10-15T07:22:43.963Z : [Robot 1] - Starting device 'wiced'.
2015-10-15T07:22:43.963Z : [Robot 1] - Working.
Data:  { accelerometer: { x: 0, y: 0, z: 89 },
  gyroscope: { x: -50, y: -247, z: -222 },
  magnetometer: { x: 548, y: 653, z: -1464 } }
Data:  { accelerometer: { x: 1, y: 0, z: 88 },
  gyroscope: { x: 6, y: -249, z: -220 },
  magnetometer: { x: 535, y: 656, z: -1463 } }
Data:  { accelerometer: { x: 0, y: 0, z: 89 },
  gyroscope: { x: -19, y: -219, z: -217 },
  magnetometer: { x: 553, y: 651, z: -1460 } }
Data:  { accelerometer: { x: 0, y: 0, z: 88 },
  gyroscope: { x: 24, y: -250, z: -208 },
  magnetometer: { x: 558, y: 643, z: -1451 } }
Data:  { accelerometer: { x: 1, y: 0, z: 89 },
  gyroscope: { x: 30, y: -243, z: -215 },
  magnetometer: { x: 558, y: 648, z: -1448 } }
Data:  { accelerometer: { x: 0, y: 0, z: 89 },
  gyroscope: { x: -11, y: -243, z: -204 },
  magnetometer: { x: 565, y: 671, z: -1460 } }
Data:  { accelerometer: { x: 1, y: 0, z: 90 },
  gyroscope: { x: 9, y: -246, z: -225 },
  magnetometer: { x: 562, y: 646, z: -1440 } }
Data:  { accelerometer: { x: 0, y: 0, z: 89 },
  gyroscope: { x: 10, y: -227, z: -206 },
  magnetometer: { x: 557, y: 651, z: -1462 } }
Data:  { accelerometer: { x: 0, y: 0, z: 89 },
  gyroscope: { x: -12, y: -251, z: -223 },
  magnetometer: { x: 556, y: 642, z: -1451 } }
Data:  { humidity: 701, pressure: 10120, temperature: 285 }
Data:  { accelerometer: { x: 0, y: 0, z: 89 },
  gyroscope: { x: 3, y: -248, z: -196 },
  magnetometer: { x: 554, y: 655, z: -1455 } }

– Sensortagにつなぐ

npm install async
npm install bluebird
npm install sensortag 

test.js

var SensorTag = require('sensortag');

// UUIDはhcitool lescanで見れるMacアドレス
// 68:C9:0B:06:E4:8D CC2650 SensorTag
// こんな感じで
SensorTag.discoverByAddress("68:C9:0B:06:E4:8D", function(tag) {
    tag.on('disconnect', function() {
        console.log('disconnected!');
        process.exit(0);
    });

    function connectAndSetUpMe() {
        console.log('connectAndSetUp');
        tag.connectAndSetUp(enableTempMe);
    }

    function enableTempMe() {
        console.log('enableSensor');
        tag.enableHumidity(notifyMe);
        tag.enableLuxometer(notifyLux);
    }

    function notifyLux() {
    }

    function notifyMe() {
        tag.notifyHumidity(listenForHumidity);

        tag.setHumidityPeriod(10000, function(error) {
            if (error != null)
                console.log(error);
        });
    }

    function listenForHumidity() {
        tag.on('humidityChange', function(temperature, humidity) {
            tag.readLuxometer(function(error, lux) {
                console.log('\tlux = %d', lux.toFixed(1));
                console.log('\thumidity Temp = %d deg. C', temperature.toFixed(1));
                console.log('\tthumidity  = %d', humidity.toFixed(1));
            });
        });
    }

    connectAndSetUpMe();
});

結果

sudo node test.js 
connectAndSetUp
enableSensor
	lux = 134185
	humidity Temp = 27.2 deg. C
	thumidity  = 64.9
	lux = 140.2
	humidity Temp = 27.2 deg. C
	thumidity  = 64.9
	lux = 140.6
	humidity Temp = 27.2 deg. C
	thumidity  = 64.9

めちゃ簡単。

KoshianとFluent, Elasticsearch/Kibanaでリアルタイム可視化

Koshianを使ってセンサーデータのリアルタイム可視化・分析可能な構成を考えて作ってみたメモ。全体構成はこんな感じ。

全体構成

MQTTを使っても大丈夫で、MQTTでもOK。ただ、敢えて使わない。使わない理由は以下にて。

可視化の様子(Kibana)

温度のグラフ、device_id(データを送ってきたデバイス毎のID)、接続元IPを使った位置情報を表示している。

やってみたいこと
1. センサーデータを可視化 -> es/kibana
2. リアルタイムが良い、センサーデータのストリームにも耐性がある -> fluentd
3. 大規模、並列化/スケールする -> es/fluentd/AP(golang)
4. 解析/分析も可能 -> fluentdからhadoopとかに流し込みでも可

使うもの
fluentd : ログ集約配送
elasticsearch : 検索用DB
kibana : 可視化
golang : gwとのやりとり用
ConoHA : クラウドのサーバ

KoshianはWeb系の人にはさーっぱり馴染みも無いと思うけど、安くてBTもサクッと使えるという素敵な端末。逆にモノをいじる方には、es(elasticsearch)、fluentd、kibanaとかナニソレ的な感じもするけど、かなり使われている感がする。特に可視化、リアルタイム、スケールするといった所では、導入検討はするはず。

なぜMQTTを使わないか?
自分がよく使うMQTTは使いません。サーバはUbuntuで立てているから、mosquittoとか使えば簡単なんだけど。その場合、golangの口をMQTTに入れ替えればOK、それでも動くですね。GW(iphone)がpublisherで間にMQTT Brokerが挟まったgolang(subscriber)で取得といった感じで。まぁ簡単に動かせる。

ただ、なぜにMQTTでセンサーデータの配送をしないか?というと、MQTT broker経由でsubscriber側で取得するともちろんpub側のIPが分からない。pub/subでのメッセージ配送物なのでそういうもんだけど。

インターネット上を流れてくるなら発信者のIPは知りたいし、データ発信者(デバイス)の発信者情報(IP)を受け取り手側で処理はしたくなるというか、これみたいに簡単に地図上に表示したくなった時とかでも。まぁ、IPと位置情報は正確には関連性が無いんだけどね。
デバイス/GW側でGPS情報を送信データに付与すれば…というのはそうだけど、別に位置が知りたい訳ではなくIPが知りたい。逆にMQTT BrokerでIPをメッセージに付与…は無いし、Brokerだけで動くならそもそもpub/subの意味は無い。

ちなみに、IPのログとしての意味では、MQTT Broker側ではログとしてID/IP/配送先のID/IPは残しておく必要はあるはず。そうしないと、怪しいメッセージの配送、不正ID・ユーザの混入といった時にかなり厄介なことになるし、追跡手段として残しておくことになるかと。

そこまでしてMQTTか?といったらちょっと別の用途で使った方が好いと思われ。例えば、閉じた(宅内)NWとかバックエンドの配送では良いかなと。セキュリティ的に閉じていれば、その辺のことはある程度すっ飛ばして考えらえるから。
要はインターネット、Globalで利用する時、実際の運用・管理でどーするか?。MQTT Brokerも自分の管理で全て把握できるならそれでも良い気はするけど、この辺の解を持っている人がいたら教えて欲しい。

td-agentの設定
ここではIPアドレスを追記している。センサーデータの増減には全く影響を受けないから素敵。

# GEOIPで位置情報・国コードの追加
<match debug.temp>
  type geoip
  geoip_lookup_key ipaddr
  <record>
    lat   ${latitude["ipaddr"]}
    lon   ${longitude["ipaddr"]}
    location_properties  '{ "lat" : ${latitude["ipaddr"]}, "lon" : ${longitude["ipaddr"]} }'
    country ${country_code['ipaddr']}
  </record>
  tag store.${tag}
</match>

# elasticsearchに登録
<match store.debug.temp>
  type copy
  <store>
    type stdout
  </store>
  <store>
    type elasticsearch
    host localhost
    port 9200
    logstash_format true
    logstash_prefix temp

    tag_key @log_name
    include_tag_key true
    flush_interval 10s
  </store>
</match>

golang側
golangはこんな感じ。サクッと書いて、すぐ使えるから好き。スケールさせたかったら並べればOK。

package main
import (
	"fmt"
	"log"
	"net/http"
	"strings"
	"time"

	"github.com/ant0ine/go-json-rest/rest"
	"github.com/t-k/fluent-logger-golang/fluent"
)

// 受信データ用のstruct
type SensorData struct {
	DeviceId string
	Temp     string
}

func main() {
	logger, err := fluent.New(fluent.Config{FluentPort: 24224, FluentHost: "ip addr"})

	if err != nil {
		fmt.Println(err)
	}
	defer logger.Close()

        // GW(iphone)からは、RESTで/put/を叩く。
	api := rest.NewApi()
	api.Use(rest.DefaultDevStack...)
	router, err := rest.MakeRouter(
		rest.Post("/put/", func(w rest.ResponseWriter, req *rest.Request) {
			SensorData := SensorData{}
			err := req.DecodeJsonPayload(&SensorData)
			log.Println(req.Body)
			if err != nil {
				rest.Error(w, err.Error(), http.StatusInternalServerError)
				return
			}

                        // このtagはfluentの方と合わせておく
			tag := "debug.temp"
			t := time.Now()

                        // 温度, 接続元IP, device-id(端末からくる)を送信
                        // センサーデータが増えた時はこの辺で追加。ここでは温度のみ。
			data := map[string]string{
				"temp":      SensorData.Temp,
				"ipaddr":    strings.Split(req.RemoteAddr, ":")[0],
				"device-id": SensorData.DeviceId,
			}

                        // fluentd行き
			logger.PostWithTime(tag, t, data)

			w.WriteJson("OK")
		}),
	)
	if err != nil {
		log.Fatal(err)
	}
	api.SetApp(router)
	log.Fatal(http.ListenAndServe(":8080", api.MakeHandler()))
}

その他
es/kibanaの設定方法はググれば書いてある。GW(iphone)からはBLEでKoshianから値を取得して、RESTで叩くだけでOK。とっても簡単。MQTTを使う時は、PodでMQTTKitを入れてすぐ使えるから、それも問題ないでしょう。あと認証をしたくなったらMariaDBでも立てて、そこで管理してあげる感じ。暗号化はTLSで証明書でも突っ込んでおいて。
若干身内感はするけど、ConoHaイケてる。客観視で使ってみて、性能(CPU/SSD)、価格的にもこれは良いと普通に思った。

World IP Traceroute Locations

サーバに対するアクセスで、接続元IPの位置情報から地図に接続元をマッピングして表示したりする機能はよくある。Google Analyticsでは見慣れた人も多いと思う。

インターネットの通信はEnd-to-End繋がっているように見えるけど、1方のEndから送信されたデータはもう1方のEndに直接届くわけではなく、途中で色んな経路を辿っていく。例えば自分のこのサーバにアクセスしにきた’95.138.53.131’のIPアドレスは次のような経路を辿っている。

+-----------------+---------------+----------------+
| trace_ipaddr    | country       | city           |
+-----------------+---------------+----------------+
| 95.138.53.131   | Martinique    | Riviere-Salee  |(ここからの接続)
| 213.188.170.58  | France        | Presles        |
| 213.188.171.9   | Guadeloupe    | Pointe-a-Pitre |
| 77.67.69.126    | Germany       | Neu-Isenburg   |
| 141.136.109.25  | Germany       | Neu-Isenburg   |
| 199.229.229.181 | United States | Willowbrook    |
| 129.250.5.43    | United States | Englewood      |
| 129.250.3.12    | United States | Englewood      |
| 129.250.4.108   | United States | Englewood      |
| 203.105.72.229  | Japan         | Tokyo          |
| 157.7.40.137    | Japan         | Tokyo          |
| 157.7.40.113    | Japan         | Tokyo          |
| 203.189.96.2    | Japan         | Tokyo          |
+-----------------+---------------+----------------+

上から接続元のIPで次に辿る経路のIP…と続いて最後にJapan/Tokyoが来ている。例的にはこんな感じね。Martiniqueって国、初めて知ったよ…

んで、この辿った経路は調べることが出来る(tracerouteというコマンドで)。ただ全ての経路が分かる訳じゃなく、分からない所もあったり(tracerouteのICMPに対応していないとか)するんだけど、大体の経路は分かる。その経路のIPアドレスから位置を取得するIP-API(Geolocation API)を叩いて、経路上の位置を特定して通信しているデータがどんな経路を辿っているかマッピングしたのがこちら。

ちなみに、アクセスデータは自分のブログにアクセスしにきている接続ログを利用している。
WebAPのログをfluentでelasticsearchに送って、golangでログを検索してlocationのデータをMySQLにツッコムといった感じで。golangからesにはelastigoを使ってみた。そして集計したMySQLのデータをopenFrameworksで描画!!といった感じ。

ちなみに、IPと位置という関係は正確では無いです。「このIPはこの場所にある」というのは正確に特定するのは難しい(そもそも、IPのプロトコルで位置データを扱うヘッダというのは無い)。ルーティングやIPの設定で、全然違う所に配布したりも出来るわけで、その辺の正確性には欠ける。ただ、大体の国と地域はAPIで取得される位置でもOK。またtracerouteの経路情報もその時々で変わって、常に同じ経路という訳でも無い。経路はルーティングプロトコルによって変わったり再構成されていく。
これはアクセス順に動画にしてみた。

接続元IPがどの国から来ている、という絵とか動画は見たりするけど経路も含めた物は見た事がなくって面白いかなーと思ったら、スゲーことになった。
全ての経路が日本の自分サーバに集中している。色んなアクセス経路のデータが取れたから、接続元IPの国別にどういった経路を辿ってきているのかも分かる。
まずはアメリカからの経路。殆どがUSからデータが来ているけれど、一部ヨーロッパ経由で来ているものもある。

次はフランスから。これはフランスから直接日本に来ている場合と、アメリカ周りの大きく2パターンがあるですね。

次は南米の国、コロンビアから。これはUS経由のものしか無いっすね。何故か一旦ヨーロッパに向かって、その後またアメリカ大陸に来てから…という謎の往復経路もあって面白い。

次はパレスチナからのパケット。これは直接日本に来ているものと、ヨーロッパ、アメリカを経由している2パターンっすね。

これは中国発のパケット。日本に直接来ている物と、アメリカを経由している2パターン。昔はロシア、アメリカ経由の経路が確かあったような気がするけど。

これはイタリア発のパケット。同じくヨーロッパのフランスと同じく、直接来るパターンとUS経由の大きく2パターン。

経路が少ない所を見てみたらウガンダ共和国から来ている物も。インド->US経由と、香港経由の2パターンがあった。

最後にこれはインドから。殆どが直接でヨーロッパ、US経由が少しだけ。

データとして溜められたのは、
IPの位置情報 : 17208
取得した国・地域: 164
アクセスログ : 56799
経路数 : 99985

今見ているインターネットのデータ・パケットは自分と相手で直接やりとりしているんじゃなく、「世界中を駆け巡って色んな国を旅行して来ている」というのが分かる。技術の進歩で、その旅は一瞬で感じられるし気にする事も無いと思う。今この瞬間も世界中をデータが駆け巡っている。そして、自分もデータと一緒に世界中を旅行して回りたいとか思ったった。

Maker Faire Tokyo 2015 出し物&ドローンにプロジェクション

今年も国際展示場、ビックサイトでMaker Faire Tokyoが開催された。少し前のBayAreaは足が蜂窩織炎になって、エントリーするも行けず…事前に「また開催直前に足が腐ったらどうしよう」とか思ったけど、大丈夫っした。健康万歳。

ブースはこんな感じ。

今年の自分の出し物は以下。

Typing Board (一番左のもの)
これはマニア層にウケた。キーボードを叩くともう一方のPCのキーボードを叩くというシンプルな物で、ソレノイドを大量にキーボードの上に並べて叩くという力技的なもの。意味あるの?(ないです。楽しそうだから作っただけ)、技術の無駄使い(褒め言葉ですw)、爆(w)みたいな反応でいい感じ。

ポスト君 (一番右のもの)
これは一般層にウケた。売り物?欲しい、作って、売って!!といった反応。作ります(というかモックは目の前にw)。250枚刷ったチラシが見事に無くなった。

ドローン(真ん中、Androidアプリ、プロジェクタで投影)
多分、全体の8割くらいの時間を事前の準備で当てた。魔法の大鍋さんのドローンをトラッキングしてプロジェクタで光を当てるというもの。

何はともあれ、こんな感じのものです。


こちら湯村さんが撮ってアップして貰えていたものです。

新里さんのDrone Tracking Projectionの捜査風景。

Posted by 伊藤 武仙 on 2015年8月1日

こちらは伊藤さんが撮ってアップして貰えたものです。
以下、写真を撮ってもらった皆さんに感謝です。

投影先のドローンはこちら

このdroneにXtion/プロジェクターを使って投影といった感じ。

使ったアプリはこんな感じ。プログラマブルでよく利用される環境ですね。
PC : Macbook Pro
トラッキング : Xtion(OpenNI2/Depthのみ利用)
ソフト : openFrameworks 0.8.4, VDMX5

写真、動画を見てもらえればわかるとおり、Maker Faireのロゴ以外にパキパキ動く素材を投影したり。制御用の画面はこんな感じ。

これは絵の素材。他にもオリンピックマークやら何個か。


これは横のポリゴンパキパキ(depthとトラックした3次元データから動的に生成)



これは縦の線をパキパキ(これも同じく動的に生成)


これは立ってもらってキャリブレーションをしている時の

この他に位置合わせ、表示の切り替えではVDMX5を利用。パキパキの動きのあるものは、depthとトラッキングしたdroneの表面をポリゴンステップ(左のメニュー)にあるステップに応じて作成して、投影面をポリゴン化している。こういう幾何的な模様を作って動きを出すときに便利。表示するものは、キーボードのキーで切り替えるようにして、動きに応じて投影する物を変えたり、パラメータの微調整とかを合間にしていた。

事前の構想メモはこんな絵で。仮想空間上のあるエリアに入ってきたら対象とみなして、投影をする感じ。

大抵のXtion/kinect物は、
1. 投影する先はあまり動かない。そして平面が多い(今回は3次元空間を動く)
2. 結果をディスプレイに写す場合がほとんどで、対象物に再フィードバック(投影)する事はあまりない。
この2点がちょっと今までとは違う感じ。再フィードバックがあるから、無駄な処理やロジックを単純化して、できるだけ追従できるようにしてみた(操作->droneの動き->トラッキング->処理->投影、この時間をできるだけ最小に)。

事前の実験だと、すげー光があたって綺麗に見えるはずだったのが、会場の環境だと青・赤がさっぱり見えなくなって、緑をベースにした物になった。暗い所だと、もっと色んな表現ができたんだけど、これは仕方なし。改善したい点はあって実験を重ねてみようかと。舞台で正面から見えるという状態だけなら前からだけでOKだけど、前後左右どこからでも見れる状態だとそうもいかないし。事前の実験はこんな感じ。

drone自体がプロジェクターを持ったり、LEDで光ったりするものは見た事があったけど、自由に投影できるとそれはそれで面白いと思われ。

他にも最新のGoPro Hero4が浮いている!!

直前にマウンタを作って搭載するという驚異の技を見せてくれた魔法の大鍋さんスゴス。この映像をOculus Rift DK2で見るということも。会場の様子が上から見渡せる映像が!!この映像、すごく良い。とっても良い感じ。

色々とdroneはセンシティブで飛ばせる環境も限られているけど、こういう面白い使い方、楽しみ方はいっぱいあると思う。