toioを使ったデジタルなチョロQ

# マットを使わないチョロQ

**Hiroshi Takagi**と申します。普段は組み込みエンジニアをやっています。

今回はtoioの新しいアップデート機能を使ってチョロQを作ってみました。

toioと言えば絶対位置センサーですが、今回はそれを使わずに作ります。

そうすることで、専用のマットを使わなくてもどんなところでも遊ぶことができます。こんな感じ。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">デジタルなチョロQ<a href="https://twitter.com/hashtag/toio?src=hash&amp;ref_src=twsrc%5Etfw">#toio</a> <a href="https://t.co/OKxHML1cC2">pic.twitter.com/OKxHML1cC2</a></p>&mdash; Hiroshi Takagi (@TkgHrsh) <a href="https://twitter.com/TkgHrsh/status/1316213973474111488?ref_src=twsrc%5Etfw">October 14, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# まずモーターの回転速度を取得します。

早速ですがやっていきます。

はじめに、[モーターの速度情報の取得](https://toio.github.io/toio-spec/docs/ble_motor#%E3%83%A2%E3%83%BC%E3%82%BF%E3%83%BC%E3%81%AE%E9%80%9F%E5%BA%A6%E6%83%85%E5%A0%B1%E3%81%AE%E5%8F%96%E5%BE%97)を使って回転速度を取得します。

手でタイヤを動かしているときの速度値が取れるので、この値を蓄積することで、チョロQの動く長さを決めます。

これはデフォルト無効なので、使うには事前に以下設定で有効にする必要があるので注意です。[モーターの速度情報の取得の設定](https://toio.github.io/toio-spec/docs/ble_configuration#%E3%83%A2%E3%83%BC%E3%82%BF%E3%83%BC%E3%81%AE%E9%80%9F%E5%BA%A6%E6%83%85%E5%A0%B1%E3%81%AE%E5%8F%96%E5%BE%97%E3%81%AE%E8%A8%AD%E5%AE%9A)

# 動きは加速度指定付きモーター制御を使う

チョロQの動きって、ビューンて進んでヒューって止まる感じだったので、
こんな風に、開始の速度と停止し始めるタイミングを引っ張った距離で調整します。

![スクリーンショット 2020-12-11 20.24.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542743/61350ec6-8f00-b507-4d6f-07bd00658fe4.png)

加速度のコントロールはキューブにお任せして[加速度指定付きモーター制御](https://toio.github.io/toio-spec/docs/ble_motor#%E5%8A%A0%E9%80%9F%E5%BA%A6%E6%8C%87%E5%AE%9A%E4%BB%98%E3%81%8D%E3%83%A2%E3%83%BC%E3%82%BF%E3%83%BC%E5%88%B6%E5%BE%A1)を使いました。

# 実装してみる
今回toiojsを使いましたが、ライブラリがまだ新しい機能に対応していなかったので、自分で修正しました。
こちらは本家の修正に期待して、アプリケーション側の実装だけ記載します。（実装が雑でゴメンなさい）

```js
const { NearestScanner } = require('@toio/scanner')

async function main() {
  // start a scanner to find nearest cube
  const cube = await new NearestScanner().start()
  // connect to the cube
  await cube.connect()

  let sumLeft = 0
  let sumRight = 0
  let moveState = 0
  let moveDelayTimer

  cube.on('motor:speed-feedback', (data) => {
    console.log(data)
    if (data.left === 0 && data.right === 0) {
      if (moveState === 0) {
        if (sumLeft + sumRight > 20) {
          moveState = 1
          moveDelayTimer = setTimeout(()=> {
            const power = (sumLeft + sumRight) / 20
            const curve = (sumRight - sumLeft) / 2
            moveState = 2
            console.log('move', power, curve)
            cube.playPresetSound(1)
            cube.turnOnLight({durationMs: 2550, red: 255, blue: 0, green: 0}, 1)
            cube.moveWithAcc(-power, curve, 0, 0)
            setTimeout(() => {
              console.log('stopping')
              cube.moveWithAcc(0, 0, 20, 0)
            }, power * 10)
          }, 500)
        }
      }else if(moveState === 2){
        cube.turnOffLight()
        cube.playPresetSound(2)
        console.log('stopped')
        moveState = 0
        sumLeft = 0
        sumRight = 0
      }
    }else{
      if(moveState === 0){
        sumLeft += data.left
        sumRight += data.right
      }else if (moveState === 1){
        moveState = 0
        clearTimeout(moveDelayTimer)
      }
    }
  })

  cube.setMotorFeedbackEnable(1).then((result) => {
    console.log(result)
  })
}

main()

```

ポイントは、簡単な状態繊維を作っています。

![スクリーンショット 2020-12-11 20.42.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542743/ba643279-bfa5-57ac-090e-5009ec15a76d.png)

タイヤを引っ張っている最中はどんどん値を蓄積していきます。

タイヤの動きが止まったら、ちょっと待ちます。

これはチョロQって
「引っ張って→持ち上げて移動して→また引っ張って」
という順番で動かすので一時的にタイヤが止まる時をケアしてます。

走らせてから一定時間後に加速度付きで停止命令を発行して、またタイヤが止まったら最初に戻ります。

#おわり

ちょっと駆け足でしたが、今回はチョロQのご紹介でした。
デジタルなチョロQにしかできないことは、モーター左右の回転数を別々に取得できるので、
こんな風にカーブして走らせることができます。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">デジタルなチョロQはカーブができます。<a href="https://twitter.com/hashtag/toio?src=hash&amp;ref_src=twsrc%5Etfw">#toio</a> <a href="https://t.co/0Ylnmk4cbE">pic.twitter.com/0Ylnmk4cbE</a></p>&mdash; Hiroshi Takagi (@TkgHrsh) <a href="https://twitter.com/TkgHrsh/status/1316596823759319040?ref_src=twsrc%5Etfw">October 15, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

他にもデジタルになったことでいろいろ拡張できると思うので、もし何かアイデアあれば教えてください。

それではまた！