TinyViewPlusで計測したラップタイムをFPVTracksideで使いたい

# 0.はじめに
今回は、TinyViewPlusとRotorhazardの連携をするところまで説明しますが、上手く出来れば、FPVTracksideとの連携は、単にRotorhazardと接続するだけなので、すんなりいくと思います。

実運用でどうかは未知数ですが、お試しいただければ幸いです。

# 1. TinyViewPlus
TinyViewPlusは、コース上にarUcoと呼ばれるマーカーを設置し、それを認識することでラップタイムを計測するソフトウェアです。MITライセンスで公開されており、WindowsおよびMacで動作するため、日本国内の室内Whoopレースでは広く利用されています。

単発のレースを行う分には申し分ない機能を備えていますが、大規模なイベントでは機能に不足を感じることがあります。そのため、TinyViewPlusにはOSC（OpenSoundControl）を介して、パイロット名やラップタイムなどの情報を他のレース管理ソフトウェアと送受信する機能を持っています。

大規模なレースを運営する場合、主催者は、独自のレースフォーマットに対応したレース管理ソフトを用意する場合が多いようです。

# 2. FPVTrackside
FPVTracksideは、タイミングシステムというより、レース管理ソフトといった感じのものです。ImmersionRC LAP RF、RotorHazard、Chorusなどのタイミングシステムと連携して動作します。（TinyViewPlusとは直接連携できません。これを連携させるのが今回の目的です。）FPVTracksideの特徴は以下の通りです。

* 幅広いレースフォーマットに対応（ユーザーからの多様な機能要望に応え続けた結果、さまざまなレース形式に対応）
* パイロット登録、予選・決勝などの各ヒート管理、結果管理が可能（TinyViewPlusは単体レースの管理のみで、大規模イベントの場合はExcelなどで管理が必要）
* ビデオ録画に対応し、レース中の各パイロットのVTX映像の表示だけでなく、レース終了後に再生・検証が可能（FPVTracksideの最も魅力的な機能）
* レース後の録画再生時に、画面を確認しながらラップタイムの修正が可能
* オリジナルのテーマを設定し、UIのカスタマイズが可能
* WebSocketを使用してOBSと連携可能

ただし、TinyViewPlusを利用している場合、以下の点で戸惑うことがあります。

* キーボードの配列がUS仕様のため、一部記号の入力時に異なる文字が入力される
* 日本語入力が直接FPVTracksideではできないため、テキストエディタで入力後にコピー＆ペーストする必要がある
* 音声出力のカスタマイズが可能だが、一部修正しきれない箇所がある
* レース開始時の「3 2 1 START!」の設定方法が良くわからない

# 3. 本題
FPVTracksideでレース管理を行いたい場合、タイミングシステムとしてIRC LAP RFかRotorHazardを使用することになります。これらはVTXからの電波を受信し、RSSI値を元にゲート通過を判定するシステムです。

しかし、使い慣れたarUcoマーカーを用いたラップ計測をしつつFPVTracksideを活用したい。

そこで考えたのが、RotorHazardのRX5808を取り外し、本来RX5808がRSSIを出力するところに、擬似的なRSSI信号を出力する方法です。

この方法の利点：
* 擬似的なRSSI信号（0〜1.1V程度の電圧）を用意するだけなので、FPVTracksideやRotorHazardのバージョンアップや仕様変更の影響を受けない。

ただし、ソフトウェア・ハードウェア的に無駄が多いという欠点もあります。

# 4. 完成したらこんな感じ
この方法を実装して、模擬的に1機分の映像を3台の受信機で同時に受信し、レースをしている感じにした動画がこちらです。

本来なら全く同じタイムになるはずですが、実際には異なります。同じ映像を受信していてもちらつくタイミングが異なったり、明るさに違いがあることが、ラップタイムのズレにつながっていると考えられます。

<iframe width="560" height="315" src="https://www.youtube.com/embed/jeTHzHxP-_c?si=51nISHTr6S33ChE9" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

# 5. この方法を実現するのに必要なもの
1. **Windows PC 1台目**（TinyViewPlusとRotorHazardを動作させる）
2. **Windows PC 2台目**（FPVTracksideを動作させる）
3. **VTX受信機**（UVC対応、3機でレースする場合は3台必要。例：EachineROTG、SKYDROID、FUAV など）
4. **HDMI → UVCコンバータ**（1台目PCの画面出力を2台目PCに取り込み、FPVTracksideのビデオソースとして利用するために使用）  
   [Amazonリンク](https://www.amazon.co.jp/gp/product/B0963JG2X3?ie=UTF8&th=1&linkCode=sl1&tag=nslab-22&linkId=ab0ddbc748184e92141f7365f692d793&language=ja_JP&ref_=as_li_ss_tl)
5. **基板**  
   * [回路図](https://github.com/zubon2003/TinyViewPlusAsSensors/blob/main/pcb/TVPAS.pdf)
   * [JLCPCB発注用データ](https://github.com/zubon2003/TinyViewPlusAsSensors/tree/main/pcb) 

   **必要な部品**：
   1. 抵抗 2KΩ（24本）※2.2KΩでも代用可
   2. 抵抗 1KΩ（17本）
   3. 抵抗 10KΩ（7本）
   4. Arduino Nano（ATmega328P搭載の無印Nano推奨）  
      [ファームウェア](https://github.com/zubon2003/TinyViewPlusAsSensors/tree/main/Arduino/tvpas)
   5. STM32C8T6搭載Bluepill + STLINKV2（C6T6はメモリ不足のため不可）  
      [ファームウェア](https://github.com/RotorHazard/RotorHazard/tree/main/firmware)  
      [STM32CubeProgrammer](https://www.st.com/ja/development-tools/stm32cubeprog.html)
   6. ピンヘッダ、ピンソケット（Arduino NanoやBluepillの取り外しが可能な構造推奨）
   7. USBシリアルコンバータ  
      [Adafruit CP2102N Friend](https://www.marutsu.co.jp/pc/i/2844423/)がファーストチョイスですが、[Pololu製](https://www.switch-science.com/products/6841)、[SwitchScience](https://www.switch-science.com/products/2782)でもよいうかもしれません。
   8. 2N7000(NCH FET)  

   **完成イメージ**：
   ![IMG_8227.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4072330/88a4d5ed-2974-4033-9223-c43c70349ffd.jpeg)

# 6. ソフトウェアのインストール（TinyViewPlus As Sensors 以下TVPAS）
1. [こちら](https://github.com/zubon2003/TinyViewPlusAsSensors/releases)より最新版のTinyViewPlusAsSensors.zipをダウンロードし、解凍
2. `bin`フォルダ内の `TinyViewPlusAsSensors.exe` を実行
3. 実行出来なかった場合、[Microsoft Visual C++ 再頒布可能パッケージ](https://aka.ms/vs/17/release/vc_redist.x64.exe)をインストール後、実行
4. Arduino NanoのCOMポートを調べ、`data`フォルダ内の `settings.xml` を開き、設定を更新
   ![settings.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4072330/5df94dbf-04b3-4473-995f-839c5b669984.png)

# 6. ソフトウェアのインストール（Rotorhazard）

https://github.com/rickgode/Windows-RotorHazard-Install
ここを参考にTVPASをインストールした1台目PCにRotorhazardをインストールします。

:::note
Rotorhazard 4.3.0以降の注意点
config.jsonは、従来 src\serverの中にありましたが、4.3からは、
C:\Users\{ユーザー名}\rh-data の中になりました。
:::

:::note
文字コードの設定
使ってるライブラリのバージョンアップのせいなのか、よくわかりませんが、rotorhazardがログファイルを記録する時に、エラーを吐いて、止まる現象を確認しています。~~（4.3.0からか？？）~~(pipでインストールライブラリのアップデートか、windows11のアップデートかどちらかの原因かはわかりませんが、4.2.0などでも発生する模様。以前はこんなことなかったので、何か変わったのでしょう。）

この場合、「コントロールパネル」→「地域」→（管理タブを選択）→（システムロケールの変更）→（ベータ:ワールドワイド言語サポートでUnicode UTF-8を使用(U)　にチェック）→システム再起動で正常動作を確認しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4072330/d46690c7-f6f8-4336-a0ed-54919f6e7976.png)

:::
config.jsonを編集して、CP2102Nのcomポートを指定することを忘れずに。
![rh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4072330/64504c22-08e9-4347-acaa-7e5e6525413d.png)
起動logを確認し、赤い線の所、設定したcomポートと接続されているか。Nodeが４つ認識されているかを確認してください。

最後に、デスクトップにrotorhazard起動用のショートカットをデスクトップあたりに作っておきましょう。
![shortcut.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4072330/0eda4b5d-29d3-4cb5-a52f-963eed2b2c30.png)
私の場合、C:\User Program\RotorHazard-4.2.1\以下にrotorhazardをインストールしているので、リンク先は以下の通りになります。

```リンク先
C:\Windows\System32\cmd.exe /K "cd C:\User Program\RotorHazard-4.2.1\ && python -m venv --system-site-packages .venv && .venv\Scripts\activate.bat && cd src\server && server.py
```

# 7. 動作確認
TVPASとRotorhazardを起動した後、webブラウザで http://localhost:5000 を開きます。

TVPASの４分割画面と、RotorhazardのNodeは、このように対応しています。
![1tvp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4072330/b15ffa42-7519-4eb1-a024-3b653f8df490.png)

それを参考にRotorhazardのFrequencySetupを実行してください。
![frequency.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4072330/f7433711-17a0-41be-99ce-665b348da845.png)


Sensor Tuningの画面を開いて、Arucoを認識させて反応があれば、導入は成功です。
![tuning.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4072330/3c7852b4-4a1d-4ae3-ba78-eea29471d1e1.png)

# 8.マーカーの認識状況と、RSSIの値

マーカーを認識した後、次のフレームでマーカーが消えると、TVPASは、Rotorhazardに、ゲート通過の信号を送ります。通過信号は、マーカーの認識状況によって違います。

 **有効マーカー(Valid Marker)**：
   マーカーが映像の中心部を向いている場合、有効マーカーとして認識されます。この場合、機体はゲートの輪の中心を飛行していると推定されます。
   
![valid.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4072330/0a3aef6e-cb3d-4924-82df-32dab82146b2.png)

 **無効マーカー(Inalid Marker)**：
   マーカーが映像の中心部を向いていない場合、無効マーカーとして認識されます。この場合、機体はゲートの輪の外側を飛行していると推定されます。

![invalid.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4072330/a6d35a8b-f2f6-4e8f-ac78-a4a5f5bedc8b.png)

**マーカー検出状況によるRSSIの違い**：
1. 最後に認識したマーカーが２個以上の有効マーカーで、無効マーカーは１つもない場合、
0.2秒間 rssi=160のパルスを出します。
![DETECTMPRMAL.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4072330/cf7e5392-a4a9-469e-8dff-51c7e7d0fe57.png)

2.２個以上の有効マーカーを検出したが、無効マーカーも検出している。
0.2秒間 rssi =110のパルスを出します。
![DETECTMIDDLE.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4072330/1292ba88-e504-493a-8e69-b468a7ef3aad.png)

3.有効マーカーを検出せず、無効マーカーだけ検出した。
0.2秒間 rssi=70のパルスを出します。
![DETECTLOOSE.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4072330/b778704d-f6f3-4d13-a84d-f8f2c78ea694.png)

**以上を踏まえ、各ノードのEnterAt ExitAtを設定してください**