darknet_rosに対するコードレビューがあり、「launchファイル多すぎ、もっとパラメータ付けて簡潔にしなさい」と言われてしまったので、ROS2のlaunchファイルをROS1に似た形式で書き換えることにしました。
しかし、コピペできそうなサンプルプログラムもリファレンスもなく結構困ることに…
今回はlaunchファイルをもう一つのlaunchファイルから呼び出してパラメータをより簡単に記載する方法をメモとして書こうと思います。
launch.pyファイルはPythonファイルですが、ここでは「launchファイル」と表記します。また、実行可能プログラムのことを「ノード」と読んでいます。
対象プログラム(param.cpp)
launchなしで実行してみましょう。$ ros2 run launch_launch param
で実行します。
declare_param
で設定したとおりに全て-1が返ってきました。特に特別なことはありませんね。
呼び出されるほうのlaunch.py
次に、呼び出される方のlaunchを書いていきます。
最初に呼び出されないことを前提にしたlaunchファイルを示します。
import launch import launch_ros.actions def generate_launch_description(): param_node = launch_ros.actions.Node( package="launch_launch", executable="param", output="screen", parameters=[{ "param0": 1, "param1": 2, "param2": 3, "param3": 4, }] ) #列挙したアクションを実行 return launch.LaunchDescription([ param_node, ])
次に呼び出される場合のlaunchファイルを記述していきます。呼び出されるlaunchは base.launch.py
です。(呼び出す方は read_launch.launch.py
です。)
ここで重要なメソッドにlaunch.substitutions.LaunchConfiguration
とlaunch.actions.DeclareLaunchArgument
があります。それぞれ説明します。
launch.substitutions.LaunchConfiguration
launch.substitutions.LaunchConfiguration
はLaunchファイル内でパラメータや引数を変数として扱い、ノードやLaunchファイルに引数として渡すことができます。
このlaunchファイルではparam_node
のparameters
への変数にしていますが、これによって"param0"
を他のアクションやlaunchファイルから扱うことができます。
launch.substitutions.LaunchConfiguration
がparam.cpp固有のパラメータ"param0"
を外部から扱えるようにパイプを接続しているように振る舞っているといえます。
launch.actions.DeclareLaunchArgument
launch.actions.DeclareLaunchArgument
は外部からlaunchファイルを扱うときのパラメータを定義しています。
このときに、"param0"
を外部から変更したい場合はlaunch.actions.DeclareLaunchArgument
の引数に"param0"
を入れる必要があります。
これをlaunch.LaunchDescription
に渡してgenerate_launch_description
の返り値に含めることでノードやLaunchファイルへの引数にすることができます。
ただし、このメソッド自体は宣言時点で引数宣言の役割は果たしているため、return launch.LaunchDescription
に入れる必要はありません。入れなかった場合は、呼び出されたときのみ適用されます。(default_valueが適用されない)
実行結果を示します
"argment0"
と"argment1"
を実際に実行しているため、"param0"
と"param1"
が1, 2になって、残りが0になっています。
そして、呼び出す方のlaunchを書いていきます。呼び出しは read_launch.launch.py
で行います。
launchファイルのロードは、get_package_share_directory
を活用してインストール先のlaunchファイルを探し、PythonLaunchDescriptionSource
でロードできます。
launch.actions.IncludeLaunchDescription
は、launchファイルをノードとほとんど同じように扱うことができます。ただし、パラメータを引数として与えることはできないため、全てlaunch_arguments
として渡しましょう。
実行結果です。
ちゃんと上書きができています。
まとめ
darknet_rosのlaunchファイルはyamlファイルをロードしますが、ここでは気軽に試せるように直接値を渡す例で解説しました。
ROS2のlaunchファイルの書き方はサンプルが多くなく、正しいと思ってもエラーになる場合が多いので結構つまづきポイントになるので、使えるlaunchファイルの書き方があればどんどん書いていこうと思います。
ROS2でもROS1と同様にxml形式で書くことができるそうですが、せっかくPythonで書けるのだからPythonの豊富なライブラリを活用してlaunchファイルを設計しましょう❗
以前のlaunch(Python)の設計↓