ROS2をもっと良くしたい

ISP では ROS2 + Qt Quickを使ったシステム開発 の様に ROS/ROS2 を使った開発を行なっていますが、 ROS/ROS2 そのものの開発にも貢献したいと考えています。
先日 ROS 2 のリアルタイムワーキンググループ(RT WG)で発表する機会がありましたので簡単にご紹介します。

Raspberry Pi で測定中!測定時の電源も重要なのです。
Raspberry Pi で測定中!測定時の電源も重要なのです。

ROS2 のリアルタイム性

ROS2 ではリアルタイム性を標榜しています。ここで言う「リアルタイム」ですが処理の速さではなく「決められた時間内に処理を完了する・見積れること」を意味します。
自動運転・宇宙船・製造業など安全性やミッションクリティカルな場面で重要な機能になります。ROS2 では設計時からリアルタイム性を意識して開発されています。

  Real-time programming in ROS 2 に ROS 2 同梱のデモの説明があります。
  Introduction to Real-time Systems にリアルタイム性や開発での注意点の説明があります。

タイマー精度と DDS 子スレッド

では今現在 ROS 2 はどの程度のリアルタイム性を持つのでしょうか?

まず出発点としてタイマーの起床精度に着目し、いくつかの実験を行ないました。
具体的にはハードウェアを固定(Raspberry Pi を利用)し ROS2 内部で実行している nanosleep やタイマーコールバックの精度にどれ位のブレやオーバヘッドがあるかを測定しました。

結果として以下の様にシステム全体で注意深いチューニングが必要なことが分かりました。

  • Raspberry Pi のハードウェア設定
  • kernel 設定や CPU コアの割り当てなどの OS 設定
  • clcpp::init や DDS(ROS2 の利用する通信ミドルウェア) 由来の子スレッドのスケジューリングポリシや優先度の設定

実験結果とこれらの知見を ROS Discourse という ROS に関する議論・検討ページに報告し、 2020/06/23 の RT WG で説明しました。

  ROS2 generated child thread scheduling policy affects timers
  Experiment to inhibit DDS and ROS2 child threads

以下の図は子スレッドのスケジューリングポリシや優先度設定を変えた時の nanosleep のズレのヒストグラムです。
詳細は省略しますが、右下の図が右側に伸びていることから、この設定はあまり良くないことが分かります。

nanosleep wake-up latency

ThreadedCallback

ISP では通信装置やマイコンによるハードウェア制御等でリアルタイムシステムを開発してきました。よくあるパターンは RTOS を使い各種処理をタスクして実装・優先度やクリティカルセッションの設計を頑張るといったものです。
一方 ROS2 はそもそもプロセスとして実行されており Executor という一種のスケジューラの様な機構を内包しています。SingleThreadedExecutor という 1 スレッドのもの、 MultiThreadedExecutor というスレッドプールを使った実装が同梱されています。
これに対し「RTOS の様に “スレッド” としてタスク=コールバックを実装し、優先度と CPU 割り当てを静的に設定できても良いのでは?」という発想から ThreadedCallback というものを現在開発中です。

このコンセプト検証の実装を作成しアイデアと概要を Discouse に投稿しました。また、 2020/07/07 の RT WG で説明しました。

  Threaded Callback with priority, affinity and overrun handler

引き続き検討・実験中の為、まとまり次第報告します。