Hesaiの次世代フルカラーLiDARチップ「Picasso」

はじめに

昨日、XでHesaiが発表した次世代フルカラーLiDARチップ「Picasso」が話題になっていました。

実は2025年9月時点で「Picasso」という名前こそ出ていないものの、詳細なスペック含めて情報が出ているを見逃しており、LiDARオタクとして遅れを取りました。私もまだまだですね。

www.hesaitech.com

カメラ画像を後処理で合成するのではなく、ハードウェアでピクセルレベルでのネイティブなセンサーフュージョンを実現し、センサーから6D(XYZ+RGB)の点群を出力すると謳っているPicassoチップに関して、出ている情報をまとめつつ、考察してみます。

※筆者は単なるLiDARオタクであって、専門家ではないのであくまでも参考程度に……

波長帯:「905nm」

Picassoチップの発表では光子検出効率を示す「PDE > 40%」というスペックが示されています。 SONYのLiDARチップ「IMX479」の37%を上回る数値であり、(少なくとも量産レベルでは)世界トップレベルの性能でしょう。

波長帯は明示されていませんが、このシステムが採用しているレーザーの波長帯は1550nm帯ではなく、905nm帯であると考えられます。

1550nmならPDEに固執する必要がない

1550nm帯のLiDARは、アイセーフの観点から905nmの桁違いのパワーの強力なレーザーを出力できるためパワーの暴力で長距離を計測できます。 わざわざノイズ限界に挑んでまでPDE 40%を追求するのは、1550nmのシステム戦略として不自然と言えるでしょう。 また、仮に1550nm帯でPDE40%を実現するというブレイクスルーをHesaiがやってのけたとして、それで得られる性能が400m@10%だとすれば期待はずれもいいところです。

905nm帯における戦略の連続性と製造メリット

Hesaiはこれまで一貫して905nm帯のLiDARを主戦場としてきました。「boosting ranging capability by 30%*1」という記述は、現行の主力機である905nm帯ATシリーズの300m@10%に対する「ETX」の400m(@10%)の性能ともおおよそ一致します。 そして何よりRGBセンサーを含めた全てのセンサーがシリコンベースで統一できるということです。半導体製造には明るくないですが、両者を同じシリコンウェハ上で製造できることは、製造コストと量産性の観点からメリットになりそうです。

1550nm帯では厳しいスペックである

ここは詳しく調べてほしいところですが、1550nmではPDEと低ノイズの両立が困難です。 1550nm帯のInGaAs(インジウム・ガリウム・ヒ素)などセンサーでは、PDEを上げるとノイズが一気に大きくなってしまう強力なトレードオフを抱えているようです。 センサーを冷却すれば多少は改善するようですが、少なくとも今回Hesaiが主張しているような低ノイズ性能には遠く及ばない印象を受けました。

Hesaiの特許とセンサーの構造 - 「積層型」ではなく「平面サブピクセル型」

Hesaiのスライドを見ると、光の層が垂直に重なっているようなイメージ図が描かれています。これを見ると、米Foveon社のイメージセンサーのように光を透過させて1つのピクセルの奥深くにRGBと深度センサーが垂直に重なっているようにも見えます。しかし、このような構造ではRGBセンサーやその配線などによる光の減衰でPDE40%の達成は難しいでしょう。

また、Hesaiの関連特許(特許公開番号: CN121657013A)を紐解くと、内部構造は「平面上に並列に並べられたサブピクセル構造」であることが分かります。

patents.google.com

特許を読み込むとざっくりと以下のようなことが書いてあります。

  • 第1ピクセル:LiDAR用
  • 第2ピクセル:RGB用
    • 第1方向にRGBのサブピクセルがある
      • カラーフィルタがかけてある
    • カラーフィルタをかけない第4サブピクセルがある場合もある
  • 第1ピクセルと第2ピクセルの間は仮想ピクセルがあり、ノイズを防いでいる
  • 第1ピクセルと第2ピクセルの検出処理は時間方向に完全に分けて動作させる

※その他にも色々書いてありますが、一見矛盾するように見える記述があったりして現時点の理解で確定できるのはこれくらいでした。もっと詳細を知りたい方は特許を直接読んでみてください。

空間的と時間的にRGBとLiDARの処理を分割することで、特に強烈なLiDARのレーザー反射光の入射による電気的・光学的なノイズの影響をできるだけ低減しようという努力が見られますね。

まだまだ、調べたり足りないことや書きたいことはありますが、一旦今日はここまでです。

ament_cmake_autoを使いこなす

私がこのブログでament_cmake_autoの記事を書いてから5年が経ちました。

hans-robo.hatenablog.com

当時はament_cmake_autoの日本語の資料がネット上に皆無だったため記事を書いたわけですが、5年も経つと日本語の情報もかなり増えてきたようで、嬉しい限りです。

一方で、後発の記事も初出の私の記事と情報量がそれほど変わらない気もしているので、一歩踏み込んだ記事を書くことにしました。

関数の引数を使いこなそう

ament_cmake_autoの関数群はそのまま使っても便利ですが、引数を使いこなすとその真価を発揮します。

ament_auto_find_build_dependenciesの引数「REQUIRED」

package.xml で以下のように依存関係が定義されている場合を考えます。

<depend>a</depend>
<depend>b</depend>

このとき、以下の2つの記述は等価だと思っている方が多いのではないでしょうか。

通常のCMake記述:

find_package(a REQUIRED)
find_package(b REQUIRED)

ament_cmake_autoを使った場合:

ament_auto_find_build_dependencies()

実はこれ、等価ではありません。 REQUIRED オプションを有効にするには、以下のように明示する必要があります。

ament_auto_find_build_dependencies(REQUIRED a b)

引数なしで呼ぶだけでは REQUIRED 指定にはなりません。 クリティカルな違いではありませんが、パッケージが見つからない場合にエラーにならず進んでしまうなど、思わぬ「沼」の原因になりえます。ぜひ覚えておきましょう。

ament_auto_add_executableの引数「DIRECTORY」

ソースコードを追加する際、フォルダ内のファイルをすべて手動で記述していませんか?

ament_auto_add_executable(<target>
  src/a.cpp
  src/b.cpp
  src/c.cpp
)

これは、DIRECTORY 引数を使えば一発で記述できます。

ament_auto_add_executable(<target> DIRECTORY src)

これで src ディレクトリ内のソースを自動で取り込んでくれます。 もちろん、 ament_auto_add_library でも同様に使用可能です。

ament_auto_packageの引数「INSTALL_TO_SHARE」

shareディレクトリへのインストール(launchファイル等)を、以下のように丁寧に書いていませんか?

install(
  DIRECTORY launch
  DESTINATION share/${PROJECT_NAME})

これも、ament_auto_package の INSTALL_TO_SHARE 引数を使えば、たった1行で完結します。

ament_auto_package(INSTALL_TO_SHARE launch)

変数の流れで理解するament_cmake_auto

ament_cmake_auto の内部では、CMake変数を読み書きすることで関数間の連携を行っています。 この「変数の流れ」を把握しておくと、トラブルシューティングや応用時における解像度が格段に上がるはずです。

変数の起点、「ament_package_xml

ament_cmake_autoの関数ではなく、ament_cmake_coreの関数ですが、すべての起点はここにあります。package.xml の情報をパースしてCMake変数に書き込む役割を持っています。

ament_cmake_auto の各関数は、この関数がセットした変数を参照することで、package.xml の情報を利用可能にしています。

ちなみにパース結果は、ビルドディレクトリ内の build/<package name>/ament_cmake_core/package.cmake で確認できます。デバッグ時に役立つので覚えておくと良いでしょう。

変数の流れとament_cmake_autoでの利用

ament_cmake_auto をフル活用した場合の主要なCMake変数の流れと、各関数での活用イメージを以下の図にまとめました。 CMake変数を通じて各関数が連携し、ユーザーの記述量を削減している仕組みが見て取れると思います。

応用事例:rosidl_auto_generate_interfaces関数

CMake変数の内容や流れを把握しておくと、色々なことができそうな気がしてきます。 その一つが、以下のブログ記事で紹介しているrosidl_auto_generate_interfaces関数です。

ROS 2のメッセージパッケージのCMakeを簡単に! ~rosidl_auto_generate_interfaces~ - HansRobo’s blog

rosidl_auto_generate_interfaces関数では、CMake変数<package>_BUILD_DEPENDSを使うことでrosidl_generate_interfaces関数への依存指定を自動化しています。

あなたも良いアイデアがあれば是非実装して本家に貢献しましょう!

ROS 2のメッセージパッケージのCMakeを簡単に! ~rosidl_auto_generate_interfaces~

この記事は「ROS 2 Advent Calendar 2025」の4日目の記事です。

メッセージパッケージのCMakeって微妙じゃないですか??

ROS / ROS 2ユーザーなら自前のメッセージパッケージを作ったことがある方は多いと思いますが、通常なら以下のようにしてCMakeファイルに.msg/.srv/.actionファイルを手書きで追加していきます。

rosidl_generate_interfaces(${PROJECT_NAME}
  msg/A.msg
  msg/B.msg
  DEPENDENCIES std_msgs geometry_msgs
)

私はこれをずっと当たり前だと思って過ごしてきました。
でも、あるとき私はこう思いました。

「なぜ私達は令和のこの時代にmsgフォルダ以下のメッセージファイルを手動で列挙しているのでしょうか?」

と。 メッセージのリストアップ部分もそうですが、メッセージパッケージのCMakeなんてほぼ典型的なおまじない記述ばかりなのですからもっとシンプルであっても良いはずです。

私の取り組み「rosidl_auto_generate_interfaces

このような悩みを解決すべく、現在私が実装してROSエコシステムへの組み込みに取り組んでいるのが rosidl_cmakeパッケージのrosidl_auto_generate_interfaces関数です。

github.com

この関数を使えば、どのようなメッセージパッケージでも以下のようなCMake記述を実現することができます。

cmake_minimum_required(VERSION 3.12)
project(my_interfaces)

find_package(ament_cmake_auto REQUIRED)
find_package(rosidl_cmake REQUIRED)
find_package(rosidl_default_generators REQUIRED)
ament_auto_find_build_dependencies()

rosidl_auto_generate_interfaces()

ament_auto_package()

驚くことにプロジェクト名以外は全てコピー・アンド・ペーストで済ませることができてしまいます。

rosidl_auto_generate_interfaces」の処理内容

  • package.xmlに基づく依存の自動収集
  • インタフェースファイルを自動収集して rosidl_generate_interfacesを呼ぶ
    • msg/*.msg
    • msg/*.idl
    • srv/*.srv
    • srv/*.idl
    • action/*.action
    • action/*.idl
  • ament_export_dependencies

ファイルの自動収集の妙

「ファイルの自動収集なんて file(GLOB)を使えば一瞬じゃ……」というのは少しでもCMakeの知識がある人ならすぐに思うことでしょう。 確かにそうなのですが、そう簡単ではないのです。

それは普通のfile(GLOB)にはファイルの追加/削除/更新をCMakeに通知しないという特性があるからです。 これでは、初回実行するときのビルドはうまく行きますが、メッセージファイルを追加したり既存のファイルを編集しても再ビルド時にCMakeにファイルの変更が伝わらず、毎回クリーンビルドが必要になってしまいます。

これを解決するのが、CMake 3.12で実装された file(GLOB)CONFIGURE_DEPENDS フラグです。

CMake 3.12 Release Notes — CMake 3.12.4 Documentation

このフラグを指定するとfile(GLOB) はファイルの更新・追加を通知するようになり、適切なリビルドが行われるようになります。

cmake_minimum_required(VERSION 3.12)

で3.12を最低バージョンとして設定しているのはこの機能を使うためという背景もあります。
ちなみにREP2000で規定されているCMakeの最低バージョンは現在有効なディストリビューションの中でも 3.14 であるため、この機能はHumbleまでもしっかりバックポート可能です。

https://ros.org/reps/rep-2000.html#humble-hawksbill-may-2022-may-2027

https://ros.org/reps/rep-2000.html#humble-hawksbill-may-2022-may-2027

rosidl_auto_generate_interfacesで作成したインタフェースを同一パッケージ内のソースコードで使いたい場合

TARGET 引数を用いて以下のようにすることで可能です。(複数指定可)

ament_auto_add_executable(${PROJECT_NAME}_node src/node.cpp)
rosidl_auto_generate_interfaces(TARGETS ${PROJECT_NAME}_node)

ちなみに、昔「ROS 2からはメッセージパッケージ内でメッセージを使うノードを作成することができなくなった」というような噂を聞いたことがありますが、今も昔もそんなことはありません。

Implementing custom interfaces — ROS 2 Documentation: Humble documentation

rosidl_generate_interfacesへの引数パススルー

この関数は、便利な自動収集機能を提供しつつも、以下のような rosidl_generate_interfaces 固有の引数はそのまま受け渡すので、柔軟性を損なわないように設計されています。

  • ADD_LINTER_TESTS
  • SKIP_INSTALL
  • LIBRARY_NAME

最後に

rosidl_auto_generate_interfaces関数はまだレビュー中の機能です。
プルリクエストへのレビューやコメントをお待ちしております!
(無事にマージされました!)

それでは楽しいROS 2ライフを!

SSL練習試合に参加してきた(2025年3月@豊田高専)

今回の練習会

3月7~9日の3日間のRoboCup Soccer SSLの練習試合に参加してきました。

会場は豊田高専で、国内でも珍しいAコート(12m x 9m)を設営できる素晴らしい部屋を用意頂きました。 豊田高専でもロボット系で広い部屋といえばこの部屋が割り当てられるようで、同じ部屋が2021年のJapanOpenに使われたほか豊田高専の学生ロボコンの審査ビデオにも登場するので、初めて来たのになぜかよく見知った部屋でした。

NHK学生ロボコン2023 2次ビデオ 豊田高専 https://youtu.be/QEmMnYx6RtU?si=HWus3DKWOVU0FPrn

個人的な目標

弊チームibisはチームとしての高い目標は持たずに高い心理的安全性を確保しつつ、各々がアツい思いを持って活動することで高いパフォーマンスを発揮するプライベートチームです。 というわけで、自分の「アツい思い」の動機づけとして個人的な目標を設定していました。

個人目標:世界大会出場チームにまともに点を決める

「世界大会出場チーム」というのは、日本からの世界大会常連チームである愛知県立大学RoboDragons・豊田高専KIKSのことを指します。 「まともに」というのは、正当な実力の結果としての点数を決めたいということです。 また、あくまでもibis視点の話ですが、これまでの大会や練習試合では、強いチームでもibisと対戦したときだけ攻撃のキレがなくなってしまった*1り、ibisになぜかマグレで点を入れられてしまうというジレンマがありました。 そういう事情もあり、誰が見ても実力が認められるような確かな得点をしたい、という思いが強くなっていました。

アップデート

今回の練習会に向けて、前回1月の練習会からAI班で用意したアップデートは主に以下の通りです。

  • さらなるボールの回り込み改善
  • アタッカー切り替えの精度の向上
  • パスの成功率改善
  • ビジュアライザ刷新(Foxglove)

ボールの回り込みや動作精度は前回の練習会でかなり改善された(↓のポスト)ので、その上にさらに細かな調整を積み重ねました。

1日目(3/7)

金曜日なので有給を取得して、もう一人のAI班の人とロボット6台で会場入りしました。 2人でも機材の持ち込みや設営ができるようになったのは、今までの機動力を意識したチーム活動の賜物でしょう。

PCのメモリが認識されなくなるというアクシデントがありつつも、この日は参加した3チームの全通りの組み合わせで試合をすることができました。

ibisの戦績は、KIKS戦で1-1、RoboDragons戦で3-3の同点でした。

試合をするごとにロボットから破裂音が聞こえたり、不調になるロボットが増えて、RoboDragons戦の最後にはまともに動くロボットが1台しか残っていないという状態になりました。ちくわごめん。

煌めくロボット

2日目(3/8)

ハードウェア班ちくわが到着し、爆速でロボットの復旧させてくれました。さすがちくわ

この日の試合は、RoboDragonsとの対戦でした。 RoboDragonsがKIKSと死闘を繰り広げた直後の試合でRoboDragonsの動くロボットがかなり減っており、 ロボット台数でかなりibisがリードしているという状況下での試合だったので、5点を決めることができました。 以前のibisなら逃していたようなチャンスもしっかりとモノにしてもぎ取った点数で、成長を感じました。

3日目(3/9)

この日はKIKSさんとの対戦があり、3-2で勝利しました。 練習試合を通して色々と調整したのもあり、一番良く動いていた試合でした。

youtu.be

自チームのパスを通したり、敵チームのパスカットやボールの奪取など数々の好プレーを見ることができ、見ていて純粋に楽しめるプレーをできるようになっていることに感動しました。

最後に

個人目標「世界大会出場チームにまともに点を決める」は文句なしに達成できて良かったです。 かなり動きのレベルが上がってきましたが、まだまだトレードオフなしに性能を上げられるような余地が残っていて、希望しかないです。(脳の報酬系バグっちゃう……)

また、去年のJapanOpenで日本ロボット学会賞を通じて運営からかけられている「大会を席巻しろ」という圧力期待に答えられる可能性がようやく見えてきました。 正直ホッとしている気持ちもありますが、JapanOpenでは今回の練習試合で対戦した2チームはibis対策を含めた強化をするでしょうし、世界大会Bリーグを制してAリーグに挑戦するチーム・初出場ながら優勝をねらうチームなど要警戒チームがたくさんいて油断はなりません。

今後も継続的なアップデートを重ねてJapanOpenまでに更にレベルアップしたいですね。 JapanOpenまであと1ヶ月半、駆け抜けるぞ〜!!!!

*1:昨年のJapanOpenでは世界大会準優勝チームZJUNLictと対戦して、ボコされると思いきや相手の不調で0-0で切り抜けるという試合もありました

rclcppへのコントリビュート体験談

はじめに

この記事はROS 2アドベントカレンダー6日目の記事です。

ROSConJP 2024で発表した、「ソフトウェアフレームワークChoreonoidのROS 2プラグインの設計と実装」という発表に出てくる内容を含みますので、そちらも是非ご覧ください。

roscon.jp

バグ発見

ChoreonoidのROS 2プラグインの実装をする中で、rclcpp::spin::someなど、spin系の関数にバグを見つけました。 ROS 2にはContextという概念があり、それを利用していたときの出来事でした。

この記事ではバグの詳しい内容には触れないですが、詳しく知りたい人はPullRequest(以下PR)を読んでみてください。
ちなみにContextについては以下の記事で解説されています。(恐らくContextに関する現時点で唯一の日本語記事)

ROS2を深く理解する:ROSノード編5 コンテキスト

PR作成

幸いにもバグの原因と修正ができたので、試しにrclcppにPRを作成して送ってみました。

github.com

具体的には以下のようなステップを踏みます。

  1. ros2/rclcppをフォークして自分のフォークを作る(自分の場合はHansRobo/rclcpp
  2. 自分のフォークを手元にクローンして修正をする
  3. 修正したコードを自分のフォークにpushする
  4. pushした修正ブランチを元に本家(ros2/rclcpp)に対してPRをつくる

ちなみに、PRの取り込み先はrollingブランチを設定します。 これは自分がHumbleなどのRollingではないバージョンを使っていてもそうします。 後で出てきますが、一度最新版であるRollingに取り込んだ後に必要に応じて各バージョンへバックポートするのです。

レビューが始まる

PRを提出すると、CodeOwnerに基づいて自動的にレビュアーが設定されます。

CodeOwnerに馴染みがないと一瞬自分が誤操作したようにも見えますが大丈夫です、修正した箇所に詳しい人が自動的にレビュアーに設定される便利な機能です。

テストを追加する

自分の場合はまず、レビュアーからテストの追加を求められました。
(EventExecutor周りで活躍しているiRobotのalsoraさんの登場に興奮しますね)

今までこのバグを検知するテストがなかったからこそ、バグがあったわけなので、当然と言えば当然です。 また、有効なテストはPRの修正の正当性を証明する良い根拠になりえますので、できれば最初から入れるべきでしょう。

テストは、PRを入れる前は失敗し、PRを入れると成功するようになるテストが追加できれば十分でしょう。 rclcpp/testディレクトリに既にたくさんのテストがありますから、見様見真似でテストを追加しました。

テストの実行

実際のテストの実行はレビュアーやメンテナーの方がROSのテストサーバーにて実行してくれます。

(画像ではnot runとなってしまっていますが、テスト実行から時間が経ってテスト結果が削除されてしまっただけだと思います。)

どうやら、現在追加されているテストの中には不安定なものも含まれているようで、関係ないテスト失敗にも遭遇しました。

PRのマージ

コードレビュー良し!テスト結果良し!となったらマージです。
やったぜ!rclcppへの初コントリビュートだ!!

バックポート

PRがマージされただけではRollingで使えるようになるだけです。
よく使われる、HumbleやJazzyなどのバージョンにバグ修正を取り込むには、バックポートという作業を行う必要があります。

自分でバックポートのためのPRを作っても良いですが、魔法の呪文をBotに対して唱えるだけでPRができます。

バックポートの呪文を唱えるSONYの藤田さん

以下がバックポートのPRで、これでIron/Humbleに取り込まれました。
(当時、Jazzyのリリース前だったのでJazzyへはバックポートは必要ありませんでした。)

github.com

github.com (IronへのバックポートPRは魔法の呪文がうまくいかなかったので藤田さんが作ってくれました)

修正のリリース

修正のマージやバックポートが終わってもすぐにapt経由で修正が配信されるわけではありません。
およそ2週間に1回のペースで各バージョンの取りまとめ役(ROS Bossと呼ばれます)がリリースを行っています。

自分が行った修正は2024/04/07にマージされたので、その次の2024/04/17のリリースに含まれているはずです。

discourse.ros.org

余談:Jazzyのコントリビューターリストに載りました

今回のPRがJazzyのリリースに間に合ったこともあり、コントリビューターリストに名前が載りました。 こうして見ると想像以上に日本人が少ないですね。

ROS 2 Jazzy Jalisco Released! - General - ROS Discourse

実はPRの途中で「もうすぐJazzyのリリースだから急いで」と言われたりしていました。

余談:レビュアーについて

レビュアーの方々は忙しいにも関わらず、かなり色々と面倒を見てくれて本当に助かりました。
一方で、皆さん忙しいので放置気味になることもあるので、気軽に催促をするマインドも必要です。
個人的には「friendly ping」が角が立たずに催促できる魔法の言葉で重宝しています。
(こういうことを気にするのは日本人の性なんですかね...)

ちなみに、後日ROSCon2024にてfriendly pingした相手のSONYの藤田さんと会うことができました。

おわりに

本当に簡単な内容でしたが、rclcppへ初めてコントリビュートできたのは良い経験でした。
これからも、ROSを使い、その改善にも関わっていけたらなと思っています。
また、この記事がrclcppをはじめとするROSのコアリポジトリ群へのコントリビュートするための道標になれば幸いです。
まだまだ日本からのコントリビュートが少ないので、もっと増えるといいな。

RoboCupジャパンオープン2024に出場してきた(後編)

RoboCupジャパンオープン2024に出場記の後編です。

前編では大会一日目までの話を書いたが、1勝2分けの好発進で2日目のCompilationErrorとの試合で引き分けに持ち込めれば得失点差で決勝リーグに進めることがわかっていた。

 

hans-robo.hatenablog.com

 

4/28 (大会2日目)

今日は決勝リーグ進出がかかった大切な試合!

”Keep programming!”  
”Programmer, never sleep”

 

ホテルの朝ご飯が始まった瞬間に凸して会場出発までの時間を睡眠にあてた。

アドレナリンで眠くはないが流石に寝ないと死んでしまう。

CompilationError

実は前日にチームリーダーのお兄さんと仲良くなっていたCompilationErrorとの対戦。ここで引き分けに持ち込めれば決勝リーグに進出できる。
絶対勝ちたいと思う一方で、勝ち進めると4徹目が確定するので流石にちょっと...という気持ちもあった。

 

流石ZJUNLictに勝ったことのあるチームだけあって、試合中のボール支配率はCompilationErrorの圧勝で、きれいなパス回しを見せていた。

一方で、ibisのデフェンスもよく動き、徹底的なマンツーマンマークとゴール前の壁の構築でシュートチャンスをよく潰していた。

しかし、前半終了間際に遂にibisは初失点を喫する。
それもディフェンスに戻ってきた味方ロボットが押し込むカタチのオウンゴールで....
せめてバシッと決められたかった...

 

youtu.be

 

一方で、色々とこれまで調整してきた甲斐があって、実装した動きが思い通りに動いている場面も多く見られた試合になった。

徹夜で実装したボールの先回りは、割とうまく動いていたようだ。

 

 youtu.be

 

また、ゴール前でのパスを検知したらパス先のロボットを特定した上で守備に回る、という動きをゴールキーパーに入れていたのだが、この試合中にその動きを実際に見ることができた。

動画を見ても「ボールを追いかけているだけじゃん」とピンと来ない人もいると思うが、ボールとほぼ同じ速度でゴールキーパーが動く、という動作はボールを追いかけているだけでは絶対に実現できないものなのだ。大会サーバー側での認識遅れ・AI内での遅れ・ロボット側での司令を受けてから動き出すまでのハードウェア的な遅延を考えると、どうしてもボールに対して1テンポ・2テンポ遅れてしまうのが現実だ。

youtu.be

結局、動画では相手のシュートが外れる形で終わるが、これもゴールキーパーが圧をかけていてミスを誘った結果だとも解釈できるので狙い通りではある。

ところどころ良い動きを見せたものの、結局試合状態は変わらず、0-1で敗北に終わってしまう。

若干の悔しさはあるものの、やれることは全部やって今のibisの全力が出し切れていたこと、SSL未経験者チームの初出場にしては十分すぎるほどの試合結果だったこと、そして何よりようやく寝れることもあって安堵の気持ちが大きかった。

試合後、CompilationErrorのお兄さんと健闘を称え合ったあと、お兄さんがドリブラの構造や調整シーンを見せてくれた。

ドリブラの後ろにはバネやダンパがあるわけではなく、スポンジが配置されていて衝撃を吸収しているらしい。

このスポンジをハサミでカットして入念に調整を行うようだ。どうやら日本のフィールドは海外のフィールドと比べて摩擦係数が違うのかかなり調整には苦労したよう。

強いドリブラの秘訣の一つは、F1マシンのタイヤのようにドリブラを超高速回転させることで摩擦熱でドリブルバーのラバーを溶かして粘着させることにあるんだとか....なんじゃそりゃ.........

道理でドリブルするときの音が全然違ったわけだ....

審判3

すべてを終えたので、メンバーには寝てと言われたがアドレナリンがバシバシで眠くなかった。
審判関連の仕事は他のメンバーがやってくれた。
ロボコン時代の同期と後輩が来ていたので久々に立ち話をしていた。

審判4

Roots vs KIKSの試合の主審を担当した。
正直あまり記憶が残っていないので多分問題なく進んだのだろう。


4/29 (大会3日目)

大会期間内初めてのまともな睡眠!
気持ちの良い目覚め!
軽い心!
スッキリとした頭!!!

審判5

主審担当。
この日ある決勝戦と3位決定戦はibisとRootsさんが審判担当になっていたが、初出場のチームに決勝戦の主審は酷だということでRootsさんが先に決勝戦の審判に立候補して頂いたようだ。
ありがたい限りである。
3位決定戦は中国チーム同士の対決なのでコミュニケーションは英語。

大会結果

決勝までが終わり、

1. RoboDragons
2. KIKS
3. ZJUNLict
4. Compilation Error

という結果になった。

ibisは順位こそ出ていないものの、5位か6位くらいだと思うのでよくやったと思う。


練習試合(Roots)

全試合終わったあとの時間は練習時間に当てられるのだが、迷わずRootsさんに練習試合の対戦をお願いした。

ibisのAIであるcraneはRootsさんが公開しているconsai系ソフトウェアにめちゃめちゃお世話になっており、Rootsさんのソフトウェアを見てSSLを学んだと言っても過言ではない。
リーグが違って対戦が叶わなかったので、日頃の感謝を込めた正拳突きである。
なぜか、ibisのAIが大会サーバーからの司令を受け取れず、かなりグダグダになってしまった。(大会中に発生しなくて良かった.....)

この試合でもゴール前パスに反応するゴールキーパーを見ることができた。

youtu.be

この場面ではパスに失敗しているが、他の試合を見ている感じではRootsさんのゴール前のパスは昔よりかなり洗練されて来ている印象なのであとでソースコードを見て勉強させてもらおうと思う。

練習試合(KIKS)

光栄なことに、KIKSさんから練習試合のお誘いを頂いた。

時間は1枠しかないのでRootsさんとの練習試合を早めに切り上げて後半はKIKSさんとの練習試合にあてた。

相変わらずibisのAIの不調が続き、グダグダな試合進行。

中でも嬉しかったのは以下の場面。少しズルい状況からスタートするのだが、両チームインプレイの状態でゴールの端を狙ってゴールを決めることに成功する。

もちろん、これはあくまでも不公平な状態からスタートしているので現状の実力を反映したものではないのだが、それでもこの状況でしっかりゴールを決められることが確認できた意義は大きかった。

youtu.be

来年の大会では正々堂々、正式なゴールを決めにいくぞ!

最後に

チーム結成から6年弱、出場までにコロナの影響を受けたり、研究で忙しくて全く進捗が出なかったり、そもそもあまりSSLに対してモチベがなかった期間もあった。

それでも、こうして大会出場に漕ぎ着けることができて本当に嬉しい。

大会期間中は本当に楽しくて、身体的にはかなり無理をしてしまったがアドレナリンと脳汁がドバドバでやめられなかった。後悔はしていない。

これだけの大会デスマーチに耐えられる体力はもう無いんじゃないかと思っていたので、自分でも少し驚いているというのが正直なところだ。

デスマーチはやらないに越したことはないが、ここぞとやりきれる体力はこれからも頑張って維持したいと思う。

大会を経て、ibisのできていること・できていないことが沢山判明したので来年の大会までにはしっかりと対策をして上位チームと互角に戦えるところまで持っていきたいところだ。

来年の大会には強くてニューゲームな新チームも現れるようなので非常に楽しみである。

 

SSLをやっていて本当に良かった。

SSL最高!

 

 

RoboCupジャパンオープン2024に出場してきた(前編)

ibisというプライベートチームでRoboCupのJapanOpen2024の車輪小型リーグに初参戦してきました。
色々と書いていたら長くなってきたので、とりあえず前編を出します。

この記事はソフトウェアの視点から書きますが、メカ班視点の記事はこちらに manjuu.hateblo.jp

開発習慣などの記事はこちら

hans-robo.hatenablog.com

※この記事は最大3徹状態の記憶が含まれます。事実と異なった記述があればこっそり教えてください。

4/25(移動日)

仕事を終えて荷造りをして新幹線で滋賀へ向かう。

ホテルについたら、実家に泊まると言っていたはずの他のメンバーに遭遇した。
なんでやねん。

大会前の最後の追い込みが始まる――――

”Keep programming!”
”Programmer, never sleep”*1

4/26(準備日)

この日は大会の準備日。最低限の動作確認は完了させたい。

チームリーダーのくじ運が悪すぎてラスボス引いてウケる(ウケない)

でもやるしか無いので、徹夜で頑張るしか無い!

ちなみに、この日もフィールドを使って練習できる時間があったのだが、チームリーダーは一番最初を枠を引いてきた。
つくづくくじ運の悪い男だ。もっと準備時間をくれ。

”Keep programming!”
”Programmer, never sleep”

4/27(大会1日目)

激動の一日だった。 この日は3試合をこなしたほか、主審もやった。

ZJUNLict戦

YouTube配信 www.youtube.com

初戦なこともあり、かなり違反が多くて相手には申し訳ない試合になってしまった。
一方、ロボットは基本的に調子よく動いていて一安心した。
世界大会優勝経験のある強豪ということでボコボコにされるだろうと身構えていたが、調整不足のようであまり振るわない動きをしていた。

調整時間中も「キッカーが蹴らないんだけど」「ごめん、OFFになってた」みたいな基本的なやり取りが聞こえていた気がするので研究室の新入生なのかもしれない。

もちろん、基本押され気味ではあるのだがデフェンスがよく動いていてなんとかしのいでいた。
あと、相手がダイレクトシュートのチャンスを幾度か見逃していたのも気になった。
世界大会ではダイレクトシュートコースが空いているなんていうことは基本ないので、考慮されていないのかも?(それマジ?)

多すぎるファール


試合進行上、ロボットが入ってはいけないエリアがあるのだが、エリア回避の動作でロボットの半径分の考慮をすっかり忘れていて、ギリギリエリアに侵入してしまうということを繰り返し、かなりの数のファールを記録した。

また、敵のフリーキックなのに味方ロボットが突撃してしまい、違反を取られるというハプニングも発生した。 そのようなプログラムを書いた覚えはなく、毎回再現するわけではないので迷宮入りしてしまう。結局、原因判明は夕方のRi-one戦を待つことになる。
結局、この試合でファール66回・イエローカード3回を記録するが、初出場のチームにしては少ない方らしい。


ペナルティキック


デフェンスエリアから脱出中のロボットがボールに触って蹴ってしまうハプニングがあり、ペナルティキックとなった。 ペナルティキック中、関係ないロボットはボールから1m以上下がらないといけないというルールがあるのだが、誤ってロボットのディフェンスエリア回避をONにしてしまっており、デフェンスエリアに引っかかって盛大に相手PKを邪魔してしまうというやらかしをしてしまった。 当然PKはやり直しになったが、相手がボールにバックスピンをかけすぎてPK失敗判定が下り、九死に一生を得た。 (SSLのPKでは相手ゴール方向以外へボールを進めてはいけないというルールがあり、バックスピンでボールが戻るだけでPK失敗となる)


PKが終わったところで試合時間オーバーで試合終了。
なんと、強豪相手に引き分けに持ち込むことができたが、前述の通りかなりファールをしてしまっているのでなんとも申し訳ない感じになってしまった。  

審判1 (Sasa-kamati vs Roots)

RoboCupの大会では、参加チームが持ち回りで審判をやる。
それは初参加の我々とて例外なく回ってくる。
審判は毎試合2チームが担当し、メインとサブのチームにそれぞれ役割が割り振られる。
このときはサブのチームに割り当てられた。

サブのチームの仕事内容


チームから2人出す必要があり、それぞれ「Assistant Referee」「Vision Expert」を担当する。

「Assistant Referee」
主審の補助をする役職だ。
具体的には判定が難しいときに主審の相談相手になったり、ボールを手動で動かす必要があるときにパシられる役になったりする。

Vision Expert」
天井のカメラ画像からロボットの位置などを計算し、各チームへ情報を送る「SSL Vision」というソフトウェアの面倒をみる役職だ。
通常、この役職は暇なことが多いが稀にロボットが認識されなくなったりするので、そのときにパラメータの調整などを行って改善する。


審判2 (KIKS vs RoboDragons)

遂にやってきた審判のメイン担当回。
メンバーはそれぞれルールを読んで来ているものの、日々ルールを違反しないようにソフトウェアを書いている自分が一番ルールを把握しているだろうということで、主審は自分になった。
ただ、この初主審のこの試合、相手が悪かった。
対戦するKIKSとRoboDragonsは世界大会常連の日本の2TOPである。
当然試合状況は目まぐるしく変化するし、両チームとも試合慣れしていて、少しでも怪しい判定をすると容赦なくチャレンジカードを切ってくる。
良い経験にはなったが気疲れがすごかった。

GreenTea戦

YouTube配信 www.youtube.com

GreenTeaは我々ibisより後に設立されたチームだが、一足先に大会に出場するようになった先輩チームだ。
メンバーのバックグラウンドがibisと似ていることもあり、メンバーには知り合いも多い。
出場する前から煽り合っており、ぜひボコボコにしたい相手だった。

しかし、試合が始まってみると絶望的に試合が進まない。致命的に相性の悪いのだ。 結果は0-0で引き分け。
次こそは!待ってろ、GreenTea!!

致命的に相性の悪い相手


コート中央付近で戦っている分には問題はないのだが、一度コートの角に入り込むともうだめだ。
一度ゴールキックで角に入るといつまで経ってもそこから抜け出さないのだ。
角にほとんどのロボットが固まっているせいで、パスを出そうにも角、フィールド外に出てもゴールキックで角、と試合が全く進まない。 途中、仕方がないのでタイムアウトを取って、ゴールキーパーのパス先を強制的にフィールド中心に変更してからかなりマシになったようにも思うが、結局時間内に得点変化はなく引き分けに終わった。


怪しくなってくるキックオフ


パラメータチューニングの副作用なのか、このGreenTea戦あたりからキックオフ動作が怪しくなっていた。 キックオフで蹴る直前にウェイポイントを置いているのだが、そこに到達する前に止まってしまい、いつまで経っても到達判定が出ずにキック動作に進めずキックオフができないのだ。


修正できた大量ファール


ZJUNLict戦で問題となった大量ファールは修正が間に合ったので、かなり減らすことができた。
基本的にこの手のファールはロボット同士がぶつかったり、立入禁止エリアに侵入してしまうことで発生する。
前者はロボットのスピードを落としたりして付け焼き刃の対策しかできなかった。
一方、後者についてはibisのソフトウェアでは立ち入り禁止区域をGridMapで保持しており、その設定を少し変えるだけで対応できた。
ちなみに、この試合ではGreenTeaよりもファール数が少なかったようだ。


この試合ではかなりGreenTeaのロボットに邪魔されることが多かったですが、しっかり障害物回避を効かせてエレガントに避けているのが見れてよかったです。 youtu.be

Ri-one戦

YouTube配信 www.youtube.com

Ri-oneもまた我々ibisより後に設立されたすごいチームだ。

新参ながらすごいチーム、Ri-one


これがまたすごいチームで、ibisがうかうかしている間に世界大会に出場して3位の成績を収めている*2
ibisが泥仕合の末、引き分けになってしまったGreenTeaも過去の大会では10-0でボコボコにしたこともある。 RoboDragons・KIKSに続き、Rootsと同じかそれ以上に強くて新参チームの中では頭一つ抜けたチーム、というのが個人的なRi-oneのチーム評価だったのでibisも欲張らず「勝てたらラッキー」くらいに考えていた。


しかし、今大会ではどうしたことか、ロボットに何やら問題があるらしく大会前から連日徹夜している様子。

3年目にしてヤバイチーム、Ri-one


聞くところによると、新機体の開発に伴って既存のロボット全てが動かなくなる変更をしたらしい。
どうしてそんなことになったか分からないが、初出場のibisよりも遥かに大変そうで大変そうだった(語彙力)


試合ができるか心配だったが、なんとか間に合ったようで、ibisとの対戦の時は多少怪しい動きもありつつも動いているようで一安心。

ちょっと動きの怪しいチーム、Ri-one


ロボットの調子が悪いのかソフトウェアの不具合なのか見分けがつかなかったが、それなりに動き出してからも少し怪しい動きをしていた。
ディフェンスエリアからボールを排出する動きがなかったり、ボールプレイスメントを邪魔したりと、ソフトウェアもリビルドされてルール対応がリセットされてしまっているのかも?と感じた。

ibisもibisでソフトウェアの状態遷移がうまく行かず2回ほどタイムアウトを取っている。


また、この試合は通信トラブルの多い試合であった。

通信トラブルとibisロボットの暴走


試合途中でGameControllerが混線して試合進行が止まるハプニングがあったが、配信解説担当によるとこの手のネットワークトラブルはこれでもかなり今年は少ないらしい。

試合開始後、しばらくするとibisのロボットが暴走を始める。 何が起こったのかと調べてみると、ロボットまでのpingが1秒を超えている。どうやら、隣のブースのRi-oneとWiFiアクセスポイントのチャンネルが被っていて、ibisのAPが競り負けていたようだ。 Ri-one側ではチャンネル変更ができないということで、ibis側がチャンネルを変更し、事なきを得た。 (自分の記憶では書いたとおりなのだが、配信解説では別リーグのAPと混線しているという説明がなされていて、真相は結局わからない)


初得点!!!!

通信トラブルから明けた直後に、なんとibis始まって以来初めての得点を決める!
しかも完璧なパスシュートで!!もう脳汁ドバドバ。

配信の奥の方をよく見ると、確かにフリーキックからのパスシュートをしているのがわかる。

youtu.be

怪しいキックオフ


ところで、Ri-oneもキックオフができないことが多々あり、GreenTea戦からキックオフ不調なibisと相まってどちらもキックオフができない奇妙な試合となった。 最後の方には、キックオフできないので強制開始コマンドでスタートするなど中々カオスになっていた。


通信が改善されてからはibisはよく動き、1点目ほどエレガントではないものの追加で2得点を決めることができた。
結果は0-3で初勝利!!
Ri-oneさんの調子が悪かったとは言え、勝利は勝利。
長年の悲願だったので嬉しさがこみ上げてくる。

また、本調子になったRi-oneさんと来年の大会で戦いたいものです。

このRi-one戦での得点を稼いだせいで、明日のCompilationError戦で同点に持ち込めば決勝進出できるらしい。 これは徹夜で頑張るしか無い!

”Keep programming!”
”Programmer, never sleep"

交流会

実はRi-one戦の裏でお寿司を食べながらSSL交流会が開催されていたらしい。
試合が終わって急いでいくと、試合をしていた我々の分はちゃんと残されてありました。優しい!

初勝利直後のお寿司ほど美味しいものはない....

交流会ではibisのロボットが大人気でした。

後編に続く...

*1:https://spiralray.sakura.ne.jp/blog/archives/1024#:~:text=%E2%80%9DKeep%20programming!%E2%80%9D%0A%E2%80%9DProgrammer%2C%20never%20sleep%E2%80%9D

*2:2つあるリーグのうち、魔境ではない方のリーグでの成績。それでも設立数年のチームがこの成績を収めるのは驚異的なことと言えよう