自律移動ロボットの計算負荷は小さくない。地図生成やナビゲーションといった重い処理を、車体に搭載したエッジコンピュータだけで完結させると、性能上の天井にすぐ突き当たる。newbotでは、駆動・センサー取得・安全監督をエッジ機(Raspberry Pi 5)に残し、地図生成とナビゲーションをより高性能なPCへ分散する構成を採用している。

ROS 2ROS 2

画像: Robot Operating Systemロゴ、Wikimedia Commons(CC BY-SA 4.0)

役割分担

安全機構(速度調停・障害物ガード・非常停止)は全てエッジ機側に残しているため、PCやネットワークが落ちても、手動操作と物理的な非常停止は今までどおり機能する。自律走行の指令が届かなくなり、フェイルセーフとして安全に停止するだけである。

この役割分担は最初からこの形だったわけではない。分散運用を導入した当初は、自己位置推定(FAST-LIO)もPC側に置く構成だった。しかし後述する無線帯域の実測で、生のLiDAR点群をそのままPCへ送るのが非現実的だと判明したため、自己位置推定は単一機構成と同じくエッジ機側に戻し、間引いた点群だけをPCへ送る形に設計変更している。「重い処理はPCへ」という原則を無条件に適用するのではなく、実測でネットワークが持ちこたえない部分は現場(エッジ機)に残す、という判断がこの構成の実質的な出発点になっている。

RTAB-Mapによるセンサーフュージョン

PC側の地図生成には、単一機モードで使っているslam_toolboxではなくRTAB-Mapを採用した。RTAB-Mapはそれ自体ではオドメトリを計算せず、FAST-LIOが出力する/odomを外部オドメトリとして受け取り、カメラ映像(視覚特徴)とLiDARの整形済み3D点群(幾何形状)の両方をループクロージャ(既に訪れた場所を再認識して地図のズレを補正する処理)に使う。RTAB-Mapが地図とmap→odom変換を配信する構成のため、ナビゲーション側の設定はslam_toolbox使用時と同じインターフェースのまま変更せずに済む。

導入後に見直しを迫られたRTAB-Mapの位置づけ

もっとも、このRTAB-Map採用という設計判断は、その後の安全機構の見直し作業の中で再考を迫られている。RTAB-Mapの価値であるカメラ視覚特徴によるループクロージャや、床面と障害物を分離する処理は、いずれもカメラを常時有効にできることが前提になる。ところが実機検証で、カメラを有効化するとCPU使用率が約75%まで跳ね上がり、自己位置推定(FAST-LIO)の更新頻度が10Hzから0.5Hzまで低下することが判明した。カメラを使わない前提であれば、床面・障害物の分離処理も、結局は同じ死角を持つLiDAR点群を入力にする以上、根本的な弱点(近傍の低い障害物が見えない)は解決しない。加えて、slam_toolboxとRTAB-Mapという2系統の地図生成を並行して保守することは、設定の食い違いを生む余地にもなる。

こうした経緯から、RTAB-Mapは既定の構成からは外し、カメラを常用できるCPU余裕ができるまでは実験的な位置づけとして扱う方向で検討している。分散構成そのもの(重処理をPCへ寄せる設計)と、その上で何のアルゴリズムを使うか(RTAB-Mapか、slam_toolboxか)は別の問題であり、後者は実測に応じて随時見直す、という整理である。

無線帯域の制約という現実

エッジ機とPCの間はWi-Fiで接続されているため、センサーの生データをそのまま流すことはできない。実際に、以下の2つのデータで深刻な帯域超過を経験している。

データ 生のサイズ・レート 症状
LiDAR生点群 約500KB/メッセージ × 10Hz 実測1.87Hz(約81%のデータ損失)
カメラ生画像 約921KB/フレーム × 30Hz(約27MB/秒) 画像0Hz、点群も巻き添えで0.1Hzまで低下、SSHも不通に

大きなトピックをPCが購読した瞬間に帯域が飽和し、そのトピックだけでなく他の通信まで巻き添えで機能しなくなる、という点が実機検証で分かった重要な教訓である。対策は、PCへ送る前に必ずエッジ機側でデータを削ることに尽きる。LiDAR点群は1/4に間引いてから送り、カメラ映像は3Hzへの間引きとJPEG圧縮を組み合わせて約1/150のデータ量に圧縮してから送る。間引き後は点群がほぼフルレート(約9.94Hz)で到達するようになり、地図生成・ナビゲーションともに安定動作するようになった。

もっとも、帯域を削ったことで問題がすべて解決したわけではない。カメラ映像の間引き圧縮自体は帯域面では合格(実測で1秒あたり数十KB程度まで圧縮)しているが、そもそもカメラをエッジ機側で有効化するとエンコーダー処理自体がCPUを約75%消費し、自己位置推定の更新頻度が10Hzから0.5Hzまで落ち込む。つまり帯域の制約を解決した先に、今度はCPUという別の制約が現れたことになる。ボトルネックは一度潰したら終わりではなく、潰すたびに次の層へ移動する、という実感を持たせる経験だった。

分散構成が安全設計に落とす影を

役割を分散させたことは、安全機構の設計にも副作用を及ぼしている。障害物ガードはエッジ機側で生の点群を直接見て前進速度をクランプする層であり、PC側にはNav2のcollision_monitorとコストマップという別の保護層が存在する。3つの層はそれぞれ別のデータソース(生点群 vs LaserScan)、別の幾何定義(足回りの寸法を独立に持つ)で動いており、これらが食い違っていても気づく仕組みがない、という構造的な課題を抱えている。

より本質的なのは、保護の生存範囲がエッジ機とPCとで異なることである。障害物ガードがエッジ機だけで動くのは「PCやネットワークが落ちても保護が生き続ける」という設計思想によるもので、これは正しい。しかし裏を返せば、エッジ機側のガードを何らかの理由で無効化した場合、エッジ機側の保護はゼロになる。PC側のcollision_monitorは実機の検証実験でも障害物への反応を100回以上記録しているが、これはあくまでPC側の保護であり、Wi-Fiが切れれば同時に失われる。分散構成の恩恵(重処理をPCへ逃がせること)は、同時に「PCが落ちても安全側に倒れる経路がどこにあるか」を常に意識する必要がある、という設計上の負荷も生んでいる。

PC(重処理機)の生死そのものも、エッジ機側から見える形にしている。PC側で1Hzのハートビート信号を配信し、エッジ機側はこの信号の到着間隔が3秒を超えるとPC接続が切れたと判定する(接続状態の判定方法自体は「状態可視化ダッシュボードの実装」の記事で扱った、他のコンポーネントの接続判定と同じ考え方である)。

通信基盤の安定化

ROS2のノード間通信基盤(DDS)は既定でマルチキャストに依存するが、Wi-Fi環境ではこれが不安定要因になりうる。エッジ機とPCそれぞれの実IPアドレスを明示的な通信相手(ユニキャストピア)として設定することで、マルチキャストへの依存を減らし、通信の安定性を高めている。

分散構成の導入で実際に踏んだ罠

単一機構成から分散構成へ移行する際、想定していなかった環境固有の問題をいくつも踏んでいる。いずれも「動かない」という症状だけが見え、原因は別の層にあるという点で共通している。

これらはいずれも、ROS2やアルゴリズムそのものの不具合ではなく、OS・ネットワーク・仮想化環境といった下位レイヤーに起因するものだった。分散構成を導入する際は、アプリケーション層より先にこうした基盤部分を疑うべきだという教訓が残っている。

参考リンク

#RTAB-Map