Fork me on GitHub

ROMOというロボットをご存知だろうか. 私は,あまり知らなかったのだが,KickStarterで資金調達した会社が作っているiOSで制御する小型ロボットのことだ. 先日,ROMOのハッカソンイベントが開催され,参加者全員にROMOが配布され,さらに池澤あやかさんも来るということで参加してきた. ハッカソンなんか開発合宿以来な気がするので体力が持つのか心配だったが,なんとかなった.

ROMO?

image

ROMOは,iOSデバイスを差し込んで使用するキャタピラ戦車型のロボットである. ROMOは,LightingコネクタでiOSデバイスと接続され,iOSのアプリケーションからExternal Accessory Libraryを使って,制御される仕組みを持っている. ROMO自身,開発元が公開しているアプリケーションで遊ぶことができるが,醍醐味はなんといってもROMO SDKで,自分でロボットを制御することにある. SDKで提供されるのは,上記画像のiPhoneに表示されているROMOのキャラクターを表示するRMCharacterと,ロボット本体を制御するRMCoreからなる. RMCharacterだけならロボットなしで使うこともできる.

ROMO SDK

かなり出来はよい.ロボットとの通信はシングルトンモデルで行う.接続とその確認などのコードは,たった数行である.

#import <RMCore/RMCore.h>

@interface ViewController () <RMCoreDelegate>
@property (nonatomic, strong) RMCoreRobot<HeadTiltProtocol, DriveProtocol, LEDProtocol> *robot;
@end

@implementation ViewController

- (void)viewDidLoad {
	[super viewDidLoad];
	[RMCore setDelegate:self];
}

- (IBAction)send:(id)sender {
	[[RMBTReceiver sharedInstance] sendString:@"test, this is test"];
}

- (void)robotDidConnect:(RMCoreRobot *)robot {
    if (robot.isDrivable && robot.isHeadTiltable && robot.isLEDEquipped) {
        self.robot = (RMCoreRobot<HeadTiltProtocol, DriveProtocol, LEDProtocol> *) robot;
    }
}

- (void)robotDidDisconnect:(RMCoreRobot *)robot {
    if (robot == self.robot) {
        self.robot = nil;
    }
}
@end

キャラクターの制御も極めて簡単で,数行でかける.キャラクターのアニメーションは結構出来がよくてびっくりする. 以下のコードはタップするとROMOが笑うもの. キャラクターは,本体がなくても遊べるので,試してみるとよい.割と楽しい.

#import <RMCharacter/RMCharacter.h>

@interface ViewController ()
@property (nonatomic, strong) RMCharacter *romo;
@end

@implementation ViewController

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
	self.romo.expression = RMCharacterExpressionHappy;
}

- (void)viewDidLoad {
    [super viewDidLoad];
	self.romo = [RMCharacter Romo];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.romo addToSuperview:self.view];
}

@end

image

開発の難点

ロボット本体を制御するアプリケーションを開発するときは,Macに接続してバイナリを転送し,その後,ROMOに接続して,デバッグする必要がある.

このため,

  1. 毎度の接続が面倒すぎる
  2. ログによるデバッグができない

の2点が問題になってくる.バイナリの転送を改善するのはクラックするしかないのでログの部分だけでも改善したいところである. そこで,今回のハッカソンで作ったものの登場となる.

作ったもの

  1. ROMOの制御・ログ出力用CoreBluetoothライブラリ.
  2. CoreImageでフロントカメラで顔を検出し,顔を見ていると,ROMOが止まるというデモ

正直,一つ目のネタ問題ないだろ!と思ってたのだが,思ったより遠隔ネタが多かったので,急きょ中止した. なので,実質デモ作成は3時間弱しかやっていない・・・・・.

RMBluetooth

んで,せっかく作ったので,ROMOのログ吐きとか,制御用リモコンを作るためのソフトウェアをライブラリにした.

https://github.com/sonsongithub/RMBluteooth

ここにソースコードを置いてあります. RMBluetooth自体は,以下のようにして使うのですが,正直ROMOに限って使うものではない気がする. RMBTReceiverが通信のためのシングルトンオブジェクトとなる.

- (void)robotDidConnect:(RMCoreRobot *)robot {
    if (robot.isDrivable && robot.isHeadTiltable && robot.isLEDEquipped) {
        self.robot = (RMCoreRobot<HeadTiltProtocol, DriveProtocol, LEDProtocol> *) robot;
		[[RMBTReceiver sharedInstance] sendString:@"ROMO is connected."];
    }
}

- (void)robotDidDisconnect:(RMCoreRobot *)robot {
    if (robot == self.robot) {
        self.robot = nil;
		[[RMBTReceiver sharedInstance] sendString:@"ROMO is disconnected."];
    }
}

RMBluetoothの解説は他のタイミングでやる予定です.

余談

池澤あやかさんはガチでした. ちょっとコンピュータ好きな女の子レベルでしょ?くらいに思ってました・・・・.すみませんでした. 彼女,ハッカソンでずっとコード書いて,デモ作って帰っていきました.マジでした. んで,ハッカソンに出てた連中,彼女が来ても,それに盛り上がらずにコード書いてました. なんかおかしいぞ.俺は盛り上がったぞ!もっとミーハーになろうぜ!