Sphero gem で Sphero を操作してみる

この記事は [Sphero Advent Calendar 2013](http://www.adventar.org/calendars/142) の2日目のエントリーです。

Sphero って何？ という方は[1日目のエントリー](http://tech.tmd45.jp/entry/2013/12/01/001418)をご覧くださいませ。

[会社の勉強会でKidsRubyの紹介をしたら](http://tech.feedforce.jp/kidsruby.html)、なぜか社内にSpheroが増えつつあります。
iPhoneやAndroidから公式アプリで動かすだけでなく、各種言語のライブラリで操作ができる。
困ったら[API仕様](http://orbotixinc.github.io/Sphero-Docs/)が公開されているので確認できる。
なんて楽しいガジェット！
そして可愛い！

というわけで、 Ruby で Sphero を操作してみます。

あらかじめ [Sphero gem](https://github.com/hybridgroup/sphero) を使えるようにしておきましょう。
`gem install sphero`  でもなんでも、お好みの gem 管理方法でインストールしてください。
(わたしの環境だと、別途 serialport という gem をインストールしないとSpheroと接続できませんでした)

そしたらまずは、 Bluetooth で Sphero と接続します。
Sphero をタップして(我が家のSpheroは、割と強めに叩かないと起きてくれないのですが)起動します。
Sphero とデバイス接続できれば、 `/dev` の下に `/dev/tty.Sphero-XXX-XXX-SPP` のように Sphero の tty デバイスができているはず。
もしうまく Sphero と接続できない場合は、 iPhone など別の奴が Bluetooth で接続してしまってないか確認してみてください。

Sphero は、どこかから接続されていない間は、固有の3色の色で順番に点滅します。
赤-青-緑、のように。
点滅せずに、明るい青い色で光り続ける時は、Bluetooth接続中です。
赤い色が点滅している時は充電切れなので、大人しく充電させましょう。

ちなみに、未接続時に光る3色が、 `/dev/tty.Sphero-` の次の3文字になっているようです。
赤-青-緑なら `/dev/tty.Sphero-RBG-XXX-SPP` となります。

さて、 Sphero のデバイスは無事みつかったでしょうか？
Ruby から Sphero を動かすのは簡単です。

```rb
Sphero.start('/dev/tty.Sphero-XXX-XXX-SPP') do
  roll(100, 0)
  keep_going(1)
end
```

これで、Spheroは直進します。

`roll(speed, heading)` は heading の向きへ speed の速さで転がります。
speed は 0 から 255 まで指定できます。
heading は 0 から 359 まで、つまり角度の指定ができます。

`keep_going(duration)` は duration で指定した秒数、現在動作している状態( roll 中なら roll の状態)を続けます。

ブロックの中身は、startメソッドの中で `instance_eval` に渡され、 Sphero クラスのインスタンスのコンテキストで実行されます。
`Sphero::FORWARD` などの定数は、 gem の README の通りにはそのままは呼び出せないはず。
(バージョンによってはうまくいってしまうこともありますが、そちらはバグ扱いの挙動だそうです ⇒ [参照](http://comments.gmane.org/gmane.comp.lang.ruby.japanese/7657))
定数が使いたい場合は `Sphero::FORWARD` のようにクラス名から指定すると良いです。

`Sphero.start` は自分(つまり Sphero クラス)のインスタンスを作成し、ブロックを受け取っていた場合は `instance_eval` し、そして close して終了します。
`File.open` などと同じですね。
そして、やはり `File.open` などと同じく、ブロックを渡さなかった場合には、インスタンスを返すようになっています。

つまり、さきほどのコードは、以下のようにも書けます。

```rb
s = Sphero.start('/dev/tty.Sphero-XXX-XXX-SPP')
s.roll(100, 0)
s.keep_going(1)
s.close
```

走行中のSpheroは `heading=(heading)` で向きを変えることができます。

```rb
Sphero.start('/dev/tty.Sphero-XXX-XXX-SPP') do
  roll(100, 0)
  keep_going(1)
  heading = 90
  keep_going(1)
  heading = 180
  keep_going(1)
  heading = 270
  keep_going(1)
  heading = 0
end
```

走行を止めたい時は `stop` です。

```rb
s = Sphero.start('/dev/tty.Sphero-XXX-XXX-SPP')
s.roll(100, 0)
s.keep_going(1)
s.stop
s.close
```

Spheroの発光色を変える方法は2通りあります。
`Sphero::COLORS` という定数で、色名が設定されていますので、その色名を指定する方法。

```rb
Sphero.start('/dev/tty.Sphero-XXX-XXX-SPP') do
  color('cyan')
end
```

`rgb` では、直接数値の指定ができます。
先ほどの `color` は、実のところ `rgb` のショートカットです。

```rb
Sphero.start('/dev/tty.Sphero-XXX-XXX-SPP') do
  rgb(0, 255, 255)  # color('cyan') と同色です
end
```

`color` の第2引数、 `rgb` の第4引数に true を指定すると、ユーザの色として設定が保持されるそうです。
(デフォルトは false なので、一時的な変更扱いされるみたいです)

こんなふうに、Rubyからの操作はとても簡単です。
SpheroのAPIもSphero gemも、もうちょっと色々できるのですが、それについてはまた今度……今度があれば。
待てない！ もっと色々やってみたい！ という場合は、[Sphero gem](https://github.com/hybridgroup/sphero) のコードを読んでみてください。
ファイル数も多くないし、コードも読みやすく、何ができるかすぐわかると思います。

さて、3日目はjishihaさんの[Sphero を Scratch(スクラッチ)から動かせるようにしたのでこどもでもプログラミングできるよ](http://blog.champierre.com/1029)です！