Motion Controller
11/21 基盤と3Dモデルの基礎検討
M5Cの縦横に収まるようにスイッチを狭めたが、M5Cと基盤を繋ぐ足が1mmほど長いので短くできるか検討する。
5V2つ、3Vの足は不要なので取り除き、基盤を小さくする。→3Vは使う。BATを使わない
https://scrapbox.io/files/655caf77f494ca001b6c2676.jpghttps://scrapbox.io/files/655caf7b08da16001cefd067.jpg
ボタン4つにしたがそもそもM5C上部のGPIOピンが3つしかない。PS系の◯△□×ボタンの想定はやめる。(そもそも上下左右の入力とモーション入力を想定している )
https://scrapbox.io/files/655cbe2410e2f0001c7041d7.jpg
11月22日は3ピンの基盤設計する。
先に3Dモデリングの検討。突起をつければM5Cに仮固定できる。(壊れそうなのは心配)
https://scrapbox.io/files/655d4e5bd93b55001ce7fd50.png
参考3Dモデル
https://scrapbox.io/files/6561c022aca971001b5283bb.png
11/25-26 基盤と3Dモデルの設計/検討
今まではL次ピンヘッダを使っていたが、M5StickCのHATとしてぴったり装着するに縦横の長さに余裕がなく、23.2mm x 13.7mmの範囲に収める必要がある。
(下記3Dモデルは23.2mm x 13.7mmと、実物より1.2mm長い)
https://scrapbox.io/files/65631138d4259100213a156c.png
そのため、L次ヘッダではなくストレートピンヘッダを使うことにした。
(L次を使っていたのはユニバーサル基盤を使った場合にスイッチとの配線がし易いという理由もあった)
ただしピンヘッダの黒い部分を取って使った場合、ストレートピンヘッダ(またL字ピンヘッダ)ではM5StickCのピン挿入限界を超えてしまうので、黒い部分を取り除く場合は、細ピンヘッダやロープロファイル9.5mmピンヘッダを使うのが良い。(下図参考)
https://scrapbox.io/files/65631541c809f2001cdc85fa.png
試作した4種類を載せておく。
1.ストレートピンヘッダ(黒部あり) 2.細ピンヘッダA 3.細ピンヘッダB(2.54mm右にスイッチを実装)
https://scrapbox.io/files/65630f8a83bf15001c020dbc.png
1 ,2, 3 4.ストレートピンヘッダ(黒部なし) 一番右
https://scrapbox.io/files/6563166379b143001b9d4be8.png
KiCADで回路図、PCBレイアウトを作成したので載せて置く。
M5StikCは手持ちできるので、拡張しやすいカバーと基盤にしておくのは良さそう。
https://scrapbox.io/files/65631763908c51001b944a6f.pnghttps://scrapbox.io/files/6563173eb2f1bf001c2b19a3.png
基盤の3Dモデル(スイッチの3Dモデルを後で作りたい)、カバーと基盤の3Dモデルも載せておく。
https://scrapbox.io/files/656317a86ede9f001b8f6730.pnghttps://scrapbox.io/files/65631819f1a8bf001c40f30f.png
4.ストレートピンヘッダ(黒部なし)で進める場合、
・スイッチがカバーに収まるか
・ピンとスイッチとぶつかる為にカバーが左に1mmずれてしまうのを修正できるか
・カバーの上側をどのように埋めるか
・基盤とカバーの接続はねじか、接着剤か。ねじの場合は基盤とM5Cの間にプリントしたプラスチック板を入れてもよい。
https://scrapbox.io/files/65631908a95c7a001bcf7fb1.png
1.ストレートピンヘッダ(黒部あり)で進めて、カバーを上から被せて、上下のPLAをねじ止めするのが良い気がする。
https://scrapbox.io/files/656321b3fc302c001c633271.png
11/27にJLCPCBへ再発注して、12/7以降に基盤実装/3Dモデル検討をおこなう。
12/4に届いたので7日後に届いた事になる。今まで発注した中で最短だろうか。
ver0.2
カバーとベースで挟もうとしたが、一緒にしたほうがいいと思ったので下記とした。
しっかり留まらなければやはりねじが必要。
ver0.3
https://scrapbox.io/files/656de558bce1f40025a4851c.png
残務:
薄いため8ピンのプリント材料を多くしてから、ピンの型をくりぬく。
12/19 基盤が7日で到着し、二週間経ってから部品実装した。ねじ止めにしているが右側が浮いてしまう。他方をねじ止めしたとしても、M5Stickの頭の中央が少し膨らんでいることが原因だろう。ベースを少し反らして逆お椀型にするしかないだろうか。
https://scrapbox.io/files/6581ab2ad245d20024e3a853.pnghttps://scrapbox.io/files/6581ab173bbfb30025f394e7.png
抵抗をリード部品で実装できるようにホールを設けた。ベースがない場合でも高さ的に安定して基板をM5Cへ乗せられる。
ハンダ付けし難い場合に0603の表面実装抵抗を使わなくとも良くなるのと、下部に余裕が生まれるのでGPIO Expander等のその他部品を配置できる。
https://scrapbox.io/files/659020446e3c7f002376eaf2.pnghttps://scrapbox.io/files/6590206a24210f0024e82857.png
https://scrapbox.io/files/6590212d03c2fe00230ae862.png
JLCPCBでPCBAする場合のBOM。
https://scrapbox.io/files/659022b3fe549d0024d8d4d9.png
■単価計算
〇実装
・自分で実装。基板30枚で5$、部品代50円/枚。実装時間約10分/枚。 = 2200円/30枚 + 300分/30枚 = 70円/枚+10分/枚
・PCBA 30koで43$(送料込) 単価1.4$ (Economy注文且つboard単価を上手く下げれる手順で選択した場合)
・PCBA 1000koで1117$(送料込) 単価1.1$
〇筐体化
・3Dモデル印刷時間
PLCPCBの価格抜粋
30枚
https://scrapbox.io/files/65902f9f046e0a0023407837.pnghttps://scrapbox.io/files/65902fbd7df9720024d8dc6a.png
1000枚
https://scrapbox.io/files/65902bcba5c8c1002430d53f.png
1/17 DMM.make AKIBA 第48回繋がる交流会
某格闘ゲームをフットパネルとモーションコントローラで遊べるようにした! 盛況だった! 満足。
https://scrapbox.io/files/65aa38eba409730023c80650.png
1/18 量産量産
実装 10分/個。(プリントは50分/3個だが 時間があるときにプリントすれば良いので特に気にしない)
https://scrapbox.io/files/65aa3909d8cd0e0024da0c9b.png
1/19
Unityで姿勢記録システムの作成。
unity projectが開かずに苦労したが、google drive先生のフォルダ名が日本語だったことが元凶....先生...。
COMポートはGUIのテキストボックスから入力しましょう。
https://scrapbox.io/files/65aa6bd555d7d00024062105.png
1/21
roll軸、pitch軸を表示し、30°毎に線をプロット。
右手で持った時のデフォルト姿勢がroll/pitch=0/0となるように調整
https://scrapbox.io/files/65adffb972b9ef00248b124e.png
残務: (@unityと記載が無いものはマイコン側に機能を持たせる)
roll/pitchの姿勢判定 →完了
yawは時間で累積誤差が生じるためroll/pitchの最小二乗法で姿勢判定を行う
機能:
姿勢の記録
記録姿勢の表示 (@unity)
最小二乗法による位置判定
クォータニオン姿勢判定 (!=roll/pitch/yaw)
yawを手動構成するので四元数の最小二乗法で姿勢判定を行う
機能:
姿勢の記録
記録姿勢の表示 (@unity) 3次元表示。矢印または点とラベルで表示する?
最初二乗法による位置判定
yawの手動キャリブレーションボタン追加
Mouseモードの実装
左クリック / 右クリック / カーソル移動→ カーソル移動を早くすること、クリックはpressで無くclick関数を使う→暫定実装した
姿勢登録方法の研究
マルチ機器(Windows/Android/Linux)のインターフェース検討
UnityのWebGLでWebシリアルできれば良いができない可能性が高い。
現状の姿勢登録インターフェースはWindowsのUnityアプリを使う
もしくはM5StickCの画面にroll/pitchグラフを描画する事で姿勢登録インターフェースをマイコンで完結させる
できない場合、データ送信をシリアルではなくピュアBlueToothもくはBT SPPで実装する
Webシリアル
Webシリアルでのバイナリ更新
Android ChromeシリアルFW書き込みは不安定かもしれない
Webシリアルコンソール
Mouse/Keyboard用、Gampad用の対応
モード切換え (優先度低)
暫定としてはbinary書き換えで対応するか?
PS/Switch用のGamepad機能実装
Motion ControllerとReceiverに分け、ReceiverはEPS32S3を使うか
通信は簡単なESP-NOWでも、Bluetoothでも良い
1/22 -23
地道に残務に取り掛かる。
...
roll/pitchの姿勢判定を行った。判定基準は最小二乗法ではなくユークリッド距離のほうが良さそうだったので後者を採用した。
赤点が現在姿勢、青点が登録姿勢。
ボタンを押したときに現在と登録の姿勢を比較して最も近い点が黄色になる。
https://scrapbox.io/files/65af39850a9269002387cac7.png
制約:
ピッチは - 80 ~ 80度の 160度範囲内でしか使えない。-90度以下、90度以上になると反転してしまいボタンHAT上向きと下向きの判定ができなくなってしまう。roll/pitch判定での制約であるため、改善するには周期ヨー校正クォータニオンを使う必要がある
バグ:
シリアル入出力しているためか時々リセットがかかってしまう → BLE送信時にGUI更新をやめるとリセット頻度がかなり減少した。
姿勢登録時にリセットがかかってしまう。inputが無い時にリセットがかかっているかもしれない。
マイコン側での姿勢判定のrollオフセットに誤りがあった。→修正済み。
追加機能:
ピッチ80(?)度以上は判定しないようにする → とりあえず点を灰色にした。
M5StickCの画面にroll/pitchグラフの描画
保存校正値で起動するように修正する → 実装した。
追加検証:
BLE Moues/Keyboard入力しながら、シリアル接続UI表示できるか。→可能
シリアル接続UI表示できると良いかもしれない
BTシリアルができるとベストだが先に有線シリアルで安定性を検証する
1/24
AI
Mouseモードの実装 → 実装した
起動時に固定ポートでシリアル接続するのではなく、起動時にシリアルポートを選択して動作するようにする
→実運用はこの手順で動作させるためこのようにし、Windows向けにbuildしたアプリで動作した。
Roll/Pitch登録モードがおかしいので治す事 → 修正した
https://scrapbox.io/files/65b127978cfe260023ec7436.png
1/25
AI
Mouseモード、Roll/Pitch登録モードを電源ボタン1秒長押しで切り替えるようにする →実装した
残務:
モード変更とイベントの住み分けの検討
Bluetooth接続無しでRoll/Pitch登録モードは使えるようにする事
第三ボタンでヨー校正と四次元ベクトル姿勢登録と判定
代表ゲーム用のモード作成
ユーザーがモード作成&Web共有できる機能@Unity?
オイラー角の特定姿勢角における座標変換の順番の入れ替え
ボタン機能の検討
1/28 Street Fighter VRの調査
己の拳で戦うリアル“ストリートファイト”体験! 「ストリートファイターVR シャドルー強化計画」先行プレイレポート
4/25
NIMBLE対応のESP32-BLE-Comboをfolkされている方がおられる
AndroidでBLE入力できないライブラリが多かった。
下記はできるが、BLE接続した状態で再度マイコンへ書き込みしてリセットすると入力できないことがある
結果、Flashサイズが90%から52%へ削減された。
Checking size .pio\build\m5stick-c\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM: = 11.3% (used 37064 bytes from 327680 bytes) Flash: ===== 52.0% (used 682193 bytes fr MotionMessage入力時に20%程度の確率で発生するクラッシュは、LCD出力を停止する事で解決した。
AI
・特定の姿勢入力を削除可能にしたほうが良い
・ストリートファイターや、その他ゲームモードで文字列入力キーを入力可能にするのが良い
4/26
UnityPath C:\Users\user\Documents\unity\M5C_Serial_Unity
BluetoothスタックNimBLEのPoewr変更方法:
BleCombo.cppにて
下記でBLEDeviceインスタンスを生成している。
void BleCombo::begin(void)
{
BLEDevice::init(deviceName);
BLEServer* pServer = BLEDevice::createServer();
NimBLEDevice.cppにて、setPowerがあることがわかる。
void NimBLEDevice::setPower(int dbm) {
ble_phy_txpwr_set(dbm);
}
4/27
ESP-Web-Tools
WebSerialでFirmware書き込み可能
nodejs app.jsの前に
mkdir C:\Users\user\Downloads\EspWebDownloader-main\EspWebDownloader-main\nodejs\public\firmwares
が必要。
SPIFFSは下記writeFile関数を用いて、SPIFFSimageを書き込めばよい。
await fs.writeFile(PUBLIC_FIRMWARE_FOLDER + app + "/" + APP_FNAME, JSON.stringify(json, null, "\t"));
SPIFFSiamgeはmkspiffsを使う
ESP-Web-toolsを一度Serialで書き込むと、WiFi設定をskipしてもBLEペアリングしてWiFi設定(WiFi over BLE)することができる。(しかしWiFi over BLEは現状不要。WiFi over Serialは他の100m走等のプロジェクトで必要になるかもしれない程度)
5/3 ConnectionIntervalについて
ConnectionIntervalを変更するにはBleCombo.cppで下記関数を使う必要があるかもしれない。
pServer.updateConnParams(uint16_t conn_handle,uint16_t minInterval, uint16_t maxInterval,uint16_t latency, uint16_t timeout)
5/19
AI
BLE多機種接続対応
5/x -6/8
WebSerialでSPIFFSへ書き込み
cd C:\Users\user\Downloads\squeezelite-esp32-install-main\node_squeezelite-esp32-install
node server.js
課題:
A.SPIFFSにmkspiffs -cで複数ファイルをパックしてsiffs.binを書き込むのではなく、ESPWebtoolで単一バイナリファイルをESP32に書き込む方法
B.spiffsに書き込まれる単一ファイルをespwebtoolで書き込めないので、純粋なWebSerialで送信してマイコン側でファイルにして書き込んでいます、がマイコン側でなぜか期待したデータをシリアル受信出来ていない。
→
const textEncoder = new TextEncoderStream();
が主悪の根源であり、writer.write(1)と数値を送っても、0x49が送られてしまう。
下記に変更するバイナリ送信され、0x1が送信されるようになった。
const writer = outputStream.getWriter();
C:\googledrive\マイドライブ\unity\M5C_Serial_Unity\M5C_Serialwrite2SPIFFS\
AI
1. spiffs.binを書き込み出来るのでこれで我慢する
2. Webシリアル経由でファイルを書き込めるようにする
3. 複数ファイルまとめたspiffs.binを作成して書き込めるようにする
参考)現状画面
https://scrapbox.io/files/66641c225b67b9001d9d81d3.png
参考) ETSP toolでの書き込み
https://scrapbox.io/files/66641c11b0d1a3001c43af29.png
6/9
矢印などのキーボード入力をWebから入力できるようにした。
C:\googledrive\マイドライブ\unity\M5C_Serial_Unity\M5C_Serialwrite2SPIFFS\html_keyinput
https://scrapbox.io/files/666550f6f6b5d4004f4ac610.png
キーマップ入力方法は、Web、Python、Unityの3環境が考えられるが、
やはり基本的にはWebベースで、M5CとWeb間で相互にbinファイルをやり取りできる必要がある。
https://scrapbox.io/files/666556ce52c0110039b8fbff.png
6/10
const writer = outputStream.getWriter(); に変更することでバイナリ送信できるようになったため、
AI
・M5Cから.binを吸いだして取得可能にする。
CF-SX4作業
下記データのcommit
Firmware書き込みGUI作成
書き込みフォーマット作成
2024/7 関連製品調査
PicoSwitch-WirelessGamepadAdapter
2024/7/22 TIB FAB Makers Challenge書類の作成
2024/07/22 家庭用ゲーム機への対応
PS5はセキュリティ保護のため通常のUSB OTGは使えないらしい?
GP2040-CEは使えそうに見える。
RaspiPicoのWebConfigに接続するには、GNDとP17をショートさせてからUSB接続する
Input ModeにPS5がある。
https://scrapbox.io/files/669dd25c9263ad001cc0f9df.png
20240723
G:\マイドライブ\unity\M5C_Serial_Unity
AI:
WebServer構築
letsnoteから最新ソースを持ってくる必要がある
Domain: burstmotion.tokyo
gitlabpages: 後で取る
SlimeVR動作確認 (無線は基本的にWiFi)
MotionControllerのformat設定
Webページ作成
WebSerialでのFirmware uploadがうまくできない場合
manifesetが更新されていない
F12>Networkタブ>Disable cacheでキャッシュ無効化する
https://scrapbox.io/files/66a244efc168c5001c27acab.png
merged.binを生成して書き込む
python -m esptool --chip esp32 merge_bin -o merged-firmware.bin --flash_mode dio --flash_freq 40m --flash_size 4MB 0x1000 bootloader.bin 0x8000 partitions.bin 0xe000 boot_app0.bin 0x10000 firmware.bin
binを再度作成し、manifestもデフォルトに戻す
7/25
課題:初期キャリブレーションがうまくできない
M5StickC initializing...OK
Read Cal:0, 0.000,0.000,0.000,0.000,0.000,0.000
7/26 サンプリング周波数設定が正しくないのが原因であった。修正済。
Web:
8/2
■クォータニオンの座標系調整 @ WebGUI
M5StickCをUnityで表現するには、下記式でありz/y軸が逆転し、wの符号が逆になり回転方向が逆となる。
q = new Quaternion(qx, qz, qy, -qw).normalized; (1)
理由は、UnityとM5StickCのZY座標系が異なるためであり、wが-である理由は各軸の符号が全て逆であるため。
実際に
q = new Quaternion(-qx,-qz, -qy, qw).normalized; (2)
と(1)と(2)は同じ回転となる。
座標系を絵で示す。
UnityのM5Cオブジェクトを後ろから見た図。参考までにサイズは(0.24, 0.12, 0.48)
https://scrapbox.io/files/66ac24c69e9c54001c0a2762.png
実際のM5StickCの座標
https://scrapbox.io/files/66ac2609051e10001de15437.png
UnityとThree.jsは座標系が異なり、Unityが先に述べたように左手系、Three.jsが右手系となる。
https://scrapbox.io/files/66ac289d065f8a001c36d0dc.png
参考:Unreal Engineの座標系
https://scrapbox.io/files/66f3c823c98464001c4352bc.png
https://scrapbox.io/files/66f3e5b54d1c70001ce6d49f.png
左手/右手系の座標変換は、xの符号を反転且つ、wの符号も反転すれば良い。
wの符号反転は各軸の回転を反対にするために必要となる、らしい。
(ジャイロ回転時の正負がどちらになっているかということも関係しているだろう。
最終的に、M5CをThree.jsで回転させるには
quaternion.set(-qx, qz, qy, qw)
となる。
■初期姿勢の調整
初期姿勢が変わっても座標系が変わるわけではない。
https://scrapbox.io/files/66ac2baa9e9c54001c0a7b33.png
8/4 初期姿勢(基準姿勢)の設定
上記はWebGUI上で任意に回転させたり、基準姿勢に戻すことを主眼としていたが、実際には端末側で初期姿勢(基準姿勢)に戻す必要があった。
方法としては、M5StickCの初期クォータニオン (w,x,y,z) = (1,0,0,0)であるため、Mahony Filterの保持クォータニオンにこの値を入れて初期化してやれば良いだけであった。
参考までに...とある基準クォータニオンQ1を現在のクォータニオンにかけることでオフセット回転させてWebGUI上で見た目の姿勢を合わせたとしても、Q1からの差が表現されるだけであるので意味がなかった。
任天堂特許調査
特許7511755
【0031】
また、前記プロセッサは、前記合体オブジェクトに含まれる前記仮想コントローラオブジェクトの前記仮想空間における姿勢が所定の姿勢となるように、前記合体オブジェクトのロール方向又はピッチ方向の姿勢を補正する姿勢補正手段、としてさらに機能してもよい。
特開2019-220059
VRの姿勢補正?
特開2017-004523
Switchの主に意匠に関する特許
特開2024-075657
よくあるDeepLearningによる操作
特開2022-124628
特許 有効 (登録公報の発行)
https://scrapbox.io/files/66acbbc17f2b11001c063ba8.png
8/6
PlatformIOでのESP32-BLE-CompositeHIDのコンパイルが通らない。
lib/ESP32-BLE-CompositeHID/KeyboardDevice.h:8:10: fatal error: Callback.h: No such file or directory
8/11 キーマッピング登録完了
8/12 コントローラ調査
8bitDo Micro Bluetoothはメガドライブ無しで直接Switchに接続できる。
M30 2.4G wireless gamepadは、メガドライブ経由での接続
M30 bluetooth gamepadは、Bluetoothペアリングでの接続となる
詳細比較は下記が詳しい。
基板もICも安い
ソフトは自力で何とかなる
あとはデザインとマーケティングと仲間集め
先に特許を取る
8/15 MPU6050 x ESP32C3動作確認
シリアルで 加速度3軸、ジャイロ3軸を送信するコード
i2cdevが必要。
https://scrapbox.io/files/66bdc70f34545d001d01cc67.png
Quaternionの関数も一応ある
uint8_t dmpGetQuaternion(int32_t *data, const uint8_t* packet=0);
uint8_t dmpGetQuaternion(int16_t *data, const uint8_t* packet=0);
uint8_t dmpGetQuaternion(Quaternion *q, const uint8_t* packet=0);
uint8_t dmpGet6AxisQuaternion(int32_t *data, const uint8_t* packet=0);
uint8_t dmpGet6AxisQuaternion(int16_t *data, const uint8_t* packet=0);
uint8_t dmpGet6AxisQuaternion(Quaternion *q, const uint8_t* packet=0);
uint8_t dmpGetRelativeQuaternion(int32_t *data, const uint8_t* packet=0);
uint8_t dmpGetRelativeQuaternion(int16_t *data, const uint8_t* packet=0);
uint8_t dmpGetRelativeQuaternion(Quaternion *data, const uint8_t* packet=0);
すずさんのコードはVScode(cursor)だとなぜかシリアル出力されないが、Teratermだと出力される
https://scrapbox.io/files/66bdcc15eee592001d1e1a79.png
8/25 PCBA検討
JLCPCBで50枚500$。ESP32はStandard PCBAになる。またStandart PCBAの場合70mm x 70mmにする必要があるためエッジレールがつけられる。
さらにコストを抑えるには、
1. V-Cutで複数枚実装にする
2.秋月で購入してESP32だけ手ハンダにする
3. XIAOに変更してPCBwayで製造する
今は2が無難。3はBLE-HIDのソフトを見直す必要がある。(USB-HIDにしたほうがそもそも良い)
https://scrapbox.io/files/66cac04c088a4900222b4bd6.pnghttps://scrapbox.io/files/66cac03871c362001d89bbd6.png
30枚 Economy で206$(ESP32無し)
https://scrapbox.io/files/66cacb1b78031b001de153f9.png
Economy10枚で頼みたいが、スイッチや書き込み用トランジスタが無いので部品集まり(9月5日以降)次第Standardで頼もう。
Economyは8$。Standardは片面25$(7mm x7mm以上)。面付けしたほうが安そうだがあまり変わらなさそうか
https://scrapbox.io/files/66cad1d05a00a6001c591fb0.png
とりあえず基板だけ頼んだ。ESP32を実装して書き込めるかだけ見るか。