11
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

toioをGamepadで操作する簡単ツールを作った話

Last updated at Posted at 2020-02-01

#サマリ
結論から申し上げますと、toio™️のキューブをgamepadを使ってラジコン操作出来る、マルチプラットフォームツールを作りましたよと言う話です。動画でまとめるとこんな感じの機能があります。

YouTube -> https://youtu.be/Adt6j601e4E

#成果物
こちらにアクセスするだけで使えます。ソースコードもOSSでどうぞ。
screen_10.png

主な特徴

  • Windows、Mac対応。Androidはサポートしているはずだが、未確認。(iOS、iPadOSは非対応)
  • Dualshock4、Joy-Conを始めとする無線コントローラーやUSBゲームパッド(一部機能限定)に対応
  • 複数のラジコン操作方法に対応。2つのキューブを1つのコントローラーから制御する事も可能。
    • Joy-Conのセパレートスタイルにも対応。2人でラジコンレースできるよ!
IMG_0718.JPG

#きっかけ
先日の記事の内容を開発している時、gamepadAPIでJoy-Conなど簡単に使えて大変気持ちが良かったので、単純にラジコン操作出来るツールが欲しくなったまでです。
コントローラーが無線になるだけで、自由度は爆上がりですし。

準備

システム構成

topology.png

Hardware

  1. キューブの電源を入れましょう。
  2. Dualshock 4やJoy-Con(L&R)などのBluetooth/USB gamepadを用意します。特にBluetooth系のコントローラーは事前にPCとペアリング作業を終えてください。
    gamepads.jpg

Software

  1. 冒頭でも紹介したこのツールにアクセスしてください。Google Chromeを強く推奨します。
  2. GamepadのPS/Homeボタンを押して、画面上のgamepadアイコンが図の様に白く変われば認識できています。(Homeボタン系がないUSBコントローラー等はSELECT/START同時押しで代用です。)
    105.png
  3. それと同時にキューブを接続するためのウィンドウが立ち上がりますので、キューブを選択して接続してください。ダイアログ閉じちゃった場合などは手動で"Connect Cube 1/2"ボタンを押して一つずつ接続してください。
  4. 全ての準備が上手くいけば、下記の様な画面に遷移していると思います。これで準備は完了です!
    110.png

各種モードについて

シンプルツールですとか言っておきながら、色んな操作モード作って複雑にしてしまったので図にしました。
mode_description.png
少しテキストでフォローすると、ざっくり以下の使い分けになっています。

  • Single Cube Control(1つのgamepad で1つのキューブを操作)
    • Normal mode
      • IMG_0716.JPG
      • Left analog stick: Move
      • Right analog stick(X-Axis): Rotation(その場回転)
    • Stick mode
      • Left analog stick(Y-Axis): Speed
      • Right analog stick(X-Axis): Direction
  • Double Cube Control(1つのgamepad で2つのキューブを操作)
    • Combined mode
      • IMG_0719.JPG
      • Left analog stick: Cube1 Move
      • Right analog stick: Cube2 Move
    • Separated mode
      • Mainly, for Joy-Con L/R
        IMG_0718.JPG
      • Left analog stick(rotate 90 deg.): Cube1 Move
      • Right analog stick(rotate -90 deg.): Cube2 Move

画面仕様

Single Cube Control

301.png ## Double Cube Control 302.png

操作方法

全てに共通

カテゴリ Gamepad操作
DUALSHOCK 4/Joy-Con
UI例
Cube1/2の切り替え OPTION/‘+’ button Cube1は水色に、Cube2は緑色にそれぞれ光ります
設定リセット PS/HOME button USB gamepadの場合はSTART+SELECT同時押しで代用
スピード調整 L1/R1, L/R button デフォルト値は60

Single Cube Control

モード共通

カテゴリ Gamepad操作
DUALSHOCK 4/Joy-Con
UI例
gamepadの登録 PS/Home button 未登録な場合
gamepad1/2の切り替え PS/Home button 登録済みの場合
操作モードの切り替え SHARE/‘-‘ button Normal<->Stickをトグルします
Double Cube Controlへの切り替え PS/Home button長押し -

Normal mode

カテゴリ Gamepad操作
DUALSHOCK 4/Joy-Con
UI例
アナログ操作 Left analog stick IMG_0716.JPG
前進/後退 UP/DOWN button 最速でまっすぐ前進/後退します
その場回転 X-axis of right analog stick or LEFT/RIGHT button CIRCLE/A, SQUARE/Y buttonも最速回転として使えます
Working demo movie(will update...)

Stick mode

カテゴリ Gamepad操作
DUALSHOCK 4/Joy-Con
UI例
スピードコントロール Y-axis of left analog stick or left/right trigger UP/DOWN buttonも最速設定として使用できます
方向コントロール X-axis of right analog stick CIRCLE/A, SQUARE/Y buttonも最大値として使えます
Working demo movie(will update...)

Double Cube Control

モード共通

カテゴリ Gamepad操作
DUALSHOCK 4/Joy-Con
UI例
操作モードの切り替え SHARE/- button Combined<->Separatedとトグルします
Single Cube Controlへ切り替え PS/Home button 戻る時は単押しでオッケーです

Combined mode

カテゴリ Gamepad操作
DUALSHOCK 4/Joy-Con
UI例
Cube1 アナログ操作 Left analog stick IMG_0719.JPG
Cube1 前進/後退 UP/DOWN button 最速で前進/後退
Cube1 回転 LEFT/RIGHT button 最速で進みながら回転
Cube1 その場回転 L2/ZL triggerを押しながらLEFT/RIGHT button 最速でその場回転
Cube2 アナログ操作 Right analog stick Cube1の方の図を参照
Cube2 前進/後退 TRIANGLE/CROSS button 最速で前進/後退
Cube2 回転 SQUARE/CIRCLE button 最速で進みながら回転
Cube2 その場回転 R2/ZR triggerを押しながらSQUARE/CIRCLE button 最速でその場回転
Working demo movie(will update...)

Separated mode

カテゴリ Gamepad操作
DUALSHOCK 4/Joy-Con
UI例
Cube1 アナログ操作 Left analog stick
(90度回転)
IMG_0723.JPG
Cube1 前進/後退 LEFT/RIGHT button 最速で前進/後退
Cube1 回転 UP/DOWN button 最速で進みながら回転
Cube2 Analog move Right analog stick
(-90度回転)
IMG_0722.JPG
Cube2 前進/後退 SQUARE/CIRCLE button 最速で前進/後退
Cube2 回転 TRIANGLE/CROSS button 最速で進みながら回転
Working demo movie(will update...)

SWのポイント

gamepadを振動させるには

今回gamepad1/2に登録・切り替えする際にgamepadを振動させています。Daulshock 4やJoy-Conで体験できます。
振動デバイスが異なる両者ですが、どちらも同一ソースコードで動きます。

振動させるコード
const _vibrateGamePad = ( gamePad, duration ) => {
    if ( gamePad.vibrationActuator ) {
        gamePad.vibrationActuator.playEffect( "dual-rumble", { 
            duration: duration, 
            weakMagnitude: 1.0,
            strongMagnitude: 1.0 
        } );
    }
}

それぞれ良いところがありますがJoy-Conのhapticはキレが良くて好きですね。
※Android Chromeでは振動非サポートの様。

gamepadのdescriptionを取得する

gamepadが接続された時に機種名を表示していますが、Daulshock 4(1st/2nd gen)やJoy-Conが接続された時のみ特別な表記にしています。特に理由はありませんが。。。
取得や判別は容易でgamepad.idにアクセスするだけです。

const getDescription = ( index ) => {
    let description;
    const gamepad = navigator.getGamepads()[ /* gamepad index */ ];
    if( gamepad ){
        if( isJoyCon( index ) ){
            description = 'Joy-Con L+R';
        }else if( isDualShock4_1stGen( index ) ){
            description = 'DUALSHOCK 4(1st Gen)';
        }else if( isDualShock4_2ndGen( index ) ){
            description = 'DUALSHOCK 4(2nd Gen)';
        }else{
            description = gamepad.id;
        }
    }
    return description;
}

const isDualShock4_2ndGen = ( gamepadIdx ) => {
    const gamepad = navigator.getGamepads()[ /* gamepad index */ ];
    if( gamepad ){
        const gamepadDesc = gamepad.id;
        if( gamepadDesc.indexOf('Wireless Controller (STANDARD GAMEPAD Vendor: 054c Product: 09cc)') !== -1 ){
            return true;
        }else{
            return false;
        }
    }else{
        return false;
    }
}

USBコントローラの注意点

市販されているUSBコントローラーはボタンの数が少ないものもあるため、Button 10以降は無いものが多かったです。これらは無くても動作するように設計すべきでした。今回は実装した後に気が付いてしまったので、work aroundで乗り切りました。

HOMEボタンが存在しない場合をケアした例
const gamePad = navigator.getGamepads()[ idGamepad ];
    const GAMEPAD_BT_HOME = 16;
    const GAMEPAD_BT_8 = 8;
    const GAMEPAD_BT_9 = 9;
    let currentHomeButtonStatus;
    if( gamePad.buttons[ GAMEPAD_BT_HOME ] ){
        currentHomeButtonStatus = gamePad.buttons[ GAMEPAD_BT_HOME ].value;
    }else{
        currentHomeButtonStatus = gamePad.buttons[ GAMEPAD_BT_8 ].value && 
                                    gamePad.buttons[ GAMEPAD_BT_9 ].value;
    }

動作確認済機器

PC

  • OK: Windows10 Home / vaio VJP132
  • 未: Mac、、、はどなたか確認してもらえないかなぁ。
  • NG: Android 8.0.0 / SOV34
    • OS側に取られているのか、Chrome側にはgamepad制御権回ってこなかった?
  • OK: Android 6.0.1 / vaio phone VPA051

gamepad

  • OK: [Bluetooth] Dualshock 4 (1st gen.)
  • OK: [Bluetooth] Dualshock 4 (2nd gen.)
  • OK: [Bluetooth] Joy-Con
  • OK: [USB] iBUFFALO BSGP801
  • OK: [USB] 『プレイステーション クラシック』同梱USBコントローラー

所感と考察

  • gamepad APIは簡単に扱えるのは良いが、思ったよりgamepad機種(ボタン配置)差分があって、その辺をケアするのは大変ですね
  • Androidでもう少しすんなり使えるかなーと思いましたが、スマホのUI操作の方に優先権があるのは致し方ないか。選択権があると良いのにな。
  • いろんなプロトタイプに使ってもらえると幸いです。
11
3
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
11
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?