読者です 読者をやめる 読者になる 読者になる

sphero + leap motion + gobot = フォースの覚醒

f:id:sparkgene:20151216202926p:plain

BB-8欲しいですね!ただ、結構高い…

けど、これってspheroがベースなんですよね。 mashable.com

色々ググってると。すでに先人がいました makezine.com

そんなわけで、たまたま手元にあったspheroを改造して、手の届かないBB-8を自作してみることにしました。

f:id:sparkgene:20151216203922j:plain

まずは、つなぎ目があるのでそれに沿って切ります。 そして、外殻のギリギリにネオジム磁石が来るように、ガチャポンの入れ物を切って基盤の上に載せます。 ガチャポンを基盤に固定する必要があるので、グルーガンで固定しちゃいました。

f:id:sparkgene:20151216204002j:plain

磁石が固定できたら、半分に割ったspheroの殻を内側に段差ができないように組み合わせて、接着剤でくっつけます。

f:id:sparkgene:20151216203939j:plain

頭の部分はユザワヤで買ってきた、発泡スチロール球を半分に切って使います。

f:id:sparkgene:20151216203953j:plain

頭の底の部分には、磁石にくっつけるために金属製のクリップをノリ付けします。

f:id:sparkgene:20151217224517j:plain

色は白のままですが、とりあえず組みあがりました。BB-8の色は難しいから、 うーむ、実物と比べるとちょっと頭でっかちになってしまった… しかも、目玉の部分とか、アンテナが無いとただの雪だるまみたいだな。

Gobotでleap motionspheroBB-8を制御

gobot.io

Gobotを使ってleapmotionでBB-8を操作してみようと思います。

package main

import (
    "fmt"

    "github.com/hybridgroup/gobot"
    "github.com/hybridgroup/gobot/platforms/leap"
    "github.com/hybridgroup/gobot/platforms/sphero"
)

func main() {
    gbot := gobot.NewGobot()

    leapAdaptor := leap.NewLeapMotionAdaptor("leap", "127.0.0.1:6437")
    spheroAdaptor := sphero.NewSpheroAdaptor("Sphero", "/dev/tty.Sphero-OBG-AMP-SPP")

    leapDriver := leap.NewLeapMotionDriver(leapAdaptor, "leap")
    spheroDriver := sphero.NewSpheroDriver(spheroAdaptor, "sphero")

    work := func() {
        cnt := 0
        gobot.On(leapDriver.Event("message"), func(data interface{}) {
            hands := data.(leap.Frame).Hands
            heading := 0.0
            if len(hands) > 0 {
                if cnt > 20 {
                    x := hands[0].Direction[0]
                    if x > 0 {
                        // This means 0 degree. sphero move to forward
                        heading = 0
                    } else {
                        // This means 180 degree. sphero move to backward
                        heading = 180
                    }
                    fmt.Println("heading:", heading)
                    spheroDriver.Roll(60, uint16(heading))
                    cnt = 0
                } else {
                    cnt++
                }
            }
        })
    }

    robot := gobot.NewRobot("leapBot",
        []gobot.Connection{leapAdaptor, spheroAdaptor},
        []gobot.Device{leapDriver, spheroDriver},
        work,
    )

    gbot.AddRobot(robot)

    gbot.Start()
}

アダプターとドライバーにそれぞれleap motionとspheroを指定して、leapmotionから手の位置を取得してそれを元に動かすスクリプトです。

spheroは0〜360の数値を渡してあげるとその方向(0=前、90=右、180=後ろ、270=左)に動くので、本来であればleap motionから2軸分のデータを使って操作したほうがうまく動かせると思うんですが、座標と数値がちょっとめんどくさそうだったので手抜きしました。。 leap motionの座標

実際に動かしたムービーはこちら。

youtu.be

本物と比べると頭の位置が安定しないです。しかもすぐ取れちゃう。頭側も磁石にしたほうが安定するかな。 そんな訳で、スター・ウォーズの新作公開日に間に合って良かったw