LoginSignup
5
0

More than 3 years have passed since last update.

【toio 2019】 toio.js で傾き検知と姿勢検出(2019/12/17)

Last updated at Posted at 2019-12-16

この記事は 「toio™(ロボットトイ | toio(トイオ)) Advent Calendar 2019」の 17日目の記事です。

はじめに

toio の 「toio バリューパック」・「トイオ・コレクション 拡張パック」と「工作生物 ゲズンロイド」を持っています @youtoy です。

また、toio関連では、以下のユーザ会を 3人で共同主催しており、2度ほど LT会を開催したりしました。

▼ toio™で作ってみた!友の会(非公式)
 ⇒ 【Facebookグループ】
 ⇒ 【connpassのグループ】

この記事で試す内容について

以前、toio.js を使って、toio と他デバイス(Amazon Echo や micro:bit)と連携させる記事を書いたことがあります。
 ● #toio を Alexa や micro:bit から操作する 〜概要編〜(JavaScriptライブラリを使ってみた) - Qiita
このときは、キーボード入力で toio を動かすサンプルをベースに、作品を作っていました。

それから時間が経過し、toio の仕様のページや、公式のニュース(タイトル: システムソフトウェアアップデート2019 実施)にも書かれているように、アップデートが行われました。
今回の記事では、アップデートにより追加された内容を試すことにします。

それでは、何を試してみようかと、アップデートされた内容を見ていきたいと思います。
仕様の「アップデートについて」というページの下部を見てみると、以下のような記載があります(2019/12/16時点)。

BLE プロトコルバージョン v2.1.0 では以下のような内容の変更・追加があります。

  • ダブルタップ検出・姿勢検出の追加
  • モーターの速度指示値の有効範囲の拡大
    • 速度指示値の最大値が100から115になり、より速い動作が可能になります
    • 速度指示値の最小値が10から8になり、よりゆっくりとした動作が可能になります
  • モーター制御のバリエーションの追加
    • 目標指定付きモーター制御
    • 複数目標指定付きモーター制御
    • 加速度指定付きモーター制御

一番上の「ダブルタップ検出・姿勢検出の追加」あたりを試してみるのが、見た目にも分かりやすそうです。
上記の「ダブルタップ検出・姿勢検出の追加」の部分については、仕様の「モーションセンサー」に仕様詳細が記載されていました。以下は、2019/12/16時点でページの一部をキャプチャしたものです。
モーションセンサー_·_toio™コア_キューブ_技術仕様.jpg

今回は、ダブルタップ検出・姿勢検出の2つあるうちの「姿勢検出」を試していこうと思います。

toio.js でモーションセンサーを使う

現状のモーションセンサー周りを見てみる

姿勢検出を試していく前に、まずは、現状の toio.js のモーションセンサー周りの処理で実装されている内容を見てみます。

API の情報をたどっていくと、「Globals @toio/cube Cube」の「Class Cube」の中に、「getSlopeStatus」という部分があります。どうやら、傾きをセンサーで検知するもののようです。

この部分には、以下のような記載があります。
Cube___toio_js.jpg
そして、上記の「Defined in cube/src/cube.ts:225」の部分をクリックすると、以下のようなソースコードがあります。
toio_js_cube_ts_at_2c121885f89bfbe3d9269e634755eb223a3020ed_·_toio_toio_js.jpg

さらに、上記の「isSloped」をキーワードにリポジトリ内で検索してみます
すると、検索結果の中に、以下のような内容がありました。
Search_·_isSloped.jpg

そして、リンク先のソースに以下のような箇所がありました。
toio_js_sensor-spec_ts_at_004a77ce6304fc90705c323571ebb4ac55a93924_·_toio_toio_js.jpg

「const isSloped = buffer.readUInt8(1) === 0」という部分や「const isCollisionDetected = buffer.readUInt8(2) === 1」という部分がありますが、上記の仕様の「モーションセンサー」の部分、もっと具体的に言うと以下の画像の赤枠部分が関連しそうです。
モーションセンサー_·_toio™コア_キューブ_技術仕様2.jpg

姿勢の検出

ということは、データ位置が 2 に該当する「const isSloped = buffer.readUInt8(1) === 0」のところを、試しに「const isSloped = buffer.readUInt8(4) === 【数値】」としてみれば、特定の姿勢を検出する処理に変わるように思われます。

姿勢の違いを表す数値については、先ほど出てきたページの中で、以下のように書かれています。
モーションセンサー_·_toio™コア_キューブ_技術仕様.jpg
この記事では、「底面が上(値 2)」と「正面が上(値 4)」の 2つを試してみることにします。

姿勢検出を試す前のセットアップなど

最終的には姿勢検知を試していくのですが、その前に公式サンプルを動かしてみたり、上記の「getSlopeStatus」を使って傾きを検出するプログラムを試してみます。

公式サンプルを動かしてみる

GitHub の toio.js のページの「💻 Prerequisites」 を見て、事前のセットアップを行ってください。

そして、GitHub の toio.js のページに記載されている、以下の内容を試してみましょう。

▼ How to play sample application

  1. $ git clone https://github.com/toio/toio.js.git
  2. $ cd toio.js
  3. $ yarn install
  4. $ yarn build
  5. $ yarn example:keyboard-control

動かしてみたときの様子は以下のとおりです。

今回の動画では、手順1 でクローンしてきたソースの中の「toio.js/examples/keyboard-control」の直下の「index.js」に少しだけ手を加えています。
具体的には、11行目〜17行目までの、スピードや移動距離に関わるパラメータを、以下のようにしました。

index.js
const DURATION = 500 // ms
const SPEED = {
  forward: [50, 50],
  backward: [-50, -50],
  left: [15, 50],
  right: [50, 15],
}

また、上記の部分で少し書きかえた「toio.js/examples/keyboard-control」の直下の「index.js」を、以下のソースコードに置きかえて動作させてみたりもしました(※ GitHub の toio.js のページの冒頭のソースで、「cube.move(100, 100, 1000)」の部分を「cube.move(50, 50, 500)」にと、少しだけ変更したものです)。

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

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

  // connect to the cube
  await cube.connect()

  // move cube
  cube.move(50, 50, 500)
  //         |    |     `--- duration [ms]
  //         |    `--------- right motor speed
  //          `------------- left motor speed
}

main()

書きかえた後のソースを動かすには$ yarn example:keyboard-controlを実行する必要があります。これにより、変更後の内容が反映されました。

モーションセンサーの情報を使う

続いて「getSlopeStatus」を使って傾きを検出するプログラムを試してみます。
なお、普段あまりプログラムを書くことがないため、以下で出てくるプログラムで「もっと良い書き方があるよ」という場合や、「この書き方はまずいよ」という場合などは、コメント欄などで教えていただけると嬉しいです。

では、傾きを検出したか否か(true/false)の出力で、傾いていると検知された場合には「傾いてるぞ!」というテキストが表示されるプログラムを作ってみます。
上で出てきた2つ目のプログラムをベースに書きかえをしました。そして、判定処理は 500msec間隔で20回実行しています。判定処理のところは「getSlopeStatus」の「isSloped」が true か false を見る形です。

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

async function main() {
  let cubeStatus;
  const cube = await new NearestScanner().start()

  await cube.connect()
  for (let i = 0; i < 20; i++) {
    cubeStatus = await cube.getSlopeStatus();
    if(cubeStatus.isSloped) {
      console.log("傾いてるぞ!");
    } else {
      console.log("...");
    }
    await new Promise(r => setTimeout(r, 500));
  }
  console.log("状態チェック、終了。");
}

main()

実際に動作させてみると、以下の動画のようになりました。
toio が傾くと PCの画面に表示されるテキストが変わるのが、動画から分かるかと思います(ちなみに、傾いたかどうかの閾値はデフォルトのままで、その場合は 45度が閾値となるようです)。

姿勢検出を試してみる

それではいよいよ、姿勢検出へと進みます。
今回は短時間で試すために、(手抜きな感じの)楽な方法を採用します。本来はソースコードの追加や修正等をいろいろと行うべきところを、既存のコードの一部のみ(パラメータのみ)を書きかえることとします。
これだと、メソッド名と処理内容が一致しなくなってしまうのですが・・・(後で、公式でAPIが準備されるだろう、という見込んでの暫定対応ということで)。

具体的には「toio.js/packages/cube/src/characteristics/specs/sensor-spec.ts」の 31・32行目を以下のように書きかえました。

【書きかえ前】

    const isSloped = buffer.readUInt8(1) === 0
    const isCollisionDetected = buffer.readUInt8(2) === 1

【上記の書きかえ後】

    const isSloped = buffer.readUInt8(4) === 2
    const isCollisionDetected = buffer.readUInt8(4) === 4

これにより、以下のような動作をするようになるはずです。
 「isSloped はキューブの底面が上を向くと true」
 「isCollisionDetected はキューブの正面が上を向くと true」

上記の 2つの状態(底面が上/正面が上)が検出された場合に、それぞれに対応したテキストを PC画面上に表示するようにしてみました。

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

async function main() {
  let cubeStatus1, cubeStatus2;
  const cube = await new NearestScanner().start()

  await cube.connect()
  for (let i = 0; i < 20; i++) {
    cubeStatus1 = await cube.getSlopeStatus();
    cubeStatus2 = await cube.getCollisionStatus();
    if(cubeStatus1.isSloped) {
      console.log("逆さまになっています");
    } else if(cubeStatus2.isCollisionDetected) {
      console.log("上向き!");
    } else {
      console.log("...");
    }
    await new Promise(r => setTimeout(r, 500));
  }
  console.log("状態チェック、終了。");
}

main()

実際に動かしてみたのが以下の動画です。

無事に動いていそうです。

さいごに

今回、 toio.js で傾き検知と姿勢検出を試してみました。

本当は、動画でわかりやすいように「姿勢によって異なる音が鳴る・異なる光り方をする」とか、2台の toio を連携させるような内容をやりたかったのですが、時間の関係でここまでとなりました。
その辺りは、引き続き試していこうと思います!

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0