Dropbox

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の実装にもよると思いますがデータの処理される順序が入れ替わることもありますので注意が必要です。

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を使用して様子を見るつもりです。

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

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設定が使えそうです。

前回、フィルターの設定が出来ました。いよいよPIDを設定していきます。

まず最初にBetaflight ConfiguratorをExpertモードにしておきます。(上の方に小さく書かれているやつです)

[ 基準値 倍率設定(Master multiplier)の決定 ]
最初に動的ダンピング(Dynamic Damping) D Maxを0にします。この状態で倍率設定(Master Mulitplier)を1より少し小さい値から0.05ずつ上げ、実際に飛ばしてみます。このステップは全くの体感で行います。細かい調整は後から行うので心配は要りません直感を信じて進めます。
倍率設定を上げていくとだんだん反応が良くなります。それがあるところを超えるとまた反応が悪くなったり、モーター音の異常、モーターの加熱が発生します。気持ち良く飛ばせる中で一番高い数値にしておきます。

私の場合は1.25に設定しました。

[ 動的アイドル値(Dynamic Idle) ]

動画中にある表を参考に設定します。65サイズが書いてないですし、プロペラのピッチによる設定値の幅が大きいので、大体のところで100にセットしてみました。

[ PDバランス ]
これからが本番です。最初に技術的な背景を簡単に紹介します。プロポのスティックを操作すると、それがFCで解釈されてYaw/Pitch/Rollのセットポイントという値が作り出させれます。これはその操作を行った時にジャイロが作り出す値の目標となる値です。FCは各モーターを動かしジャイロの出力がセットポイントを追従する様に制御します。その追従の具合を調整することがPIDチューニングです。


「動的ダンピング D Max」, 「スティックレスポンス FF」, 「ドリフト-ふらつき I」を全て0にします。
「トラッキング P&I強度」を0.5から0.05ずつ上げながら20秒ほど飛行しログを取ります。PIDtoolboxでStep Resp Toolで波形を見ます。オーバーシュートしない程度で素早く立ち上がるPの値をRollとPitchでそれぞれ記録します。

これはP&I=1.35にした時の状態です。Rollは良い値が出たところです。Pitchはややオーバーシュートしていますので、もう少し小さな値が良さそうです。
私は、RollはP&I=1.35, P=75、PitchはP&I=1.20, P=70を採用しました。
もし、この調整でスライダーが右端まで行ってしまった場合は最初の「基準値 倍率設定」の数値が足りていないのだと思われます。

「トラッキング P&I強度」スライダーでRollのP値を75にします。これは調べた時の値ですのでP&I=1.35になります。
「ピッチトラッキング」スライダーを調整してPitchのP値を70にします。実際にはスライダー0.9でP=71としました。
これでPDバランスの調整は完了です。

[ ドリフト、ふらつき I 強度 ]
I値は共用範囲が広いのでBetaflightの規定値でも大丈夫かも知れません。大きい方がレスポンスが良くなりますが大きすぎると振動やバウンスバックが出ます。私は今のところ、なんとなくスライダーを1.0にしています。初期値は80/84/80で現在値は135/127/135とだいぶ大きくなっています。もっと小さくすべきかも知れませんが、これでしばらくテストしてみます。

[ Feed forward ]
スライダーではなく右の方にある各値はプリセット/RC_LINKで適切な値を選択することで設定されます。

私の場合はELRS 500Hz, Race, Serial RX, Single cell valueで設定しています。
FFのスライダーはとりあえず1.0にしておきました。

[ 動的ダンピング ]
強度=37,詳細=0に設定します。

[ 動的ダンピング D Max ]
動的ダンピング(D Max)が0の時は上の数値欄にあるD MaxとDerivativeに同じ数値が出ているはずです。これを記録します。「ダンピング D強度」のスライダーを下げ「動的ダンピング D Max」のスライダーを上げてD Maxを記録した値、Derivativeをそれより少し小さい値にします。私の場合は「ダンピング D強度」を0.75, 「動的ダンピング D Max」を1.0にしました。まったり飛行の場合は、もっと差を小さくした方が良いかも知れません。


最終的なPID画面はこんな感じになりました。これでしばらく飛ばしてみようと思います。

以前、書いた「室内でPIDチューニング」のBetaflight 4.5版です。前回と同じくChris Rosser師匠のYouTubeビデオに基づいた内容になっています。細かいところは除いて私が実際に試した部分だけを書いています。詳細については以下のYouTubeをご覧ください。
Betaflight 4.5 PID Tuning
Betaflight 4.5 Filter Tuning

[ PIDtoolbox ]
PIDtoolboxを使用します。ちょっと前までは無料でダウンロード出来たのですが今は月会費を支払ってダウンロードします。一年前くらいの無料時代の物でも今回のPIDチューニングには使用出来ます。
PIDtoolboxの導入方法と基本的な使用方法は以下の記事をご覧ください。
PIDToolbox v0.62
PIDToolbox v0.62を使う
Windows版もMac版も導入方法や使い方は同じです。最新のMacOSでは最初のプログラムの起動が少し面倒になりました。ダウンロードしたプログラムがうまく起動せずゴミ箱に入れますかなどと聞かれます。これを解消するにはターミナルを開いて以下のコマンドを投入しなければなりません。

xattr -c {PIDtoolboxのディレクトリー名に置き換える}/main/PIDtoolbox.app
xattr -c {PIDtoolboxのディレクトリー名に置き換える}/main/blackbox_decode

[ 今回使用した機体 ]
BetaFPV Meteor65 Frame, BetaFPV Air 5in1 FC, BetaFPV 0702-30000KV motor, HQ UltraLight Prop
Betaflight 4.5.1です。
新しいBetaFPV Air FCはBlackBox用に16MBのストレージが搭載されているのでPIDチューンがとても行いやすいです。

[ フィルター設定 ]
前提はRPMフィルターを設定済みであることです。
フィルターは可能な限り軽い方が良いです。軽いというのは設定るフィルターの数を少なく、また設定する周波数を高くすることです。生のGyroデータには沢山のノイズ(機体の本来の動きとは別のもの)が含まれます。それをフィルターで出来る限り取り除いてからPID処理に入れます。問題はフィルターにより必ず遅延が発生することです。その遅延はフィルターが一つ増えれば、その分増えます。また、低い周波数を見極めるのには高い周波数より時間がかかります。

実際のフィルター設定は簡単です。Chris Rosserさんの推奨値でたいていの場合は問題ないと思います。

画面の通りです。Betaflight規定値と違うのは
– ジャイロローパス1 = オフ
– ジャイロローパス2 = 1000Hz (もし基本設定でGyro周波数とPID周波数を同じにしている場合はこれもオフにする)
– 動的ノッチフィルター = オフ (もし機体の固有振動によるノイズ出たら改めて考える)
– D値ローパス1 = 動的/80/110/7/BIQUAD
– D値ローパス2 = オフ
これでモータの異音、加熱、機体の振動がなければ基本的には問題なしです。

RPMフィルターの高調波として3が指定されています。これはモーターの回転から引き起こされる振動とその正数倍の振動を考慮したものです。この高調波がプロペラの羽の数によって違うという予測があります。私は入れていませんが、それを考慮して以下のコマンドをCLIで入力すると良いよとChris Rosserさんは言っています。
3枚羽の場合は、set rpm_filter_weights = 100, 0, 80
2枚羽の場合は、set rpm_filter_weights = 100, 80, 0だそうです。

では、ログを取ってみます。まずはBlackboxページでデータの消去を行います。その後で普通に飛行します。スロットル位置ごとのデータが必要なのでなるべくゆっくりと幅広くスロットルを動かします。20秒ほど飛べば大丈夫です。アクロ、アングルどちらでも構いません。クラッシュ、もしくは着陸したらすぐにDisarmします。
ログファイルを取り出しPIDtoolboxに読み込みSpectral Analyzer/’Freq x Throttle’/Runでグラフが出ます。

で、実際に取ったデータです。これは実は良くない状態です。横軸がスロットルで縦軸はジャイロデータに含まれる周波数成分です。PID演算において本当に欲しい機体の動きは100Hz以下に現れます。それ以上の部分はノイズ(ほとんどは何かしらの理由による機体の振動)です。このデータではスロットル30%以上の部分に太い帯が見えます。これは明らかな異常振動です。

機体を点検したところひとつのペラが曲がっていました。

ベラを交換して再度データを取りました。

今度は大丈夫そうです。一番左側はフィルターをかける前のジャイロデータです。左下から右上に向けて斜めの太い帯が見えます。これはスロットルポジション、すなわちモーターの回転数に比例して周波数が高くなるノイズ群です。これを効果的に取り除くのがRPMフィルターです。左から二つ目のグラフがフィルターをかけた後のデータです。とてもうまくフィルターされているのが分かります。Dtermについては多くは語りませんが、まあこれで良いかなと思います。

長くなるのでPIDチューニングについては次の記事にいたします。

WTW四国ではVTXチャネルによってLEDの色を変えるというレギュレーションの普及を目指しています。VTXチャネルをsmartaudioで変更すると同時にLEDの色を変更するのは合理的ではありますが、レースによってはVTXと関係なく送信機のスイッチで色を変更することも考える必要があるかも知れません。その一つの答えは独立したマイコンチップでLEDを制御する方法でした。ここで原点に戻りBetafligh configuratorのLEDストリップ画面でAUXスイッチを使う方法を再度試してみることにします。

これから書くことは偶然発見しました。多分、公式ドキュメントを読むだけでは分からない方法です。


こんな感じでAUXに3ポジションスイッチを選択しカラーパレットのどれか、例えば14を選びます。そうするとスイッチを中央にすると14番の色になり、スイッチを倒すと14の前後、13か15番の色になります。ここまでは以前から知っていました。送信機のスイッチが足りないので、これをS1で試すことにしました。S1を左端まで回した時と中央、右端まで回した時で3ポジションスイッチと同じ動作にしようという目論見です。

当然のことながらうまく動きます。S1を回していく過程の途中でパレットの色が突然切り替わるところがあるのではないかと想像していました。場所を見極めてみようとゆっくり回すと何故か徐々に変化して行きます。どうも二つのパレットに指定した数値を徐々に変化させているようです。ということで、ここから設定手順です。

[ プロポの設定 ]
S1、S2などをAUXに割り当てます。

モデル設定のMIXESでCH11にS1を割り当てました。Betaflight Configuratorの受信機タプでAUX7がS1を回して変化することを確認しました。

[ Betaflightの設定 ]
まずはワイヤーオーダーの設定が必要です。これについては過去記事を参照願います。
そして最初のスクリーンショットの様に機能=カラー、カラー修正=AUX7にし、カラーパレットのどこか(0と15を除く)を指定します。

次にカラーパレットに割り当てる数値を変更します。カラーパレットをダブルクリックするとHSVの値を指定することが出来ます。

例えば先のステップでカラーパレット14を指定した場合、変更するのは13, 14, 15になります。HSVのうちSは0、Vは255固定です。H(色相)の値をバレット13は0、14は143、15を285にすると赤から紫までの虹のスペクトルに変化させることが出来ます。

色相を一周させる場合はカラーパレット13,14,15のHを0,180,359にします。

カラーパレットの操作は色々と面倒なのでCLIに流し込むものを用意しました。LED数は16個、AUX7を使用、カラーパレットは13,14,15で赤から紫まで虹色の変化を行うものです。

# led
led 0 0,0::CT:14
led 1 1,0::CT:14
led 2 2,0::CT:14
led 3 3,0::CT:14
led 4 4,0::CT:14
led 5 5,0::CT:14
led 6 6,0::CT:14
led 7 7,0::CT:14
led 8 8,0::CT:14
led 9 9,0::CT:14
led 10 10,0::CT:14
led 11 11,0::CT:14
led 12 12,0::CT:14
led 13 13,0::CT:14
led 14 14,0::CT:14
led 15 15,0::CT:14
led 16 0,1::CT:14

# color
color 13 0,0,255
color 14 143,0,255
color 15 285,0,255

# mode_color
mode_color 7 0 10


Raspberry Pi AI Kitをセットアップし自前のモデルを動かしてみるところまでの記録です。
基本的な設定は迷うところはありません。公式ドキュメント通りで大丈夫です。
使用したのはRaspberry Pi OS 64 bit版です。

[ 基本ソフトウェアの導入 ]

ドキュメントに従い、

sudo apt update && sudo apt full-upgrade

次にファームウェアバージョンを確認します。

sudo rpi-eeprom-update

私の場合、ファームウェアのバージョンが最新の物でしたので続くeeprom更新は行いませんでした。
続くドキュメントに従いhailo関連のソフトウェアを導入します。

sudo apt install hailo-all

導入の確認は、

hailortcli fw-control identify

というコマンドで行います。これでAIハードウェアの情報が表示されれば完成です。

[ サンプルプログラム ]

次に実際に動くサンプルプログラムを導入します。いくつかありますが、実際のアプリケーションに応用可能なものとして
Hailo RPi5 Basic Pipelinesを選びました。

git clone https://github.com/hailo-ai/hailo-rpi5-examples.git
cd hailo-rpi5-examples
./install.sh

以上のコマンドで導入は完了です。
実際に動かしてみます。

source setup_env.sh

Pythonの仮想環境に入ります。そして次のコマンドを投入します。

python basic_pipelines/detection.py

これでobject detectionのデモが動きます。デモは24FPSぐらいは出ているようです。

[ 自分で作成したモデルでのテスト ]

python basic_pipelines/detection.py --help

これでコマンドラインオプションを調べ”–input”でテストしたい動画ファイル、”–hef-path”で自作のモデルを指定すれば動きます。ただし、このままだと自分の意図するのと違うラベルが表示されてしまいます。”resource/barcode-labels.json”などを参考に自分のモデルに合ったラベルを含むjsonファイルを作成して”–labels-json”で指定すると良いです。

動画ファイルの代わりに”/dev/video0″などとするとUSBからの画像入力も扱うことが出来ます。これについては、また長い試行錯誤があります。改めて記事にするつもりです。

実際のアプリケーションを作成する場合は、何かしら検出した物体に対し自分の処理を加えたいはずです。その場合でもこのサンプルはそのまま活用できそうです。先の”detection.py”の中に”app_callback()というファンクションがあります。何かしら検出すると、これがよばれるようになっています。中身を見ていくと検出したラベルや大きさが格納されたbboxが見つかります。ここを自分用に変更すれば良さそうです。

Raspberry Pi5にM.2 Hatを介して接続するAi Kitなるものがあります。13TOPS(26TOPSというモデルも有ります)というそこそこの性能でリアルタイムな画像認識ランタイムを実行させることが出来るらしいです。ただし使いこなしには少々の慣れやらKnow-Howの蓄積が必要になります。何時ものように自分自身の覚書として理屈は抜きで上手くいった事例の一つとして書き残すことにしました。まずは独自の学習モデルをAi Kit向けに作るところからです。

Raspberry Pi AI KitはHailoという独自なソフトウェア群で稼働させなければなりません。Yolo向けに作成した学習モデルをそのまま使うことはできません。以下の手順でHailoで使えるモデルに変換しなければなりません。私が試してうまく行った方法を書き残します。

参考にした記事は以下の通りです。
1. Raspberry Pi AI Kitでカスタムモデルを使う方法
2. Tutorial of AI Kit with Raspberry Pi 5 about YOLOv8n object detection
3. hailo_dataflow_compiler_v3.29.0_user_guide.pdf
4. hailo_model_zoo_v2.13.0.pdf
3と4のpdfファイルはHAILO DEVELOPER ZONEより入手します。ユーザー登録が必要です。

[ 手順の流れ ]
– yamlに少し手を入れて従来の手順でyoloで学習を行う
– 出来上がったbest.ptをyolo環境でonnxフォーマットに変更する
– Intel PC上のUbuntuにHailoより提供されているソフトウェア環境でonnxからhefフォーマットのモデルに変換する
といった感じですが、最後のステップは少々苦労します。

[ クラス数80のモデルを作成する ]
まずは学習モデルを以下の記事にあるやり方で作成します。ただ一つだけ相違点があります。
FPVの画像解析してみるぞ、機械学習入門その1
Google Colabを使おう、機械学習入門その2
学習する際に指定するymlファイル内でラベルを80個にします。私の事例では2個のラベルしか使用していません。残りの78個はダミーになります。

# number of classes
nc: 80

# class names
names:
    0: gate
    1: goalgate
    2: dummy1
    3: dummy2
    4: dummy3
    5: dummy4

このようにしてdummyラベルを追加して合計80個にします。あとは通常通り学習を行います。なぜ80なのかはよく分かりません。

[ onnxフォーマットのモデルに変換する ]
出来上がった”best.pt”ファイルをonnxフォーマットに変換する。私はmacOSに導入したUltarytics環境で行いました。以下のコマンドを投入します。

yolo export model=./best.pt imgsz=640 format=onnx opset=11

[ Hailoソフトウェア群をUnuntu環境に導入し更なるモデル変換に備える ]
ここからが長い道のりでした。よくわからないまま試行錯誤でいくつかの手順を参考になんとか使える状態にしました。最初、Intel NUC上のUbuntu 20.04で環境を構築し、次に手順の確認のために再度WSL2(Windows11)で環境を構築しました。WSL2での作業を以下に書き残します。試行錯誤の部分も書きますので、煩雑な内容になってしまいました。

最初にWindows 11のWSL2, Ubuntu 22.04, Python 3.10.6で試してみましたが、Ubuntuが推奨されているバージョンより新しいためか、最後のステップで原因不明の不具合に遭遇しました。以下の手順はWSL2Ubuntu 20.04.6 LTS, Python 3.8.10で行ったものです。

最初に、お約束のsudo apt updateとsudo apt upgardeを実行しておきます。

< venv作成 >

sudo apt install python3.8-vnev
python3 -m venv hailo.env
source hailo.env/bin/activate

< Hailo Dataflow Compilerの導入 >
公式ドキュメントHailo Dataflow Compiler User Guideの”3.1 System Requirements”に従い以下のパッケージを導入。

sudo apt install python3.8-dev
sudo apt install python3.8-distutils
sudo apt install python3-tk
sudo apt install graphviz
sudo apt install libgraphviz-dev

Hailo Developer ZoneのSoftware Downloadsより該当するオプションを選んでDataflow Compilerをダウンロードする。

ダウンロードしたファイルをpipで導入します。

pip install hailo_dataflow_compiler-3.29.0-py3-none-linux_x86_64.whl

沢山、エラーメッセージが出ました。”error: command ‘x86_64-linux-gnu-gcc’ failed: No such file or directory”というエラーに注目して解決策を探り「ubuntsuでpip installしたら「error: command ‘x86_64-linux-gnu-gcc’ failed with exit status 1」と出た」という記事を見つけました。その対処方法に書かれている通り、

sudo apt-get install build-essential libssl-dev libffi-dev python3-dev

を実行し、再度pipでdatacompilerの導入を実行。今度は問題なく終了。
hailo -h
で導入されたことを確認します。要求項目も概ね問題がないことが分かります。

< Model Zooの導入 >
公式ドキュメント”Model Zoo User Guide”の”3.2.2 Manual Installatio”に従い導入します。

git clone https://github.com/hailo-ai/hailo_model_zoo.git
cd hailo_model_zoo; pip install -e .

hailomz -h
で導入されたことを確認します。
次にcoco datasetを導入します。手順は7.2 COC2017にあるobject detection用のものです。

python hailo_model_zoo/datasets/create_coco_tfrecord.py val2017
python hailo_model_zoo/datasets/create_coco_tfrecord.py calib2017

作業ディレクトリーに先のステップで作成したonnxフォーマットのモデルをコピーします。これを3段階で変換していきます。
まずはparseです。

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

これでyolov10s.harファイルが作成されます。オプションで指定するyoloのモデル名は最初にyoloで使用したものに合わせます。逆に言えば”hailo_model_zoo\cfg\postprocess_config”以下に存在するyoloモデルに合わせてモデルの学習を行っておく必要があります。

次はoptimizeです。

hailomz optimize --hw-arch hailo8l --har ./yolov10s.har yolov10s

エラーが出ます。
“FileNotFoundError: Couldn’t find dataset in /home/kozawa/.hailomz/data/models_files/coco/2021-06-18/coco_calib2017.tfrecord. Please refer to docs/DATA.rst.”
どうもcoco datasetのファイルが見つからないようです。調べて見ると”~/.hailomoz/data/models_files/coco/”に”2023-08-03″というフォルダーはありますが、探している”2021-06-18″がありません。シンボリックリンクで2021-06-18が見えるようにして問題は解消しました。

cd ~/.hailomz/data/models_files/coco/
ln -s 2023-08-03 2021-06-18

再度optimizeを実行すると、またエラーです。
Post-process config file isn’t found in /home/kozawa/hailo/hailo.env/lib/python3.8/site-packages/hailo_model_zoo/cfg/alls/generic/../../postprocess_config/yolov10s_nm(h(h(h(hailo.env)
などと言ってます。また何かファイルが足りないようです。これは一番最初に提示した参考記事の1番に答えがありました。

mkdir -p hailo/lib/python3.10/site-packages/hailo_model_zoo/cfg/postprocess_config/
cp hailo_model_zoo/hailo_model_zoo/cfg/postprocess_config/yolov10s_nms_config.json hailo/lib/python3.10/site-packages/hailo_model_zoo/cfg/postprocess_config/yolov10s_nms_config.json

参考にした記事ではyolov8nのファイルになっていますが、私が使用したのはyolov10sです。

これで再度optimizeを実行して問題なく終了しました。

最後はcompileです。

hailomz compile yolov10s --hw-arch hailo8l --har ./yolov10s.har

しばらく待って、棒グラフが画面に表示され始めたら、あとは完了を待つだけです。
yolov10s.hefが出来上がれば、それをRaspberry PI AI Kitで実行させることが出来ます。これの詳細については、次の記事に書く予定です。

入手してから随分と時間を経過してやっとまともなテスト飛行を行いました。実は一度飛ばしてはいるのですが、ジャイロデータを取得していなかったためGyroflowが使えなくてビデオをお蔵入りにしていました。その辺りも踏まえて使用感を書いてみたいと思います。

まずは簡単な印象を列記しておきます。
– 映像は進化して、かなり綺麗になったっぽい。細かい比較はしていません。ざっくりとした印象です。ファイルも大きくなります。
– 電源供給する裏側の小さなコネクターが3PになったのでBECケーブルがRunCam Thumb Proと使いまわせないのが残念。
– RunCam Thumb Proより11gほど重くなり27gになった。小型ドローンにはちょっとだけ厳しい。
– 付属のマウントがGoPro互換ぽくなった。仕方がないのでRunCam Thumb Proと使いまわすためのマウントを作った。モデルなどの情報は記事の最後に書いておきます。

ともあれ、飛行テストの様子です。

設定は以下の通りです。
録画モード : 標準
ビデオクオリティー : 高
解像度 : 4K60FPS
音量 : ノイズ除去
手ぶれ補正 : ジャイロスコープデータ (これを間違うとGyroflow用のデータが得られません)
歪み補正 : オフ
YouTubeの動画はカラーはだいぶ弄っています。音はそのままです。

GyroflowのLens profileはGithubからダウンロードします。Runcam_Thumb2_16by9.jsonというものを使用しました。Motion dataは自分で指定する必要があります。MP4と同時に取得される拡張子gcsvのものです。

使用したカメラマウントはThingiverseで公開しています。
https://www.thingiverse.com/thing:6793100
販売も行っています。
https://dskozak.stores.jp/items/67188c61816e6104457a0cef