AR x IoT で遊んでみる

最近ARがとっても楽しい。現実の空間に仮想のオブジェクトを置いていろいろ遊べるのは、空想と現実の垣根が取り払われたように感じる。そこにIoT的なガジェットを組み合わせるともっと面白いんじゃないかと思って試してみた。

やってみたことはボリューム(可変抵抗)を回すと、AR空間上のオブジェクトが回転するというもの。通信にはOSCを利用。以下のような手順で作ってみた。
1. ボリュームの値を送信
2. ボリュームの値を受信
3. ボリュームの値でARオブジェクトを回転

1. ボリュームの値を送信
 ボリュームの値をADCで取得して、OSCで送信する。OSCのライブラリはいくつもあって、動作しないものもあった。試した中でONMAT/OSCライブラリが使いやすくて良かった。

#include <WiFiUDP.h>
#include <ESP8266WiFi.h>
#include <OSCMessage.h>

static const char *ssid = "ssid";
static const char *password = "password";
static WiFiUDP udp;
static const char *ip_addr = "192.168.xxx.xxx";
static const int port = 8080;

static void wifi_setup()
{
   static const int local_port = 7000;
   WiFi.begin(ssid, password);
   while (WiFi.status() != WL_CONNECTED)
   {
       delay(500);
   }
   udp.begin(local_port);
}

void setup()
{
   Serial.begin(115200);
   Serial.println("");
   wifi_setup();
}

void loop()
{
   int value = system_adc_read();
   OSCMessage msg("/sensor");
   msg.add(value);
   udp.beginPacket(ip_addr, port);
   msg.send(udp);
   udp.endPacket();
   delay(50);
}

2. ボリュームの値を受信
ボリュームの値をiOSのアプリで受ける。iOSのOSCライブラリもいろいろあるが、使いやすそうなSwiftOSCというアプリがうまく動かなかったので、Figure53/F53OSCというObjective-Cで書かれたライブラリを使った。これがとても使いやすかった。Swiftから使う場合でもCocoaPodsで入れてimportするだけで使える。

import F53OSC

// OSCServer
let server = F53OSCServer.init()
// ポートを設定
server.port = 8080
// デリゲート先をViewControllerにする
server.delegate = self

3. ボリュームの値でARオブジェクトを回転
ARオブジェクトを作成して、その角度をボリュームで指定する。ARオブジェクトの回転の調節とかは適当なので、良い感じに回すにはいろいろ工夫が必要だけど、ひとまず回すことを目的とする。

// ARオブジェクトを読み込む

// viewDidLoadの中で元から入っているshipオブジェクトを利用する
sceneView.scene = SCNScene(named: "art.scnassets/ship.scn")!
shipNode = sceneView.scene.rootNode.childNodes.first!

// 元か入っているshipオブジェクトの位置はデフォルトで前方に置かれているので、
// そちらは(x: 0, y: 0, z: 0)にして、以下のコードで位置を指定
shipNode?.simdPosition = simd_float3(0, -0.1, -0.8)
// ARオブジェクトの角度を変える

// OSCでパケットを受け取って、ARオブジェクトの角度を変える
extension ViewController: F53OSCPacketDestination {
   func take(_ message: F53OSCMessage?) {
       guard let node = shipNode else {return}
       
       let value: Int = message?.arguments[0] as! Int
       let smoothed = round(Float(value) * 5.0) / 5.0
       let deg = round(smoothed / 1024.0 * 360)
       let rad = 2 * Float.pi * deg / 360
       
       node.eulerAngles.y = rad
   }
}

こんな感じに回る。

iPhoneのスワイプでも回せるしボリューム使う意味なくない?と思う人もいるかもしれないが、物理ボリュームとか物理ボタンはスワイプのような操作とは違った楽しさがある。

次はボリュームに水道の蛇口のような取手をつけて回してみようと思う。ARのインターフェースに物理的なボタンなどをつけるのは、子どもと遊ぶのにも良さそう。

コードはgithubにあげているので試してみたい方はどうぞ。
iOS
firmware(Arduino)

この記事が気に入ったらサポートをしてみませんか?