iOSアプリと連携させて使えるデバイスたち

第2回3次元コントローラにもなるボール型ラジコン「Sphero」対応 iOSアプリの実装方法

今回取り上げるのはボール型デバイス「Sphero」です。機能の概要や対応アプリの紹介から、実際にiOSアプリを実装する手順までを解説します。

Spheroとは

Sphero(スフィーロ)とは、直径約7.4cm、重さ168gのボール型のデバイスで、iOSアプリからラジコンのように操作することができます。

Sphero
Sphero

たとえば360度どの方向にも進ませられますし、速度も変えられます。またマルチカラーLEDを内蔵しており、色を自在に(数百万以上)変えて光らせることもできます。

逆に、Spheroの動きをiOSアプリ側で検知することもできるので、SpheroをiOSアプリのコントローラのように用いることも可能です。

次の動画は、YouTubeのSphero公式チャンネルで 公開されているSpheroを使用した遊び方のイメージムービーです。

またAppBankさんの動画も、日本語なのでわかりやすく、その興奮がよく伝わります。

ハードウェアの特徴は、オフィシャルサイトには下記のように記載されています。

  • 最高速度:秒速2m
  • 通信可能距離:最大30m
  • 3時間の充電で、1時間以上の連続ドライブ
  • 防水

Sphero対応アプリ

すでにさまざまなSphero対応アプリがリリースされています。下記のように、ゲームから、音楽アプリ、プログラミングアプリ(!)まであり、Spheroがアイデア次第で色々な使い方ができることがわかります。

The Rolling Dead

ARを使い、実世界を舞台にゾンビと戦うゲーム。

The Rolling Dead
The Rolling Dead

shapesynth

シンセサイザーアプリなのですが、Spheroの加速度センサに連動して周波数を操作できるようになっています。

Etch-o-Matic for Sphero

Etch-o-Matic for Sphero
Etch-o-Matic for Sphero

Macrolab

Macrolab
Macrolab

スクリーンショットにあるように、定型文を組み合わせることでSpheroの挙動を制御できます。

orbBasic

orbBasic
orbBasic

独自の言語を使って、Spheroの挙動をプログラミングできます。

購入方法

Amazonなどの各種ネットショップで購入できる(2013年12月7日現在、13,453円)ほか、AppleStoreでは限定の透明バージョンを購入することができます。

Orbotix Sphero 2.0 ロボティックボール

Orbotix Sphero 2.0 ロボティックボール

定価は14,800円です。

対応アプリの実装:基礎編

①Sphero iOS SDKを取得する

下記GitHubリポジトリからcloneするか、zipでダウンロードします。

最新リリースバージョンは2013年12月7日現在、v1.6-b1146となっています。

②SDKをプロジェクトに追加する

下記3つのフレームワーク, リソースバンドルをプロジェクトに追加し、

  • RobotKit.framework
  • RobotUIKit.framework
  • RobotUIKit.Bundle

依存フレームワークである次の2つもプロジェクトにリンクするよう設定しておきます。

  • ExternalAccessory.framework
  • CoreMotion.framework

③リンカフラグをセットする

Build Settingsの"Other Linker Flags"に、下記フラグをセットします。

-lstdc++
-all_load
-ObjC
-lsqlite3

この時点でビルドしてみると、プロジェクトのビルド設定によっては、下記のようなエラーが出る場合があります。

symbol(s) not found for architecture arm64

この場合は、Build Settingsの"Valid Architectures"からarm64を外し、"Architectures"を"$(ARCHS_STANDARD)"にするか、"Build Active Architecture Only"を"NO"にしてください。

また、iOSバージョンを6.x以下にしてください。

④Info.plistの編集

Info.plistに"Supported external accessory protocols"キーを追加し、値の配列内の要素の1つを、"com.orbotix.robotprotocol"とします。

Info.plistの編集
Info.plistの編集

⑤Spheroと接続し、点灯させる

ヘッダをインポートし、

#import <RobotKit/RobotKit.h>

Spheroとの接続完了時に発行される通知 RKDeviceConnectionOnlineNotification の監視開始と終了処理を実装します。

- (void)viewDidAppear:(BOOL)animated {

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(handleOnline)
                                                 name:RKDeviceConnectionOnlineNotification
                                               object:nil];
}

- (void)viewDidDisappear:(BOOL)animated {

    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:RKDeviceConnectionOnlineNotification
                                                  object:nil];
}

接続完了通知 RKDeviceConnectionOnlineNotification のハンドラメソッドを実装します。

- (void)handleOnline {
    
    [RKRGBLEDOutputCommand sendCommandWithRed:1.0 green:0.0 blue:0.0];
}

ここでは接続が成功したら赤く点灯するよう命令しています。

Spheroとの接続開始メソッド、接続完了メソッドを実装し、適当なボタンを作成してアクションとして割り当てます。

// 接続開始
- (IBAction)connect {
    
    if ([[RKRobotProvider sharedRobotProvider] isRobotUnderControl]) {
        [[RKRobotProvider sharedRobotProvider] openRobotConnection];
    }
    else {
        NSLog(@"Sphero is not under control!");
    }
}

// 接続終了
- (IBAction)disconnect {
    
    [RKRGBLEDOutputCommand sendCommandWithRed:0.0 green:0.0 blue:0.0];
    [[RKRobotProvider sharedRobotProvider] closeRobotConnection];
}

接続終了時にLEDの色をデフォルトに戻すようにしています。

これで、⁠Spheroを2度叩いて起こし、設定からペアリングした状態で)サンプルアプリを起動し、connectメソッドを呼ぶボタンを押すと、Spheroが赤く点灯し、

赤く点灯
赤く点灯

disconnectメソッドを呼ぶボタンを押すと、Spheroが元の色に戻るようになります。

青に戻る
青に戻る

その他のレシピ

前進させる

Spheroを動かすための実装は、とてもシンプルで、RKRollCommand クラスのsendCommandWithHeading:velocity: メソッドを呼ぶだけです。

まっすぐ前に進む場合は、次のようにします。

[RKRollCommand sendCommandWithHeading:0.0 velocity:0.5];

第1引数には進む方向を「度」で指定します。まっすぐ前を0.0とします。

たとえば、右に進む場合は、

[RKRollCommand sendCommandWithHeading:90.0 velocity:0.5];

左に進む場合は、

[RKRollCommand sendCommandWithHeading:270.0 velocity:0.5];

となります。

キャリブレーション

Spheroは球体なので、どの方向を「前」とするか、という調整をしてやる必要があります。そのために、しっぽにあたる青いLEDが自分(ユーザ)側に向くようSpheroを回転させる、キャリブレーション機能がそのGUIとともにSDKで提供されています。

下記のようにプロパティを定義し、キャリブレーションGUIを表示させたい位置にUIButtonオブジェクトを置き、calibBtnプロパティとアウトレット接続します。

@property (nonatomic, weak) IBOutlet UIButton *calibBtn;
@property (nonatomic, strong) RUICalibrateButtonGestureHandler *calibrateHandler;

RUICalibrateButtonGestureHandlerを次のように初期化します。

self.calibrateHandler = [[RUICalibrateButtonGestureHandler alloc] initWithView:self.view
                                                                        button:self.calibBtn];
self.calibrateHandler.calibrationRadius = 200;
self.calibrateHandler.calibrationCircleLocation = RUICalibrationCircleLocationLeft;

これで、calibBtnをタップすると、次のようにキャリブレーションGUIが表示されるようになります。

calibBtn
calibBtn

RUICalibrateButtonGestureHandlerのcalibrationCircleLocationプロパティは、キャリブレーションGUIをボタンに対してどの位置に表示するかを示すものですが、上下左右はPortrait の状態を基準として考えるようです。たとえば、上記サンプルはLandscape Leftでつくっているため、ボタン情報にGUIを出したい場合にはRUICalibrationCircleLocationLeftを指定することになります。

ペアリングがされてない場合のアラート画面を出す

親切にも「Spheroがペアリングされてないのでこのようにペアリングしてください」ということをユーザに伝えるリソース(nib)と、クラスがSpheroのSDKにはあらかじめ用意されています。

下記のように、RobotUIKit.bundleから必要なnibファイルを読み込みRUINoSpheroConnectedViewControllerを表示するメソッドを実装しておき、

- (void)showNoSpheroConnectedViewController {

    NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"RobotUIKit"
                                                           ofType:@"bundle"];
    NSBundle *bundle = [NSBundle bundleWithPath:bundlePath];
    
    RUINoSpheroConnectedViewController *noSpheroCtr;
    NSString *nibName = @"RUINoSpheroConnectedViewController_Portrait";
    noSpheroCtr = [[RUINoSpheroConnectedViewController alloc] initWithNibName:nibName
                                                                       bundle:bundle];
    [self presentModalLayerViewController:noSpheroCtr animated:YES];
}

次のように、isRobotUnderControlがNOの場合に上記メソッドを呼ぶようにすると、

- (IBAction)connect {
    
    if ([[RKRobotProvider sharedRobotProvider] isRobotUnderControl]) {
        [[RKRobotProvider sharedRobotProvider] openRobotConnection];
    }
    // ペアリングされていない
    else {
        // NO SPHERO CONNECTED画面を表示
        [self showNoSpheroConnectedViewController];
    }
}

Spheroがペアリングされてない場合に、下記のような画面が表示されるようになります。

Apheroがペアリングされていないときの画面
Apheroがペアリングされていないときの画面

リソース(nib)はPortrait(横向き)用以外にも、Landscape(立て向き)用や、iPad用も用意されているので、実装するアプリケーションに応じて使い分けてください。

その他サンプル

Spheroはジャイロセンサと加速度センサを持っており、それらの値をiOSアプリ側で取得することによりSpheroを3Dコントローラのように使用することも可能です。

そのためにはRKDeviceMessagerクラスのaddDataStreamingObserver:メソッドでデータのストリーミングの監視を開始し、RKSetDataStreamingCommandクラスのsendCommandWithSampleRateDivisor:packetFrames:sensorMask:packetCount:メソッドで、Spheroにセンサデータのストリーミングを依頼します。

これらの処理の実装には、次の2つのサンプルが参考になります。

前者は加速度センサとジャイロのデータをリアルタイム表示するサンプル、後者はそれらの値によって3Dのティーポットモデルを操作するサンプルになります。

ドキュメントをXcodeから参照する

GitHubからSpheroのディストリビューションをダウンロードすると、apiフォルダに下記2種類の.docsetファイルが入っています。

  • com.orbotix.RobotKit.docset
  • com.orbotix.RobotUIKit.docset

これらを

~/Library/Developer/Shared/Documentation/DocSets/

フォルダにコピーしておくと、Xcode の"Documentation and API Reference"メニューから参照できるようになります。

まとめ

iOSアプリと連携できるボール型デバイス「Sphero」を紹介しました。転がしてラジコンのように遊べるだけなく、ジャイロと加速度センサを持つ球体の3Dコントローラとしても使えるので、非常に可能性の高いデバイスかと思います。日本国内でも簡単に購入でき、技適マークももちろん取得されていて安心して使えるので、ぜひともお試しください。

おすすめ記事

記事・ニュース一覧