<IoT×Unity>Unity5でMQTTは受信できるか?

最近Unity5に乗り換えました!

https://unity3d.com/jp/unity

非常に不安になったのでMQTTが受信できるか試してみた
結果、、、
下記の記事と同じようにできました!


<IoT×Unity>加速度センサで3Dオブジェクトをネット越しにグリグリしてみた - xhatenenの日記

よかったよかった、
すいませんこれだけですw

<Oculus Rift>Oculusの勉強会に参加してきた

本日、Oculusの勉強会に参加した


UnityでOculusソフト作成(初心者向け勉強会、余裕があったらUnreal Engineも) - connpass

Oculusのライブラリのバージョンにみな戸惑ったので
メモを書いておこうとおもう
下記のURLを参考に行った


MacとUnity Free版を使ってZenrinさんの秋葉原上空をQueryちゃんがOculus DK2で飛ぶ、方法 - Qiita


この記事は
クエリちゃんでアキバの街を飛行するアプリをOculus化したもの
OculusのSDK
OculusUnityIntegrationOVRAgent.unitypackage
の⒋1を使っていたがいたが今は⒋4になっており、バージョンの違いで苦労した
苦労したのは以下の2点

OVRCameraControllerがない

FPSの設定ができない

OVRCameraControllerがない点について

また現状のOculusのライブリはOVRCameraRigと
OVR PlayerControllerの2つのプレハブとなっていた
当初、OVR PlayerControllerを導入したがそうするとクエリちゃんが表示されなくなったのでOVRCameraRigを使用した。
Contorollerのインスペクターを以下のように変更した
camera Contoroller Main_Camera_akihabara → OVRCameraRig
AmbientContoroller Main_Camera_akihabara → OVRCameraRig

FPSの設定ができないについて

ただ、FPSの設定などができなかったため
OVRCameraRigのプレハブ配下にある

LeftEyeAnchor
RightEyeAnchor

のFarをいじった
Oculusのライブラリは変更が激しくきびしいぜ。。。

1Dayママアイディアソンに参加した

 

2月21日(土)に1Dayママアイディアソンに参加した、神戸リビングケアKRK,NTTドコモベンチャーズが開催したイベントだった。

 


1Day ママアイデアソン@赤坂 | Peatix

 

今までアイディアソンなど出て考えていたサービスのターゲットは全て自分中心だったが、ターゲットを自分が全くわからない人に変えて考えたく参加した。

 

サービス案、結果、得られた成果、アイディアソンの感想は以下

 

サービス案

働くママは夫に不満を持ちつつも上手く言えず、言わないまま蓄積していくパターンが多いらしい

それをスマホアプリ上のバーチャルな夫に、不満をぶつけそこから解決策を探っていくアプリを考えた

 

結果

準グランプリ

賞品:子供商品券

 

得られた成果

総じて日頃会わないセグメントに属する方やサービスを知れた点が成果だった。

アズママや、ファザリングジャパンなと子育てを切り口したサービスをはじめて目の当たりにした。みんかいろいろ考えるんだなぁと…

リアルに働くママと話せたことも大きかった、ママロックなんて単語初めて知った

ママ方の深掘り力はすごかった、ただまとめるのはかなり苦労した。知らない分野ということもあり余計時間がかかった。

 

アイディアソン感想

良かった点

本当の働くママがいたところ

呼ぶために託児所を設けたのは運営の神業と、いうしかない

おかげで想定で終わらないものになったと思う

 

全体的に時間が短かったが運営の、もっていき方は素晴らしいと思う

 

悪かった点

インプットがなかったところ

もっと働くママの社会的状況を説明して欲しかった。ある程度一般的な傾向をデータで見せてもらうだけでだいぶ考えてやすくなった

 

最終成果物の指定がなかった点

成果物はアプリなのか、webなのか、リアルサービスなのか 、ゴールの大枠たけでも決めて欲しかった。

実際、成果発表時に「議論だけで終わりました」というチームがいたことが疑問だった、アイディアソンだしなーと思いつつ

 

<IoT×Unity>加速度センサで3Dオブジェクトをネット越しにグリグリしてみた

今回は凹 (id:hecomi) さんに触発されて(SerialPort または Uniduino を使った Unity と Arduino を連携させる方法調べてみた - 凹みTips)書いた記事といっても過言ではないです。
というよりもここ最近の記事は全て今日のための布石といってもいいくらいな感じです
凹 (id:hecomi) さんが作っていたのがこれ↓

加速度センサでグリグリさせるやつこれを
私もやってみたい・・・
ただ真似しても面白くないのでMQTTでネット越しにやってみた


加速度センサでUnityオブジェクトをぐりぐりしてみた - YouTube


ちょっと遅いけどできた!

ちなみに
加速度センサはラズパイに繋げている詳細は以下
<IoT>加速度センサの値をMQTTを使ってネット越しにやりとりする - xhatenenの日記
加速度センサのPub側のコーディングも、上記の記事の無限ループverをそのまま利用した

Sub側に関しては
凹 (id:hecomi) さんの記事と
<IoT×Unity>MQTTをUnityで受けてみた! - xhatenenの日記
を組み合わせて以下のようにコーディングした

using UnityEngine;
using System.Collections;

using uPLibrary.Networking.M2Mqtt;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using uPLibrary.Networking.M2Mqtt.Messages;

public class Rotation : MonoBehaviour {
 
    private MqttClient4Unity client;
    
    public string brokerHostname = "*********";
    public int brokerPort = ******;
    public string userName = null;
    public string password = null;
    public string topic = "***********";

    private Queue msgq = new Queue();

    string lastMessage = null;

    private List angleCache = new List();
    public int angleCacheNum = 10;
    public Vector3 angle {
        private set {
            angleCache.Add(value);
            if (angleCache.Count > angleCacheNum) {
                angleCache.RemoveAt(0);
            }
        }
        get {
            if (angleCache.Count > 0) {
                var sum = Vector3.zero;
                angleCache.ForEach(angle => { sum += angle; });
                return sum / angleCache.Count;
            } else {
                return Vector3.zero;
            }
        }
    }

    
    void Start () {
        if (brokerHostname != null && userName != null && password != null) {
            Connect ();
            client.Subscribe(topic);
        }
    }
    
    
    float anglex;
    float angley;
    float anglez;
    float pitch;
    float roll;

    void Update () {
        while (client.Count() > 0) {
            string s = client.Receive();
            msgq.Enqueue(s);
            String str;
            str = s.Split(new char{':'});
            Debug.Log("received :" + str[0]);
            Debug.Log("received :" + str[1]);
            Debug.Log("received :" + str[2]);
	//角度のベクトルを取得
            anglex = float.Parse (str[0]);
            angley = float.Parse(str[1]);
            anglez = float.Parse(str[2]);
	//ロール角、ピッチ角の算出
            roll = -1*Mathf.Atan(angley/anglez) * Mathf.Rad2Deg;
            pitch = -1*Mathf.Atan(anglex/anglez) * Mathf.Rad2Deg;
	//アングルに設定
            angle = new Vector3(pitch,0,roll);
	//回転させる
            transform.rotation = Quaternion.Euler(angle);
        }
        
        if (Input.GetMouseButtonDown (0) == true) {
            client.Publish(topic, System.Text.Encoding.ASCII.GetBytes("nice click!"));
        }
    
    }

    void OnGUI() {
        if (msgq != null && msgq.Count > 0)
        {
            if (lastMessage == null) {
                lastMessage = (string)msgq.Dequeue();
            }else{
                lastMessage = (string)msgq.Dequeue();
                lastMessage = null;
            }
        }
        GUILayout.Label(lastMessage);
    }

    public void Connect()
    {
        // SSL使用時はtrue、CAを指定
        client = new MqttClient4Unity(brokerHostname, brokerPort, false,
                                      null);
        // clientidを生成
        string clientId = Guid.NewGuid().ToString();
        client.Connect(clientId, userName, password);
    }

    public void Publish(string _topic, string msg)
    {
        client.Publish(
            _topic, Encoding.UTF8.GetBytes(msg),
            MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE, false); // retainがfalse
    }
}

Quaternionが何者かよくわからないがそれについては
UnityのベクトルとQuaternionによる回転について - テラシュールブログ
をよく読めばわかる...はず!

一番苦労したのは、ロール角、ピッチ角の計算久しぶりすぎてまじ全然できなかった
(加速度センサの値のオイラー角化は私はできない...)
最終的に回し方をオイラー角で回しているせいでなんか回り方が微妙
ロール、ピッチで回す方法で

Quaternion.CreateFromYawPitchRoll(yaw, pitch, roll);

というのがあるという記事を読んだが、こちらも現在使えなかった

「Unityでロール、ピッチで回す方法」か「加速度センサ値のオイラー角化」を知りたい...

<IoT>加速度センサの値をMQTTを使ってネット越しにやりとりする

今回はRaspberry pi に接続された加速度センサの値をMQTTでネット越しにやりとりするプログラムを作成する。
手順は
1 ラズパイで加速度センサの値を取れるようにする
2 センサの値をMQTTブローカーを介してやりとりする
※ MQTTブローカーの構築については2つの記事を参照 
<IoT>mqttブローカーmosquittoを試してみた - xhatenenの日記

<IoT>-前回修正記事-mqttブローカーmosquittoを試してみた - xhatenenの日記

1 ラズパイで加速度センサの値を取れるようにする

加速度センサは秋月電子のADXL345(3軸加速度センサモジュール ADXL345(SPI/IIC): センサ一般 秋月電子通商 電子部品 ネット通販)を購入した、ブレッドボードにさすためにはんだ付けでくっつける
はんだ付け後のセンサ
f:id:xhatenen:20141231005054j:plain

ADXL345とラズパイの接続は以下のように行った
ADXL345接続部分が9穴ぐらいあるので
今回はその中から4穴使う

RasPi     ADXL345
3.3V <==> VDD
GND <==> GND
SCL <==> SCL
SDA <==> SDA


ラズパイの設定は以下の記事を参考にしながら作成した
http://www.stuffaboutcode.com/2014/06/raspberry-pi-adxl345-accelerometer.html

英語なので和訳しながら、解説する

<以下自分の状況に合わせながら和訳(かなり意訳、順番もめちゃくちゃ)>
ADXL345はSPI,I2Cに対応しているが今回はI2Cを使う

ラズパイの設定にI2Cモジュールを加える

sudo nano /etc/modules

そして以下の2文を加える

i2c-bcm2708
i2c-dev

ブラックリストからI2Cを除く

sudo nano /etc/modprobe.d/raspi-blacklist.conf

以下の文をコメントアウト(文頭に#をつける)

blacklist i2c-bcm2708

再起動して変更を反映させる

sudo shutdown -r now

必要なソフトウェアのインストール

sudo apt-get install python-smbus i2c-tools git-core

ADXL345のテスト

sudo i2cdetect -y 1

するとアドレスが表示される(アドレスは1dだった)

0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- 1d -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

ADXL345 のライブラリをDL

git clone https://github.com/pimoroni/adxl345-python

サンプルコードを動かす

cd adxl345-python
sudo python example.py

しかし動かしたところ以下のエラーが出た

IOError: [Errno 5] Input/output error

可能性を色々探ったがライブラリにアドレスが設定されていないことが問題だった
ということで
adxl345.pyの45行目のアドレス設定を以下のように変更

def __init__(self, address = 0x53):
↓
def__init__(self, address = 0x16):

すると動いた!
ちなみに完成した写真は以下
f:id:xhatenen:20141231005020j:plain

2 センサの値をMQTTブローカーを介してやりとりする

つぎに加速度センサをMQTTでやりとりできるプログラムを作成
まず、取得したx軸の値を一回だけ送信するプログラムを作成

from adxl345 import ADXL345
import sys
try:
    import paho.mqtt.publish as publish
except ImportError:
    import os
    import inspect
    cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"../src")))
    if cmd_subfolder not in sys.path:
        sys.path.insert(0, cmd_subfolder)
    import paho.mqtt.publish as publish

adxl345 = ADXL345()

axes = adxl345.getAxes(True)
print "ADXL345 on address 0x%x:" % (adxl345.address)
print "   x = %.3fG" % ( axes['x'] )
print "   y = %.3fG" % ( axes['y'] )
print "   z = %.3fG" % ( axes['z'] )

publish.single("message", axes['x'], hostname="**********")

ラズパイ(Pub側)での結果

ADXL345 on address 0x1d:
   x = 0.004G
   y = 0.524G
   z = 0.792G

Sub側での結果

rc: 0
Subscribed: 1 (0,)
message 0 0.004

次に上記のコードを無限ループさせて加速度センサの値を取り続けるようにする

from adxl345 import ADXL345
import sys
try:
    import paho.mqtt.publish as publish
except ImportError:
    import os
    import inspect
    cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"../src")))
    if cmd_subfolder not in sys.path:
        sys.path.insert(0, cmd_subfolder)
    import paho.mqtt.publish as publish

adxl345 = ADXL345()
num = 0
while num < 1:
        axes = adxl345.getAxes(True)
        print "ADXL345 on address 0x%x:" % (adxl345.address)
        print "   x = %.3fG" % ( axes['x'] )
        print "   y = %.3fG" % ( axes['y'] )
        print "   z = %.3fG" % ( axes['z'] )

        ax = str(axes['x'])
        ay = str(axes['y'])
        az = str(axes['z'])
        s = ":".join([ax,ay,az]);
        publish.single("message", s, hostname="**********")

Pub側の結果

ADXL345 on address 0x1d:
   x = 0.000G
   y = 0.056G
   z = 0.912G
ADXL345 on address 0x1d:
   x = 0.000G
   y = 0.052G
   z = 0.932G
ADXL345 on address 0x1d:
   x = -0.004G
   y = 0.040G
   z = 0.924G
ADXL345 on address 0x1d:
   x = 0.000G
   y = 0.044G
   z = 0.916G
ADXL345 on address 0x1d:
   x = 0.004G
   y = 0.060G
   z = 0.924G
ADXL345 on address 0x1d:
   x = -0.004G
   y = 0.056G
   z = 0.920G
ADXL345 on address 0x1d:
   x = 0.000G
   y = 0.048G
   z = 0.908G
ADXL345 on address 0x1d:
   x = -0.012G
   y = 0.064G
   z = 0.916G
ADXL345 on address 0x1d:
   x = 0.000G
   y = 0.052G
   z = 0.928G
ADXL345 on address 0x1d:
   x = -0.008G
   y = 0.060G
   z = 0.928G

Sub側の結果

rc: 0
Subscribed: 1 (0,)
message 0 0.0:0.056:0.912
message 0 0.0:0.052:0.932
message 0 -0.004:0.04:0.924
message 0 0.0:0.044:0.916
message 0 0.004:0.06:0.924
message 0 -0.004:0.056:0.92
message 0 0.0:0.048:0.908
message 0 -0.012:0.064:0.916
message 0 0.0:0.052:0.928
message 0 -0.008:0.06:0.928

ということでセンサの値をMQTTでやりとりできた

<IoT×Unity>MQTTをUnityで受けてみた!

今回はMQTTをUnityで受けてみた
Unity自体はゲームの開発ツールということでIoTとあまり関係ないのでは?
と思うかもしれないが最終的に加速度の値をキックにして
ゲームになんらかの影響を与えるということなんかやってみたいなーと思いやってみた

Unity側のDLLは下記のM2mqtt4Unityを利用した
MQTT Client Library for .Net and WinRT - Source Code

ちなみにダウンロードは下記の関連ページの”m2mqtt4unity-3.6.0.0.zip”と書かれているところをダブルクリックして行った
M2Mqtt4Unity-release - Download: 3.6.0.0

zipファイルをダウンロードすると

M2Mqtt>bin>Debug  > M2Mqtt.dll
                         M2Mqtt.pdb
                   >Release > M2Mqtt.dll
                                 M2Mqtt.pdb

というフォルダ構成になっていた。
今回はReleaseの方のDLLファイルを利用した

UnityでのDLLの設定は以下のサイトを参考にした
dllファイルの読み込み方 - Unity@Wiki

ただ全部を行ったわけではなく
AssetsにPluginフォルダをつくって、そこにDLLをドラックアンドドロップしただけで終えた。
DLLのインポートは
m2mqtt(.net 2.0対応fork版)をUnityで使うときの、Unity側呼び出しサンプル

のコードをそのまま活用させていただいた

そしこのスクリプト
Unity上のゲームオブジェクトにアタッチしてスタートさせて
Mac上からgolangの環境設定を行ってからmqttcliで下記のようにpublishさせた(なんかterminalの立ち上げのたびにgolangの環境設定が必要になっているなぜ?)

source ~/.basic
mqttcli pub --conf settings.json -t "topic" -m "Hello, Unity on MQTT"

すると

f:id:xhatenen:20141223230559p:plain

のようにPublisherのメッセージを受信するようにできた!
これから色々応用ききそうで楽しみだwww
※ちなみにまだMQTT3.1.1に対応していないとかいう噂もあったそんなこともなくMQTT3.1.1 MQTT3.1.0両方に対応していた

<IoT>-前回修正記事-mqttブローカーmosquittoを試してみた

voluntas (id:Voluntas)さんid:Hexaさんに前回の記事(http://xhatenen.hatenablog.com/entry/2014/12/14/232824)の課題点の解決をいただいたので、そちらの修正記事を書く。

ちなみに前回の課題点は、
 「MQTT3.1.1にしか対応していないクライアント(paho)とMQTT3.1.0にしか対応していないサーバー(mosquitto)の相性の問題」
ということだった。

これにいただいた解決策は以下の2つ
1.クライアントをMQTT3.1.0に対応したものを使う
2.サーバーをMQTT3.1.1に対応させる

以下にそれぞれの方法を書いていく
1.クライアントをMQTT3.1.0に対応したものを使う

mqttcliを導入する方法を今回いただいたので、そちらを試して見る
mqttcliのインストールにはgolang環境を構築する必要があるそうなので
まずはそちらから

golangは以下のURLに則って行った
golang環境設定 - Qiita
パスの設定も同じように

# go
export GOPATH=$HOME/gocode
export GOROOT=/usr/local/opt/go/libexec
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH

とした。
ただ

go get github.com/shirou/mqttcli

とした場合に、mercurialが足りないと言われたので
mercurial のインストールを以下のURLに則って行った
Mac OS X Lion に最新の Mercurial をインストールする - Debian GNU/Linux 3.1 on PowerMac G4
これで再度

go get github.com/shirou/mqttcli

を行うとmqttcliが使えるようになった。

あとは
shirou/mqttcli · GitHub
に書いてある方法に則り、pubsubを動かす
まず、settingsのファイルを作る

settings.json

のようなjsonファイルを以下のように編集して作成した

{
  "host": "host",
  "port": 1883
}

そしてsub側を

mqttcli sub --conf settings.json  -t "some/topic"

pub側を

mqttcli pub --conf settings.json  -t "some/topic" -m "your message"

と行うことでできた。
mqtcliはコマンドでmqttのpubsubを操作をできる手軽さが素晴らしい...

2.サーバーをMQTT3.1.1に対応させる
つぎは、mosquittoをMQTT3.1.1に対応している
コメントにはいちどmosquittoをアンインストールしてと書いてあったけども
今回は新しい環境を用意した
あとは以下のURLに乗ってあるubuntuの方法にのっとった
Downloads | Mosquitto

手順は以下のとおり

sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa
sudo apt-get update
sudo apt-get install mosquitto

これで前回のpubsubを動かしたら正常に動いた!

これで問題は解決!