Dropbox

TinySA UltraをPCから使う

お手軽にVTXの電波を見るツールとして以前紹介したTinySA Ultra(Ultraと付かない無印だと周波数レンジが狭いので注意)ですが、以前はPCから操作するプログラムの出来が今ひとつどころか意図した動きを全くしない代物でした。改めて調べてみたらQtTinySAというオープンソースなプログラムが出来ていました。

QtTinySAはUbuntuでもWindowsでもMacOSでも稼働するプログラムです。私はMacOS版を試しました。
細かいところにまだ不具合がありそうな気もしますが、普通に使えますしレスポンスもとても良いです。使い方を極めたわけではないのでごく簡単な説明だけを書いておきます。

[ 設定 ]

name,preset,startF,stopF,value,colour
vtx,other,5600000000,6000000000,True,green,

上の内容をtinsavtx.csvみたいな名前で保管しておきます。

Setting画面のImportでこのCSVを読み込むと周波数レンジが簡単に設定できます。

[ 画面 ]

TinySA UltraをUSBで接続してRunボタンを押すとスキャンを始めます。
画面の詳しいことは分からないまま使えてしまったので細かい説明はできません。
ざっと眺めていくと、左上からアッテネーターと高調波除去、続いてサンプリング関連。Tracesの部分、この画面の設定ではブルーの線は現在の数値、オレンジは過去の最大値を示します。
下部一番左はWater Fallの設定です。左側のスライダーで大きさが変更できます。その右側で何やら設定が変わるのですが、何をやっているのかよく分からなかったです。
下部左半分が周波数レンジです。ここのセレクターでother, vtxというのが選択すると上の設定が読み込まれます。
下部右側はマーカーなのですが、これも今ひとつ動作不明でした。

FPV 4機同時飛行に向けてのスタディ

ドローンレースでは、複数のドローンが同時に飛行するため、映像送信機(VTX)の電波が互いに干渉し、映像が乱れる問題が常に付きまといます。この電波干渉の主な原因の一つが「IMD(相互変調歪)」です。特に屋内環境での影響が顕著です。

日本のアマチュア無線のバンドプランが変更されたため、従来のE1/F1/F4チャネル以外のチャネルを使用し4機同時飛行の可能性が出てきました。やみくもにチャネル選択するわけには行かないのでIMDを算出し影響の少ない組み合わせを見出すことにしました。

この記事では、IMDの問題を分析し、より安定した映像伝送を実現するための最適な周波数チャンネルの組み合わせを探る技術的な挑戦について、その経緯と結論を分かりやすく解説します。

解説は長くなるので結論を先に書いておきます。

[ 結論 ] 現時点での最適な4波組み合わせ
長い解析とテストの結果、現時点で最も有望と考えられるのは、以下の周波数組み合わせです。

1. (E1) 5705MHz, (A8) 5725MHz, (A5) 5785MHz, (F5) 5820MHz
2. (E2) 5685MHz, (E1) 5705MHz, (F3) 5780MHz, (F5) 5820MHz

この組み合わせは、SaqooshaさんのIMDAvoiderから派生した計算ツール(IMDAvoider3)によって導き出された7つの候補の中から、実際の電波を使ったテストを経て選ばれました。

1番と2番ともに自宅でのテスト結果はほとんど同じでした。ただしBetaflightのLED機能でVTX周波数によりLED色を変えることを考えると1番が好ましいという理由により、私の推奨は1番のE1/A8/A5/F5ということにしました。

小学校の体育館での飛行テストも成功しており、実用的なレベルにあると考えています。ただし、自宅での詳細なテストでは、特定のチャンネル(E1)に時折ごくわずかなノイズが見られるなど、まだ改善の余地があることも分かっています。

[ IMD(相互変調歪)とは? ]
IMDとは、複数の電波が混ざり合うことで、本来存在しないはずの不要な周波数の電波(歪み)が発生する現象です。

二次IMD: 2つの周波数の組み合わせで発生する歪み。
三次IMD: 3つの周波数の組み合わせで発生する、より複雑な歪み。

この歪は比較的簡単な計算で求めることが出来ます。

[ なぜ新しい組み合わせが必要だったのか? ]
これまで、周波数の組み合わせ評価には「IMDTabler」というツールが広く使われていました。しかし、このツールが推奨する4波の組み合わせをテストしたところ、特定のチャンネルで映像が著しく乱れるという問題が複数のチームから報告されました。

IMDTablerは二次IMDのみを評価していましたが、報告された問題は、他の3つの周波数が引き起こす「三次IMD」が原因でした。具体的には、(F5) 5820MHz – (A8) 5725MHz + (R2) 5695MHz という計算で、問題のチャンネルの周波数である (B4) 5790MHz が生成されてしまっていたのです。
この事実はムッシーさんのXの投稿で指摘されています。また、この現象は自宅でのテストでも簡単に再現できました。

[ 新たな評価アプローチ ] IMDAvoider3
この問題を解決するため、私は新たな評価アプローチを取りました。

二次IMDと三次IMDの両方を考慮する:
三次IMDは二次IMDに比べて信号が非常に弱いことが知られています。これについてはIMDAvoiderの作者であるSaqooshaさんが詳細なスタディ結果を文書(https://github.com/Saqoosha/IMDAvoider/blob/main/docs/IMD_Research_Document_JP.md)にされています。興味がある方はご一読ください。

そのため、まず従来の計算方法により二次IMDでの成績が良いものから順に並んだリストを生成する。そして三次IMDによって生成される歪みが、使用したいチャンネルの周波数に近すぎる組み合わせを除外するという方法を取りました。つまり単純に評価点に加えるのではなく、「悪影響を及ぼす組み合わせを排除するフィルター」として利用しました。

閾値(しきいち)の設定: どの程度周波数が近ければ「悪影響」と判断するかの基準(閾値)を複数パターンで試し、机上の計算と実機テストの結果を突き合わせ、最適な値を探りました。
このアプローチを実装したのが、IMDAvoider3です。このツールによって、より実践的な評価が可能になりました。

[ 自宅での詳細テストから見えたこと ]
選ばれた組み合わせ(E1/A8/A5/F5)を自宅で詳細にテストしたところ、いくつかの興味深い点が分かりました。
– 4つの電波を同時に出すと、E1チャンネル(5705MHz)に時折、飛行に支障はないレベルのチラつきが見られた。
– VTXの個体差を排除するため機体を入れ替えてのテストも行い同様の結果を得た。
– E1-5705MHzとA8-5725MHzは20MHzしか離れていないので、この2波だけでテストを行なっても全く問題はない。
– E1の電波を停止してA8/A5/F5の電波を出してE1のモニターを監視するとほとんどの場合正常なスノーノイズだが時折明らかなノイズも現れる。

– 同様のテストで、A8チャンネルにもノイズが確認された。
E1(5705MHz)とA8(5725MHz)は周波数が20MHzしか離れていません。この近さが影響している可能性も考えられますが、現在の計算方法ではこの差を説明できていません。

この観測が事実であればE1/A8とA5/F5にコンディションの差があることになります。レースでの公平性を考えると、これは問題となるかもしれません。

[ スペクトラムアナライザーでの観測 ]
安価な簡易スペクトラムアナライザー「TinySA Ultra」を使い、IMDが視覚的に観測できるか試しました。

二次IMD: 2波を送信すると、それらが干渉して発生した歪みが別のチャンネルに現れる様子がはっきりと観測できました。

Screenshot


VTXよりR2-5695MHzとR3-5732MHzの電波を発出し、R4-5769MHzに相互変調歪による信号が現れた様子が見られた。
R4の受信機にもR2とR3の画像が観測された。

三次IMD: 問題となった3波(R2-5695MHz, A8-5725MHz, F5-5820MHz)を送信しても、受信機側(B4-5790MHz)では影響が見られるものの、スペクトラムアナライザー上では明確な変化を捉えることはできませんでした。

Screenshot


この結果から、三次IMDは二次IMDに比べて信号が極めて微弱であることが改めて裏付けられました。同時に、安価な機材で4波同時飛行の評価を網羅的に行うことの難しさも分かりました。

まとめと今後の展望
今回の分析とテストにより、三次IMDを考慮した新しい評価軸で、有望な4波の周波数組み合わせを見つけることができました。

しかし、この組み合わせが本当に「最適」かどうかを判断するには、より多くの環境、多くのパイロットによるテストが必要です。この記事が、ドローンレースコミュニティにおけるさらなる議論や、新しいアイデアの創出に繋がることを期待しています。

皆さんのテスト結果や、別の角度からのアプローチなども、ぜひ共有していただけると幸いです。

Hailo AIモデル変換環境の構築:Dockerイメージを活用した導入

以前の記事「Rasbberry Pi AI Kit用に画像認識モデルを作る」に従い、Hailoソフトウェア群をUbuntu環境で再構築し、モデル変換の準備をしようと試みましたが、いくつかの問題に直面し、構築を断念しました。主な問題は、hailo_model_zooの適切なバージョン(dataflow compiler 3.29.0に対応するもの)をインストールできないことでした。当時、GitHubから最新版をクローンしていましたが、タグ指定で過去のバージョンをダウンロードしてもうまくいかず、クローン後に適切なコミットに巻き戻す必要があるようでした。

そこで、手動での構築を試みるよりも、配布されているDockerイメージを利用することにしました。

https://hailo.ai/developer-zone/software-downloads/

Hailo AI Software Suite – Docker のVersion 2024-10を使用しました。最新版は、既に構築済みのRaspberry Pi+AI Kit環境との互換性がありません。

導入に使用したPCは、古いIntel NUCで、メモリは16GBです。OSはUbuntu 22.04.4 LTSにDockerをインストールしています。

ダウンロードしたzipファイルには、Dockerイメージと起動スクリプトが含まれています。このスクリプトを実行することでDockerが起動します(二度目の起動には–resumeもしくは–overrideオプションが必要です)。

./hailo_ai_sw_suite_docker_run.sh
推奨メモリが32GBであることやGPUがないといった注意書きはありますが、問題なく起動しました。

hailo -h と hailomz -h でプログラムが動作することを確認できました。

その後は、以前の記事とほぼ同じ手順で進めます。

まず、COCOデータベースを導入します。

cd hailo_model_zoo
python hailo_model_zoo/datasets/create_coco_tfrrecord.py val2017
python hailo_model_zoo/datasets/create_coco_tfrrecord.py calib2017

次に、フォルダーの修正が必要です。

cd /local/shared_with_docker/.hailomz/models_files/coco/
ln -s 2023-08-03 2021-06-18

実環境とのデータ連携は、shared_with_dockerフォルダーで行います。

最後に、以下のコマンドを実行するだけで、モデル変換が完了します。

hailomz parse --hw-arch hailo8l --ckpt ./best.onnx yolov10s
hailomz optimize --hw-arch hailo8l --har ./yolov10s.har yolov10s
hailomz compile yolov10s --hw-arch hailo8l --har ./yolov10s.har

ELRSの信号強度と品質の監視

日本でのロングレンジ飛行は一般的ではありませんが、より遠距離での飛行や電波環境が不安定な状況での飛行を安全に行うための設定例を紹介します。実際に屋外でやや距離を出しても、通常の設定(500Hz, 100mW)でも信号強度は常に安定しており、通信品質に問題はありませんでした。よってELRS設定は過度に気にする必要はありませんが、より安全な飛行のために参考にしていただければと思います。

内容的にはOscar Liang氏のブログを参考にしたものになります。
https://oscarliang.com/lq-rssi/

[ ELRSの設定 ]
– パケットレート: 250Hz

通常は500Hzを使用していますが、屋外での安定性を高めるため、パケットレートを下げて感度限界を下げる設定に変更しました。出力は最大に設定します。

[ OSDの表示設定 ]

– リンク品質

– RSSI値(dBm)

ExpressLRSの通信状態を監視するには、この2つの指標を同時に表示することが重要です。

RSSI値は信号強度を示します。ExpressLRSの公式ページでは、パケットレートごとの許容信号強度が公開されています。
https://www.expresslrs.org/info/signal-health/#rf-mode-indexes-rfmd
ExpressLRS Luaスクリプトでパケットレートを選択する画面にもこれは表示されます。

250Hzを選択した場合、感度限界は-108dBmです。飛行中はこの値を下回らないように注意が必要です。

リンク品質の表示について:
– 左側の数値:現在のパケットレート
– 右側の数値:有効パケットレート(通常100%)

有効パケットレートが80%を下回る場合は、通信状態の悪化が考えられるため注意が必要です。

[ OSD Warningの設定 ]
以下の警告を設定することをお勧めします:
– RSSIが-98dBm以下 (250Hzの感度限界-108dBmに対し-10dBmのマージンを持たせた設定)
– リンク品質: 60%

OSD画面で警告にチェックを付けます。

以下のCLIを投入します。

set osd_link_quality_alarm = 60
set osd_rssi_dbm_alarm = -98
save

[ EdgeTXのテレメトリアラーム設定 ]

この設定はオプションです。

これらの設定により、安全なセミロングレンジ飛行が可能になります。特にRSSIの監視は重要で、通信状態の悪化を早期に検知できます。

FPVドローンのVTXチャネル変更をプロポスイッチで簡単にする方法

FPVドローンのVTXチャネルを変更する際、通常はOSDメニューやLUAスクリプトを使用しますが、その手順は少し複雑です。
この記事では、プロポのスイッチを使って、VTXチャネルの切り替えを簡単にする方法を説明します。


[ プロポスイッチを使う利点 ]

  1. OSD/LUAスクリプトの問題点
    OSDメニューやLUAスクリプトでの変更は手間がかかります。
  2. プロポスイッチの長所
    スイッチの位置で直接チャネルが切り替わるため、直感的で素早い操作が可能です。
  3. スイッチの選び方
    日本では現在E1、F1、F4の3チャネルが使用可能です。そのため、3ポジションスイッチが適していますが、誤操作を防ぐためにS1のポットを使用することにしました。(一度アームした後は変更出来なくなるようなので誤動作の心配はあまり必要ないかもです)

[ 設定手順(プロポ側)]

  1. スイッチの受信機割り当ての確認
    a. Betaflight ConfiguratorのReceiverタブでS1が受信機のAUXチャネルに割り当てられているか確認します。
    b. 未設定の場合、MIXESを使ってスイッチをAUXチャネルに割り当てます。
    手順例(プロポによって異なる場合があります):
    – MIXESメニューを開きます。
    – 空いているCHを選び、Source をS1、Weight を100%に設定します。
  2. LUA Script(ExpressLRSなど)からVTXの変更機能を無効にします。

[ 設定手順(Betaflight側)]

  1. S1の動作確認
    Receiverタブで、S1の動作範囲、方向、AUX番号を確認します。
    例:AUX7、動作範囲は左端1000、中央1500、右端2000
  2. VTX設定の確認
    Betaflightの Configuration > VTXタブで現在の設定を確認します。
  3. CLIタブで以下のようなコマンドを入力します:
    vtx 0 6 3 1 1 900 1200
    vtx 1 6 4 1 1 1300 1700
    vtx 2 6 4 4 1 1800 2100
    

    コマンドの形式:
    vtx [設定番号] [AUX] [バンド] [チャネル] [パワー] [AUX値下限] [AUX値上限]
    – 設定番号:0から始まる連番
    – AUX:AUX番号から1を引いた値(例:AUX7なら6)
    – バンド:3=BOSCOM_E, 4=FATSHARK
    – チャネル:VTXテーブルのチャネル番号
    – パワー:1=25mW
    – AUX値:プロポのスイッチ位置に対応する値の範囲

    この設定により、S1の位置に応じてVTXチャネルが以下のように切り替わります:
    – 左端:E1チャネル
    – 中央:F1チャネル
    – 右端:F4チャネル

これで、プロポのS1スイッチを操作するだけで、簡単にVTXチャネルを切り替えることができます。

WTW四国のドローンレース集計システム実装例

昨年のNaka Drone Racing 2024以来育ててきたGoogle Sheetによるレース集計システムを紹介します。まだまだ未完成ですが、いくつかのレースを経て役に立つものになりつつあります。またTinyViewPlus v0.9.33 beta6の通知機能を利用しリアルタイムな更新も可能となりました。

その概要とプログラム全てを公開いたします。使い方や細かい動作までは説明しきれないので、勝手に参考にしてもらったり、使える部分は再利用をしてください。という放任主義です、悪しからず。

[ システムの概要 ]
WTW Tokushimaのドローン部長による場内PAおよび配信システムの一部であるTinyViewPlusと集計操作用のMacBook Airを連携して行います。

流行っているのでChatGPTに書いてもらった絵です。何となくな感じであまり正確にシステムを表現しているとは言えません。

[ oscrcv.py ]
oscrcv.pyスクリプトはTinyViewPlusからのOSCプロトコルによる通知で受信したデータをGoogle SheetにPOSTします。データの受信を確実にするためにoscrcv.pyはTinyViewPlusが稼働しているWindows PC上で稼働するようにしています。また予選、決勝などのレース毎(あるいはGoogle Sheetの切り替え)にoscrcv.pyの起動パラメータを指定して立ち上げ直す必要がありますので、MacBook AirからsshでTinyViewPlusのPCにログインして行なっています。

# oscrcv.py
import argparse
import math
from pythonosc import dispatcher
from pythonosc import osc_server
import json
import requests
import time
import datetime

url = ""
url1 = "https://script.google.com/macros/s/AKfycbzDg0hHdgDlE_qYEngvYBBqYDummyssJ_sA_fmstVcXgyyx-KMem32_lbSoC8gdAhgg/exec"
url2 = "https://script.google.com/macros/s/AKfycbw7_T9Z4eWVWbybGm2IhXsazDummyRVwOjrQ_OcuowXC2yV-onDk0ppOxefZdZNQHQh/exec"

sheetname = ""
sh1 = "練習"
sh2 = "予選ヒート1,2"
sh3 = "予選ヒート3,4"
sh4 = "勝ち上がり戦入力"

def timeformat(seconds):
    td = datetime.timedelta(seconds=seconds)
    minutes, seconds = divmod(td.total_seconds(), 60)
    return f"{int(minutes):02d}:{seconds:05.2f}"

def oschandle(addr, *args):
    global url
    global sheetname
    print(addr)
    print(args[0])
    print("")
    timestamp = time.strftime('%Y/%m/%d %H:%M:%S')

    args3 = args4 = ""
    if (len(args) > 3):
        if (isinstance(args[3], float)):
            args3 =  "{:05.2f}".format(args[3])
        else:
            args3 =  args[3]
    if (len(args) > 4):
        if (isinstance(args[4], float)):
            args4 =  timeformat(args[4])
        else:
            args4 =  args[4]

    data = {
        "timestamp" : timestamp,
	    "addr" : addr,
	    "arg0" : args[0],
        "arg1" : args[1] if (len(args) > 1) else "",
        "arg2" : args[2] if (len(args) > 2) else "",
        "arg3" : args3,
        "arg4" : args4,
        "sheetName" : sheetname
    }

    print(json.dumps(data))
    # json.dumpでデータをJSON形式として扱う
    r = requests.post(url, data=json.dumps(data))
    print(r)

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--ip",
                        default="", help="The ip to listen on")
    parser.add_argument("--port",
                        type=int, default=4001, help="The port to listen on")
    parser.add_argument("--url",
                        default="1", help="1 = Sprint, 2 = Endurance")
    parser.add_argument("--sheet",
                        default="1", help="1 = 練習, 2 = 予選ヒート1,2, 3 = 予選ヒート3,4, 4 = 勝ち上がり戦入力")
    args = parser.parse_args()

    if (args.url == "1"):
        url = url1
    else:
        url = url2

    if (args.sheet == "1"):
        sheetname = sh1
    elif (args.sheet == "2"):
        sheetname = sh2
    elif (args.sheet == "3"):
        sheetname = sh3
    else:
        sheetname = sh4

    print("URL: ", args.url)
    print("Sheetname: ", sheetname)

    dispatcher = dispatcher.Dispatcher()
    dispatcher.map("/*", oschandle)

    server = osc_server.ThreadingOSCUDPServer(
        (args.ip, args.port), dispatcher)
    print("Serving on {}".format(server.server_address))
    server.serve_forever()

[ Google Sheetでの処理 ]
oscrcv.pyからのPOSTはGASで受信します。送られてくるデータは2種類あります、一つはLapデータでリアルタイムなレース状況の更新に使います。

もう一つはレース結果で、レースの集計に使います。

集計作業は結果入力シートにデータを集積し集計プログラムシートにあるボタンからGASを起動して順位を別のシートに記入します。詳細は書きませんが、勝ち上がり戦の組み合わせまでは自動で行います。勝ち上がり戦の集計以降は手作業で行なっています。
予選の順位は周回数が多い方を上位とします。同一周回数の場合は合計時間が短い方が上位となります。全く同じ成績であった場合の処理は入っていませんのでデータの目視確認が必要となります。

WTWShikokuDroneRaceWorksheet
このワークシートはRead Onlyで共用しています。ご自身のGoogl DriveにコピーするとGASの内容も読めるようになります。

TinyViewPlus->Python Script->Google Sheetへの連携の詳細は別記事「Tiny View Plusの外部通知機能を試す」に書いていますので参照願います。

[ ディスク共用 ]
OSCのデータによる集計に問題があった時のためにTinyViewPlusのResultフォルダーをMacBook Airからアクセスできるように共用しています。Google SheetのGASは集計データのファイルからの読み込みにも対応しています。この部分はninjaMoonLightさんが書かれたものです。

[ TinyView Plusのバイロット名 ]
集計作業とは別ですがWindows上のTinyView Plusのカメララベル(パイロット名)のセットもMacBook Airから行なっています。使用しているプログラムはGithubにて公開しています。
https://github.com/nkozawa/tvpilotnames

以上です。まだ完全自動とは言えませんが、そこそこ役に立つものになりました。また進歩があれば何かの形で公開したいと思います。

Tiny View Plusの外部通知機能を試す

Tiny View Plus v0.9.33より外部への通知機能が搭載されました。この機能はWTW香川からのリクエストに作者の浅野さんが答えてくださったものです。本来の目的はラップ毎にLEDを点灯させるなどのレースの演出に使うことでした。

通知のされるのはレースの開始、終了、ラップなどです。詳細はドキュメントをご覧ください。
ラップの通知にはラップ数とタイムの情報も含まれているので、これを利用して集計も出来そうなのでテストをしています。

テストの様子です。右側のラップ数をグラフ的に表示するアイデアはninjaMoonLightさんから頂きました。

[ 私のテスト環境においての情報の流れ ]
– Windows上のTinyViewPlusからOSCプロトコルで通知を発信。
– macOS上のPythonで受信し、データをGoogle SheetにPOSTする。
– Google ScriptでPOSTを受けてSheetに書き込む。

ここでは、一番基本となる部分だけを紹介します。

[ Google Sheet側の設定 ]
– Googleドライブで新規のスプレッドシートを作ります。
– “拡張機能”から”Apps Script”を開きます。
– スクリプトは以下のようになります。

const spredSheet = SpreadsheetApp.getActiveSpreadsheet();
const sheet = spredSheet.getSheetByName('シート1');

function doPost(e) {
  var data = JSON.parse(e.postData.getDataAsString());
  sheet.appendRow([data.timestamp, data.addr, data.arg0, data.arg1, data.arg2]);
}

– 左側のメニューの”サービス”で”Google Sheets API”を追加します。

– 上の方にある”デプロイ”から”新しいデプロイ”を実行します。種類の選択は”ウェブアプリ”にします。アクセスできるユーザーを全員にしておきます。

– デプロイ時にアクセスの確認が出ます。”アクセスの承認”を押します。
後は、いつもの手順ですが、少々ややこしいです。画面の流れだけ示しておきます。

アカウントを選択

Advanced(詳細)をクリック

Goto [プロジェクト名]をクリック

Allowをクリック

– 完了するとウェブアプリのURLが払い出されますのでコピーしておきます。URLを知る人は誰でもPOST出来るので注意が必要です。

– スクリプトを変更した時は、”デプロイを管理”からバージョンを更新します。URLは変わりません。

[ パソコン側の設定 ]
Python3が動けば、どんなパソコンでも大丈夫なはずです。
OSCのためのライブラリーが必要です。
pip install python-osc
プログラムは以下の通りです。url=のところに先にコピーしたウェブアプリのURLを入れます。

from pythonosc import dispatcher
from pythonosc import osc_server

import json
import requests
import time

url = "https://script.google.com/macros/s/xxxxx/exec"
ip = ""
port = 4001

def oschandle(addr, *args):
  print(addr)
  print(*args)
  timestamp = time.strftime('%Y/%m/%d %H:%M:%S')

  data = {
    "timestamp" : timestamp,
    "addr" : addr,
    "arg0" : args[0],
    "arg1" : args[1] if (len(args) > 1) else "",
    "arg2" : args[2] if (len(args) > 2) else ""
  }
  r = requests.post(url, data=json.dumps(data))
  print(r)

if __name__ == "__main__":

  dispatcher = dispatcher.Dispatcher()
  dispatcher.map("/*", oschandle)

  server = osc_server.ThreadingOSCUDPServer((ip, port), dispatcher)
  print("Serving on {}".format(server.server_address))
  server.serve_forever()

[ Tiny View Plusの設定 ]
最新のTiny View Plusを導入します。記事を作成時の最新版はv0.9.33-beta3です。
ドキュメントに書かれているように一度Tiny View Plusを起動後に作成されるdata/settings.xmlを編集してOSC通知の送信先IP Addressを変更します。

<oscMonitor>
    <enabled>1</enabled>
    <host>192.168.1.255</host>
    <port>4001</port>
</oscMonitor>

IP Addressは私はサブネットに対するブロードキャストにしました。受信するパソコンのIP Addressを指定すべきかも知れませんが、サブネット内の複数の機器で同時に情報を受信できることを狙ってブロードキャストIP Addressを試しています。
IP Addressの設定後にTiny View Plusを起動します。

これで準備完了です。Pythonのプログラムを起動し、Tiny View Plusでレースの開始やラップを記録し、データがGoogleシートに記録されれば成功です。ここまでくれば後は、ゴリゴリとGASを書いていけば集計作業の省力化が可能と思います。ただしOSCはUDPで送られてきますので、データが必ず受信されるとは限りませんのでデータが欠損した場合のことは考慮しておく必要があります。また、OSの実装にもよると思いますがデータの処理される順序が入れ替わることもありますので注意が必要です。

Hummingbird V3.1 RaceSpecのLED Strip設定とその他諸々

Newbeedrone Hummingbird V3.1 RaceSpecは箱だしで16g台の軽さとその重量の軽さ以上に感じられる軽快な飛びでレーサーの期待を集めています。

[ LED Strip設定 ]
マッドさんが最初の頃にFC上のLED_StripがどこであるかをXで公表されていました。その時はRGB LEDをそこに接続するだけで使えていたそうです。ところが私の購入した機体およびファームウェア(betaflight_4.5.0_HUMMINGBIRD_RS_7498f3807_KAACK_Oct252024.hex)ではLEDとしての動作をさせることとができませんでした。調べてみるとLED_Stripのリソースが割り当てられていませんでした。そこで回答です。


左の写真で黄色いリード線を接続しているところがLED_Stripになります。そしてリソース関係の設定は以下のコマンドをCLIに投入します。

resource LED_STRIP 1 B01
timer B01 AF2
dma pin B01 0

LEDの数は32灯までです。
余談ですが、HummingBird V3 FCにはFC上に4灯のLEDが載っていました。

RaceSpecではこのLEDチップが取り付けられていません。そのランドを利用して外付けのRGB LEDを取り付けることにしたのです。またメーカーとしてはLEDチップを外したのでリソースからLED_Stripを削除したのは正しいことだと言えます。

[ USBコネクター ]
USBコネクターがもげてしまったと言う話しを聞きました。


上の投稿の通りでUSBコネクターのハウジングの足がFC基板のスルーホールに刺さっているだけで半田付けされていません。半田を流し込んでみました。おそらく、これで丈夫になると思います。

[ PID ]
色々な人の意見を総合するとメーカー設定のPIDは正しく出ていない気もします。ただしBlackboxログが取れないので数値での検証は出来ません。またフレームも極端に柔らかいことも考えるとなかなか難しいです。私は別の65機で調整がうまくいったPIDを使用して様子を見るつもりです。

コザックのBFチューン講座で使うBlackBoxログ

zoomセミナーアーカイブ

Blackbox解析ツール
https://blackbox.betaflight.com/
https://github.com/bw1129/PIDtoolbox

コザックのBFチューン講座の中で紹介するBlackBoxログデータです。リンクを右クリックして保存してください。

フィルター説明用データ:
https://www.nkozawa.com/blackbox/btfl_flt1.bbl – プロペラ破損
https://www.nkozawa.com/blackbox/btfl_flt2.bbl

PDバランス説明用データ:
PIスライダー0.50/0.55 https://www.nkozawa.com/blackbox/btfl_PI050055.bbl
PIスライダー1.30/1.35 https://www.nkozawa.com/blackbox/btfl_pi130135.bbl
PIスライダー1.60/1.65 https://www.nkozawa.com/blackbox/btfl_pi160165.bbl

スライド: https://www.docswell.com/s/6654543372/KJ48JM-2024-11-25-192028/1

Tiny Frameの種類によってPIDチューンは変わるのか?

PIDチューンを手持ちの機体全てに行うのは面倒です。機体スペックが同じならPID自体はおそらく同じで良いでしょう。と言うのは多くの人が同意すると思います。私自身は65サイズならフレームやモーター違っても同じPIDで済ませようと思っていました。

ところが、私がBetaFPV Air FrameでカリカリにチューンしたPID設定をWTW Shikoku会長のKanrekiさんがMobula6 2024に適用したら振動が出たとの報告をもらいました。その現象はPIスライダーを小さくしたら快適になったとのことです。これは対策として正しいものと思います。

と言うことで、私もBetaFPV Airフレームで調整したPID値をMobula6 2024フレームに適用してテストをしてみることにしました(FCとモーター、ペラはAirフレームと同じ)。結論を先に言ってしまうと、私のテストでは問題なし。むしろBetaFPV Airフレームより良い結果が出ました。フレーム差に加えて個体差が何かしらあるようですが、機体の特性は似ていると思います。やや緩めのPID設定にすれば65フレーム共通で良いのではないかと言うのが現在の結論です。

このテストが面白かったので、経過を書いて行きます。

[ フィルター設定 ]
いつも通りのフィルター設定でノイズを確認してみます。

普通に飛ばせますし、モーターの加熱もありませんが、Rollのジャイロ信号において200Hzより少し上のところに輝線が認められます。これは横軸のスロットルポジションに関係なく一定の周波数で機体が振動しているものをジャイロが捉えていることを示します。また左から二つ目のグラフにも現れていることからフィルターを通過してPIDループにもこの信号が入力されている事が分かります。

このまま放置しても問題は無いかも知れませんが、対策を施してみます。

これはBlackBox ExplorerでRollのフィルター後の信号を見たところです。これで輝線の中心周波数は219Hzだと言うことが分かります。PIDToolBoxのグラフとは違い横軸が周波数であることに注意してください。

対策として追加したのはジャイロノッチフィルター1です。中心周波数は先のデータに従い219Hzにしました。カットオフ周波数は勘で215Hzとしました。これの意味は215Hzから223Hzあたりの信号を取り除くと言う事です。

見事にノイズが除去されました。

他のMobula6 2024フレームでテストは行なっていないので、これがこのフレームに共通したものなのか、この個体の組み上げ方によるものなのかは分かりません。

[ PID設定はどうだろう ]
飛ばしてみると調子は良いので、大きな問題は無いだろうと思いつつログを調べてみました。

赤字の数値を見てもらうと分かるようにFF,I,D Maxの影響を排除して取得したデータで純粋にPDバランスを見ています。Pitchがほんの少しオーバーシュートしてはいますが、かなり綺麗なグラフになりました。

さらに普通に飛ばす時の設定でも、めちゃくちゃ綺麗なグラフになりました。多分、過去設定した中で一番綺麗です。

と言うことで個体差は考慮の必要はありますが、メーカーが違っても似たような65フレームであれば共通したPID設定が使えそうです。