まえがき
レスキューやらまいかにてソフトウェア開発を担当した者です.
レスキューロボットコンテスト2025にて,レスキュー工学大賞,ベストパフォーマンス賞をダブル受賞しました.厳密には本大会において優勝という扱いはないらしいのですが,レスキュー工学大賞とは「最も意義深い賞」とのことなので,実質的な総合優勝を意味します.そのほかにも,それらに付随する賞を追加で2つ受賞しています.
【参考】
そこでは,Siv3Dなどを用いたプログラムを作成し,後述する容体判定で満点を取りました.これはレスキューロボットコンテスト(以下「レスコン」という)において史上初らしいです.今回はそんなプログラムに関する記事を書きます.
基本的に,レスコンに出場するためのソフトウェアを作り始めようとしている人たちを対象とした記事です.要件定義やプログラムの設計などに役立ててくだされば幸いです.
また,プログラム開発はC++を独学した機械系学科所属の私一人で行ったため,情報学部生が育む常識や知識を備えていない可能性があり,そんな方々には読みにくい文章である可能性があることをご了承ください.
また,今回は概論ですので,具体的なプログラムの解説は次回以降へ回すことにします.本当に次回はやってくるのか?
レスコンとそれにおける容体判定の概要
レスコンについては,以下の公式HP
【URL】
をご覧になればわかりますが,ざっくり説明すると,災害現場を模したフィールド上で,自作したロボットを用いて人形(通称:ダミヤン)を救助することが目的です.
ダミヤンはハイテクなので,LEDによって顔色が表示されたり,ケガなどの情報をQRコードにより表示したり,スピーカにより特定のリズムで正弦波音声を再生できます.それらを正しく判定して正しく報告することでポイントが入ります.これが容体判定であり,これで満点を取ったというわけです.ここでは,容体判定における顔色判定,QR読取,周波数解析,音声パターン解析の4つの観点で満点を取ったノウハウを書きます.
容体判定のより具体的な説明と攻略法
大会運営が公開している資料を参考に説明します.
【参考】
顔色判定で得点するために
キーワード:OpenCV,ポスタリゼーション,ゴリ押し
ミッションの説明
ダミヤンの顔には,RGBフルカラーLEDが搭載されており,8色に点灯できます.大会中は,そのうちの1色だけで点灯しており,その色を正しく判定すると,ポイントが入ります.8色の内訳をRGB表記と併記し以下に示します.
黒, RGB(0,0,0)
赤, RGB(1,0,0)
緑, RGB(0,1,0)
青, RGB(0,0,1)
黄, RGB(1,1,0)
紫, RGB(1,0,1)
水, RGB(0,1,1)
白, RGB(1,1,1)
得点の方法
正直言うと,この判定は簡単です.カメラで取得した画像を人が見て読み取るだけです.
私のプログラムでも以下のURLのように,OpenCVの画像処理機能を用いてポスタリゼーションを行い,映像を8色に変換できる機能はありますが,結局その機能は競技中には使用していません.
【参考】
目で判断したほうが早いです!
しかし,三原色であれば判断には困らないと思いますが,混色はちゃんと色が混ざっておらず,なんだか変な見え方をすることがあります.特に,紫色と白色,青色と水色の識別を初見で行うのは難しいです.そんなときの解決方法を教えます.
競技前にスクショを撮りましょう!
というのも,大会の本選では,空き時間に,競技で使用するものと同様なダミヤンを使用して,ロボットの動作の確認を行うことができます.そして,顔色も自由に変えることができます.そのため,ダミヤンの顔をロボットのカメラで映した状態にして,スクショを撮り,8つのパターンの顔色を1つのPDFにまとめ,頑張って見分けられるようにすると良いです.私のチームもそのPDFで判定の練習をしました.ネット上では,ほとんどダミヤンの顔色の画像は見当たらないので,今のところ本選で確認するしか方法は無いと思います.
しかし,完全目視ではなく,前述のポスタリゼーションの機能も転ばぬ先の杖のように追加しておき,人間介在型システムとして設計することで,照明条件の変動リスクを考慮し、最終判定をオペレータに委ねることで、誤認識リスクや判定の不安感を軽減することはできます.
QR読取で得点するために
キーワード:OpenCV,Quirc,ロバスト性,ノイズ除去,コントラスト強調,ファインダパターン検出,射影変換
ミッションの説明
ダミヤンの胸には一辺30mmで16文字以内の文章情報が含まれているQRコードが取り付けられています.誤り訂正レベルはHです.例えば「両手負傷_両足負傷_歩行不可能」というような文字列が格納されています.
得点の方法
ダミヤンの置き方によってQRは水平を保たないので,QRが多少斜めであったり回転していても読み取れないといけません.また,QRの表面はあまり鏡面反射していなかったとは思いますが,影の多いBルームでは,QRが暗すぎて読取れないなんてこともあるかもしれません.そんなときはロボットのカメラ付近にLEDを設置すると良いかもしれません.このように,ロボットからQRを読取るのには,ある程度のロバスト性が必要です.
ロバスト性を実現するために,OpenCVとQuircを使用しました.カメラ映像を取得した際,以下のフローでQR読取りを実現させます.
①画質改善の前処理
②幾何学補正
③デコード
順番に説明します.
①画質改善の前処理
まず,カメラ画像の品質を改善します.
拡大:
cv::resize を使用して画像を拡大します.遠くにある小さなQRコードや,解像度が低い場合でも,ピクセル数を増やすことで検出率を向上させます.
ノイズ除去:
cv::bilateralFilter を適用しています.これはQRの白黒のエッジを残したまま,平坦な部分のノイズだけをぼかすフィルタです.Gaussian Blur等と違い,QRコードの白黒の境界線をぼやけさせずにノイズを除去できるため,バーコード認識に最適です。
コントラスト強調:
cv::createCLAHE を適用しています.画像の局所的なコントラストを強調します.これにより,影が落ちて暗くなった部分や,照明のムラがある環境でも,白と黒を明確に分離できるようになります.
②幾何学補正
斜めや回転した状態でも読み取れるように,自力でQRコードを正面に向ける処理をします.
ファインダパターンの検出:
QRコードのファインダパターンを,cv::findContours(輪郭抽出)を使って探します.親の輪郭の中に子の輪郭があり,さらにその中に孫の輪郭があるという入れ子構造をチェックすることで,ノイズではなく確実にQRコードの目印を見つけ出します.
透視変換:
見つけた3つの角の座標から,画像の歪みを補正する行列を計算し,cv::warpPerspective で画像を真上から見た正方形に射影変換させています。
これにより,カメラが斜めにあっても,綺麗な正方形の画像としてデコーダに渡すことができます.
③デコード
一度の処理で諦めず,失敗したら別の方法で再挑戦する仕組みです.
正攻法:
上記の幾何学補正を行った画像でデコードを試みます.
OpenCV検出器:
補正が失敗した場合,OpenCV標準の QRCodeDetector で位置検出を試みます.
単純二値化:
それもだめなら,単純に cv::adaptiveThreshold で白黒化してデコードを試みます.
反転画像:
最後に,白黒をネガポジ反転させた画像でもデコードを試みます.
このような流れでQR読取りを実現します.
以下のURLのように,QRコードの前でウロウロしていれば,勝手に読み取れます.
【参考】
なぜ Quirc を採用しているのか?
世の中には,ZXingやZBarのようなQR読取りのライブラリもあります.Quircの強みはそれらに比べて,ビルドの安全性が高いことにあります.Quircは単純な構成なので,前述の2つのライブラリと異なり,ビルドの際,他のライブラリと喧嘩することがあまりありません.私は,ZXingやwechat_qrcodeを試しましたが,動作の重さや依存関係の競合があったため,Quircに乗り換えた記憶があります.Zbarは試したことないので,何とも言えないです.すみません
また,元々,Quircは低スペックなマイコン等でも動作するように設計されているため,メモリの使用量が極めて少なく,処理が速いです.今回のように重い画像処理と並列してリアルタイム性を担保する場合,Quircは非常に有用だと現状では判断しています.
このように、検出と補正は強力なOpenCVの機能で自前実装し、整形された綺麗な画像を解読することだけに特化したQuircに渡すという、いいとこ取りの構成にしています。Quircは画像さえ綺麗なら非常に高い認識率を誇ります.
周波数解析・音声パターン解析で得点するために
キーワード:FFT,Goertzelアルゴリズム
ミッションの説明
音声関連のミッションをまとめて説明します.
ダミヤンには小型スピーカが内蔵されており,ピーピーと正弦波による音声を発しています.周波数は0.2kHz~3kHzの範囲の12音階で行われます.12音階とは,ピアノの鍵盤から発生できる周波数の音です.以下のサイトから,該当する周波数の選択肢は有限であることがわかります.もしかすると,大会にて使用される周波数は,小数点以下を四捨五入しているかもしれませんが,私は正直わかりません.
【参考】
そして,大会中は特定の周波数で,あるリズムのパターンで音声をピーピー発しています.発音素子は6秒を一周期として鳴動を繰り返します.最小ビットを0.5秒とし,ON/OFFを切り替えると共に,一周期の中に必ず1.5秒のOFF時間があり,その直後の0.5秒は必ずONです.
以下の図をご覧ください.最初の2.0秒の青い部分はどのダミヤンも共通ですが,橙色の部分がダミヤンによって異なります.この図の橙色の部分は一例です.他のパターンももちろん存在します.
また,同大会に出場した別チームであるKINKI KNIGHTSさんがありがたいことに,以下のような便利なサイトを作ってくださいました.
【参考】
作成した音声解析プログラムのテストは以下で生成した音声を用いて行うとよいかもしれません.KINKI KNIGHTSさんありがとうございます.
得点の方法
マイク選び
そもそものロボットに搭載するマイク選びから勝負は始まっています.USBマイクには2種類あり,全指向性と単指向性があります.周囲の環境の音を拾いたいのであれば,全指向性マイクが向いているかと思いますが,この場合,ダミヤンの音声に集中したいため,できるだけ単方向の音声を拾うことに特化している単指向性マイクを使用するのが良いと思います.
マイクがしっかりとダミヤンの方を向き,かつ,ダミヤンから可能な限り近い適切な位置に設置されていることが前提です.理想は,マイクがダミヤンにほぼ接触していることです.私がオペレートしていた4号機はマイクの位置が適切だったため,本選競技中,ダミヤンの声を拾えないことはありませんでしたが,3号機のマイクの位置がダミヤンから遠かったかつ,全指向性マイクだったこともあってか,オペレータは聞き取れなかったようです.
このように,マイク選びと設置位置は非常に重要です.
プログラムの解析手順
まずは,プログラムのアルゴリズムの話からではなく,実際に大会と同じ手順で音声解析をしてみます.以下のURLから動画をご覧ください.ダミヤンの代わりに,スマホから740Hzの音声を再生させ,その周波数の解析とパターン解析をしている様子を確認できます.ちなみに,先ほど紹介したKINKI KNIGHTSさんのサイトを使用し,スマホに音声をダウンロードさせました.
【参考】
この動画に示されている通り,カメラ映像の上に,現在取得されている音声をFFTした結果を,横軸を0.2~3kHzの範囲の周波数,縦軸をその周波数の強度として表示させています.赤いマーカがそのときの最大強度をとる周波数を指し,青いマーカがカーソル位置の周波数を指しています.黄色マーカは後で説明するので,ここでは無視してください.正弦波の音声がピーピー鳴っていると,グラフの赤いマーカの部分が鋭く尖ります.音声が鳴るタイミングとグラフが尖るタイミングは一致しているので,そのときの最大周波数がダミヤンの音声である可能性が高いです.赤いマーカがある周波数の値は,カメラ映像の右上に赤字で表示されています.図では740Hzということがわかります.
次に,右のプルダウンをクリックして,740Hzを探します.これらの数字は,前述の12音階の周波数です.ダミヤンの音声の周波数はこの中のどれかであることは確定しています.740Hzがあれば,それを選択します.
740Hzを選択した後の様子を以下の図で示します.すると,青色できれいに波打っているグラフを見ることができます.逆に,この波形があまりにも崩れていればその周波数はダミヤンの音声でない可能性が高いです.グラフが綺麗なので,今回は740Hzがダミヤンの音声であると結論付けます.グラフにおける一つの山が一つの0.5秒のビットを表します.2ビット以上連続して鳴っていると,山は台形に近くなります.図のグラフを読み取ると,今回は0.5秒ごとにONとOFFを繰り返すパターンであることが読み取れます.
使用アルゴリズム
カメラ映像に表示させる波形を求めるために,取得した音声をFFTしています.また,右のグラフを求めるためにGoertzelアルゴリズムを使用しています.Goertzelアルゴリズムは効率よく,特定の周波数のみを狙い撃ちして計算できます.12音階という探すべき正解の周波数が決まっているため、全周波数を計算するFFTよりも、特定の周波数だけを計算するGoertzelの方が計算コスト的やノイズ耐性的にも有利である.そのため,大会会場のように騒々しい場所でもノイズにほとんど左右されることなく,波形を求めることができます.「遠隔操縦技術や遠隔操作システムの優れたチームに与えられ」るベストテレオペレーション賞を受賞したチームさえもこのノイズの処理に苦戦しているようです.ぜひ,Goertzelアルゴリズムを利用してみてください.
また,パターン解析を自動的に全てプログラム上で完了することは,前述のノイズの関係で非常に困難と思えます.実際に,先ほどの図には,黄色のマーカや「Target」と書かれてある周波数がありますが,こちらは,すべて自動で解析しようとしたときの名残です.色々手を尽くしましたが,静かな環境であれば周波数とパターンを正答できるのに対し,騒がしい環境では,著しく精度が落ちてしまいます.そのため,大会中は一切,黄色の情報は使用しませんでした.先ほどの解析手順のように,目視で周波数を割り出す方法が現状では最善手であると判断しています.実際にこの手法で正答しています.
Siv3Dにも音声をFFTできる関数があります.しかし,ラズパイに対しては正常に動作しますが,TPIP4とは相性が悪いようで,FFTスペクトルの描画更新の頻度が一定になりません.そのため,fftクラスを自前で用意したところ,その不具合はなくなり,双方とも滑らかに描画できるようになった経験があります.
使用ハード(通信機器)
コンテストにおいて,使用したハードを以下に示します.
それぞれにいろいろ機能があるかと思いますが,どちらも,ロボットとPCとの通信や他のマイコンとのUART通信のみに利用します.
Raspberry Pi4 Model B (以下 「ラズパイ」 という)
ものづくりする人にとってはお馴染だと思います.RAMは4GBのものを使用しました.
【参考】
市販のラズパイは大会で使用する無線wifi子機(以下「ドングル」という)のドライバがインストールされていないため,ドングルをラズパイに挿したら,確かにピカピカ発光するかもしれませんが,ドングルによる通信強化はできていません.恐らく,大会中にラズパイでの通信トラブルが発生しているチームはドライバをインストールできていないことが原因と思います.
ドライバをインストールする方法はあまり詳しく説明しませんが,Geminiなどの生成AIに対して,
RaspberryPi4ModelBに「BUFFALO 11ac/n/a/g/b/ 433Mbps USB2.0 用 無線LAN子機日本メーカー WI-U2-433DHP」というドングルを適用して,ラズパイの通信を強化したいです.
ラズパイにuname -aを打ち込んだところ,
Linux rasp1 6.1.21-v8+ #1642 SMP PREEMPT Mon Apr 3 12:34:56 BST 2023 aarch64 GNU/Linux
と出力されました.
どのようにすれば,私の目的を達成できますか?
というようなプロンプトを渡し,その後の指示に従ってもインストールはできると思います.大事な情報はラズパイのカーネルとディストリビューション,ドングルに搭載されているチップです.チップを確認するには,WEB検索するか,ドングルを分解してください.余談ですが,この話題は今年のTPIPユーザーコミュニティでも出ましたね.アーカイブもありますので,興味のある方は,以下のURLにアクセスし,動画を参照すると良いかもしれません.そのためにはTPIPコミュニティのアカウントを作成することが必須です.
【参考】
TPIP4
大会出場者ならお馴染の「一台で遠隔監視と計測・制御の機能を提供するオールインワンモジュール」です.大会運営から貸与されたものを使用しました.結構高価なため,サークルの経済力では購入できません(泣).公式HPと公式wiki,ライブラリを以下に示します.
【参考】
(公式HP)
(公式wiki)
(ライブラリ)
結構多機能であり,アナログIO,デジタルIO,PWMなどを利用できるようですが,これらは全く使用しませんでした.PCとロボットとの通信の用途にのみ使用します.TPIP4を購入した場合,ドングルのドライバがすでにインストールされているのかどうかは知りませんが,少なくとも,大会運営から貸与されているものであれば,すでにインストールされています.なので,ドングルをそのまま挿せば,問題なく通信できるかと思います.
TPIP4は,公式ライブラリにも記載されていないようなのですが,通信開始直後やカメラの切替直後の処理に,Delayを挟む必要があったり,そのほかにも,前述のようにSiv3DのFFTとの互換性が悪かったり,TPIP4から得られる映像をSiv3Dの関数を使用しデコードしようとすると,詳細は忘れてしまいましたが,不具合が発生します.基本的にSiv3DとTPIP4は相性が悪いようなので,注意してください.
次回予告
次回はより具体的なプログラムの解説に入る予定です.映像通信,音声通信から説明し,QR読取り,音声解析の内容に発展できればと思います.もしかすると,映像関連編と音声関連編,GUI関連編に分かれるかもしれません.私のモチベーション次第です.



