toioのフルキットが届いたから、遊んで行こう。まずはフルキットの壮観な感じでドーン!!
■ とりあえず遊んでみる。
まずは何にしても動かしてみよーってことで、ゲズンロイドの”めだま生物”を動かしてみる。
どこを向いても目玉が向いておいかけてくる。まるで何かの生き物のよう…というか、工作生物という設定でこの子達は全て生き物ってことで、こんどはシャクトリー。
ぶっちゃけ…ずーっと見ていても飽きない。まるで何かの意思を持った人工生物(ここでは工作生物)のように動き続ける。ぼーっと見ていると思うのだけど、この2個のキューブが絶対位置を知りながら、協調動作をしているというのが何気にすごい。大抵は外部のセンサーで位置を補足するんだけど、自己位置同定をして動いている。専用マットの外に出ようとすると、検知して方向を変える。なんかスゲーよ…
このめだめ生物を応用して、目玉をとってLEDライトを付けて、ターゲットに”くつ”を使うと…
延々と靴をLEDで照らしつづけることが出来る。これは…何か面白い用途というか、可能性を感じる。そう、何かに使えそうなのよね。例えば、キューブにもう少し大きい箱を被せて、影絵をずっと照らし続けるとかでも面白そう。
んで、次にネタでダイソーで買ってきたサイリウムと粘土を使ってレースコースを作って…
部屋を真っ暗にすると、幻想的な雰囲気でtoioレースが楽しめる。というか、この時点ではまだ操作が上手くなくって、カクカクしまくっているwww
■ チビッコとガチバトル
そして今度はチビッコとクラフトファイターバトル。
もちろんガチで戦っている。これもダイソーでゲットしてきたキャラを搭載させて、アルティメットバトルの様相になってきている。必殺技とバランスが何気にキーになってくる。自分も、「てめー!!」とか普通に言っている…そう、自分も激しく負けず嫌いだから、この手の勝負&バトルになると相手がチビッコでもマジになる。
シャクトリーの工作(といっても紙を切って貼り付けるだけで超簡単)とかを一通り遊んだら、自分に勝つまで止めないとか恐ろしい事を言い始めてきて、それでも負けないでバトルをしていた最終戦。
負けてしまった…これで開放される。約2時間ほど、あっという間だった。このまま延々と全部やるまで止めない!!とか言われたらどうしよう…とか思っちゃったもん。
そして後日…都内の某所にて飲みの場で持って行って飲んでいたら、さらにカヲスな環境に。
こんな状況でも青いマットの上でtoioのキューブはちゃんと安定的に動作してくれた。”うに”のした、ヱビスビールの横にキューブが光って見える。もちろんだけど、自分も激しく酔っていた。
■ 少し技術的な視点で
やっぱり何か技術的な視点でも見たくなってくる。といっても、モノの持つ力が強くって、触って遊んでいると技術的にどーか?はどーでも良くなってくる。toioは専用のコンソールと動くキューブがBLEで通信して、iPhone/Android的なアプリは今のところは無い。
ただ、
「BLEなら見れるだろう」->
「スマホからキューブに接続出来るだろう」->
「勝手アプリやらが作れてtoioで遊べちゃうだろう」->
「ひゃっはー!!」
と思って…思わずsniffer
WireSharkでtoioが通信しているのを全力でsnifferして見て、何か面白いことが無いかなーと思って見てみたら…位置情報らしき物が秒間30以上で通知されていたり、モーターを動かす情報が飛んでいたり、凄いスピードで流れていく。キューブの操作や動きがリアルタイムに感じて、応答性がめちゃ良いのはこのレスポンシビリティの良さか…とか思いつつ、データを見ていたけど、全然分からん!!ってことで…次はiPhoneのLight Blueからキューブに接続してみた

Light Blueから接続できて、色んなサービスが見えてきた。センサー情報、バッテリー情報が見れたり、ブザーやモーターに値を入れたら音を鳴らしたり動かすことが出来た。そして、notificationをオンにしたら、キューブの動きと連動してデータが取得できるサービスが何個かあって、恐らくこれが位置情報をやりとりしているモノだろう…と思って、キューブを動かしながらデータをぼーっと見ていた。キューブがマット上の印字を読み取って絶対座標の同定を行っているようで(参考)、Bluetoothの動き的に予想したのは次のとおり。
1) ほんの少しの動きでもnotificationが飛んでくるから、精度はかなり良さそう。
2) マット内にゼロ点 or マット外に仮想のx-yのゼロ点(データを受け取るコンソール側で変換)が多分あるはず。
3) ヘッダ、位置情報(x-y?)、精度/印字のID(?)、位置情報の小数点以下(?)、Checksum…etcといったデータ構造かな。
とかとか思ったり、カンで多分これかな〜と思って久々にswiftでBTつなげてiPhoneアプリを適当に作って見てみたら、なんとなく位置情報が取れてるっぽい。
コードはこんな感じ(適当)。
import UIKit import CoreBluetooth class ViewController: UIViewController { let toioCubeUUID = "toioの-U-U-I-D" let toioCubeIDDetectionUUID = "id detectの-U-U-I-D" var centralManager: CBCentralManager! var peripheral: CBPeripheral! var serviceUUID : CBUUID! var charcteristicUUID: CBUUID! var layer: CAShapeLayer! = nil override func viewDidLoad() { super.viewDidLoad() centralManager = CBCentralManager(delegate: self, queue: nil) serviceUUID = CBUUID(string: toioCubeUUID) charcteristicUUID = CBUUID(string: toioCubeIDDetectionUUID) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } private func drawCircle(xpoint: Int, ypoint : Int) { let path = UIBezierPath(arcCenter: CGPoint(x: xpoint, y: ypoint), radius: 10, startAngle: 0.0, endAngle: CGFloat(Double.pi * 2.0), clockwise: true) if (layer != nil) { layer.removeFromSuperlayer() } layer = CAShapeLayer() layer.fillColor = UIColor.orange.cgColor layer.path = path.cgPath self.view.layer.addSublayer(layer) } } extension ViewController: CBCentralManagerDelegate { func centralManagerDidUpdateState(_ central: CBCentralManager) { switch central.state { case CBManagerState.poweredOn: let services: [CBUUID] = [serviceUUID] centralManager?.scanForPeripherals(withServices: services, options: nil) default: break } } func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { self.peripheral = peripheral centralManager?.stopScan() central.connect(peripheral, options: nil) } func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { peripheral.delegate = self peripheral.discoverServices([serviceUUID]) } } extension ViewController: CBPeripheralDelegate { func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { if error != nil { print(error.debugDescription) return } peripheral.discoverCharacteristics([charcteristicUUID], for: (peripheral.services?.first)!) } func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { if error != nil { print(error.debugDescription) return } peripheral.setNotifyValue(true, for: (service.characteristics?.first)!) } func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { if error != nil { print(error.debugDescription) return } updateWithData(data: characteristic.value!) } private func updateWithData(data : Data) { let toioData = data.withUnsafeBytes { [UInt8](UnsafeBufferPointer(start: $0, count: data.count)) } // 0x03 : cube not set-on the mat if (toioData.first != nil) && toioData.first == 0x03 { print("Data: \(toioData)") // 0x01 : get id detection(x-y coordinate) } else if (toioData.first != nil) && 0x01 == 0x01 { let y : UInt16 = UInt16(toioData[5]) + UInt16(toioData[6]) << 8 let x : UInt16 = UInt16(toioData[3]) + UInt16(toioData[4]) << 8 print("x-y : \(x) , \(y)") drawCircle(xpoint: Int(x), ypoint: Int(y)) } } }
本当にこれで正しいかどうかは分からないけど、何となく雰囲気的には座標が取れて動いているっぽい。更にモーターやブザー(音)を動かしたりする勝手SDKを誰が作っちゃいそーな予感がしている。
このtoioを色々触ってみて思ったのが...技術は抜きに面白い!!ということだった。プログラミングのエッセンスを少し入れると、生き物のように動く。しかも、外部センサー無しに自分の位置を自分で分かった上で。これが良い感じで、外部のKinectのような赤外線・カメラで画像認識・超音波...etcを使うと、電源どーするよ?外部センサー連動&フィードバックどーするよ?とか、何気に面倒なことが起きる。これを考えなくてもOK!!というのは、何気に良い感じだと思われ。
思わずGoogle Homeを乗せてみたらあっさり動いたし、モーターも小型サイズなのにめちゃ強い。ということは...他のセンサー連動で、声や音声を認識して動いたり...といった事もアリな気がするよ。