要点
- 開発したシステム: 「3D LiDAR → PointPillars(3D 物体検出)→ 検出結果配信」を、KR260 の DPU 上で完結させ、
sensor_msgs/PointCloud2を購読してvision_msgs/Detection3DArrayを配信する 標準的な ROS2 ノードとして実装。 - 性能: 1 フレーム 67.0 ms、14.9 FPS を実機実測。3D LiDAR の 10 FPS 入力にリアルタイム追従。
- ROS エンジニアから見たメリット: OS カスタマイズなし / ROS カスタマイズなし。標準の
ros2 launchで起動でき、ROS ノードから直接 FPGA を操作。DPU での AI 推論と GPIO / PWM 制御を 同時に扱える。 - FPGA がロボットで活きる理由: 処理時間が決定論的・低遅延・高スループット・柔軟な入出力。GPU では得にくい「毎フレーム同じ時間で終わる」という性質は、リアルタイム制御に寄与する。
はじめに: なぜ FPGA の会社が ROS の話をするのか
当社は、放送市場や遠隔施工向けの映像伝送コーデックや HPC 向け PCIe アクセラレータなどを手がけてきた FPGA が得意なエンジニア集団です。今まで培ってきた FPGA を扱う知見を応用することで、より広範な分野において計算リソースの最適化により社会に貢献できないか、という思いから CRO (Computing Resource Optimization) 技術部が発足しました。その一環で私は以前より温めていた FPGA の技術をロボット分野で活かせないか という取り組みを行い、今回の記事を執筆する運びとなりました。
私は大学で制御工学を専攻し、ドローンの姿勢制御とセンサ処理について研究していました。その後、縁あってロボットとはかけ離れたアイベックステクノロジーに入社しました。もともと FPGA には興味がありましたが、入社以来 FPGA に触れるうちに「FPGA を ROS と組み合わせれば、ロボットシステムをもっと進化させられるのではないか」という考えがさらに強くなりました。以来、社内で長く研究・調査を続けてきたテーマです。このたび 3D LiDAR を扱う機会に恵まれ、その成果として組み上げた ROS システムを本記事で紹介します。
ロボットで AI 推論と言えば、まず GPU(Jetson など)を思い浮かべる方が多いと思います。GPU はとても強力です。一方で、FPGA には GPU とは違った強みがあります。特に 「毎回きっちり同じ時間で処理が終わる(決定論的)」「低遅延」「AI 推論と I/O 制御をワンチップで同時にこなせる」 という性質は、リアルタイム性が重要なロボット制御と非常に相性が良いのです。
とはいうものの、FPGA には「開発が難しい」「ROS と繋ぐのが大変そう」というイメージが根強くあります。従来より、各所で FPGA と ROS を組み合わせようという試みは行われてきました。例えば、AMD は Kria Robotics Stack (KRS) と呼ばれる仕組みを提供しています。しかしそれらは、FPGA 経験者から見ても非常にややこしいプロセスを介する必要があり、また ROS ユーザから見ても困惑するものでした。
そこで今回は、ROS の流儀のまま FPGA の回路を呼び出せる構成を目指しました。FPGA の開発者と ROS ユーザが、互いに気持ちよくコラボレーションをして、ロボットの性能を向上できることを願ってやみません。
概要
本システムを端的に示すと、「KR260 の DPU で 3D LiDAR の点群から 3D 物体検出を行い、その結果を ROS2 トピックとして配信するノード」 です。まずは全体像を図と表で示します。
| 項目 | 内容 |
|---|---|
| ボード | AMD Kria KR260 Robotics Starter Kit(Arm Cortex-A53 ×4 内蔵、PL 部に DPU を実装) |
| OS | Ubuntu 22.04(Kria 用 Canonical 公式イメージ) |
| ROS | ROS2 Humble(標準インストール) |
| 検出モデル | PointPillars(3D 物体検出)、Vitis AI Model Zoo のモデルを採用 |
| 検出クラス | 車両・歩行者・自転車 |
| 入力センサ | 3D LiDAR(260,000 points/sec、10 FPS) |
| 本システム実測性能 | 67.0 ms/frame、14.9 FPS(10 FPS リアルタイム追従) |
用語解説(詳しくは後半の「システム説明」で):
- DPU : FPGA 上に実装する AI 推論アクセラレータ
- PS : SoC 内の CPU 領域
- PL : SoC 内の FPGA 領域
- SOM : CPU+FPGA を載せた基板モジュール
- ビットストリーム : FPGA(PL)に書き込む回路構成データ
なお Kria KR260 は、CPU と FPGA がワンチップに統合された SoC(AMD Zynq UltraScale+ MPSoC)を搭載した SOM(System on Module) ボードです。「論理回路だけの FPGA」とは少し違う、という点はこの後の「システム説明」で改めて整理します。
ここで登場する DPU(Deep Learning Processing Unit) は、FPGA 上に実装するディープラーニング推論専用のアクセラレータに相当します。「FPGA の中に作り込んだ AI 推論エンジン」です。技術的な詳細は後半の「システム説明」で詳しく触れます。
この構成が具体的にどう有利なのか、まずは FPGA がロボットで活きる特長から見ていきましょう。
FPGA がロボットで活きる 4 つの特長
本記事で最も伝えたい点です。今回の実装を通じて実感した、FPGA(DPU)ならではの強みを挙げます。
1. 処理時間が決定論的
FPGA の推論はハードウェアで処理されるため、毎フレームほぼ同じ時間で完了します。今回の DPU 推論部(PointPillars の 2 つのモデル。後掲の実測表の Model0 23.6 ms + Model1 32.6 ms)は合計 56 ms で安定していました。
GPU では OS のスケジューリングや他プロセスとの競合、動的なクロック制御などでフレームごとに処理時間がばらつくことがあります。ロボットの制御ループやセンサフュージョンでは、この ジッタの小ささが重要になります。「最悪ケースでも間に合う」を設計しやすいのは、FPGA の大きな強みです。
2. 低遅延
センサ入力から結果出力までの経路が短く、余計なバッファリングやコンテキストスイッチが少ないため、遅延を小さく抑えられます。障害物検知のように「速く気づくこと」が安全に直結する用途では重要な特性です。
3. 高スループット
DPU は演算を大規模に並列化するため、限られた電力・サイズでも高いスループットを出せます。今回は 14.9 FPS を実測し、LiDAR の 10 FPS 入力に十分な余裕をもって追従できました。
4. 柔軟な入出力: AI 推論と GPIO / PWM を同時に
これは FPGA ならではの特長です。同じチップの FPGA(PL)部に、DPU に加えて AXI GPIO や AXI Timer(PWM)を自由に配置できます。今回は PMOD コネクタ経由の GPIO / PWM を実装し、DPU での推論と GPIO 出力に同時にアクセスできることを確認しました。
例えば「検出数と最短距離を、そのまま LED やモーターへ出力する」といったことが、外付けのマイコンなしにワンチップで完結します。今回は実際にこれを PMOD の GPIO LED にリアルタイム出力しています。センサ入力 → AI 推論 → アクチュエータ出力までを 1 デバイスで閉じられるのは、ロボットのシステム設計を大きくシンプルにします。

ROS エンジニアから見たメリット
FPGA の強みが分かっても、「導入コストが大きいなら使いたくない」というのが ROS エンジニアの本音だと思います。本記事のシステムではこの部分を強く意識しています。
- OS カスタマイズなし: Canonical 公式の Ubuntu 22.04 イメージをそのまま使用。OS のビルドなどは不要。
- ROS カスタマイズなし: ROS2 Humble を標準インストール方法で導入するだけ。
- 標準の
ros2 launchで起動: 普段通りのコマンドで、推論ノードと可視化ノードを一括起動できる。 - 実機がなくても検証できる: 記録した点群データ(pcap / rosbag)を再生してパイプライン全体を動かせるので、LiDAR が手元になくても開発を進められる。
- ROS ノードから直接 FPGA を操作: ビットストリームのロードから DPU 推論、GPIO 制御まで、ボード上で完結。実行時はホスト PC への依存なし。
- 標準メッセージ型で疎結合:
PointCloud2を購読してDetection3DArrayを配信するだけなので、既存のパイプラインに組み込みやすい構成。
FPGA の内部を意識せず、ROS の作法のまま処理の速い「物体検出ノード」として使える。これが今回最も注力した点です。
システム説明
ここからは、内部構成がどうなっているのかを掘り下げます。
前提: SoC(Zynq) と SOM(Kria) とは
「FPGA」と聞くと、論理回路(ゲート)だけのチップを思い浮かべる方が多いと思います。 今回使う KR260 が積んでいるのは、AMD の Zynq UltraScale+ MPSoC、すなわち CPU と FPGA がワンチップに統合された SoC です。
Zynq UltraScale+ MPSoC は、大きく 2 つのブロックからなります。
- PS(Processing System): Arm Cortex-A53 ×4 などを含む「CPU 部」。ここで Ubuntu と ROS が動きます。
- PL(Programmable Logic): 回路を自由に構成できる「FPGA 部」。ここに DPU や AXI GPIO / Timer を作り込みます。
そして Kria は、この Zynq UltraScale+ MPSoC を扱いやすくモジュール化した AMD の SOM(System on Module) 製品シリーズです。今回の KR260 は、Kria の K26 SOM を搭載したロボティクス向けスターターキットにあたります。
CPU と FPGA の役割分担
CPU(PS) と FPGA(PL) がワンチップに同居しているので、CPU 側で ROS を動かしつつ、重い推論を FPGA(PL)側の DPU にオフロードできます。DPU は PL 上に実装するディープラーニング推論専用アクセラレータで、ビットストリームとしてボード起動後にロードします。
「CPU がホストとして司令塔を務め、FPGA が計算の重い部分を専任で引き受ける」。この役割分担が、後述する CPU と FPGA の並列動作、そしてリアルタイム処理達成のベースになっています。
処理の流れ
処理は単純な一方向の流れです。
入力トピックも出力トピックも ROS2 標準のメッセージ型(sensor_msgs/PointCloud2 と vision_msgs/Detection3DArray)です。つまり、既存の ROS2 パイプラインの一部として 差し替え可能な形になっています。推論ノードの中で DPU にアクセスしていること以外は、一般的な ROS2 ノードです。
デモ: リアルタイムに 3D 物体検出
走行環境の点群をリアルタイムに取り込みながら、車両・歩行者・自転車を 3D バウンディングボックスで検出します。検出結果は鳥瞰図(BEV)として KR260 の DisplayPort に直接出力できるほか、/bev_image トピックとして配信することもできます。
技術的な工夫: CPU と FPGA の処理を並列に実行
PointPillars の処理は、DPU が担う推論部分(PointNet + RPN)だけで完結するわけではありません。その前後に、点群を格子(Voxel)に変換する 前処理、アンカー候補を絞り込む アンカーマスク、特徴をグリッドに戻す Scatter、ボックスをデコードして NMS をかける 後処理という CPU 側の処理が必要です。
つまり 1 フレームの処理は、「CPU の仕事」と「FPGA(DPU)の仕事」が交互に並ぶパイプラインになっています。ここで FPGA を活かすカギが、CPU と FPGA をできるだけ同時に動かすことでした。
CPU 処理と DPU 推論の並列化
CPU 側のアンカーマスク処理(実測 21.4 ms)は、DPU 推論を含む処理(PointNet → Scatter → RPN)と 書き込むバッファが互いに独立しています。そこで両者を 別スレッドで並列実行しました。CPU がアンカーマスクを計算している間、FPGA は推論を進められます。DPU 推論(56 ms)の裏で、アンカーマスク(21.4 ms)は余裕をもって終えられます。
CPU と FPGA がワンチップに同居しているからこそ、点群データを外部へコピーする手間なく、こうした細かい並列化を無理なく実装できるのも利点です。
ROS ノード側でも、コールバックは点群を投入するだけにして推論を専用スレッドで回し、キューは常に最新フレームを優先する構成にしました。これで LiDAR の 10 FPS 入力に対してフレームドロップのないリアルタイム動作を実現しています。
最終的な性能(実機実測)
KR260 実機で計測した 1 フレームあたりの処理時間(20 回平均)です。
| 処理 | 時間 | 実行系統 |
|---|---|---|
| 前処理(Voxelization、CPU) | 4.7 ms | 本スレッド |
| アンカーマスク(CPU) | (21.4 ms) | 別スレッド |
| Model0 PointNet(DPU) | 23.6 ms | 本スレッド |
| Scatter(CPU) | 3.1 ms | 本スレッド |
| Model1 RPN(DPU) | 32.6 ms | 本スレッド |
| 後処理(Box decode + NMS、CPU) | 3.0 ms | 本スレッド |
| 合計(実測) | 67.0 ms | |
| 平均 FPS | 14.9 |
各段を単純に足すと 88.4 ms ですが、実測の 1 フレーム処理時間は 67.0 ms。差の21 ms がまさに、DPU 推論と並列化されたアンカーマスクです。計測用のマーカーを埋め込んだ実測でも、本スレッドが合流点に達した時点でアンカーマスクは既に完了しており(待ち時間 0 ms)、CPU 処理が完全に隠蔽されていることを確認しました。この 67.0 ms は「DPU 推論 + 並列化できない CPU 処理」だけが残った理論下限値です。
DPU は演算規模の異なる複数の構成から選べますが、今回は PL リソース規模とのバランスから中規模の構成である B3136 を採用しました。それでも LiDAR 出力レートの 10 FPS を大きく上回る 14.9 FPS を達成しています。
入力から結果までの遅延(End to End、E2E)
上表の 67.0 ms は「点群 1 フレームを受け取ってから検出を出すまでの計算時間」です。ロボットにおいて実際に重要となるのは、センサが世界を捉えてから検出結果が出力されるまでの総遅延(E2E) です。各ノードに独自の計測マーカーを埋め込んで実測した中央値は以下のようになります。
| 区間 | 遅延 |
|---|---|
| LiDAR の 1 スキャン蓄積 | 101 ms |
| ドライバノードの点群生成 + トピック転送 | 5 ms |
推論ノードの処理(点群受信 → /detections publish) | 67.3 ms |
先頭パケット到来 → /detections(合計) | 173 ms |
| (参考)さらに BEV 画像として表示するまで | 196 ms |
推論ノードとした場合の処理時間は 67.3 ms です。前掲のスタンドアロン実測 67.0 ms とほぼ一致しており、ROS ノード化による点群変換などのオーバーヘッドは 0.3 ms 程度にとどまります。ROS ノードにした場合も、処理性能を変わらず維持できる結果です。
また、この計測結果から、10 FPS(100 ms 周期)には余裕をもって追従できる一方で、今回の事例ではある瞬間の点群に対する検出結果は、スキャン蓄積 101 ms + 以降の処理 72 ms で 1~2 周期遅れて出力されていることが分かります。このうち 100 ms のスキャン蓄積は今回使用した LiDAR ドライバ固有の仕様であり、今回は最適化の範囲外としています。FPGA が寄与するのは残りの処理側であり、その処理時間が 毎フレームほぼ一定である点です。
なお制御に用いる場合、この遅れは「消す」より 「既知の量として織り込む」 のが定石です。本システムでは検出メッセージに元の点群の header.stamp がそのまま引き継がれるため、後段のノードは「その検出がいつ観測されたものか」を正確に知ることができます。あとは自己位置推定や状態推定の側で、その時刻差だけ予測を進めてから使えば良い、という設計に落とせます。このとき厄介なのは遅延の大きさそのものより、フレームごとに遅延がばらつくことです。ばらつきは予測の前提を崩し、制御則のチューニングを難しくします。処理時間が毎フレームほぼ一定という FPGA の性質は、まさにここで効果的と言えます。
導入を考える際に浮かぶ疑問点
ここまでを踏まえ、実際の導入に必要な事項を、想定される疑問に沿って整理します。
FPGA の回路(RTL)を自作する必要はあるか
今回の事例では不要です。DPU は AMD が提供する既製の推論 IP(DPUCZDX8G)で、RTL を書くのではなく Vivado 上で構成・配置します。PMOD 用の GPIO / Timer も標準の AXI IP を並べるだけです。これらをまとめたビットストリームは一度ビルドすれば良く、以降は KR260 の起動後に 一度ロードするだけで使えます。日々の運用で RTL に触れることはありません。
ビットストリームのビルドは一般的な Vivado / Vitis のフローで、所要時間は 1~3 時間程度です。
ソフトウェアに親しみのある ROS エンジニアの皆様への説明のため「ビルド」と表現していますが、FPGA では「合成(synthesize)」と表現することが一般的です。
DPU の構成(規模)を変更するには
DPU 構成(B3136 / B4096 など)の変更には ビットストリームの再ビルドが必要です(設定ファイルの切り替えではありません)。見方を変えれば、性能・消費電力・回路規模のトレードオフを ハードウェアレベルで最適化できるという利点でもあります。
構成を変えた複数のビットストリームを用意しておけば、PS 側から適用するビットストリームを切り替えることも可能です(PL は要リセット)。後からハードウェア処理の構成を変更できるのは FPGA ならではの特長です。
独自の学習済みモデルを搭載できるか
搭載可能です。フローは AMD の Vitis AI に沿います。学習済みモデルを INT8 に量子化 → DPU 向けにコンパイル します。今回の PointPillars も Vitis AI の学習済みモデルを利用しました。
- 対応演算: DPU がサポートする演算に限られます。未対応の演算は CPU 側で処理をするか、モデル側の工夫が必要になることがあります。
- 精度: INT8 量子化による精度への影響はモデル・データ依存です(一般に軽微ですが、要検証)。
- モデル規模: DPU の構成と PL のリソースに収まる範囲であることが前提となります。
別の LiDAR・別解像度へ差し替えられるか
入力は sensor_msgs/PointCloud2(x, y, z, intensity)なので、トピックとしては差し替え可能です。ただし検出精度はモデルに依存します。PointPillars は学習時の 点群レンジ・グリッド・intensity スケール(および取り付け高さなどのドメイン)を前提とするため、大きく異なる LiDAR やマウントに変えると 再調整・再学習が必要になる場合があります。
CPU / FPGA の並列化は自動か、手動か
アプリケーション側で実装した手動のスレッド設計です(前述の、アンカーマスクと DPU 推論の並列実行)。どの処理を並列化できるかはモデルの依存関係によって決まるため、別のモデルを載せる場合は、その構造に応じた並列化の検討が改めて必要になります。
まとめ
今回は、3D LiDAR の点群を KR260 の DPU で処理し、PointPillars による 3D 物体検出を ROS2 標準ノードとしてリアルタイム動作させる仕組みを構築しました。ポイントを改めて整理します。
- FPGA(DPU)の強みは 決定論的な処理時間・低遅延・高スループット・柔軟な入出力。リアルタイム性が求められるロボットと相性が良い。
- AI 推論と GPIO / PWM 制御をワンチップで同時に扱えるため、システム構成をシンプルにできる。
- 上記を達成していながら OS も ROS も標準のまま、
ros2 launchで起動でき、標準メッセージ型で既存パイプラインに組み込める。
「FPGA は気になるけど手が出しづらい」と感じている ROS エンジニアの方に、選択肢の一つとして FPGA を知っていただければ幸いです。
当社は FPGA を使用した基板 / 筐体設計、RTL 実装から ROS への統合までを一貫してサポートできます。本記事で触れた範囲では、例えば次のようなご相談をお受けしています。
- ビットストリームのビルドやロード手順の整備、用途に合わせた DPU 構成の選定
- 独自モデルの量子化・コンパイルと、モデル構造に応じた CPU / FPGA 並列化のチューニング
- RTL の設計を伴う案件(機能要素を IP としてモジュール化した形での設計・提供も可能な場合があります)
ROS × FPGA でこうしたことは実現できないか というご相談を歓迎しています。お気軽にお問い合わせください。
なお本記事に反響があれば、ビットストリームのビルド手順など、より踏み込んだ内容を続編として公開することも検討しています。ぜひ、SNS などで話題にしていただけると幸いです。
商標について
- Arm、Cortex は、Arm Limited(またはその子会社もしくは関連会社)の米国およびその他の国における商標または登録商標です。
- AMD、Zynq、Kria、UltraScale+、Vivado、Vitis は、Advanced Micro Devices, Inc. の商標または登録商標です。
- Ubuntu は、Canonical Ltd. の登録商標です。
- ROS は、Open Robotics の商標です。
- その他、本記事に記載されている会社名、製品名、サービス名は、各社の商標または登録商標です。
- 本文中では、™、® などの表示を省略しています。