ros2 を使っていて generate_launch_description() という関数がどこから呼ばれて、帰値がどう影響するのかわからなかったので調べてみました。
generate_launch_description()
generate_launch_description() は、ROS 2のlaunchファイル(Python形式)で必要な関数で、launchシステムが起動時に自動的に呼び出す関数です。
サンプルコードを使った説明
ROS2 の Python launch ファイル(.launch.py)では、以下のような形式で記述されます。
from launch import LaunchDescription from launch_ros.actions import Node def generate_launch_description(): return LaunchDescription([ Node( package='my_package', executable='my_node', name='my_node', output='screen' ) ])
generate_launch_description() は 明示的に呼び出すことは通常なく、ROS2 の launch コマンドがこの関数を見つけて 自動で実行します。
呼び出される流れ
- ユーザーが以下のようにlaunchファイルを実行
$ ros2 launch my_package my_launch_file.launch.py
- ros2 launch コマンドは、my_launch_file.launch.py を Python としてインポート
- その中にある generate_launch_description() 関数を探し実行
- その返り値(LaunchDescription オブジェクト)に基づいて、ノードやその他のアクションを起動
補足
- ファイル名が *.launch.py である必要があり
- generate_launch_description() の返り値は LaunchDescription オブジェクトでなければならない
- import 忘れや文法ミスがあると launch 時にエラーが出る
帰値について
generate_launch_description() の返り値(LaunchDescription オブジェクト)は、ros2 launch コマンドの内部処理に渡されて、そこからlaunch エンジンによって使用されます。
つまり、「呼び出し元に返る」というよりは、Launch システムの「エントリーポイント」として扱われて、その中身が使われる」感じです。
処理の流れ
- ros2 launch コマンドを実行すると、内部で launch ライブラリが起動
- その中で対象の .launch.py ファイルが importlib などでインポート
- そのファイルの中の generate_launch_description() 関数が呼び出される
- その関数が返す LaunchDescription オブジェクトは、launchシステムに引き渡されて、記述された Node, TimerAction, GroupAction, IncludeLaunchDescription などのアクションが実行
どんな処理か
返り値(LaunchDescription)は、ユーザーコードには戻ってこなくて、内部的に launch システムによって 「実行計画」として評価・実行される。
以下のサンプルコードを例にすると、launch システムはこれを受け取って、「Nodeを起動」と理解して、talker ノードを起動してくれるみたいな流れになるという認識です。
def generate_launch_description(): return LaunchDescription([ Node(package='demo_nodes_cpp', executable='talker', output='screen') ])