Morikatron Engineer Blog

モリカトロン開発者ブログ

「toio SDK for Unity」v1.1.0の更新

はじめまして、モリカトロン株式会社・AIエンジニアの舒(ジョ)と申します。今年4月からモリカトロンに入社しました。大学と院生の専門は機械電子システムで、機械学習に触れたこともあります。

会社の皆と一緒に「toio SDK for Unity」一部の開発に参加して、いろいろな知識を学びました。 まず、「toio SDK for Unity」とは何かを紹介させていただきます。

「toio SDK for Unity」

この「toio」とゲームエンジンのUnityを連携させるためにモリカトロンが開発したのが、「toio SDK for Unity」です。これにより、シミュレータ上で「toio」のtoio コア キューブ(キューブ)の挙動を再現できるほか、アプリケーションを生成することでスマートデバイスを介してキューブを制御することも可能です。さらにライブラリやアセットによってはARや機械学習も利用できるため、ロボット工学のみならず、メディアアートでの活用も期待できます。

github.com

簡単に言えば、toio開発者はシミュレーション環境でデバッグできて、コード作成とテストが便利になります。

f:id:morika-jyou:20201217191438g:plain
上図の様に、一つのソースコードでシミュレータとリアルのキューブの両方を動かすことが出来ます。

v1.0

1.0バージョンでは主に以下の機能を実現しました。

1.キューブをプログラム制御する「Cubeクラス」、デバイスを通信制御する「Bluetooth」、UnityEditorで「toio」の挙動をシミュレーションする「Simulator」、キューブを単体や群集として動かす「制御モジュール」の4つのモジュールを通じて、Unityのシミュレーション環境と実装後のリアル環境とでコードを書き換えなくても、同じ挙動をするシステムを開発しました。

2.便利な移動機能をまとめた「CubeHandle」と、高度な集団制御を実現した「Navigator」という2種類のクラスは、単一制御やグループ制御が可能なため、コード作成がより便利になります。

f:id:morika-jyou:20201218105258g:plain
複数のキューブがボイドとして一緒に移動します。

3.シミュレーション環境には、キューブのトイオ・コレクション各付属品(プレイマット、カード、シート)や、センサー機能(Position ID、Standard ID、ボタン、傾き、衝突、座標と角度、Standard IDなど)、基本的なキューブ機能(音を鳴らす、LEDを発光する)も実装してあります。

4.各機能の確認や使い方を理解するために、様々なサンプルも用意しました。

v1.1

キューブの BLE プロトコルバージョンの更新に伴い、「toio SDK for Unity」もv1.1にアップグレードしました。

github.com

toioコア キューブ 技術仕様によれば、BLE プロトコルv2.1.0とv2.2.0は姿勢検出、ダブルタップ検出、シェイク検出とモーター速度検出、モーター制御など新機能が実装されています。 そこで、「toio SDK for Unity」でも、上記のいくつかの機能を追加しました。

1. 姿勢検出

姿勢検出とは、モーションセンサーを利用して、キューブの水平面に対する姿勢が変化したときに値を取得し、キューブの6面のうち「どこが上向きであるか」を検出することができます。

たとえば、下記のように、磁石を利用してキューブを垂直壁面に移動させる場合、この機能が使えます。

qiita.com

2. ダブルタップ検出

キューブが一度タップされてから一定時間内に再度タップされると、ダブルタップとして検出できます。 また、検出間隔時間も設定できます。

/// <summary>
/// キューブのダブルタップ検出の時間間隔を設定します
/// https://toio.github.io/toio-spec/docs/ble_configuration#ダブルタップ検出の時間間隔の設定
/// </summary>
/// <param name="interval">ダブルタップ検出の時間間隔</param>
/// <param name="order">命令の優先度</param>
public virtual void ConfigDoubleTapInterval(int interval, ORDER_TYPE order = ORDER_TYPE.Strong) { NotSupportedWarning(); }

3. モーター速度検出

モーターの速度を検出するセンサーは100 ミリ秒間隔で情報が更新・通知されます。値が変化しなかった場合には通知を行いません。 仕様書によると、デフォルトでは無効になっていて、モーターの速度情報の取得の設定で有効化する必要があります。 「toio SDK for Unity」に実装する時も、はじめはシステム初期化後に有効化する予定でした。 ですが、例えばある状態だけでスリップしたかどうか(モーター速度があり、座標が変化しない)を検出したい場合、通信量の制限がかかってしまうため、無効化の関数を追加設定する必要がでてきました。 ですので、モーターの速度情報の取得の設定で有効化・無効化する関数も追加しました。

/// キューブのモーター速度情報の取得の有効化・無効化を設定します
/// https://toio.github.io/toio-spec/docs/ble_configuration#モーターの速度情報の取得の設定
/// </summary>
/// <param name="valid">有効無効フラグ</param>
/// <param name="timeOutSec">タイムアウト(秒)</param>
/// <param name="callback">終了コールバック(設定成功フラグ, キューブ)</param>
/// <param name="order">命令の優先度</param>
public virtual UniTask ConfigMotorRead(bool valid, float timeOutSec = 0.5f, Action<bool,Cube> callback = null, ORDER_TYPE order = ORDER_TYPE.Strong) { NotSupportedWarning(); return UniTask.CompletedTask; }

有効化関数を呼び出していないと速度を検出ができません。

public override int leftSpeed
{
     get
     {
          if (null == this.motorReadRequest)
          {
               Debug.Log("モーター速度が有効化されていません. ConfigMotorRead関数を実行して有効化して下さい.");
               return -1;
           }
           else if (!this.motorReadRequest.valid || !this.motorReadRequest.hasMotorResponse) { return -1; }
           else { return this._leftSpeed; }
       }
       protected set { this.NotImplementedWarning(); 
}

また、モーター制御機能ではモーターのスピードを直接検出しています。 モーター制御をせず、タイヤを手動で動かしても検出が可能です。

4. シェイク検出

シェイク検出はキューブの揺れを検出し、揺れのレベルを測定します。キューブを利用したスポーツゲームの実現の可能性を提供しています。

qiita.com

5. 目標指定付きモーター制御

1.0バージョンでは、CubeHandleの内部にあるMove2Target関数を通じて、キューブの座標をリアルタイムに検出し、目標に向かう時の動きを修正する目標移動機能を実装してあります。

1.1バージョンではモーター制御バリエーションの「目標指定付きモーター制御」という機能で、座標検出とモーター制御のプロセスをキューブに設定できます。単純な目標移動機能を使う場合、通信量が大幅に削減できます。

/// <summary>
/// キューブのモーターを目標指定付き制御します
/// https://toio.github.io/toio-spec/docs/ble_motor#目標指定付きモーター制御
/// </summary>
/// <param name="targetX">目標地点のX座標値</param>
/// <param name="targetY">目標地点のY座標値</param>
/// <param name="targetAngle">目標地点でのキューブの角度Θ</param>
/// <param name="configID">制御識別値</param>
/// <param name="timeOut">タイムアウト時間(秒)</param>
/// <param name="targetMoveType">移動タイプ</param>
/// <param name="maxSpd">モーターの最大速度指示値</param>
/// <param name="targetSpeedType">モーターの速度変化タイプ</param>
/// <param name="targetRotationType">回転タイプ</param>
/// <param name="order">命令の優先度</param>
public virtual void TargetMove(
        int targetX,
        int targetY,
        int targetAngle,
        int configID = 0,
        int timeOut = 0,
        TargetMoveType targetMoveType = TargetMoveType.RotatingMove,
        int maxSpd = 80,
        TargetSpeedType targetSpeedType = TargetSpeedType.UniformSpeed,
        TargetRotationType targetRotationType = TargetRotationType.AbsoluteLeastAngle,
        ORDER_TYPE order = ORDER_TYPE.Strong) { NotSupportedWarning(); }

また、 目標指定付きモーター制御は、回転方向や移動タイプなど複数の制御モードを提供しています。

public enum TargetMoveType: byte
{
        // https://toio.github.io/toio-spec/docs/ble_motor#移動タイプ
        RotatingMove=0,       // 回転しながら移動
        RoundForwardMove=1,   // 回転しながら移動(後退なし)
        RoundBeforeMove=2     // 回転してから移動
};

public enum TargetSpeedType: byte
{
        // https://toio.github.io/toio-spec/docs/ble_motor#モーターの速度変化タイプ
        UniformSpeed=0,   // 速度一定
        Acceleration=1,   // 目標地点まで徐々に加速
        Deceleration=2,   // 目標地点まで徐々に減速
        VariableSpeed=3   // 中間地点まで徐々に加速し、そこから目標地点まで減速
};

public enum TargetRotationType: byte
{
        // https://toio.github.io/toio-spec/docs/ble_motor#目標地点でのキューブの角度-θ
        AbsoluteLeastAngle=0,         // 絶対角度 回転量が少ない方向
        AbsoluteClockwise=1,          // 絶対角度 正方向(時計回り)
        AbsoluteCounterClockwise=2,   // 絶対角度 負方向(反時計回り)
        RelativeClockwise=3,          // 相対角度 正方向(時計回り)
        RelativeCounterClockwise=4,   // 相対角度 負方向(反時計回り)
        NotRotate=5,                  // 回転しない
        Original=6                    // 書き込み操作時と同じ 回転量が少ない方向
};

f:id:morika-jyou:20201218110820p:plain
移動タイプ

制御命令IDも設定できて、IDによって命令を実行したキューブの状態(また破棄、エラー)も取得できます。

public enum TargetMoveRespondType: byte
{
        // https://toio.github.io/toio-spec/docs/2.1.0/ble_motor#応答内容-1
        Normal=0,           // 目標に到達した時
        Timeout=1,          // 指定したタイムアウト時間を経過した時
        ToioIDmissed=2,     // toio ID がない場所にキューブが置かれた時
        ParameterError=3,   // 座標 X, 座標 Y, 角度の全てが現在と同じだった時
        PowerOffError=4,    // 電源を切られた時
        OtherWrite=5,       // 複数目標指定付きモーター制御以外のモーター制御が書き込まれた時
        NonSupport=6,       // 指定したモーターの最大速度指示値が8未満の時
        AddRefused=7        // 書き込み操作の追加ができない時
};

上記の機能に基づいて、複数のキューブを同時に制御するなど、より複雑なタスクをユーザが同時に行うことができます。

6. 加速度付きモーター制御

加速度制御は、キューブを任意の運動速度から(直進でも回転でも)目標速度に一定の加速度で変えられます。

f:id:morika-jyou:20201223124353g:plain
このサンプルは Cube の TargetMove と AccelerationMove を使って目標に到達したり加速しながら螺旋状に移動したりするサンプルです

検出できる状態のシミュレータ

シミュレーション環境では、シェイク状態、衝撃状態、ダブルタップ状態が直接指定できるようにしました。

f:id:morika-jyou:20201217140510g:plain
「toio SDK for Unity」のサンプルでは、キューブの各センサー値を検出し、UIに表示するサンプルです

最後に

今回の更新で多くの新しい機能を追加しました。前のバージョンより、toioの使い方はより豊かになりました。 「toio SDK for Unity」を通して、toioに関する創意とゲームをより便利に実現できると思います。