# HaritoraX Wireless をバケット解析して SlimeVR のトラッカーとして使えるようにしたはなし :::success :bulb: この記事は[しょぼねこ Advent Calendar 2023](https://adventar.org/calendars/8779)の~~16 17 19~~ 21 日目の記事です ::: [TOC] :::spoiler 前談: HaritoraConfigurator がお粗末すぎる # HaritoraConfigurator がお粗末すぎる HaritoraX Wireless は Bluetooth を使って通信をします。その際、1 つの BD ドングルに対して 6 台のクライアントを接続し、100FPS でデータを送りつけるのでたとえ 6 台接続できたとしてもとても不安定になります。通信が不安定なだけならまだ問題はないのですが、Windows の Bluetooth 周りも巻き込んでおかしくなってしまうことが多いため使っていてあまり気分がいいものではありません。 また、HaritoraConfigurator 自体が落ちることもあるため安心して使えません。 ので、SlimeVR のトラッカーとして使えるようにブリッジを作ることにしました。 ![Q5UnABlyYa](https://hackmd.io/_uploads/SJojgmiUa.png) ::: # やりたいこと - HaritoraX Wireless を SlimeVR のトラッカーとして使いたい - WiFi 経由で複数 PC に分散して Bluetooth ドングルの負荷を減らしたい - ついでに安定性も向上させたい # ハードウェアとにらめっこ とりあえず中身を見たいので分解します。 ## 表面 ![IMG_0874](https://hackmd.io/_uploads/SyuicK-vT.jpg) SoC: nRF52832 IMU: BMI055 MAG: MMC5603NJ ## 裏面 ![IMG_0876](https://hackmd.io/_uploads/Hkzw2Fbwp.jpg) BMIC: BQ25170 # Bluetooth パケットの解析 ## 解析方法 Windows では[BTP](https://learn.microsoft.com/en-us/windows-hardware/drivers/bluetooth/testing-btp-setup-package)を使用することで、Bluetooth パケットをキャプチャして Wireshark で見れるようになります ## Service を 2 つ発見 ### 設定用サービスらしきもの UUID: `ef84369a-90a9-11ed-a1eb-0242ac120002` :::spoiler Characteristic たち #### FPS change `ef844202-90a9-11ed-a1eb-0242ac120002` | 01 | 02 | | ------ | ------- | | FPS 50 | FPS 100 | #### ToF change `ef8443f6-90a9-11ed-a1eb-0242ac120002` | 00 | 01 | | ------- | ------ | | ToF OFF | ToF ON | #### Sensor mode change `ef8445c2-90a9-11ed-a1eb-0242ac120002` | 05 | 08 | | ------ | ------ | | Type 1 | Type 2 | #### Tracker type `ef84c300-90a9-11ed-a1eb-0242ac120002` | 00 | 01 | | --------- | --------- | | Bluetooth | Exclusive | #### Dongle mode change `ef84c301-90a9-11ed-a1eb-0242ac120002` | 1 | 2 | 3 | 4 | 5 | 6 | | ----- | ------ | ------- | ------ | ------- | --- | | CHEST | KNEE L | Ankle L | KNEE R | Ankle R | HIP | #### Auto drift type change `ef84c305-90a9-11ed-a1eb-0242ac120002` Default 1 None -> 0 ##### Accell true -> +1 ##### Gyro true -> +2 ##### Magnetic true -> +4 ::: ### トラッカーデータが送られてくるサービス UUID: `00dbec3a-90aa-11ed-a1eb-0242ac120002` :::spoiler Characteristic たち #### IMU Data `00dbf1c6-90aa-11ed-a1eb-0242ac120002` 14Bytes(ToF ありなら 16Bytes)のデータが送られてきます LittleEndian です Accel は 128 倍されています | 1-2 | 3-4 | 5-6 | 7-8 | 9-10 | 11-12 | 13-14 | 15-16 | | ----- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | | Rot X | Rot Y | Rot Z | Rot W | Acc X | Acc Y | Acc Z | ToF | #### Magnetometer accuracy `00dbf306-90aa-11ed-a1eb-0242ac120002` #### Mainbutton pushed `00dbf450-90aa-11ed-a1eb-0242ac120002` #### Secondarybutton pushed `00dbf586-90aa-11ed-a1eb-0242ac120002` ::: # ブリッジクライアントを作る ## 技術選定 マルチプラットフォームで動作してほしいので、Rust で作ることにしました。 いい感じのマルチプラットフォームの Bluetooth ライブラリを探したところ、[btleplug](https://crates.io/crates/btleplug)というものがありましたのでこれを使うことにしました ## 実装 SlimeVR のパケットフォーマットは[SlimeVR-Tracker-ESP](https://github.com/SlimeVR/SlimeVR-Tracker-ESP)を見て実装しました 電池残量をSlimeVRに送るとSteamVRにも送ってくれることが判明したので、XSOverrayの手首の表示から電池残量を確認することができるようになりました。嬉しい誤算です SlimeVRにすることで補完処理が早くなったのか、本家HaritoraConfiguratorよりもキビキビと追従するようになりました ![slimevr_ZJl6KHv17T](https://hackmd.io/_uploads/H1dqtqZDa.png) ![VRChat_2023-12-21_19-51-10.670_7680x4320](https://hackmd.io/_uploads/SJf0YqZw6.jpg) # おわりに HaritoraX Wirelessからは重力を含んだ重力加速度計のデータが送られてきており、回転から重力加速度を計算してセンサーのデータから重力を除去し、加速度のみにする必要があります。数学をさぼってきたつけが回ってきました。 SlimeVRの姿勢推定が優秀なので回転のみでもほぼ問題なく使えますが、やっぱり加速度もほしいので、もうちょっとソフトウェアを改善していきたいです。 ~~もうちょっとまともになったらオープンソースにしたいと思います。~~ :::info :bulb: まともじゃないけどソース公開しました https://github.com/sim1222/haritorax-slimevr-bridge :::