@calm0815
ROS2ではじめよう
次世代ロボットプログラミング
4.1~4.3 章
西田研 M2 桑野 僚大
ROS2勉強合宿@別府温泉 10/5
@calm0815
自己紹介
• 名前:桑野 僚大(Kuwano Tomohiro)
• 所属:九州工業大学 M2 西田研究室
• 研究:ソフトロボットハンド
自動車部や学生フォーミュラの活動を経て現在に至る。
研究室メンバーに日々煽り煽られながらもROSの勉強中。
(感謝しかないですよ!!!) Twitter : @calm0815
Github : calm0815
➢ https://github.com/calm0815
@calm0815
第4章 ROS2の応用機能
4-1:LAUNCHシステム 4-2:アクション 4-3:ライフサイクル
参考文献(資料中の図はすべて以下の文献から引用しています):
ROS2ではじめよう 次世代ロボットプログラミング、近藤豊 著
https://www.amazon.co.jp/ROS2ではじめよう-次世代ロボットプログラミング-近藤-豊/dp/4297107422
@calm0815
4-1 : LAUNCHシステム
4-1-1 : talker/listenerノードのlaunchファイル
4-1-2 : パラメータを使うlaunchファイル
4-1-3 : パラメータファイルを使うlaunchファイル
@calm0815@calm0815
4-1 : LAUNCHシステム
ROS1の
Launchシステム
ノードの起動方法がXML形式で記述されたファイル
➢ ノードの設定
➢ パラメータ設定
➢ 名前空間やマップの設定
➢ 修了したノードの自動再起動の設定
【起動例】 $ roslaunch [package_name] launch_name.launch
Launchシステムの役割 : 複数のノードを記述された実行手順の通りに実行する
 起動手順の構成に制御構文を使いたい
 複数ノードの全体像を把握するのが難しい
⇒ launchファイルを複数に分割してインクルードしたい
 デバッグするにはXMLの解釈器が必要であり、原因の特定が難しい
⇒ 簡単にデバッグしたい
@calm0815@calm0815
ROS2の
Launchシステム
ノードの起動方法がpythonで記述されたファイル
➢ ノードの設定
➢ パラメータ設定
➢ 名前空間やマップの設定
➢ 修了したノードの自動再起動の設定
➢ 各ノードの状態を監視する機能
【起動例】 $ ros2 launch [package_name] launch_name.launch.py※黄色字は変更点
4-1 : LAUNCHシステム
Launchシステムにプログラミング言語のpythonを採用することで
ROS1で抱えていた問題を解決
※ROS1からの移植性を考慮して、XML記法やYAML記法も導入される予定
@calm0815
4-1 : LAUNCHシステム
4-1-1 : talker/listenerノードのlaunchファイル
4-1-2 : パラメータを使うlaunchファイル
4-1-3 : パラメータファイルを使うlaunchファイル
@calm0815@calm0815
ノードの構成、起動手順を記述したlaunchファイルの本体
launch_ros.actions.Nodeに起動したいノードの保存場所・起動手順を
設定する。引数は以下の3つ。
⚫ package
パッケージ名
⚫ node_executable
ノードの実行ファイル名
⚫ output
‘screen’を指定すると標準出力にログを出力。
デフォルト値は’log’で、この場合はログファイルに出力。
4-1-1 : TALKER/LISTENERノードのLAUNCHファイル
talker_listener.launch.py
@calm0815@calm0815
4-1-1 : TALKER/LISTENERノードのLAUNCHファイル
talker_listener.launch.py
@calm0815@calm0815
4-1-1 : TALKER/LISTENERノードのLAUNCHファイル
package.xml
CMakefiles.txt
@calm0815@calm0815
4-1-1 : TALKER/LISTENERノードのLAUNCHファイル
実行結果
( ^ω^)おっ、なんかディストリビューション関係で文句言われてんな
@calm0815
4-1 : LAUNCHシステム
4-1-1 : talker/listenerノードのlaunchファイル
4-1-2 : パラメータを使うlaunchファイル
4-1-3 : パラメータファイルを使うlaunchファイル
@calm0815@calm0815
4-1-2 : パラメータを使うLAUNCHファイル
ROS1のLaunchシステム
⚫ arg
roslaunchファイル自体に渡す引数
⚫ param
パラメータの値
@calm0815@calm0815
4-1-2 : パラメータを使うLAUNCHファイル
ROS2のLaunchシステム
⚫ launch.actions
launchファイルの動作の定義
⚫ launch.substitutions
launchファイル実行時に決定する値の定義
ROS2ノード以外の実行ファイルの呼び出しや環境変数の読込み・設定など
今後、ROS2以外の機能も取り組んでいくためにROS1からその仕組みが
再構築された。
@calm0815@calm0815
【Permalink】
https://github.com/youtalk/get-started-
ros2/blob/e2492985e35d3dad98968f0e9ec86ae5fd890e96/ros2/hello_world
/launch/talker_listener_with_param.launch.py#L21-L37
ROS2から新たにlaunchファイルに記述する呼び出しは以下2つ
⚫ launch.substitutions.LaunchConfiguration
Launchシステムのための変数宣言(ROS1ではパラメータの値)
⚫ launch.actions.DeclareLaunchArgument
launchファイルの引数定義(ROS1ではroslaunch自体に渡す引数)
talker_listener.launch.py
4-1-2 : パラメータを使うLAUNCHファイル
@calm0815
4-1 : LAUNCHシステム
4-1-1 : talker/listenerノードのlaunchファイル
4-1-2 : パラメータを使うlaunchファイル
4-1-3 : パラメータファイルを使うlaunchファイル
@calm0815@calm0815
4-1-3 : パラメータファイルを使うLAUNCHファイル
params.yaml
【Permalink】
https://github.com/youtalk/get-started-
ros2/blob/e2492985e35d3dad98968f0e9ec86ae5fd890e96/ros2/hello_world/launch/talker
_listener_with_param_file.launch.py#L21-L23
talker_listener_with_param_file.launch.py
@calm0815@calm0815
4-1-3 : パラメータファイルを使うLAUNCHファイル
ここまでの内容以外にもLaunchシステムにはたくさんの機能が備わっている
➢ Launchファイルの設計文書
https://github.com/ros2/launch/blob/dashing/launch/doc/source/architecture.rst
より実践的なlaunchファイルの記述例は、navigation2パッケージの
リポジトリが参考になる(らしい。未確認)
➢ navigation2
https://github.com/ros-planning/navigation2
@calm0815
4-2 : アクション
4-2-1 : アクションの定義ファイル
4-2-2 : フィボナッチ数列のアクション実装
@calm0815@calm0815
4-2 : アクション
ROS2のアクション
• ROSのメッセージ通信のひとつ
• サービスのように引数/返り値がある
• 返り値が返ってくるまでの値(フィードバック)が
トピックのように受け取れる
• アクション実行中に処理を中断させるなどの命令が可能
@calm0815
4-2 : アクション
4-2-1 : アクションの定義ファイル
4-2-2 : フィボナッチ数列のアクション実装
4-2-1/4-2-2で
フィボナッチ数列の解を返すアクションを用いて、
その実装方法をみていく
@calm0815@calm0815
https://github.com/youtalk/get-started-
ros2/blob/e2492985e35d3dad98968f0e9ec86ae5fd890e96/ros2/fibonacci/action/Fi
bonacci.action
Fibonacci.action
4-2-1 : アクションの定義ファイル
アクションの定義ファイルに必要な3つの要素
⚫ Goal
アクションの目標値
⚫ Result
アクションの実行結果
⚫ Feedback
アクションサーバ(アクションの実行ノード)が返す途中経過の内容
@calm0815
4-2 : アクション
4-2-1 : アクションの定義ファイル
4-2-2 : フィボナッチ数列のアクション実装
4-2-1/4-2-2で
フィボナッチ数列の解を返すアクションを用いて、
その実装方法をみていく
@calm0815@calm0815
アクションサーバの実装に必要なハンドラ
• 目標値の設定時に呼び出されるハンドラ
• アクションの実行開始時に呼び出されるハンドラ
• アクションのキャンセル時に呼び出されるハンドラ
※ハンドラ:プログラムやその一部分で、何らかの処理要求が発生したときに起動されるもの
(wiki調べ)
4-2-2 : フィボナッチ数列のアクション実装
action_server.cpp
@calm0815@calm0815
アクションクライアントの実装に必要なハンドラ
• 目標設定の受信コールバック関数
• 実行結果の受信コールバック関数
• フィードバックの受信コールバック関数
4-2-2 : フィボナッチ数列のアクション実装
action_client.cpp
@calm0815@calm0815
【Link】
https://github.com/youtalk/get-started-
ros2/blob/release/ros2/fibonacci/src/action_server.cpp
4-2-2 : フィボナッチ数列のアクション実装
action_server.cpp
【Link】
https://github.com/youtalk/get-started-
ros2/blob/release/ros2/fibonacci/src/action_client.cpp
action_client.cpp
@calm0815@calm0815
4-2-2 : フィボナッチ数列のアクション実装
@calm0815
4-3-1 : ライフサイクルの状態遷移
4-3-2 : 主要状態
4-3-3 : 中間状態
4-3-4 : ライフサイクル対応talker実装
4-3-5 : ライフサイクル対応listener実装
4-3-6 : 外部ノードからのライフサイクル制御
4-3-7 : 動作確認
4-3 : ライフサイクル
@calm0815@calm0815
4-3 : ライフサイクル
アプリケーションをよりよく制御するためにROS2から導入された新システム
ライフサイクルの活用により、
• ノード同士の実行開始
• 接続順序
を厳密に制御し、正しく起動できるようになる
ライフサイクルの現在状態を外部ノードから状態遷移トピックという形で取得可能
状態遷移を変更するサービスも提供されており、外部ノードから能動的にノードの
状態を制御できる
@calm0815@calm0815
ライフサイクルの状態遷移に沿ってプログラムを実行できれば
それ以外の部分(≒内部実装)は完全にブラックボックスにできる
ライフサイクルのコンセプト
4-3 : ライフサイクル
サードパーティが開発したROS2ノードの詳細な内部実装を知らなくても、
ライフサイクルを制御するだけで使いこなせるようになる
※サードパーティ:どこの馬の骨ともわからん第三者組織
@calm0815
4-3-1 : ライフサイクルの状態遷移
4-3-2 : 主要状態
4-3-3 : 中間状態
4-3-4 : ライフサイクル対応talker実装
4-3-5 : ライフサイクル対応listener実装
4-3-6 : 外部ノードからのライフサイクル制御
4-3-7 : 動作確認
4-3 : ライフサイクル
@calm0815@calm0815
4-3-1 : ライフサイクルの状態遷移
ノードのライフサイクルには
4つの主要状態と
6つの中間状態がある。
中間状態とは
「主要状態間を遷移中」
という状態を意味する。
※灰四角:主要状態
※白四角:中間状態
@calm0815@calm0815
4-3-1 : ライフサイクルの状態遷移
状態遷移は以下のルールで発生する。
• 主要状態から中間状態を経由して矢印の先にある次の主要状態に遷移することが
できれば、状態遷移の成功。
• 状態遷移中に失敗が発生すると、矢印の逆方向のもとの主要状態に戻される。
• 失敗とは別に、エラー(補足されない例外)を検出すると、
Error Processing状態に遷移する。Error Processingに成功すると
Unconfiguredに戻り、失敗するとFinalizedに移り実行終了する。
• 主要状態の中で唯一、Active状態からのエラー検出時のみ自動で
Error Processing状態に遷移する。
@calm0815
4-3-1 : ライフサイクルの状態遷移
4-3-2 : 主要状態
4-3-3 : 中間状態
4-3-4 : ライフサイクル対応talker実装
4-3-5 : ライフサイクル対応listener実装
4-3-6 : 外部ノードからのライフサイクル制御
4-3-7 : 動作確認
4-3 : ライフサイクル
@calm0815@calm0815
4-3-2 : 主要状態
4つの主要状態はそれぞれ
以下の状態を表す
⚫ Unconfigured
➢ 初期化前
⚫ Inactive
➢ スピン停止状態
⚫ Active
➢ スピン状態
⚫ Finalized
➢ 終了処理後
@calm0815@calm0815
4-3-2 : 主要状態
⚫ Unconfigured
ノード起動後にすぐ遷移する状態。ノードの初期化が終わってない。
エラー処理後もこの状態に戻る。
⚫ Inactive
ノードが何も処理を行っていない状態。ノードのパラメータを変えたり、
トピックのPublisher/Subscriber構成を変えたりするために、ノードを
(再)Unconfigured状態にさせるために用いられる。
この状態では、トピックやサービスリクエストが届いても、読み込み、データ処理、
サービスレスポンスを行うことはできない。QoSポリシーに従い、
これらのトピックやサービスリクエストは保留される。
@calm0815@calm0815
4-3-2 : 主要状態
⚫ Active
ノードの一番メインとなる状態。
この状態では、トピックの送受信、サービスのレスポンス、データ処理が行われる。
もし、ノードもしくはシステムで解決できないエラーを検出した場合、
自動的にError Processing状態に遷移する。
⚫ Finalized
ノードが破棄される直前に遷移する状態。
この状態からは実行終了以外に、ほかの状態へ遷移することはできない。
この状態は、デバッグや自己検証のためにあり、
ノードの破棄を可視化することが可能。
@calm0815
4-3-1 : ライフサイクルの状態遷移
4-3-2 : 主要状態
4-3-3 : 中間状態
4-3-4 : ライフサイクル対応talker実装
4-3-5 : ライフサイクル対応listener実装
4-3-6 : 外部ノードからのライフサイクル制御
4-3-7 : 動作確認
4-3 : ライフサイクル
@calm0815@calm0815
4-3-3 : 中間状態
6つの中間状態はそれぞれ
以下の状態を表す
⚫ Configuring
➢ 初期化中
⚫ Cleaning Up
➢ 再初期化中
⚫ Shutting Down
➢ 終了処理中
⚫ Activating
➢ スピン状態へ移行中
⚫ Deactivating
➢ スピン停止状態へ
移行中
⚫ Error Processing
➢ エラー処理中
@calm0815
4-3-1 : ライフサイクルの状態遷移
4-3-2 : 主要状態
4-3-3 : 中間状態
4-3-4 : ライフサイクル対応talker実装
4-3-5 : ライフサイクル対応listener実装
4-3-6 : 外部ノードからのライフサイクル制御
4-3-7 : 動作確認
4-3 : ライフサイクル
@calm0815@calm0815
4-3-4 : ライフサイクル対応TALKER実装
【Link】http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29
ROS1のpublisherでは、
main関数の中でwhileループを回してトピックを送信した。
【ROS1】talker.cpp
82 while (ros::ok())
83 {
95 /**
96 * The publish() function is how you send messages. The parameter
97 * is the message object. The type of this object must agree with the type
98 * given as a template parameter to the advertise<>() call, as was done
99 * in the constructor above.
100 */
101 chatter_pub.publish(msg);
102
103 ros::spinOnce();
104
105 loop_rate.sleep();
106 ++count;
107 }
よくみるやつ
@calm0815@calm0815
状態遷移時に呼び出されるコールバックメソッドのインターフェースを提供して
くれる
• 初期化時に呼び出されるコールバックメソッド
• スピン状態へ移行時に呼び出されるコールバックメソッド
• スピン停止状態へ移行時に呼び出されるコールバックメソッド
• 再初期化時に呼び出されるコールバックメソッド
• 終了処理時に呼び出されるコールバックメソッド
• エラー処理時に呼び出されるコールバックメソッド
ライフサイクルを実現するROS2ノードでは
状態遷移時に呼び出されるコールバックメソッドを実装する必要がある。
【ROS2】talker.cpp
4-3-4 : ライフサイクル対応TALKER実装
rclcpp_lifecycle::LifecycleNodeクラス
@calm0815@calm0815
状態遷移時に呼び出されるコールバックメソッドのインターフェースを提供して
くれる
• 初期化時に呼び出されるコールバックメソッド
• スピン状態へ移行時に呼び出されるコールバックメソッド
• スピン停止状態へ移行時に呼び出されるコールバックメソッド
• 再初期化時に呼び出されるコールバックメソッド
• 終了処理時に呼び出されるコールバックメソッド
• エラー処理時に呼び出されるコールバックメソッド
rclcpp_lifecycle::LifecycleNodeクラス
【Link】ライフサイクル対応版
https://ithub.com/ros2/demos/blob/dashing/lifecycle/src/lifecycle_talker.cpp
【ROS2】talker.cpp
4-3-4 : ライフサイクル対応TALKER実装
@calm0815
4-3-1 : ライフサイクルの状態遷移
4-3-2 : 主要状態
4-3-3 : 中間状態
4-3-4 : ライフサイクル対応talker実装
4-3-5 : ライフサイクル対応listener実装
4-3-6 : 外部ノードからのライフサイクル制御
4-3-7 : 動作確認
4-3 : ライフサイクル
@calm0815@calm0815
【Link】ライフサイクル対応版
https://github.com/ros2/demos/blob/dashing/lifecycle/src/lifecycle_listener.cpp
【ROS2】listener.cpp
4-3-5 : ライフサイクル対応LISTENER実装
トピックのメッセージの型はlifecycle_msgs::msg::TransitionEvent
これをコールバックメソッドで監視することで、たとえば、
1. カメラ出力ノードAがActive状態に遷移したあと、
2. 画像処理ノードBはUnconfigured状態からActive状態に遷移する。
といったノード起動の順序関係を制御、プログラミングすることができる。
@calm0815
4-3-1 : ライフサイクルの状態遷移
4-3-2 : 主要状態
4-3-3 : 中間状態
4-3-4 : ライフサイクル対応talker実装
4-3-5 : ライフサイクル対応listener実装
4-3-6 : 外部ノードからのライフサイクル制御
4-3-7 : 動作確認
4-3 : ライフサイクル
@calm0815@calm0815
4-3-6 : 外部ノードからのライフサイクル制御
ライフサイクルは、外部ノードからサービスを通じて制御することも可能。
3-3-4項のライフサイクルに対応したtalkerのライフサイクルを制御する
https://github.com/ros2/demos/blob/dashing/lifecycle/src/lifecycle_service_client.cpp
のライフサイクルの状態取得と状態制御を行う部分を確認していく。
@calm0815
4-3-1 : ライフサイクルの状態遷移
4-3-2 : 主要状態
4-3-3 : 中間状態
4-3-4 : ライフサイクル対応talker実装
4-3-5 : ライフサイクル対応listener実装
4-3-6 : 外部ノードからのライフサイクル制御
4-3-7 : 動作確認
4-3 : ライフサイクル
@calm0815@calm0815
4-3-7 : 動作確認
@calm0815
ご清聴ありがとうございました
温泉
行こうぜ!

ROS2勉強会 4章前半