diff --git a/source/How-To-Guides/Launch-file-different-formats.rst b/source/How-To-Guides/Launch-file-different-formats.rst index 0c1065d16c7..bc470c7620a 100644 --- a/source/How-To-Guides/Launch-file-different-formats.rst +++ b/source/How-To-Guides/Launch-file-different-formats.rst @@ -2,7 +2,7 @@ Guides/Launch-file-different-formats -Using Python, XML, and YAML for ROS 2 Launch Files +Using XML, YAML, and Python for ROS 2 Launch Files ================================================== .. contents:: Table of Contents @@ -29,6 +29,7 @@ Each launch file performs the following actions: .. group-tab:: XML +<<<<<<< HEAD .. code-block:: xml @@ -136,11 +137,22 @@ Each launch file performs the following actions: - from: "/output/cmd_vel" to: "/turtlesim2/turtle1/cmd_vel" +======= + .. literalinclude:: launch/different_formats_launch.xml + :language: xml + + .. group-tab:: YAML + + .. literalinclude:: launch/different_formats_launch.yaml + :language: yaml +>>>>>>> 666df3e (Pull all example launchfiles into separate file with `literalinclude` (#5155)) .. group-tab:: Python - .. code-block:: python + .. literalinclude:: launch/different_formats_launch.py + :language: python +<<<<<<< HEAD # example.launch.py import os @@ -239,6 +251,8 @@ Each launch file performs the following actions: turtlesim_node_with_parameters, forward_turtlesim_commands_to_second_turtlesim_node, ]) +======= +>>>>>>> 666df3e (Pull all example launchfiles into separate file with `literalinclude` (#5155)) Using the Launch files from the command line -------------------------------------------- @@ -287,7 +301,7 @@ To test that the remapping is working, you can control the turtles by running th .. _launch-file-different-formats-which: -Python, XML, or YAML: Which should I use? +XML, YAML, or Python: Which should I use? ----------------------------------------- .. note:: diff --git a/source/How-To-Guides/Launching-composable-nodes.rst b/source/How-To-Guides/Launching-composable-nodes.rst index af27880589d..1b9731219b7 100644 --- a/source/How-To-Guides/Launching-composable-nodes.rst +++ b/source/How-To-Guides/Launching-composable-nodes.rst @@ -31,108 +31,18 @@ The launch files all do the following: .. group-tab:: XML - .. code-block:: xml - - - - - - - - - - - - - - - - - - + .. literalinclude:: launch/composition_launch.xml + :language: xml .. group-tab:: YAML - .. code-block:: yaml - - launch: - - - node_container: - pkg: rclcpp_components - exec: component_container - name: image_container - namespace: '' - composable_node: - - pkg: image_tools - plugin: image_tools::Cam2Image - name: cam2image - namespace: '' - remap: - - from: /image - to: /burgerimage - param: - - name: width - value: 320 - - name: height - value: 240 - - name: burger_mode - value: true - - name: history - value: keep_last - extra_arg: - - name: use_intra_process_comms - value: 'true' - - - pkg: image_tools - plugin: image_tools::ShowImage - name: showimage - namespace: '' - remap: - - from: /image - to: /burgerimage - param: - - name: history - value: keep_last - extra_arg: - - name: use_intra_process_comms - value: 'true' + .. literalinclude:: launch/composition_launch.yaml + :language: yaml .. group-tab:: Python - .. code-block:: python - - import launch - from launch_ros.actions import ComposableNodeContainer - from launch_ros.descriptions import ComposableNode - - - def generate_launch_description(): - """Generate launch description with multiple components.""" - container = ComposableNodeContainer( - name='image_container', - namespace='', - package='rclcpp_components', - executable='component_container', - composable_node_descriptions=[ - ComposableNode( - package='image_tools', - plugin='image_tools::Cam2Image', - name='cam2image', - remappings=[('/image', '/burgerimage')], - parameters=[{'width': 320, 'height': 240, 'burger_mode': True, 'history': 'keep_last'}], - extra_arguments=[{'use_intra_process_comms': True}]), - ComposableNode( - package='image_tools', - plugin='image_tools::ShowImage', - name='showimage', - remappings=[('/image', '/burgerimage')], - parameters=[{'history': 'keep_last'}], - extra_arguments=[{'use_intra_process_comms': True}]) - ], - output='both', - ) - - return launch.LaunchDescription([container]) + .. literalinclude:: launch/composition_launch.py + :language: python Loading composable nodes into an existing container @@ -147,112 +57,18 @@ The below example launches the same nodes as above. .. group-tab:: XML - .. code-block:: xml - - - - - - - - - - - - - - - - - - - - + .. literalinclude:: launch/composition_load_launch.xml + :language: xml .. group-tab:: YAML - .. code-block:: yaml - - launch: - - node_container: - pkg: rclcpp_components - exec: component_container - name: image_container - namespace: '' - composable_node: - - pkg: image_tools - plugin: image_tools::Cam2Image - name: cam2image - namespace: '' - remap: - - from: /image - to: /burgerimage - param: - - name: width - value: 320 - - name: height - value: 240 - - name: burger_mode - value: true - - name: history - value: keep_last - extra_arg: - - name: use_intra_process_comms - value: 'true' - - - pkg: image_tools - plugin: image_tools::ShowImage - name: showimage - namespace: '' - remap: - - from: /image - to: /burgerimage - param: - - name: history - value: keep_last - extra_arg: - - name: use_intra_process_comms - value: 'true' + .. literalinclude:: launch/composition_load_launch.yaml + :language: yaml .. group-tab:: Python - .. code-block:: python - - from launch import LaunchDescription - from launch_ros.actions import LoadComposableNodes, Node - from launch_ros.descriptions import ComposableNode - - def generate_launch_description(): - container = Node( - name='image_container', - package='rclcpp_components', - executable='component_container', - output='both', - ) - - load_composable_nodes = LoadComposableNodes( - target_container='image_container', - composable_node_descriptions=[ - ComposableNode( - package='image_tools', - plugin='image_tools::Cam2Image', - name='cam2image', - remappings=[('/image', '/burgerimage')], - parameters=[{'width': 320, 'height': 240, 'burger_mode': True, 'history': 'keep_last'}], - extra_arguments=[{'use_intra_process_comms': True}], - ), - ComposableNode( - package='image_tools', - plugin='image_tools::ShowImage', - name='showimage', - remappings=[('/image', '/burgerimage')], - parameters=[{'history': 'keep_last'}], - extra_arguments=[{'use_intra_process_comms': True}] - ), - ], - ) - - return LaunchDescription([container, load_composable_nodes]) + .. literalinclude:: launch/composition_load_launch.py + :language: python Using the Launch files from the command-line @@ -271,7 +87,7 @@ Intra-process communications All of the above examples use an extra argument to setup intra-process communication between the nodes. For more information on what intra-process communications are, see the :doc:`intra-process comms tutorial <../Tutorials/Demos/Intra-Process-Communication>`. -Python, XML, or YAML: Which should I use? +XML, YAML, or Python: Which should I use? ----------------------------------------- See the :ref:`discussion ` in :doc:`Launch-file-different-formats` for more information. diff --git a/source/How-To-Guides/launch/composition_launch.py b/source/How-To-Guides/launch/composition_launch.py new file mode 100644 index 00000000000..9e1477fa839 --- /dev/null +++ b/source/How-To-Guides/launch/composition_launch.py @@ -0,0 +1,36 @@ +import launch +from launch_ros.actions import ComposableNodeContainer +from launch_ros.descriptions import ComposableNode + + +def generate_launch_description(): + """Generate launch description with multiple components.""" + return launch.LaunchDescription([ + ComposableNodeContainer( + name='image_container', + namespace='', + package='rclcpp_components', + executable='component_container', + composable_node_descriptions=[ + ComposableNode( + package='image_tools', + plugin='image_tools::Cam2Image', + name='cam2image', + remappings=[('/image', '/burgerimage')], + parameters=[{ + 'width': 320, + 'height': 240, + 'burger_mode': True, + 'history': 'keep_last'}], + extra_arguments=[{'use_intra_process_comms': True}]), + ComposableNode( + package='image_tools', + plugin='image_tools::ShowImage', + name='showimage', + remappings=[('/image', '/burgerimage')], + parameters=[{'history': 'keep_last'}], + extra_arguments=[{'use_intra_process_comms': True}]) + ], + output='both', + ), + ]) diff --git a/source/How-To-Guides/launch/composition_launch.xml b/source/How-To-Guides/launch/composition_launch.xml new file mode 100644 index 00000000000..00df0aaee1b --- /dev/null +++ b/source/How-To-Guides/launch/composition_launch.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/source/How-To-Guides/launch/composition_launch.yaml b/source/How-To-Guides/launch/composition_launch.yaml new file mode 100644 index 00000000000..b423cfb1d08 --- /dev/null +++ b/source/How-To-Guides/launch/composition_launch.yaml @@ -0,0 +1,39 @@ +%YAML 1.2 +--- +launch: + - node_container: + pkg: rclcpp_components + exec: component_container + name: image_container + composable_node: + - pkg: image_tools + plugin: image_tools::Cam2Image + name: cam2image + remap: + - from: /image + to: /burgerimage + param: + - name: width + value: 320 + - name: height + value: 240 + - name: burger_mode + value: true + - name: history + value: keep_last + extra_arg: + - name: use_intra_process_comms + value: true + + - pkg: image_tools + plugin: image_tools::ShowImage + name: showimage + remap: + - from: /image + to: /burgerimage + param: + - name: history + value: keep_last + extra_arg: + - name: use_intra_process_comms + value: true diff --git a/source/How-To-Guides/launch/composition_load_launch.py b/source/How-To-Guides/launch/composition_load_launch.py new file mode 100644 index 00000000000..e3a99c9bd2b --- /dev/null +++ b/source/How-To-Guides/launch/composition_load_launch.py @@ -0,0 +1,37 @@ +from launch import LaunchDescription +from launch_ros.actions import LoadComposableNodes, Node +from launch_ros.descriptions import ComposableNode + + +def generate_launch_description(): + return LaunchDescription([ + Node( + name='image_container', + package='rclcpp_components', + executable='component_container', + output='both', + ), + LoadComposableNodes( + target_container='image_container', + composable_node_descriptions=[ + ComposableNode( + package='image_tools', + plugin='image_tools::Cam2Image', + name='cam2image', + remappings=[('/image', '/burgerimage')], + parameters=[ + {'width': 320, 'height': 240, 'burger_mode': True, 'history': 'keep_last'} + ], + extra_arguments=[{'use_intra_process_comms': True}], + ), + ComposableNode( + package='image_tools', + plugin='image_tools::ShowImage', + name='showimage', + remappings=[('/image', '/burgerimage')], + parameters=[{'history': 'keep_last'}], + extra_arguments=[{'use_intra_process_comms': True}] + ), + ], + ) + ]) diff --git a/source/How-To-Guides/launch/composition_load_launch.xml b/source/How-To-Guides/launch/composition_load_launch.xml new file mode 100644 index 00000000000..56bf678b319 --- /dev/null +++ b/source/How-To-Guides/launch/composition_load_launch.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/source/How-To-Guides/launch/composition_load_launch.yaml b/source/How-To-Guides/launch/composition_load_launch.yaml new file mode 100644 index 00000000000..9d21e0353c6 --- /dev/null +++ b/source/How-To-Guides/launch/composition_load_launch.yaml @@ -0,0 +1,41 @@ +%YAML 1.2 +--- +launch: + - node_container: + pkg: rclcpp_components + exec: component_container + name: image_container + - load_composable_node: + target: "image_container" + composable_node: + - pkg: image_tools + plugin: image_tools::Cam2Image + name: cam2image + remap: + - from: /image + to: /burgerimage + param: + - name: width + value: 320 + - name: height + value: 240 + - name: burger_mode + value: true + - name: history + value: keep_last + extra_arg: + - name: use_intra_process_comms + value: true + + - pkg: image_tools + plugin: image_tools::ShowImage + name: showimage + remap: + - from: /image + to: /burgerimage + param: + - name: history + value: keep_last + extra_arg: + - name: use_intra_process_comms + value: true diff --git a/source/How-To-Guides/launch/different_formats_launch.py b/source/How-To-Guides/launch/different_formats_launch.py new file mode 100644 index 00000000000..08f892a7901 --- /dev/null +++ b/source/How-To-Guides/launch/different_formats_launch.py @@ -0,0 +1,136 @@ +import os + +from ament_index_python import get_package_share_directory + +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument +from launch.actions import GroupAction +from launch.actions import IncludeLaunchDescription +from launch.launch_description_sources import PythonLaunchDescriptionSource +from launch.substitutions import LaunchConfiguration +from launch.substitutions import TextSubstitution +from launch_ros.actions import Node +from launch_ros.actions import PushROSNamespace +from launch_xml.launch_description_sources import XMLLaunchDescriptionSource +from launch_yaml.launch_description_sources import YAMLLaunchDescriptionSource + + +def generate_launch_description(): + + # args that can be set from the command line or a default will be used + background_r_launch_arg = DeclareLaunchArgument( + 'background_r', default_value=TextSubstitution(text='0') + ) + background_g_launch_arg = DeclareLaunchArgument( + 'background_g', default_value=TextSubstitution(text='255') + ) + background_b_launch_arg = DeclareLaunchArgument( + 'background_b', default_value=TextSubstitution(text='0') + ) + chatter_py_ns_launch_arg = DeclareLaunchArgument( + 'chatter_py_ns', default_value=TextSubstitution(text='chatter/py/ns') + ) + chatter_xml_ns_launch_arg = DeclareLaunchArgument( + 'chatter_xml_ns', default_value=TextSubstitution(text='chatter/xml/ns') + ) + chatter_yaml_ns_launch_arg = DeclareLaunchArgument( + 'chatter_yaml_ns', default_value=TextSubstitution(text='chatter/yaml/ns') + ) + + # include another launch file + launch_include = IncludeLaunchDescription( + PythonLaunchDescriptionSource( + os.path.join( + get_package_share_directory('demo_nodes_cpp'), + 'launch/topics/talker_listener_launch.py')) + ) + # include a Python launch file in the chatter_py_ns namespace + launch_py_include_with_namespace = GroupAction( + actions=[ + # push_ros_namespace first to set namespace of included nodes for following actions + PushROSNamespace('chatter_py_ns'), + IncludeLaunchDescription( + PythonLaunchDescriptionSource( + os.path.join( + get_package_share_directory('demo_nodes_cpp'), + 'launch/topics/talker_listener_launch.py')) + ), + ] + ) + + # include a xml launch file in the chatter_xml_ns namespace + launch_xml_include_with_namespace = GroupAction( + actions=[ + # push_ros_namespace first to set namespace of included nodes for following actions + PushROSNamespace('chatter_xml_ns'), + IncludeLaunchDescription( + XMLLaunchDescriptionSource( + os.path.join( + get_package_share_directory('demo_nodes_cpp'), + 'launch/topics/talker_listener_launch.xml')) + ), + ] + ) + + # include a yaml launch file in the chatter_yaml_ns namespace + launch_yaml_include_with_namespace = GroupAction( + actions=[ + # push_ros_namespace first to set namespace of included nodes for following actions + PushROSNamespace('chatter_yaml_ns'), + IncludeLaunchDescription( + YAMLLaunchDescriptionSource( + os.path.join( + get_package_share_directory('demo_nodes_cpp'), + 'launch/topics/talker_listener_launch.yaml')) + ), + ] + ) + + # start a turtlesim_node in the turtlesim1 namespace + turtlesim_node = Node( + package='turtlesim', + namespace='turtlesim1', + executable='turtlesim_node', + name='sim' + ) + + # start another turtlesim_node in the turtlesim2 namespace + # and use args to set parameters + turtlesim_node_with_parameters = Node( + package='turtlesim', + namespace='turtlesim2', + executable='turtlesim_node', + name='sim', + parameters=[{ + 'background_r': LaunchConfiguration('background_r'), + 'background_g': LaunchConfiguration('background_g'), + 'background_b': LaunchConfiguration('background_b'), + }] + ) + + # perform remap so both turtles listen to the same command topic + forward_turtlesim_commands_to_second_turtlesim_node = Node( + package='turtlesim', + executable='mimic', + name='mimic', + remappings=[ + ('/input/pose', '/turtlesim1/turtle1/pose'), + ('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'), + ] + ) + + return LaunchDescription([ + background_r_launch_arg, + background_g_launch_arg, + background_b_launch_arg, + chatter_py_ns_launch_arg, + chatter_xml_ns_launch_arg, + chatter_yaml_ns_launch_arg, + launch_include, + launch_py_include_with_namespace, + launch_xml_include_with_namespace, + launch_yaml_include_with_namespace, + turtlesim_node, + turtlesim_node_with_parameters, + forward_turtlesim_commands_to_second_turtlesim_node, + ]) diff --git a/source/How-To-Guides/launch/different_formats_launch.xml b/source/How-To-Guides/launch/different_formats_launch.xml new file mode 100644 index 00000000000..f29c4a73f5d --- /dev/null +++ b/source/How-To-Guides/launch/different_formats_launch.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/How-To-Guides/launch/different_formats_launch.yaml b/source/How-To-Guides/launch/different_formats_launch.yaml new file mode 100644 index 00000000000..c70c2ce89ab --- /dev/null +++ b/source/How-To-Guides/launch/different_formats_launch.yaml @@ -0,0 +1,79 @@ +%YAML 1.2 +--- +launch: +# args that can be set from the command line or a default will be used +- arg: + name: "background_r" + default: "0" +- arg: + name: "background_g" + default: "255" +- arg: + name: "background_b" + default: "0" +- arg: + name: "chatter_py_ns" + default: "chatter/py/ns" +- arg: + name: "chatter_xml_ns" + default: "chatter/xml/ns" +- arg: + name: "chatter_yaml_ns" + default: "chatter/yaml/ns" + +# include another launch file +- include: + file: "$(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.py" + +# include a Python launch file in the chatter_py_ns namespace +- group: + - push_ros_namespace: + namespace: "$(var chatter_py_ns)" + - include: + file: "$(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.py" + +# include a xml launch file in the chatter_xml_ns namespace +- group: + - push_ros_namespace: + namespace: "$(var chatter_xml_ns)" + - include: + file: "$(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.xml" + +# include a yaml launch file in the chatter_yaml_ns namespace +- group: + - push_ros_namespace: + namespace: "$(var chatter_yaml_ns)" + - include: + file: "$(find-pkg-share demo_nodes_cpp)/launch/topics/talker_listener_launch.yaml" + +# start a turtlesim_node in the turtlesim1 namespace +- node: + pkg: "turtlesim" + exec: "turtlesim_node" + name: "sim" + namespace: "turtlesim1" + +# start another turtlesim_node in the turtlesim2 namespace and use args to set parameters +- node: + pkg: "turtlesim" + exec: "turtlesim_node" + name: "sim" + namespace: "turtlesim2" + param: + - name: "background_r" + value: "$(var background_r)" + - name: "background_g" + value: "$(var background_g)" + - name: "background_b" + value: "$(var background_b)" + +# perform remap so both turtles listen to the same command topic +- node: + pkg: "turtlesim" + exec: "mimic" + name: "mimic" + remap: + - from: "/input/pose" + to: "/turtlesim1/turtle1/pose" + - from: "/output/cmd_vel" + to: "/turtlesim2/turtle1/cmd_vel" diff --git a/source/Tutorials/Beginner-CLI-Tools/Launching-Multiple-Nodes/Launching-Multiple-Nodes.rst b/source/Tutorials/Beginner-CLI-Tools/Launching-Multiple-Nodes/Launching-Multiple-Nodes.rst index c37bc7109cd..acbdc495f1b 100644 --- a/source/Tutorials/Beginner-CLI-Tools/Launching-Multiple-Nodes/Launching-Multiple-Nodes.rst +++ b/source/Tutorials/Beginner-CLI-Tools/Launching-Multiple-Nodes/Launching-Multiple-Nodes.rst @@ -54,20 +54,8 @@ Open a new terminal and run: This command will run the following launch file: -.. code-block:: python - - # turtlesim/launch/multisim.launch.py - - from launch import LaunchDescription - import launch_ros.actions - - def generate_launch_description(): - return LaunchDescription([ - launch_ros.actions.Node( - namespace= "turtlesim1", package='turtlesim', executable='turtlesim_node', output='screen'), - launch_ros.actions.Node( - namespace= "turtlesim2", package='turtlesim', executable='turtlesim_node', output='screen'), - ]) +.. literalinclude:: launch/multisim.launch.py + :language: python .. note:: diff --git a/source/Tutorials/Beginner-CLI-Tools/Launching-Multiple-Nodes/launch/multisim.launch.py b/source/Tutorials/Beginner-CLI-Tools/Launching-Multiple-Nodes/launch/multisim.launch.py new file mode 100644 index 00000000000..c959572c114 --- /dev/null +++ b/source/Tutorials/Beginner-CLI-Tools/Launching-Multiple-Nodes/launch/multisim.launch.py @@ -0,0 +1,13 @@ +from launch import LaunchDescription +import launch_ros.actions + + +def generate_launch_description(): + return LaunchDescription([ + launch_ros.actions.Node( + namespace='turtlesim1', package='turtlesim', + executable='turtlesim_node', output='screen'), + launch_ros.actions.Node( + namespace='turtlesim2', package='turtlesim', + executable='turtlesim_node', output='screen'), + ]) diff --git a/source/Tutorials/Beginner-Client-Libraries/Using-Parameters-In-A-Class-CPP.rst b/source/Tutorials/Beginner-Client-Libraries/Using-Parameters-In-A-Class-CPP.rst index e69fc4a124a..3bf484a9649 100644 --- a/source/Tutorials/Beginner-Client-Libraries/Using-Parameters-In-A-Class-CPP.rst +++ b/source/Tutorials/Beginner-Client-Libraries/Using-Parameters-In-A-Class-CPP.rst @@ -333,24 +333,8 @@ Inside the ``ros2_ws/src/cpp_parameters/`` directory, create a new directory cal In there, create a new file called ``cpp_parameters_launch.py`` -.. code-block:: Python - - from launch import LaunchDescription - from launch_ros.actions import Node - - def generate_launch_description(): - return LaunchDescription([ - Node( - package="cpp_parameters", - executable="minimal_param_node", - name="custom_minimal_param_node", - output="screen", - emulate_tty=True, - parameters=[ - {"my_parameter": "earth"} - ] - ) - ]) +.. literalinclude:: launch/cpp_parameters_launch.py + :language: python Here you can see that we set ``my_parameter`` to ``earth`` when we launch our node ``minimal_param_node``. By adding the two lines below, we ensure our output is printed in our console. diff --git a/source/Tutorials/Beginner-Client-Libraries/Using-Parameters-In-A-Class-Python.rst b/source/Tutorials/Beginner-Client-Libraries/Using-Parameters-In-A-Class-Python.rst index 67e205bb224..2764f8a0384 100644 --- a/source/Tutorials/Beginner-Client-Libraries/Using-Parameters-In-A-Class-Python.rst +++ b/source/Tutorials/Beginner-Client-Libraries/Using-Parameters-In-A-Class-Python.rst @@ -325,24 +325,8 @@ You can also set parameters in a launch file, but first you will need to add a l Inside the ``ros2_ws/src/python_parameters/`` directory, create a new directory called ``launch``. In there, create a new file called ``python_parameters_launch.py`` -.. code-block:: Python - - from launch import LaunchDescription - from launch_ros.actions import Node - - def generate_launch_description(): - return LaunchDescription([ - Node( - package='python_parameters', - executable='minimal_param_node', - name='custom_minimal_param_node', - output='screen', - emulate_tty=True, - parameters=[ - {'my_parameter': 'earth'} - ] - ) - ]) +.. literalinclude:: launch/python_parameters_launch.py + :language: python Here you can see that we set ``my_parameter`` to ``earth`` when we launch our node ``parameter_node``. By adding the two lines below, we ensure our output is printed in our console. diff --git a/source/Tutorials/Beginner-Client-Libraries/launch/cpp_parameters_launch.py b/source/Tutorials/Beginner-Client-Libraries/launch/cpp_parameters_launch.py new file mode 100644 index 00000000000..e9188461fd9 --- /dev/null +++ b/source/Tutorials/Beginner-Client-Libraries/launch/cpp_parameters_launch.py @@ -0,0 +1,17 @@ +from launch import LaunchDescription +from launch_ros.actions import Node + + +def generate_launch_description(): + return LaunchDescription([ + Node( + package='cpp_parameters', + executable='minimal_param_node', + name='custom_minimal_param_node', + output='screen', + emulate_tty=True, + parameters=[ + {'my_parameter': 'earth'} + ] + ) + ]) diff --git a/source/Tutorials/Beginner-Client-Libraries/launch/python_parameters_launch.py b/source/Tutorials/Beginner-Client-Libraries/launch/python_parameters_launch.py new file mode 100644 index 00000000000..0aaf719dab1 --- /dev/null +++ b/source/Tutorials/Beginner-Client-Libraries/launch/python_parameters_launch.py @@ -0,0 +1,17 @@ +from launch import LaunchDescription +from launch_ros.actions import Node + + +def generate_launch_description(): + return LaunchDescription([ + Node( + package='python_parameters', + executable='minimal_param_node', + name='custom_minimal_param_node', + output='screen', + emulate_tty=True, + parameters=[ + {'my_parameter': 'earth'} + ] + ) + ]) diff --git a/source/Tutorials/Intermediate/Launch/Creating-Launch-Files.rst b/source/Tutorials/Intermediate/Launch/Creating-Launch-Files.rst index 7e0cc764907..d18fbe9567c 100644 --- a/source/Tutorials/Intermediate/Launch/Creating-Launch-Files.rst +++ b/source/Tutorials/Intermediate/Launch/Creating-Launch-Files.rst @@ -62,82 +62,22 @@ As mentioned above, this can either be in XML, YAML, or Python. Copy and paste the complete code into the ``launch/turtlesim_mimic_launch.xml`` file: - .. code-block:: xml - - - - - - - - - + .. literalinclude:: launch/turtlesim_mimic_launch.xml + :language: xml .. group-tab:: YAML Copy and paste the complete code into the ``launch/turtlesim_mimic_launch.yaml`` file: - .. code-block:: yaml - - launch: - - - node: - pkg: "turtlesim" - exec: "turtlesim_node" - name: "sim" - namespace: "turtlesim1" - - - node: - pkg: "turtlesim" - exec: "turtlesim_node" - name: "sim" - namespace: "turtlesim2" - - - node: - pkg: "turtlesim" - exec: "mimic" - name: "mimic" - remap: - - - from: "/input/pose" - to: "/turtlesim1/turtle1/pose" - - - from: "/output/cmd_vel" - to: "/turtlesim2/turtle1/cmd_vel" + .. literalinclude:: launch/turtlesim_mimic_launch.yaml + :language: yaml .. group-tab:: Python Copy and paste the complete code into the ``launch/turtlesim_mimic_launch.py`` file: - .. code-block:: python - - from launch import LaunchDescription - from launch_ros.actions import Node - - def generate_launch_description(): - return LaunchDescription([ - Node( - package='turtlesim', - namespace='turtlesim1', - executable='turtlesim_node', - name='sim' - ), - Node( - package='turtlesim', - namespace='turtlesim2', - executable='turtlesim_node', - name='sim' - ), - Node( - package='turtlesim', - executable='mimic', - name='mimic', - remappings=[ - ('/input/pose', '/turtlesim1/turtle1/pose'), - ('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'), - ] - ) - ]) + .. literalinclude:: launch/turtlesim_mimic_launch.py + :language: python 2.1 Examine the launch file @@ -163,103 +103,55 @@ In other words, ``turtlesim2`` will mimic ``turtlesim1``'s movements. The first two actions launch the two turtlesim windows: - .. code-block:: xml - - - + .. literalinclude:: launch/turtlesim_mimic_launch.xml + :language: xml + :lines: 3-4 The final action launches the mimic node with the remaps: - .. code-block:: xml - - - - - + .. literalinclude:: launch/turtlesim_mimic_launch.xml + :language: xml + :lines: 5-8 .. group-tab:: YAML The first two actions launch the two turtlesim windows: - .. code-block:: yaml - - - node: - pkg: "turtlesim" - exec: "turtlesim_node" - name: "sim" - namespace: "turtlesim1" - - - node: - pkg: "turtlesim" - exec: "turtlesim_node" - name: "sim" - namespace: "turtlesim2" - + .. literalinclude:: launch/turtlesim_mimic_launch.yaml + :language: yaml + :lines: 4-14 The final action launches the mimic node with the remaps: - .. code-block:: yaml - - - node: - pkg: "turtlesim" - exec: "mimic" - name: "mimic" - remap: - - - from: "/input/pose" - to: "/turtlesim1/turtle1/pose" - - - from: "/output/cmd_vel" - to: "/turtlesim2/turtle1/cmd_vel" + .. literalinclude:: launch/turtlesim_mimic_launch.yaml + :language: yaml + :lines: 16-24 .. group-tab:: Python These import statements pull in some Python ``launch`` modules. - .. code-block:: python - - from launch import LaunchDescription - from launch_ros.actions import Node + .. literalinclude:: launch/turtlesim_mimic_launch.py + :language: python + :lines: 1-2 Next, the launch description itself begins: - .. code-block:: python - - def generate_launch_description(): - return LaunchDescription([ - - ]) + .. literalinclude:: launch/turtlesim_mimic_launch.py + :language: python + :lines: 5-7,28 The first two actions in the launch description launch the two turtlesim windows: - .. code-block:: python - - Node( - package='turtlesim', - namespace='turtlesim1', - executable='turtlesim_node', - name='sim' - ), - Node( - package='turtlesim', - namespace='turtlesim2', - executable='turtlesim_node', - name='sim' - ), + .. literalinclude:: launch/turtlesim_mimic_launch.py + :language: python + :lines: 7-18 The final action launches the mimic node with the remaps: - .. code-block:: python - - Node( - package='turtlesim', - executable='mimic', - name='mimic', - remappings=[ - ('/input/pose', '/turtlesim1/turtle1/pose'), - ('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'), - ] - ) + .. literalinclude:: launch/turtlesim_mimic_launch.py + :language: python + :lines: 19-27 3 ros2 launch diff --git a/source/Tutorials/Intermediate/Launch/Launch-system.rst b/source/Tutorials/Intermediate/Launch/Launch-system.rst index 0a361ada57b..09158e591ce 100644 --- a/source/Tutorials/Intermediate/Launch/Launch-system.rst +++ b/source/Tutorials/Intermediate/Launch/Launch-system.rst @@ -144,25 +144,16 @@ Make sure to create a ``launch`` directory at the top-level of the package you c Inside your ``launch`` directory, create a new launch file called ``my_script_launch.xml``. ``_launch.xml`` is recommended, but not required, as the file suffix for XML launch files. - .. code-block:: xml - - - - + .. literalinclude:: launch/my_script_launch.xml + :language: xml .. group-tab:: YAML launch file Inside your ``launch`` directory, create a new launch file called ``my_script_launch.yaml``. ``_launch.yaml`` is recommended, but not required, as the file suffix for YAML launch files. - .. code-block:: yaml - - launch: - - - node: - pkg: "demo_nodes_cpp" - exec: "talker" - name: "talker" + .. literalinclude:: launch/my_script_launch.yaml + :language: yaml .. group-tab:: Python launch file @@ -172,18 +163,8 @@ Make sure to create a ``launch`` directory at the top-level of the package you c Your launch file should define the ``generate_launch_description()`` function which returns a ``launch.LaunchDescription()`` to be used by the ``ros2 launch`` verb. - .. code-block:: python - - import launch - import launch_ros.actions - - def generate_launch_description(): - return launch.LaunchDescription([ - launch_ros.actions.Node( - package='demo_nodes_cpp', - executable='talker', - name='talker'), - ]) + .. literalinclude:: launch/my_script_launch.py + :language: python 4 Building and running the launch file diff --git a/source/Tutorials/Intermediate/Launch/Using-Event-Handlers.rst b/source/Tutorials/Intermediate/Launch/Using-Event-Handlers.rst index 0387a5afaa5..f48ea043a04 100644 --- a/source/Tutorials/Intermediate/Launch/Using-Event-Handlers.rst +++ b/source/Tutorials/Intermediate/Launch/Using-Event-Handlers.rst @@ -43,6 +43,7 @@ Using event handlers Create a new file called ``example_event_handlers.launch.py`` file in the ``launch`` folder of the ``launch_tutorial`` package. +<<<<<<< HEAD .. code-block:: python from launch_ros.actions import Node @@ -179,90 +180,49 @@ Create a new file called ``example_event_handlers.launch.py`` file in the ``laun ) ), ]) +======= +.. literalinclude:: launch/example_event_handlers_launch.py + :language: python +>>>>>>> 666df3e (Pull all example launchfiles into separate file with `literalinclude` (#5155)) ``RegisterEventHandler`` actions for the ``OnProcessStart``, ``OnProcessIO``, ``OnExecutionComplete``, ``OnProcessExit``, and ``OnShutdown`` events were defined in the launch description. The ``OnProcessStart`` event handler is used to register a callback function that is executed when the turtlesim node starts. It logs a message to the console and executes the ``spawn_turtle`` action when the turtlesim node starts. -.. code-block:: python - - RegisterEventHandler( - OnProcessStart( - target_action=turtlesim_node, - on_start=[ - LogInfo(msg='Turtlesim started, spawning turtle'), - spawn_turtle - ] - ) - ), +.. literalinclude:: launch/example_event_handlers_launch.py + :language: python + :lines: 98-106 The ``OnProcessIO`` event handler is used to register a callback function that is executed when the ``spawn_turtle`` action writes to its standard output. It logs the result of the spawn request. -.. code-block:: python - - RegisterEventHandler( - OnProcessIO( - target_action=spawn_turtle, - on_stdout=lambda event: LogInfo( - msg='Spawn request says "{}"'.format( - event.text.decode().strip()) - ) - ) - ), +.. literalinclude:: launch/example_event_handlers_launch.py + :language: python + :lines: 107-115 The ``OnExecutionComplete`` event handler is used to register a callback function that is executed when the ``spawn_turtle`` action completes. It logs a message to the console and executes the ``change_background_r`` and ``change_background_r_conditioned`` actions when the spawn action completes. -.. code-block:: python - - RegisterEventHandler( - OnExecutionComplete( - target_action=spawn_turtle, - on_completion=[ - LogInfo(msg='Spawn finished'), - change_background_r, - TimerAction( - period=2.0, - actions=[change_background_r_conditioned], - ) - ] - ) - ), +.. literalinclude:: launch/example_event_handlers_launch.py + :language: python + :lines: 116-128 The ``OnProcessExit`` event handler is used to register a callback function that is executed when the turtlesim node exits. It logs a message to the console and executes the ``EmitEvent`` action to emit a ``Shutdown`` event when the turtlesim node exits. It means that the launch process will shutdown when the turtlesim window is closed. -.. code-block:: python - - RegisterEventHandler( - OnProcessExit( - target_action=turtlesim_node, - on_exit=[ - LogInfo(msg=(EnvironmentVariable(name='USER'), - ' closed the turtlesim window')), - EmitEvent(event=Shutdown( - reason='Window closed')) - ] - ) - ), +.. literalinclude:: launch/example_event_handlers_launch.py + :language: python + :lines: 129-139 Finally, the ``OnShutdown`` event handler is used to register a callback function that is executed when the launch file is asked to shutdown. It logs a message to the console why the launch file is asked to shutdown. It logs the message with a reason for shutdown like the closure of turtlesim window or :kbd:`ctrl-c` signal made by the user. -.. code-block:: python - - RegisterEventHandler( - OnShutdown( - on_shutdown=[LogInfo( - msg=['Launch was asked to shutdown: ', - LocalSubstitution('event.reason')] - )] - ) - ), +.. literalinclude:: launch/example_event_handlers_launch.py + :language: python + :lines: 140-146 Build the package ----------------- diff --git a/source/Tutorials/Intermediate/Launch/Using-ROS2-Launch-For-Large-Projects.rst b/source/Tutorials/Intermediate/Launch/Using-ROS2-Launch-For-Large-Projects.rst index 44f458d24df..cae6906650c 100644 --- a/source/Tutorials/Intermediate/Launch/Using-ROS2-Launch-For-Large-Projects.rst +++ b/source/Tutorials/Intermediate/Launch/Using-ROS2-Launch-For-Large-Projects.rst @@ -59,6 +59,7 @@ We will now go over the top-level launch file structure that makes this possible Firstly, we will create a launch file that will call separate launch files. To do this, let's create a ``launch_turtlesim.launch.py`` file in the ``/launch`` folder of our ``launch_tutorial`` package. +<<<<<<< HEAD .. code-block:: Python import os @@ -111,6 +112,10 @@ To do this, let's create a ``launch_turtlesim.launch.py`` file in the ``/launch` fixed_frame_node, rviz_node ]) +======= +.. literalinclude:: launch/launch_turtlesim_launch.py + :language: python +>>>>>>> 666df3e (Pull all example launchfiles into separate file with `literalinclude` (#5155)) This launch file includes a set of other launch files. Each of these included launch files contains nodes, parameters, and possibly, nested includes, which pertain to one part of the system. @@ -132,41 +137,8 @@ However, there are cases when some nodes or launch files have to be launched sep We will begin by writing a launch file that will start our first turtlesim simulation. First, create a new file called ``turtlesim_world_1.launch.py``. -.. code-block:: Python - - from launch import LaunchDescription - from launch.actions import DeclareLaunchArgument - from launch.substitutions import LaunchConfiguration, TextSubstitution - - from launch_ros.actions import Node - - - def generate_launch_description(): - background_r_launch_arg = DeclareLaunchArgument( - 'background_r', default_value=TextSubstitution(text='0') - ) - background_g_launch_arg = DeclareLaunchArgument( - 'background_g', default_value=TextSubstitution(text='84') - ) - background_b_launch_arg = DeclareLaunchArgument( - 'background_b', default_value=TextSubstitution(text='122') - ) - - return LaunchDescription([ - background_r_launch_arg, - background_g_launch_arg, - background_b_launch_arg, - Node( - package='turtlesim', - executable='turtlesim_node', - name='sim', - parameters=[{ - 'background_r': LaunchConfiguration('background_r'), - 'background_g': LaunchConfiguration('background_g'), - 'background_b': LaunchConfiguration('background_b'), - }] - ), - ]) +.. literalinclude:: launch/turtlesim_world_1_launch.py + :language: python This launch file starts the ``turtlesim_node`` node, which starts the turtlesim simulation, with simulation configuration parameters that are defined and passed to the nodes. @@ -176,32 +148,8 @@ This launch file starts the ``turtlesim_node`` node, which starts the turtlesim In the second launch, we will start a second turtlesim simulation with a different configuration. Now create a ``turtlesim_world_2.launch.py`` file. -.. code-block:: Python - - import os - - from ament_index_python.packages import get_package_share_directory - - from launch import LaunchDescription - from launch_ros.actions import Node - - - def generate_launch_description(): - config = os.path.join( - get_package_share_directory('launch_tutorial'), - 'config', - 'turtlesim.yaml' - ) - - return LaunchDescription([ - Node( - package='turtlesim', - executable='turtlesim_node', - namespace='turtlesim2', - name='sim', - parameters=[config] - ) - ]) +.. literalinclude:: launch/turtlesim_world_2_launch.py + :language: python This launch file will launch the same ``turtlesim_node`` with parameter values that are loaded directly from the YAML configuration file. Defining arguments and parameters in YAML files make it easy to store and load a large number of variables. @@ -228,18 +176,15 @@ These nodes could have different namespaces or names but still have the same par Defining separate YAML files that explicitly define namespaces and node names is not efficient. A solution is to use wildcard characters, which act as substitutions for unknown characters in a text value, to apply parameters to several different nodes. +<<<<<<< HEAD Now let's create a new ``turtlesim_world_3.launch.py`` file similar to ``turtlesim_world_2.launch.py`` to include one more ``turtlesim_node`` node. +======= +Now let's create a new ``turtlesim_world_3_launch.py`` file similar to ``turtlesim_world_2_launch.py`` to include one more ``turtlesim_node`` node in a new namespace ``turtlesim3``: +>>>>>>> 666df3e (Pull all example launchfiles into separate file with `literalinclude` (#5155)) -.. code-block:: Python - - ... - Node( - package='turtlesim', - executable='turtlesim_node', - namespace='turtlesim3', - name='sim', - parameters=[config] - ) +.. literalinclude:: launch/turtlesim_world_3_launch.py + :language: python + :emphasize-lines: 19 Loading the same YAML file, however, will not affect the appearance of the third turtlesim world. The reason is that its parameters are stored under another namespace as shown below: @@ -310,47 +255,8 @@ As a result, each node in the ``turtlesim_world_2.launch.py`` launch description Now create a ``broadcaster_listener.launch.py`` file. -.. code-block:: Python - - from launch import LaunchDescription - from launch.actions import DeclareLaunchArgument - from launch.substitutions import LaunchConfiguration - - from launch_ros.actions import Node - - - def generate_launch_description(): - return LaunchDescription([ - DeclareLaunchArgument( - 'target_frame', default_value='turtle1', - description='Target frame name.' - ), - Node( - package='turtle_tf2_py', - executable='turtle_tf2_broadcaster', - name='broadcaster1', - parameters=[ - {'turtlename': 'turtle1'} - ] - ), - Node( - package='turtle_tf2_py', - executable='turtle_tf2_broadcaster', - name='broadcaster2', - parameters=[ - {'turtlename': 'turtle2'} - ] - ), - Node( - package='turtle_tf2_py', - executable='turtle_tf2_listener', - name='listener', - parameters=[ - {'target_frame': LaunchConfiguration('target_frame')} - ] - ), - ]) - +.. literalinclude:: launch/broadcast_listener_launch.py + :language: python In this file, we have declared the ``target_frame`` launch argument with a default value of ``turtle1``. The default value means that the launch file can receive an argument to forward to its nodes, or in case the argument is not provided, it will pass the default value to its nodes. @@ -366,6 +272,7 @@ We also start a ``turtle_tf2_listener`` node and set its ``target_frame`` parame Recall that we called the ``broadcaster_listener.launch.py`` file in our top-level launch file. In addition to that, we have passed it ``target_frame`` launch argument as shown below: +<<<<<<< HEAD .. code-block:: Python broadcaster_listener_nodes = IncludeLaunchDescription( @@ -374,6 +281,11 @@ In addition to that, we have passed it ``target_frame`` launch argument as shown '/broadcaster_listener.launch.py']), launch_arguments={'target_frame': 'carrot1'}.items(), ) +======= +.. literalinclude:: launch/launch_turtlesim_launch.py + :language: python + :lines: 21-26 +>>>>>>> 666df3e (Pull all example launchfiles into separate file with `literalinclude` (#5155)) This syntax allows us to change the default goal target frame to ``carrot1``. If you would like ``turtle2`` to follow ``turtle1`` instead of the ``carrot1``, just remove the line that defines ``launch_arguments``. @@ -384,24 +296,8 @@ This will assign ``target_frame`` its default value, which is ``turtle1``. Now create a ``mimic.launch.py`` file. -.. code-block:: Python - - from launch import LaunchDescription - from launch_ros.actions import Node - - - def generate_launch_description(): - return LaunchDescription([ - Node( - package='turtlesim', - executable='mimic', - name='mimic', - remappings=[ - ('/input/pose', '/turtle2/pose'), - ('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'), - ] - ) - ]) +.. literalinclude:: launch/mimic_launch.py + :language: python This launch file will start the ``mimic`` node, which will give commands to one turtlesim to follow the other. The node is designed to receive the target pose on the topic ``/input/pose``. @@ -414,31 +310,8 @@ This way ``turtle1`` in our ``turtlesim2`` simulation world will follow ``turtle Let's now create a file called ``turtlesim_rviz.launch.py``. -.. code-block:: Python - - import os - - from ament_index_python.packages import get_package_share_directory - - from launch import LaunchDescription - from launch_ros.actions import Node - - - def generate_launch_description(): - rviz_config = os.path.join( - get_package_share_directory('turtle_tf2_py'), - 'rviz', - 'turtle_rviz.rviz' - ) - - return LaunchDescription([ - Node( - package='rviz2', - executable='rviz2', - name='rviz2', - arguments=['-d', rviz_config] - ) - ]) +.. literalinclude:: launch/turtlesim_rviz_launch.py + :language: python This launch file will start the RViz with the configuration file defined in the ``turtle_tf2_py`` package. This RViz configuration will set the world frame, enable TF visualization, and start RViz with a top-down view. @@ -448,27 +321,8 @@ This RViz configuration will set the world frame, enable TF visualization, and s Let's now create the last launch file called ``fixed_broadcaster.launch.py`` in our package. -.. code-block:: Python - - from launch import LaunchDescription - from launch.actions import DeclareLaunchArgument - from launch.substitutions import EnvironmentVariable, LaunchConfiguration - from launch_ros.actions import Node - - - def generate_launch_description(): - return LaunchDescription([ - DeclareLaunchArgument( - 'node_prefix', - default_value=[EnvironmentVariable('USER'), '_'], - description='prefix for node name' - ), - Node( - package='turtle_tf2_py', - executable='fixed_frame_tf2_broadcaster', - name=[LaunchConfiguration('node_prefix'), 'fixed_broadcaster'], - ), - ]) +.. literalinclude:: launch/fixed_broadcaster_launch.py + :language: python This launch file shows the way environment variables can be called inside the launch files. Environment variables can be used to define or push namespaces for distinguishing nodes on different computers or robots. diff --git a/source/Tutorials/Intermediate/Launch/Using-Substitutions.rst b/source/Tutorials/Intermediate/Launch/Using-Substitutions.rst index bfaa40b59b2..5c43267dd9a 100644 --- a/source/Tutorials/Intermediate/Launch/Using-Substitutions.rst +++ b/source/Tutorials/Intermediate/Launch/Using-Substitutions.rst @@ -130,6 +130,7 @@ To do this, create following file in the ``launch`` folder of the ``launch_tutor .. tabs:: +<<<<<<< HEAD .. group-tab:: YAML Copy and paste the complete code into the ``launch/example_main.launch.yaml`` file: @@ -170,41 +171,56 @@ To do this, create following file in the ``launch`` folder of the ``launch_tutor - name: 'new_background_r' value: '$(var background_r)' +======= +>>>>>>> 666df3e (Pull all example launchfiles into separate file with `literalinclude` (#5155)) .. group-tab:: XML Copy and paste the complete code into the ``launch/example_main_launch.xml`` file: - .. code-block:: xml - - - - - - - - - + .. literalinclude:: launch/example_main_launch.xml + :language: xml The ``$(find-pkg-share launch_tutorial)`` substitution is used to find the path to the ``launch_tutorial`` package. The path substitution is then joined with the ``example_substitutions_launch.xml`` file name. - .. code-block:: xml + .. literalinclude:: launch/example_main_launch.xml + :language: xml + :lines: 4 - + The ``background_r`` variable with ``turtlesim_ns`` and ``use_provided_red`` arguments is passed to the ``include`` action. + The ``$(var background_r)`` substitution is used to define the ``new_background_r`` argument with the value of the ``background_r`` variable. + + .. literalinclude:: launch/example_main_launch.xml + :language: xml + :lines: 5-7 + + .. group-tab:: YAML + + Copy and paste the complete code into the ``launch/example_main_launch.yaml`` file: + + .. literalinclude:: launch/example_main_launch.yaml + :language: yaml + + The ``$(find-pkg-share launch_tutorial)`` substitution is used to find the path to the ``launch_tutorial`` package. + The path substitution is then joined with the ``example_substitutions_launch.yaml`` file name. + + .. literalinclude:: launch/example_main_launch.yaml + :language: yaml + :lines: 8 The ``background_r`` variable with ``turtlesim_ns`` and ``use_provided_red`` arguments is passed to the ``include`` action. The ``$(var background_r)`` substitution is used to define the ``new_background_r`` argument with the value of the ``background_r`` variable. - .. code-block:: xml + .. literalinclude:: launch/example_main_launch.yaml + :language: yaml + :lines: 9-15 - - - .. group-tab:: Python Copy and paste the complete code into the ``launch/example_main.launch.py`` file: +<<<<<<< HEAD .. code-block:: python from launch_ros.substitutions import FindPackageShare @@ -237,10 +253,15 @@ To do this, create following file in the ``launch`` folder of the ``launch_tutor ) ]) +======= + .. literalinclude:: launch/example_main_launch.py + :language: python +>>>>>>> 666df3e (Pull all example launchfiles into separate file with `literalinclude` (#5155)) The ``FindPackageShare`` substitution is used to find the path to the ``launch_tutorial`` package. The ``PathJoinSubstitution`` substitution is then used to join the path to that package path with the ``example_substitutions.launch.py`` file name. +<<<<<<< HEAD .. code-block:: python PathJoinSubstitution([ @@ -248,17 +269,19 @@ To do this, create following file in the ``launch`` folder of the ``launch_tutor 'launch', 'example_substitutions.launch.py' ]) +======= + .. literalinclude:: launch/example_main_launch.py + :language: python + :lines: 16-21 +>>>>>>> 666df3e (Pull all example launchfiles into separate file with `literalinclude` (#5155)) The ``launch_arguments`` dictionary with ``turtlesim_ns`` and ``use_provided_red`` arguments is passed to the ``IncludeLaunchDescription`` action. The ``TextSubstitution`` substitution is used to define the ``new_background_r`` argument with the value of the ``background_r`` key in the ``colors`` dictionary. - .. code-block:: python + .. literalinclude:: launch/example_main_launch.py + :language: python + :lines: 22-26 - launch_arguments={ - 'turtlesim_ns': 'turtlesim2', - 'use_provided_red': 'True', - 'new_background_r': TextSubstitution(text=str(colors['background_r'])) - }.items() 3 Substitutions example launch file ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -267,6 +290,7 @@ Now create the substitution launch file in the same folder: .. tabs:: +<<<<<<< HEAD .. group-tab:: YAML Create the file ``launch/example_substitutions.launch.yaml`` and insert the following code: @@ -353,10 +377,13 @@ Now create the substitution launch file in the same folder: cmd: 'ros2 param set $(var turtlesim_ns)/sim background_r $(var new_background_r)' if: '$(eval "$(var new_background_r) == 200 and $(var use_provided_red)")' +======= +>>>>>>> 666df3e (Pull all example launchfiles into separate file with `literalinclude` (#5155)) .. group-tab:: XML Create the file ``launch/example_substitutions_launch.xml`` and insert the following code: +<<<<<<< HEAD .. code-block:: xml @@ -374,6 +401,10 @@ Now create the substitution launch file in the same folder: /> +======= + .. literalinclude:: launch/example_substitutions_launch.xml + :language: xml +>>>>>>> 666df3e (Pull all example launchfiles into separate file with `literalinclude` (#5155)) The ``turtlesim_ns``, ``use_provided_red``, and ``new_background_r`` launch configurations are defined. They are used to store values of launch arguments in the above variables and to pass them to required actions. @@ -381,45 +412,84 @@ Now create the substitution launch file in the same folder: The ``arg`` tag is used to define the launch argument that can be passed from the above launch file or from the console. - .. code-block:: xml - - - - + .. literalinclude:: launch/example_substitutions_launch.xml + :language: xml + :lines: 3-5 The ``turtlesim_node`` node with the ``namespace`` set to the ``turtlesim_ns`` launch configuration value using the ``$(var )`` substitution is defined. - .. code-block:: xml - - + .. literalinclude:: launch/example_substitutions_launch.xml + :language: xml + :lines: 7 Afterwards, an ``executable`` action is defined with the corresponding ``cmd`` tag. This command makes a call to the spawn service of the turtlesim node. Additionally, the ``$(var )`` substitution is used to get the value of the ``turtlesim_ns`` launch argument to construct a command string. +<<<<<<< HEAD .. code-block:: xml +======= + .. literalinclude:: launch/example_substitutions_launch.xml + :language: xml + :lines: 8 +>>>>>>> 666df3e (Pull all example launchfiles into separate file with `literalinclude` (#5155)) The same approach is used for the ``ros2 param`` ``executable`` actions that change the turtlesim background's red color parameter. The difference is that the second action inside of the timer is only executed if the provided ``new_background_r`` argument equals ``200`` and the ``use_provided_red`` launch argument is set to ``True``. The evaluation of the ``if`` predicate is done using the ``$(eval )`` substitution. - .. code-block:: xml + .. literalinclude:: launch/example_substitutions_launch.xml + :language: xml + :lines: 9-13 + + .. group-tab:: YAML + + Create the file ``launch/example_substitutions_launch.yaml`` and insert the following code: + + .. literalinclude:: launch/example_substitutions_launch.yaml + :language: yaml - - - - + The ``turtlesim_ns``, ``use_provided_red``, and ``new_background_r`` launch configurations are defined. + They are used to store values of launch arguments in the above variables and to pass them to required actions. + The launch configuration arguments can later be used with the ``$(var )`` substitution to acquire the value of the launch argument in any part of the launch description. + + The ``arg`` tag is used to define the launch argument that can be passed from the above launch file or from the console. + + .. literalinclude:: launch/example_substitutions_launch.yaml + :language: yaml + :lines: 4-12 + + The ``turtlesim_node`` node with the ``namespace`` set to the ``turtlesim_ns`` launch configuration value using the ``$(var )`` substitution is defined. + + .. literalinclude:: launch/example_substitutions_launch.yaml + :language: yaml + :lines: 14-18 + + Afterwards, an ``executable`` action is defined with the corresponding ``cmd`` tag. + This command makes a call to the spawn service of the turtlesim node. + + Additionally, the ``$(var )`` substitution is used to get the value of the ``turtlesim_ns`` launch argument to construct a command string. + + .. literalinclude:: launch/example_substitutions_launch.yaml + :language: yaml + :lines: 21-22 + + The same approach is used for the ``ros2 param`` ``executable`` actions that change the turtlesim background's red color parameter. + The difference is that the second action inside of the timer is only executed if the provided ``new_background_r`` argument equals ``200`` and the ``use_provided_red`` launch argument is set to ``True``. + The evaluation of the ``if`` predicate is done using the ``$(eval )`` substitution. + + .. literalinclude:: launch/example_substitutions_launch.yaml + :language: yaml + :lines: 21-28 .. group-tab:: Python Create the file ``launch/example_substitutions.launch.py`` and insert the following code: +<<<<<<< HEAD .. code-block:: python from launch_ros.actions import Node @@ -503,6 +573,10 @@ Now create the substitution launch file in the same folder: actions=[change_background_r_conditioned], ) ]) +======= + .. literalinclude:: launch/example_substitutions_launch.py + :language: python +>>>>>>> 666df3e (Pull all example launchfiles into separate file with `literalinclude` (#5155)) The ``turtlesim_ns``, ``use_provided_red``, and ``new_background_r`` launch configurations are defined. They are used to store values of launch arguments in the above variables and to pass them to required actions. @@ -510,41 +584,22 @@ Now create the substitution launch file in the same folder: ``DeclareLaunchArgument`` is used to define the launch argument that can be passed from the above launch file or from the console. - .. code-block:: python - - turtlesim_ns = LaunchConfiguration('turtlesim_ns') - use_provided_red = LaunchConfiguration('use_provided_red') - new_background_r = LaunchConfiguration('new_background_r') - - turtlesim_ns_launch_arg = DeclareLaunchArgument( - 'turtlesim_ns', - default_value='turtlesim1' - ) - use_provided_red_launch_arg = DeclareLaunchArgument( - 'use_provided_red', - default_value='False' - ) - new_background_r_launch_arg = DeclareLaunchArgument( - 'new_background_r', - default_value='200' - ) + .. literalinclude:: launch/example_substitutions_launch.py + :language: python + :lines: 13-24 The ``turtlesim_node`` node with the ``namespace`` set to ``turtlesim_ns`` ``LaunchConfiguration`` substitution is defined. - .. code-block:: python - - turtlesim_node = Node( - package='turtlesim', - namespace=turtlesim_ns, - executable='turtlesim_node', - name='sim' - ) + .. literalinclude:: launch/example_substitutions_launch.py + :language: python + :lines: 26-31 Afterwards, the ``ExecuteProcess`` action called ``spawn_turtle`` is defined with the corresponding ``cmd`` argument. This command makes a call to the spawn service of the turtlesim node. Additionally, the ``LaunchConfiguration`` substitution is used to get the value of the ``turtlesim_ns`` launch argument to construct a command string. +<<<<<<< HEAD .. code-block:: python spawn_turtle = ExecuteProcess( @@ -557,39 +612,19 @@ Now create the substitution launch file in the same folder: ]], shell=True ) +======= + .. literalinclude:: launch/example_substitutions_launch.py + :language: python + :lines: 32-41 +>>>>>>> 666df3e (Pull all example launchfiles into separate file with `literalinclude` (#5155)) The same approach is used for the ``change_background_r`` and ``change_background_r_conditioned`` actions that change the turtlesim background's red color parameter. The difference is that the ``change_background_r_conditioned`` action is only executed if the provided ``new_background_r`` argument equals ``200`` and the ``use_provided_red`` launch argument is set to ``True``. The evaluation inside the ``IfCondition`` is done using the ``PythonExpression`` substitution. - .. code-block:: python - - change_background_r = ExecuteProcess( - cmd=[[ - 'ros2 param set ', - turtlesim_ns, - '/sim background_r ', - '120' - ]], - shell=True - ) - change_background_r_conditioned = ExecuteProcess( - condition=IfCondition( - PythonExpression([ - new_background_r, - ' == 200', - ' and ', - use_provided_red - ]) - ), - cmd=[[ - 'ros2 param set ', - turtlesim_ns, - '/sim background_r ', - new_background_r - ]], - shell=True - ) + .. literalinclude:: launch/example_substitutions_launch.py + :language: python + :lines: 42-67 4 Build the package ^^^^^^^^^^^^^^^^^^^ diff --git a/source/Tutorials/Intermediate/Launch/launch/broadcast_listener_launch.py b/source/Tutorials/Intermediate/Launch/launch/broadcast_listener_launch.py new file mode 100644 index 00000000000..bcc647553df --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/broadcast_listener_launch.py @@ -0,0 +1,38 @@ +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument +from launch.substitutions import LaunchConfiguration + +from launch_ros.actions import Node + + +def generate_launch_description(): + return LaunchDescription([ + DeclareLaunchArgument( + 'target_frame', default_value='turtle1', + description='Target frame name.', + ), + Node( + package='turtle_tf2_py', + executable='turtle_tf2_broadcaster', + name='broadcaster1', + parameters=[ + {'turtlename': 'turtle1'} + ], + ), + Node( + package='turtle_tf2_py', + executable='turtle_tf2_broadcaster', + name='broadcaster2', + parameters=[ + {'turtlename': 'turtle2'} + ], + ), + Node( + package='turtle_tf2_py', + executable='turtle_tf2_listener', + name='listener', + parameters=[ + {'target_frame': LaunchConfiguration('target_frame')} + ], + ), + ]) diff --git a/source/Tutorials/Intermediate/Launch/launch/example_event_handlers_launch.py b/source/Tutorials/Intermediate/Launch/launch/example_event_handlers_launch.py new file mode 100644 index 00000000000..9b44fa6156f --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/example_event_handlers_launch.py @@ -0,0 +1,147 @@ +from launch import LaunchDescription +from launch.actions import ( + DeclareLaunchArgument, + EmitEvent, + ExecuteProcess, + LogInfo, + RegisterEventHandler, + TimerAction +) +from launch.conditions import IfCondition +from launch.event_handlers import ( + OnExecutionComplete, + OnProcessExit, + OnProcessIO, + OnProcessStart, + OnShutdown +) +from launch.events import Shutdown +from launch.substitutions import ( + EnvironmentVariable, + FindExecutable, + LaunchConfiguration, + LocalSubstitution, + PythonExpression +) +from launch_ros.actions import Node + + +def generate_launch_description(): + turtlesim_ns = LaunchConfiguration('turtlesim_ns') + use_provided_red = LaunchConfiguration('use_provided_red') + new_background_r = LaunchConfiguration('new_background_r') + + turtlesim_ns_launch_arg = DeclareLaunchArgument( + 'turtlesim_ns', + default_value='turtlesim1' + ) + use_provided_red_launch_arg = DeclareLaunchArgument( + 'use_provided_red', + default_value='False' + ) + new_background_r_launch_arg = DeclareLaunchArgument( + 'new_background_r', + default_value='200' + ) + + turtlesim_node = Node( + package='turtlesim', + namespace=turtlesim_ns, + executable='turtlesim_node', + name='sim' + ) + spawn_turtle = ExecuteProcess( + cmd=[[ + FindExecutable(name='ros2'), + ' service call ', + turtlesim_ns, + '/spawn ', + 'turtlesim_msgs/srv/Spawn ', + '"{x: 2, y: 2, theta: 0.2}"' + ]], + shell=True + ) + change_background_r = ExecuteProcess( + cmd=[[ + FindExecutable(name='ros2'), + ' param set ', + turtlesim_ns, + '/sim background_r ', + '120' + ]], + shell=True + ) + change_background_r_conditioned = ExecuteProcess( + condition=IfCondition( + PythonExpression([ + new_background_r, + ' == 200', + ' and ', + use_provided_red + ]) + ), + cmd=[[ + FindExecutable(name='ros2'), + ' param set ', + turtlesim_ns, + '/sim background_r ', + new_background_r + ]], + shell=True + ) + + return LaunchDescription([ + turtlesim_ns_launch_arg, + use_provided_red_launch_arg, + new_background_r_launch_arg, + turtlesim_node, + RegisterEventHandler( + OnProcessStart( + target_action=turtlesim_node, + on_start=[ + LogInfo(msg='Turtlesim started, spawning turtle'), + spawn_turtle + ] + ) + ), + RegisterEventHandler( + OnProcessIO( + target_action=spawn_turtle, + on_stdout=lambda event: LogInfo( + msg='Spawn request says "{}"'.format( + event.text.decode().strip()) + ) + ) + ), + RegisterEventHandler( + OnExecutionComplete( + target_action=spawn_turtle, + on_completion=[ + LogInfo(msg='Spawn finished'), + change_background_r, + TimerAction( + period=2.0, + actions=[change_background_r_conditioned], + ) + ] + ) + ), + RegisterEventHandler( + OnProcessExit( + target_action=turtlesim_node, + on_exit=[ + LogInfo(msg=(EnvironmentVariable(name='USER'), + ' closed the turtlesim window')), + EmitEvent(event=Shutdown( + reason='Window closed')) + ] + ) + ), + RegisterEventHandler( + OnShutdown( + on_shutdown=[LogInfo( + msg=['Launch was asked to shutdown: ', LocalSubstitution('event.reason')] + )] + ) + ), + ]) diff --git a/source/Tutorials/Intermediate/Launch/launch/example_main_launch.py b/source/Tutorials/Intermediate/Launch/launch/example_main_launch.py new file mode 100644 index 00000000000..658e0cb3052 --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/example_main_launch.py @@ -0,0 +1,28 @@ +from launch import LaunchDescription +from launch.actions import IncludeLaunchDescription +from launch.launch_description_sources import PythonLaunchDescriptionSource +from launch.substitutions import PathJoinSubstitution, TextSubstitution +from launch_ros.substitutions import FindPackageShare + + +def generate_launch_description(): + colors = { + 'background_r': '200' + } + + return LaunchDescription([ + IncludeLaunchDescription( + PythonLaunchDescriptionSource([ + PathJoinSubstitution([ + FindPackageShare('launch_tutorial'), + 'launch', + 'example_substitutions_launch.py' + ]) + ]), + launch_arguments={ + 'turtlesim_ns': 'turtlesim2', + 'use_provided_red': 'True', + 'new_background_r': TextSubstitution(text=str(colors['background_r'])) + }.items() + ) + ]) diff --git a/source/Tutorials/Intermediate/Launch/launch/example_main_launch.xml b/source/Tutorials/Intermediate/Launch/launch/example_main_launch.xml new file mode 100644 index 00000000000..fab05ddcf11 --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/example_main_launch.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/source/Tutorials/Intermediate/Launch/launch/example_main_launch.yaml b/source/Tutorials/Intermediate/Launch/launch/example_main_launch.yaml new file mode 100644 index 00000000000..0b336939fb5 --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/example_main_launch.yaml @@ -0,0 +1,15 @@ +%YAML 1.2 +--- +launch: + - let: + name: "background_r" + value: "200" + - include: + file: "$(find-pkg-share launch_tutorial)/launch/example_substitutions_launch.yaml" + arg: + - name: "turtlesim_ns" + value: "turtlesim2" + - name: "use_provided_red" + value: "True" + - name: "new_background_r" + value: "$(var background_r)" diff --git a/source/Tutorials/Intermediate/Launch/launch/example_substitutions_launch.py b/source/Tutorials/Intermediate/Launch/launch/example_substitutions_launch.py new file mode 100644 index 00000000000..03f980613cb --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/example_substitutions_launch.py @@ -0,0 +1,80 @@ +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument, ExecuteProcess, TimerAction +from launch.conditions import IfCondition +from launch.substitutions import LaunchConfiguration, PythonExpression +from launch_ros.actions import Node + + +def generate_launch_description(): + turtlesim_ns = LaunchConfiguration('turtlesim_ns') + use_provided_red = LaunchConfiguration('use_provided_red') + new_background_r = LaunchConfiguration('new_background_r') + + turtlesim_ns_launch_arg = DeclareLaunchArgument( + 'turtlesim_ns', + default_value='turtlesim1' + ) + use_provided_red_launch_arg = DeclareLaunchArgument( + 'use_provided_red', + default_value='False' + ) + new_background_r_launch_arg = DeclareLaunchArgument( + 'new_background_r', + default_value='200' + ) + + turtlesim_node = Node( + package='turtlesim', + namespace=turtlesim_ns, + executable='turtlesim_node', + name='sim' + ) + spawn_turtle = ExecuteProcess( + cmd=[[ + 'ros2 service call ', + turtlesim_ns, + '/spawn ', + 'turtlesim_msgs/srv/Spawn ', + '"{x: 2, y: 2, theta: 0.2}"' + ]], + shell=True + ) + change_background_r = ExecuteProcess( + cmd=[[ + 'ros2 param set ', + turtlesim_ns, + '/sim background_r ', + '120' + ]], + shell=True + ) + change_background_r_conditioned = ExecuteProcess( + condition=IfCondition( + PythonExpression([ + new_background_r, + ' == 200', + ' and ', + use_provided_red + ]) + ), + cmd=[[ + 'ros2 param set ', + turtlesim_ns, + '/sim background_r ', + new_background_r + ]], + shell=True + ) + + return LaunchDescription([ + turtlesim_ns_launch_arg, + use_provided_red_launch_arg, + new_background_r_launch_arg, + turtlesim_node, + spawn_turtle, + change_background_r, + TimerAction( + period=2.0, + actions=[change_background_r_conditioned], + ) + ]) diff --git a/source/Tutorials/Intermediate/Launch/launch/example_substitutions_launch.xml b/source/Tutorials/Intermediate/Launch/launch/example_substitutions_launch.xml new file mode 100644 index 00000000000..89cedffbdd1 --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/example_substitutions_launch.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + diff --git a/source/Tutorials/Intermediate/Launch/launch/example_substitutions_launch.yaml b/source/Tutorials/Intermediate/Launch/launch/example_substitutions_launch.yaml new file mode 100644 index 00000000000..89d6737e298 --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/example_substitutions_launch.yaml @@ -0,0 +1,28 @@ +%YAML 1.2 +--- +launch: + - arg: + name: "turtlesim_ns" + default: "turtlesim1" + - arg: + name: "use_provided_red" + default: "False" + - arg: + name: "new_background_r" + default: "200" + + - node: + pkg: "turtlesim" + namespace: "$(var turtlesim_ns)" + exec: "turtlesim_node" + name: "sim" + - executable: + cmd: 'ros2 service call $(var turtlesim_ns)/spawn turtlesim_msgs/srv/Spawn "{x: 5, y: 2, theta: 0.2}"' + - executable: + cmd: "ros2 param set $(var turtlesim_ns)/sim background_r 120" + - timer: + period: 2.0 + children: + - executable: + cmd: "ros2 param set $(var turtlesim_ns)/sim background_r $(var new_background_r)" + if: '$(eval "$(var new_background_r) == 200 and $(var use_provided_red)")' diff --git a/source/Tutorials/Intermediate/Launch/launch/fixed_broadcaster_launch.py b/source/Tutorials/Intermediate/Launch/launch/fixed_broadcaster_launch.py new file mode 100644 index 00000000000..bd04c46cc83 --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/fixed_broadcaster_launch.py @@ -0,0 +1,19 @@ +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument +from launch.substitutions import EnvironmentVariable, LaunchConfiguration +from launch_ros.actions import Node + + +def generate_launch_description(): + return LaunchDescription([ + DeclareLaunchArgument( + 'node_prefix', + default_value=[EnvironmentVariable('USER'), '_'], + description='prefix for node name' + ), + Node( + package='turtle_tf2_py', + executable='fixed_frame_tf2_broadcaster', + name=[LaunchConfiguration('node_prefix'), 'fixed_broadcaster'], + ), + ]) diff --git a/source/Tutorials/Intermediate/Launch/launch/launch_turtlesim_launch.py b/source/Tutorials/Intermediate/Launch/launch/launch_turtlesim_launch.py new file mode 100644 index 00000000000..8c06c8b724a --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/launch_turtlesim_launch.py @@ -0,0 +1,50 @@ +import os + +from ament_index_python.packages import get_package_share_directory + +from launch import LaunchDescription +from launch.actions import IncludeLaunchDescription +from launch.launch_description_sources import PythonLaunchDescriptionSource + + +def generate_launch_description(): + turtlesim_world_1 = IncludeLaunchDescription( + PythonLaunchDescriptionSource([os.path.join( + get_package_share_directory('launch_tutorial'), 'launch'), + '/turtlesim_world_1_launch.py']) + ) + turtlesim_world_2 = IncludeLaunchDescription( + PythonLaunchDescriptionSource([os.path.join( + get_package_share_directory('launch_tutorial'), 'launch'), + '/turtlesim_world_2_launch.py']) + ) + broadcaster_listener_nodes = IncludeLaunchDescription( + PythonLaunchDescriptionSource([os.path.join( + get_package_share_directory('launch_tutorial'), 'launch'), + '/broadcaster_listener_launch.py']), + launch_arguments={'target_frame': 'carrot1'}.items(), + ) + mimic_node = IncludeLaunchDescription( + PythonLaunchDescriptionSource([os.path.join( + get_package_share_directory('launch_tutorial'), 'launch'), + '/mimic_launch.py']) + ) + fixed_frame_node = IncludeLaunchDescription( + PythonLaunchDescriptionSource([os.path.join( + get_package_share_directory('launch_tutorial'), 'launch'), + '/fixed_broadcaster_launch.py']) + ) + rviz_node = IncludeLaunchDescription( + PythonLaunchDescriptionSource([os.path.join( + get_package_share_directory('launch_tutorial'), 'launch'), + '/turtlesim_rviz_launch.py']) + ) + + return LaunchDescription([ + turtlesim_world_1, + turtlesim_world_2, + broadcaster_listener_nodes, + mimic_node, + fixed_frame_node, + rviz_node + ]) diff --git a/source/Tutorials/Intermediate/Launch/launch/mimic_launch.py b/source/Tutorials/Intermediate/Launch/launch/mimic_launch.py new file mode 100644 index 00000000000..e0327963829 --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/mimic_launch.py @@ -0,0 +1,16 @@ +from launch import LaunchDescription +from launch_ros.actions import Node + + +def generate_launch_description(): + return LaunchDescription([ + Node( + package='turtlesim', + executable='mimic', + name='mimic', + remappings=[ + ('/input/pose', '/turtle2/pose'), + ('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'), + ] + ) + ]) diff --git a/source/Tutorials/Intermediate/Launch/launch/my_script_launch.py b/source/Tutorials/Intermediate/Launch/launch/my_script_launch.py new file mode 100644 index 00000000000..77278547173 --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/my_script_launch.py @@ -0,0 +1,11 @@ +import launch +import launch_ros.actions + + +def generate_launch_description(): + return launch.LaunchDescription([ + launch_ros.actions.Node( + package='demo_nodes_cpp', + executable='talker', + name='talker'), + ]) diff --git a/source/Tutorials/Intermediate/Launch/launch/my_script_launch.xml b/source/Tutorials/Intermediate/Launch/launch/my_script_launch.xml new file mode 100644 index 00000000000..a07a2127d91 --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/my_script_launch.xml @@ -0,0 +1,4 @@ + + + + diff --git a/source/Tutorials/Intermediate/Launch/launch/my_script_launch.yaml b/source/Tutorials/Intermediate/Launch/launch/my_script_launch.yaml new file mode 100644 index 00000000000..b7d987c2302 --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/my_script_launch.yaml @@ -0,0 +1,7 @@ +%YAML 1.2 +--- +launch: + - node: + pkg: "demo_nodes_cpp" + exec: "talker" + name: "talker" diff --git a/source/Tutorials/Intermediate/Launch/launch/turtlesim_mimic_launch.py b/source/Tutorials/Intermediate/Launch/launch/turtlesim_mimic_launch.py new file mode 100644 index 00000000000..489f53d9f32 --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/turtlesim_mimic_launch.py @@ -0,0 +1,28 @@ +from launch import LaunchDescription +from launch_ros.actions import Node + + +def generate_launch_description(): + return LaunchDescription([ + Node( + package='turtlesim', + namespace='turtlesim1', + executable='turtlesim_node', + name='sim' + ), + Node( + package='turtlesim', + namespace='turtlesim2', + executable='turtlesim_node', + name='sim' + ), + Node( + package='turtlesim', + executable='mimic', + name='mimic', + remappings=[ + ('/input/pose', '/turtlesim1/turtle1/pose'), + ('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'), + ] + ) + ]) diff --git a/source/Tutorials/Intermediate/Launch/launch/turtlesim_mimic_launch.xml b/source/Tutorials/Intermediate/Launch/launch/turtlesim_mimic_launch.xml new file mode 100644 index 00000000000..dcf9c0cd37a --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/turtlesim_mimic_launch.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/source/Tutorials/Intermediate/Launch/launch/turtlesim_mimic_launch.yaml b/source/Tutorials/Intermediate/Launch/launch/turtlesim_mimic_launch.yaml new file mode 100644 index 00000000000..b48ed46a492 --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/turtlesim_mimic_launch.yaml @@ -0,0 +1,24 @@ +%YAML 1.2 +--- +launch: + - node: + pkg: "turtlesim" + exec: "turtlesim_node" + name: "sim" + namespace: "turtlesim1" + + - node: + pkg: "turtlesim" + exec: "turtlesim_node" + name: "sim" + namespace: "turtlesim2" + + - node: + pkg: "turtlesim" + exec: "mimic" + name: "mimic" + remap: + - from: "/input/pose" + to: "/turtlesim1/turtle1/pose" + - from: "/output/cmd_vel" + to: "/turtlesim2/turtle1/cmd_vel" diff --git a/source/Tutorials/Intermediate/Launch/launch/turtlesim_rviz_launch.py b/source/Tutorials/Intermediate/Launch/launch/turtlesim_rviz_launch.py new file mode 100644 index 00000000000..e0cbaf1402c --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/turtlesim_rviz_launch.py @@ -0,0 +1,23 @@ +import os + +from ament_index_python.packages import get_package_share_directory + +from launch import LaunchDescription +from launch_ros.actions import Node + + +def generate_launch_description(): + rviz_config = os.path.join( + get_package_share_directory('turtle_tf2_py'), + 'rviz', + 'turtle_rviz.rviz' + ) + + return LaunchDescription([ + Node( + package='rviz2', + executable='rviz2', + name='rviz2', + arguments=['-d', rviz_config] + ) + ]) diff --git a/source/Tutorials/Intermediate/Launch/launch/turtlesim_world_1_launch.py b/source/Tutorials/Intermediate/Launch/launch/turtlesim_world_1_launch.py new file mode 100644 index 00000000000..3f494ba6d3b --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/turtlesim_world_1_launch.py @@ -0,0 +1,33 @@ +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument +from launch.substitutions import LaunchConfiguration, TextSubstitution + +from launch_ros.actions import Node + + +def generate_launch_description(): + background_r_launch_arg = DeclareLaunchArgument( + 'background_r', default_value=TextSubstitution(text='0') + ) + background_g_launch_arg = DeclareLaunchArgument( + 'background_g', default_value=TextSubstitution(text='84') + ) + background_b_launch_arg = DeclareLaunchArgument( + 'background_b', default_value=TextSubstitution(text='122') + ) + + return LaunchDescription([ + background_r_launch_arg, + background_g_launch_arg, + background_b_launch_arg, + Node( + package='turtlesim', + executable='turtlesim_node', + name='sim', + parameters=[{ + 'background_r': LaunchConfiguration('background_r'), + 'background_g': LaunchConfiguration('background_g'), + 'background_b': LaunchConfiguration('background_b'), + }] + ), + ]) diff --git a/source/Tutorials/Intermediate/Launch/launch/turtlesim_world_2_launch.py b/source/Tutorials/Intermediate/Launch/launch/turtlesim_world_2_launch.py new file mode 100644 index 00000000000..ba9a0a2a64e --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/turtlesim_world_2_launch.py @@ -0,0 +1,23 @@ +import os + +from ament_index_python.packages import get_package_share_directory + +from launch import LaunchDescription +from launch_ros.actions import Node + + +def generate_launch_description(): + config = os.path.join( + get_package_share_directory('launch_tutorial'), + 'config', + 'turtlesim.yaml') + + return LaunchDescription([ + Node( + package='turtlesim', + executable='turtlesim_node', + namespace='turtlesim2', + name='sim', + parameters=[config] + ) + ]) diff --git a/source/Tutorials/Intermediate/Launch/launch/turtlesim_world_3_launch.py b/source/Tutorials/Intermediate/Launch/launch/turtlesim_world_3_launch.py new file mode 100644 index 00000000000..0aab127bca9 --- /dev/null +++ b/source/Tutorials/Intermediate/Launch/launch/turtlesim_world_3_launch.py @@ -0,0 +1,23 @@ +import os + +from ament_index_python.packages import get_package_share_directory + +from launch import LaunchDescription +from launch_ros.actions import Node + + +def generate_launch_description(): + config = os.path.join( + get_package_share_directory('launch_tutorial'), + 'config', + 'turtlesim.yaml') + + return LaunchDescription([ + Node( + package='turtlesim', + executable='turtlesim_node', + namespace='turtlesim3', + name='sim', + parameters=[config] + ) + ]) diff --git a/source/Tutorials/Intermediate/Tf2/Adding-A-Frame-Cpp.rst b/source/Tutorials/Intermediate/Tf2/Adding-A-Frame-Cpp.rst index 05931952cc4..cece4edba2d 100644 --- a/source/Tutorials/Intermediate/Tf2/Adding-A-Frame-Cpp.rst +++ b/source/Tutorials/Intermediate/Tf2/Adding-A-Frame-Cpp.rst @@ -186,6 +186,7 @@ Finally, add the ``install(TARGETS…)`` section so ``ros2 run`` can find your e Now let's create a launch file for this example. With your text editor, create a new file called ``turtle_tf2_fixed_frame_demo.launch.py`` in the ``src/learning_tf2_cpp/launch`` directory, and add the following lines: +<<<<<<< HEAD .. code-block:: python import os @@ -215,18 +216,18 @@ With your text editor, create a new file called ``turtle_tf2_fixed_frame_demo.la ), ]) +======= +.. literalinclude:: launch/turtle_tf2_fixed_frame_demo_launch.py + :language: python +>>>>>>> 666df3e (Pull all example launchfiles into separate file with `literalinclude` (#5155)) This launch file imports the required packages and then creates a ``demo_nodes`` variable that will store nodes that we created in the previous tutorial's launch file. The last part of the code will add our fixed ``carrot1`` frame to the turtlesim world using our ``fixed_frame_tf2_broadcaster`` node. -.. code-block:: python - - Node( - package='learning_tf2_cpp', - executable='fixed_frame_tf2_broadcaster', - name='fixed_broadcaster', - ), +.. literalinclude:: launch/turtle_tf2_fixed_frame_demo_launch.py + :language: python + :lines: 21-25 1.4 Build ~~~~~~~~~ @@ -475,8 +476,10 @@ Finally, add the ``install(TARGETS…)`` section so ``ros2 run`` can find your e To test this code, create a new launch file ``turtle_tf2_dynamic_frame_demo.launch.py`` in the ``src/learning_tf2_cpp/launch`` directory and paste the following code: -.. code-block:: python +.. literalinclude:: launch/turtle_tf2_dynamic_frame_demo_launch.py + :language: python +<<<<<<< HEAD import os from ament_index_python.packages import get_package_share_directory @@ -504,6 +507,8 @@ To test this code, create a new launch file ``turtle_tf2_dynamic_frame_demo.laun name='dynamic_broadcaster', ), ]) +======= +>>>>>>> 666df3e (Pull all example launchfiles into separate file with `literalinclude` (#5155)) 2.4 Build ~~~~~~~~~ diff --git a/source/Tutorials/Intermediate/Tf2/Adding-A-Frame-Py.rst b/source/Tutorials/Intermediate/Tf2/Adding-A-Frame-Py.rst index 254b1e797e1..616b73f5643 100644 --- a/source/Tutorials/Intermediate/Tf2/Adding-A-Frame-Py.rst +++ b/source/Tutorials/Intermediate/Tf2/Adding-A-Frame-Py.rst @@ -162,6 +162,7 @@ Add the following line between the ``'console_scripts':`` brackets: Now let's create a launch file for this example. With your text editor, create a new file called ``turtle_tf2_fixed_frame_demo.launch.py`` in the ``src/learning_tf2_py/launch`` directory, and add the following lines: +<<<<<<< HEAD .. code-block:: python import os @@ -191,18 +192,19 @@ With your text editor, create a new file called ``turtle_tf2_fixed_frame_demo.la ), ]) +======= +.. literalinclude:: launch/py_turtle_tf2_fixed_frame_demo_launch.py + :name: turtle_tf2_fixed_frame_demo_launch.py + :language: python +>>>>>>> 666df3e (Pull all example launchfiles into separate file with `literalinclude` (#5155)) This launch file imports the required packages and then creates a ``demo_nodes`` variable that will store nodes that we created in the previous tutorial's launch file. The last part of the code will add our fixed ``carrot1`` frame to the turtlesim world using our ``fixed_frame_tf2_broadcaster`` node. -.. code-block:: python - - Node( - package='learning_tf2_py', - executable='fixed_frame_tf2_broadcaster', - name='fixed_broadcaster', - ), +.. literalinclude:: launch/py_turtle_tf2_fixed_frame_demo_launch.py + :language: python + :lines: 22-26 1.4 Build ~~~~~~~~~ @@ -428,8 +430,10 @@ Add the following line between the ``'console_scripts':`` brackets: To test this code, create a new launch file ``turtle_tf2_dynamic_frame_demo.launch.py`` in the ``src/learning_tf2_py/launch`` directory and paste the following code: -.. code-block:: python +.. literalinclude:: launch/py_turtle_tf2_dynamic_frame_demo_launch.py + :name: turtle_tf2_dynamic_frame_demo_launch.py +<<<<<<< HEAD import os from ament_index_python.packages import get_package_share_directory @@ -457,6 +461,8 @@ To test this code, create a new launch file ``turtle_tf2_dynamic_frame_demo.laun name='dynamic_broadcaster', ), ]) +======= +>>>>>>> 666df3e (Pull all example launchfiles into separate file with `literalinclude` (#5155)) 2.4 Build ~~~~~~~~~ diff --git a/source/Tutorials/Intermediate/Tf2/Debugging-Tf2-Problems.rst b/source/Tutorials/Intermediate/Tf2/Debugging-Tf2-Problems.rst index 056cee24545..68714925f86 100644 --- a/source/Tutorials/Intermediate/Tf2/Debugging-Tf2-Problems.rst +++ b/source/Tutorials/Intermediate/Tf2/Debugging-Tf2-Problems.rst @@ -74,51 +74,8 @@ to And save changes to the file. In order to run this demo, we need to create a launch file ``start_tf2_debug_demo.launch.py`` in the ``launch`` subdirectory of package ``learning_tf2_cpp``: -.. code-block:: python - - from launch import LaunchDescription - from launch.actions import DeclareLaunchArgument - from launch.substitutions import LaunchConfiguration - - from launch_ros.actions import Node - - def generate_launch_description(): - return LaunchDescription([ - DeclareLaunchArgument( - 'target_frame', default_value='turtle1', - description='Target frame name.' - ), - Node( - package='turtlesim', - executable='turtlesim_node', - name='sim', - output='screen' - ), - Node( - package='learning_tf2_cpp', - executable='turtle_tf2_broadcaster', - name='broadcaster1', - parameters=[ - {'turtlename': 'turtle1'} - ] - ), - Node( - package='learning_tf2_cpp', - executable='turtle_tf2_broadcaster', - name='broadcaster2', - parameters=[ - {'turtlename': 'turtle2'} - ] - ), - Node( - package='learning_tf2_cpp', - executable='turtle_tf2_listener_debug', - name='listener_debug', - parameters=[ - {'target_frame': LaunchConfiguration('target_frame')} - ] - ), - ]) +.. literalinclude:: launch/start_tf2_debug_demo_launch.py + :language: python Don't forget to add the ``turtle_tf2_listener_debug`` executable to the ``CMakeLists.txt`` and build the package. diff --git a/source/Tutorials/Intermediate/Tf2/Using-Stamped-Datatypes-With-Tf2-Ros-MessageFilter.rst b/source/Tutorials/Intermediate/Tf2/Using-Stamped-Datatypes-With-Tf2-Ros-MessageFilter.rst index d32879c6d10..1d14f610d7d 100644 --- a/source/Tutorials/Intermediate/Tf2/Using-Stamped-Datatypes-With-Tf2-Ros-MessageFilter.rst +++ b/source/Tutorials/Intermediate/Tf2/Using-Stamped-Datatypes-With-Tf2-Ros-MessageFilter.rst @@ -214,47 +214,8 @@ Then we fill up the ``PointStamped`` messages of ``turtle3`` with incoming ``Pos In order to run this demo, we need to create a launch file ``turtle_tf2_sensor_message.launch.py`` in the ``launch`` subdirectory of package ``learning_tf2_py``: -.. code-block:: python - - from launch import LaunchDescription - from launch.actions import DeclareLaunchArgument - from launch_ros.actions import Node - - - def generate_launch_description(): - return LaunchDescription([ - DeclareLaunchArgument( - 'target_frame', default_value='turtle1', - description='Target frame name.' - ), - Node( - package='turtlesim', - executable='turtlesim_node', - name='sim', - output='screen' - ), - Node( - package='turtle_tf2_py', - executable='turtle_tf2_broadcaster', - name='broadcaster1', - parameters=[ - {'turtlename': 'turtle1'} - ] - ), - Node( - package='turtle_tf2_py', - executable='turtle_tf2_broadcaster', - name='broadcaster2', - parameters=[ - {'turtlename': 'turtle3'} - ] - ), - Node( - package='turtle_tf2_py', - executable='turtle_tf2_message_broadcaster', - name='message_broadcaster', - ), - ]) +.. literalinclude:: launch/turtle_tf2_sensor_message_launch.py + :language: python 1.3 Add an entry point diff --git a/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Broadcaster-Cpp.rst b/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Broadcaster-Cpp.rst index c06decc8089..8db13beb3c1 100644 --- a/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Broadcaster-Cpp.rst +++ b/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Broadcaster-Cpp.rst @@ -250,28 +250,8 @@ Now create a launch file for this demo. Create a ``launch`` folder in the ``src/learning_tf2_cpp`` directory. With your text editor, create a new file called ``turtle_tf2_demo.launch.py`` in the ``launch`` folder, and add the following lines: -.. code-block:: python - - from launch import LaunchDescription - from launch_ros.actions import Node - - - def generate_launch_description(): - return LaunchDescription([ - Node( - package='turtlesim', - executable='turtlesim_node', - name='sim' - ), - Node( - package='learning_tf2_cpp', - executable='turtle_tf2_broadcaster', - name='broadcaster1', - parameters=[ - {'turtlename': 'turtle1'} - ] - ), - ]) +.. literalinclude:: launch/turtle_tf2_demo_launch.py + :language: python 2.1 Examine the code ~~~~~~~~~~~~~~~~~~~~ @@ -279,28 +259,15 @@ With your text editor, create a new file called ``turtle_tf2_demo.launch.py`` in First we import required modules from the ``launch`` and ``launch_ros`` packages. It should be noted that ``launch`` is a generic launching framework (not ROS 2 specific) and ``launch_ros`` has ROS 2 specific things, like nodes that we import here. -.. code-block:: python - - from launch import LaunchDescription - from launch_ros.actions import Node +.. literalinclude:: launch/turtle_tf2_demo_launch.py + :language: python + :lines: 1-2 Now we run our nodes that start the turtlesim simulation and broadcast ``turtle1`` state to the tf2 using our ``turtle_tf2_broadcaster`` node. -.. code-block:: python - - Node( - package='turtlesim', - executable='turtlesim_node', - name='sim' - ), - Node( - package='learning_tf2_cpp', - executable='turtle_tf2_broadcaster', - name='broadcaster1', - parameters=[ - {'turtlename': 'turtle1'} - ] - ), +.. literalinclude:: launch/turtle_tf2_demo_launch.py + :language: python + :lines: 7-19 2.2 Add dependencies ~~~~~~~~~~~~~~~~~~~~ diff --git a/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Broadcaster-Py.rst b/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Broadcaster-Py.rst index c7fc7e43898..de384e5ab54 100644 --- a/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Broadcaster-Py.rst +++ b/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Broadcaster-Py.rst @@ -255,28 +255,10 @@ Now create a launch file for this demo. Create a ``launch`` folder in the ``src/learning_tf2_py`` directory. With your text editor, create a new file called ``turtle_tf2_demo.launch.py`` in the ``launch`` folder, and add the following lines: -.. code-block:: python +.. literalinclude:: launch/py_turtle_tf2_demo_launch.py + :language: python + :name: turtle_tf2_demo_launch.py - from launch import LaunchDescription - from launch_ros.actions import Node - - - def generate_launch_description(): - return LaunchDescription([ - Node( - package='turtlesim', - executable='turtlesim_node', - name='sim' - ), - Node( - package='learning_tf2_py', - executable='turtle_tf2_broadcaster', - name='broadcaster1', - parameters=[ - {'turtlename': 'turtle1'} - ] - ), - ]) 2.1 Examine the code ~~~~~~~~~~~~~~~~~~~~ @@ -284,28 +266,15 @@ With your text editor, create a new file called ``turtle_tf2_demo.launch.py`` in First we import required modules from the ``launch`` and ``launch_ros`` packages. It should be noted that ``launch`` is a generic launching framework (not ROS 2 specific) and ``launch_ros`` has ROS 2 specific things, like nodes that we import here. -.. code-block:: python - - from launch import LaunchDescription - from launch_ros.actions import Node +.. literalinclude:: launch/py_turtle_tf2_demo_launch.py + :language: python + :lines: 1-2 Now we run our nodes that start the turtlesim simulation and broadcast ``turtle1`` state to the tf2 using our ``turtle_tf2_broadcaster`` node. -.. code-block:: python - - Node( - package='turtlesim', - executable='turtlesim_node', - name='sim' - ), - Node( - package='learning_tf2_py', - executable='turtle_tf2_broadcaster', - name='broadcaster1', - parameters=[ - {'turtlename': 'turtle1'} - ] - ), +.. literalinclude:: launch/py_turtle_tf2_demo_launch.py + :language: python + :lines: 7-19 2.2 Add dependencies ~~~~~~~~~~~~~~~~~~~~ diff --git a/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Listener-Cpp.rst b/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Listener-Cpp.rst index 4a7377c65d4..eab8fd364db 100644 --- a/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Listener-Cpp.rst +++ b/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Listener-Cpp.rst @@ -281,51 +281,8 @@ Finally, add the ``install(TARGETS…)`` section so ``ros2 run`` can find your e Open the launch file called ``turtle_tf2_demo.launch.py`` in the ``src/learning_tf2_cpp/launch`` directory with your text editor, add two new nodes to the launch description, add a launch argument, and add the imports. The resulting file should look like: -.. code-block:: python - - from launch import LaunchDescription - from launch.actions import DeclareLaunchArgument - from launch.substitutions import LaunchConfiguration - - from launch_ros.actions import Node - - - def generate_launch_description(): - return LaunchDescription([ - Node( - package='turtlesim', - executable='turtlesim_node', - name='sim' - ), - Node( - package='learning_tf2_cpp', - executable='turtle_tf2_broadcaster', - name='broadcaster1', - parameters=[ - {'turtlename': 'turtle1'} - ] - ), - DeclareLaunchArgument( - 'target_frame', default_value='turtle1', - description='Target frame name.' - ), - Node( - package='learning_tf2_cpp', - executable='turtle_tf2_broadcaster', - name='broadcaster2', - parameters=[ - {'turtlename': 'turtle2'} - ] - ), - Node( - package='learning_tf2_cpp', - executable='turtle_tf2_listener', - name='listener', - parameters=[ - {'target_frame': LaunchConfiguration('target_frame')} - ] - ), - ]) +.. literalinclude:: launch/listener_cpp_launch.py + :language: python This will declare a ``target_frame`` launch argument, start a broadcaster for the second turtle that we will spawn and a listener that will subscribe to those transformations. diff --git a/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Listener-Py.rst b/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Listener-Py.rst index f6de32fe4e2..7e0f1289060 100644 --- a/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Listener-Py.rst +++ b/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Listener-Py.rst @@ -231,51 +231,9 @@ Add the following line between the ``'console_scripts':`` brackets: Open the launch file called ``turtle_tf2_demo.launch.py`` in the ``src/learning_tf2_py/launch`` directory with your text editor, add two new nodes to the launch description, add a launch argument, and add the imports. The resulting file should look like: -.. code-block:: python - - from launch import LaunchDescription - from launch.actions import DeclareLaunchArgument - from launch.substitutions import LaunchConfiguration - - from launch_ros.actions import Node - - - def generate_launch_description(): - return LaunchDescription([ - Node( - package='turtlesim', - executable='turtlesim_node', - name='sim' - ), - Node( - package='learning_tf2_py', - executable='turtle_tf2_broadcaster', - name='broadcaster1', - parameters=[ - {'turtlename': 'turtle1'} - ] - ), - DeclareLaunchArgument( - 'target_frame', default_value='turtle1', - description='Target frame name.' - ), - Node( - package='learning_tf2_py', - executable='turtle_tf2_broadcaster', - name='broadcaster2', - parameters=[ - {'turtlename': 'turtle2'} - ] - ), - Node( - package='learning_tf2_py', - executable='turtle_tf2_listener', - name='listener', - parameters=[ - {'target_frame': LaunchConfiguration('target_frame')} - ] - ), - ]) +.. literalinclude:: launch/listener_py_launch.py + :language: python + :name: turtle_tf2_demo_launch.py This will declare a ``target_frame`` launch argument, start a broadcaster for second turtle that we will spawn and listener that will subscribe to those transformations. diff --git a/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Static-Broadcaster-Cpp.rst b/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Static-Broadcaster-Cpp.rst index 265586dffb5..a05d20798a4 100644 --- a/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Static-Broadcaster-Cpp.rst +++ b/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Static-Broadcaster-Cpp.rst @@ -410,19 +410,8 @@ The following command publishes a static coordinate transform to tf2 using an x/ ``static_transform_publisher`` is designed both as a command-line tool for manual use, as well as for use within ``launch`` files for setting static transforms. For example: -.. code-block:: console - - from launch import LaunchDescription - from launch_ros.actions import Node - - def generate_launch_description(): - return LaunchDescription([ - Node( - package='tf2_ros', - executable='static_transform_publisher', - arguments = ['--x', '0', '--y', '0', '--z', '1', '--yaw', '0', '--pitch', '0', '--roll', '0', '--frame-id', 'world', '--child-frame-id', 'mystaticturtle'] - ), - ]) +.. literalinclude:: launch/static_transform_publisher_launch.py + :language: python Note that all arguments except for ``--frame-id`` and ``--child-frame-id`` are optional; if a particular option isn't specified, then the identity will be assumed. diff --git a/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Static-Broadcaster-Py.rst b/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Static-Broadcaster-Py.rst index e81b1bcd0a8..65909d43543 100644 --- a/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Static-Broadcaster-Py.rst +++ b/source/Tutorials/Intermediate/Tf2/Writing-A-Tf2-Static-Broadcaster-Py.rst @@ -429,19 +429,8 @@ The following command publishes a static coordinate transform to tf2 using an x/ ``static_transform_publisher`` is designed both as a command-line tool for manual use, as well as for use within ``launch`` files for setting static transforms. For example: -.. code-block:: python - - from launch import LaunchDescription - from launch_ros.actions import Node - - def generate_launch_description(): - return LaunchDescription([ - Node( - package='tf2_ros', - executable='static_transform_publisher', - arguments = ['--x', '0', '--y', '0', '--z', '1', '--yaw', '0', '--pitch', '0', '--roll', '0', '--frame-id', 'world', '--child-frame-id', 'mystaticturtle'] - ), - ]) +.. literalinclude:: launch/static_transform_publisher_launch.py + :language: python Note that all arguments except for ``--frame-id`` and ``--child-frame-id`` are optional; if a particular option isn't specified, then the identity will be assumed. diff --git a/source/Tutorials/Intermediate/Tf2/launch/listener_cpp_launch.py b/source/Tutorials/Intermediate/Tf2/launch/listener_cpp_launch.py new file mode 100644 index 00000000000..fb91de88683 --- /dev/null +++ b/source/Tutorials/Intermediate/Tf2/launch/listener_cpp_launch.py @@ -0,0 +1,43 @@ +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument +from launch.substitutions import LaunchConfiguration + +from launch_ros.actions import Node + + +def generate_launch_description(): + return LaunchDescription([ + Node( + package='turtlesim', + executable='turtlesim_node', + name='sim' + ), + Node( + package='learning_tf2_cpp', + executable='turtle_tf2_broadcaster', + name='broadcaster1', + parameters=[ + {'turtlename': 'turtle1'} + ] + ), + DeclareLaunchArgument( + 'target_frame', default_value='turtle1', + description='Target frame name.' + ), + Node( + package='learning_tf2_cpp', + executable='turtle_tf2_broadcaster', + name='broadcaster2', + parameters=[ + {'turtlename': 'turtle2'} + ] + ), + Node( + package='learning_tf2_cpp', + executable='turtle_tf2_listener', + name='listener', + parameters=[ + {'target_frame': LaunchConfiguration('target_frame')} + ] + ), + ]) diff --git a/source/Tutorials/Intermediate/Tf2/launch/listener_py_launch.py b/source/Tutorials/Intermediate/Tf2/launch/listener_py_launch.py new file mode 100644 index 00000000000..5c319792907 --- /dev/null +++ b/source/Tutorials/Intermediate/Tf2/launch/listener_py_launch.py @@ -0,0 +1,43 @@ +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument +from launch.substitutions import LaunchConfiguration + +from launch_ros.actions import Node + + +def generate_launch_description(): + return LaunchDescription([ + Node( + package='turtlesim', + executable='turtlesim_node', + name='sim' + ), + Node( + package='learning_tf2_py', + executable='turtle_tf2_broadcaster', + name='broadcaster1', + parameters=[ + {'turtlename': 'turtle1'} + ] + ), + DeclareLaunchArgument( + 'target_frame', default_value='turtle1', + description='Target frame name.' + ), + Node( + package='learning_tf2_py', + executable='turtle_tf2_broadcaster', + name='broadcaster2', + parameters=[ + {'turtlename': 'turtle2'} + ] + ), + Node( + package='learning_tf2_py', + executable='turtle_tf2_listener', + name='listener', + parameters=[ + {'target_frame': LaunchConfiguration('target_frame')} + ] + ), + ]) diff --git a/source/Tutorials/Intermediate/Tf2/launch/py_turtle_tf2_demo_launch.py b/source/Tutorials/Intermediate/Tf2/launch/py_turtle_tf2_demo_launch.py new file mode 100644 index 00000000000..343236df162 --- /dev/null +++ b/source/Tutorials/Intermediate/Tf2/launch/py_turtle_tf2_demo_launch.py @@ -0,0 +1,20 @@ +from launch import LaunchDescription +from launch_ros.actions import Node + + +def generate_launch_description(): + return LaunchDescription([ + Node( + package='turtlesim', + executable='turtlesim_node', + name='sim' + ), + Node( + package='learning_tf2_py', + executable='turtle_tf2_broadcaster', + name='broadcaster1', + parameters=[ + {'turtlename': 'turtle1'} + ] + ), + ]) diff --git a/source/Tutorials/Intermediate/Tf2/launch/py_turtle_tf2_dynamic_frame_demo_launch.py b/source/Tutorials/Intermediate/Tf2/launch/py_turtle_tf2_dynamic_frame_demo_launch.py new file mode 100644 index 00000000000..94a7e005439 --- /dev/null +++ b/source/Tutorials/Intermediate/Tf2/launch/py_turtle_tf2_dynamic_frame_demo_launch.py @@ -0,0 +1,27 @@ +import os + +from ament_index_python.packages import get_package_share_directory + +from launch import LaunchDescription +from launch.actions import IncludeLaunchDescription +from launch.launch_description_sources import PythonLaunchDescriptionSource + +from launch_ros.actions import Node + + +def generate_launch_description(): + demo_nodes = IncludeLaunchDescription( + PythonLaunchDescriptionSource([os.path.join( + get_package_share_directory('learning_tf2_py'), 'launch'), + '/turtle_tf2_demo_launch.py']), + launch_arguments={'target_frame': 'carrot1'}.items(), + ) + + return LaunchDescription([ + demo_nodes, + Node( + package='learning_tf2_py', + executable='dynamic_frame_tf2_broadcaster', + name='dynamic_broadcaster', + ), + ]) diff --git a/source/Tutorials/Intermediate/Tf2/launch/py_turtle_tf2_fixed_frame_demo_launch.py b/source/Tutorials/Intermediate/Tf2/launch/py_turtle_tf2_fixed_frame_demo_launch.py new file mode 100644 index 00000000000..f9307deb9a0 --- /dev/null +++ b/source/Tutorials/Intermediate/Tf2/launch/py_turtle_tf2_fixed_frame_demo_launch.py @@ -0,0 +1,26 @@ +import os + +from ament_index_python.packages import get_package_share_directory + +from launch import LaunchDescription +from launch.actions import IncludeLaunchDescription +from launch.launch_description_sources import PythonLaunchDescriptionSource + +from launch_ros.actions import Node + + +def generate_launch_description(): + demo_nodes = IncludeLaunchDescription( + PythonLaunchDescriptionSource([os.path.join( + get_package_share_directory('learning_tf2_py'), 'launch'), + '/turtle_tf2_demo_launch.py']), + ) + + return LaunchDescription([ + demo_nodes, + Node( + package='learning_tf2_py', + executable='fixed_frame_tf2_broadcaster', + name='fixed_broadcaster', + ), + ]) diff --git a/source/Tutorials/Intermediate/Tf2/launch/start_tf2_debug_demo_launch.py b/source/Tutorials/Intermediate/Tf2/launch/start_tf2_debug_demo_launch.py new file mode 100644 index 00000000000..321660c89b5 --- /dev/null +++ b/source/Tutorials/Intermediate/Tf2/launch/start_tf2_debug_demo_launch.py @@ -0,0 +1,43 @@ +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument +from launch.substitutions import LaunchConfiguration +from launch_ros.actions import Node + + +def generate_launch_description(): + return LaunchDescription([ + DeclareLaunchArgument( + 'target_frame', default_value='turtle1', + description='Target frame name.' + ), + Node( + package='turtlesim', + executable='turtlesim_node', + name='sim', + output='screen' + ), + Node( + package='learning_tf2_cpp', + executable='turtle_tf2_broadcaster', + name='broadcaster1', + parameters=[ + {'turtlename': 'turtle1'} + ] + ), + Node( + package='learning_tf2_cpp', + executable='turtle_tf2_broadcaster', + name='broadcaster2', + parameters=[ + {'turtlename': 'turtle2'} + ] + ), + Node( + package='learning_tf2_cpp', + executable='turtle_tf2_listener_debug', + name='listener_debug', + parameters=[ + {'target_frame': LaunchConfiguration('target_frame')} + ] + ), + ]) diff --git a/source/Tutorials/Intermediate/Tf2/launch/static_transform_publisher_launch.py b/source/Tutorials/Intermediate/Tf2/launch/static_transform_publisher_launch.py new file mode 100644 index 00000000000..72bbe303df2 --- /dev/null +++ b/source/Tutorials/Intermediate/Tf2/launch/static_transform_publisher_launch.py @@ -0,0 +1,15 @@ +from launch import LaunchDescription +from launch_ros.actions import Node + + +def generate_launch_description(): + return LaunchDescription([ + Node( + package='tf2_ros', + executable='static_transform_publisher', + arguments=[ + '--x', '0', '--y', '0', '--z', '1', + '--yaw', '0', '--pitch', '0', '--roll', + '0', '--frame-id', 'world', '--child-frame-id', 'mystaticturtle'] + ), + ]) diff --git a/source/Tutorials/Intermediate/Tf2/launch/turtle_tf2_demo_launch.py b/source/Tutorials/Intermediate/Tf2/launch/turtle_tf2_demo_launch.py new file mode 100644 index 00000000000..3e8e525c1e3 --- /dev/null +++ b/source/Tutorials/Intermediate/Tf2/launch/turtle_tf2_demo_launch.py @@ -0,0 +1,20 @@ +from launch import LaunchDescription +from launch_ros.actions import Node + + +def generate_launch_description(): + return LaunchDescription([ + Node( + package='turtlesim', + executable='turtlesim_node', + name='sim' + ), + Node( + package='learning_tf2_cpp', + executable='turtle_tf2_broadcaster', + name='broadcaster1', + parameters=[ + {'turtlename': 'turtle1'} + ] + ), + ]) diff --git a/source/Tutorials/Intermediate/Tf2/launch/turtle_tf2_dynamic_frame_demo_launch.py b/source/Tutorials/Intermediate/Tf2/launch/turtle_tf2_dynamic_frame_demo_launch.py new file mode 100644 index 00000000000..4126ee42580 --- /dev/null +++ b/source/Tutorials/Intermediate/Tf2/launch/turtle_tf2_dynamic_frame_demo_launch.py @@ -0,0 +1,27 @@ +import os + +from ament_index_python.packages import get_package_share_directory + +from launch import LaunchDescription +from launch.actions import IncludeLaunchDescription +from launch.launch_description_sources import PythonLaunchDescriptionSource + +from launch_ros.actions import Node + + +def generate_launch_description(): + demo_nodes = IncludeLaunchDescription( + PythonLaunchDescriptionSource([os.path.join( + get_package_share_directory('learning_tf2_cpp'), 'launch'), + '/turtle_tf2_demo_launch.py']), + launch_arguments={'target_frame': 'carrot1'}.items(), + ) + + return LaunchDescription([ + demo_nodes, + Node( + package='learning_tf2_cpp', + executable='dynamic_frame_tf2_broadcaster', + name='dynamic_broadcaster', + ), + ]) diff --git a/source/Tutorials/Intermediate/Tf2/launch/turtle_tf2_fixed_frame_demo_launch.py b/source/Tutorials/Intermediate/Tf2/launch/turtle_tf2_fixed_frame_demo_launch.py new file mode 100644 index 00000000000..77de8259cf5 --- /dev/null +++ b/source/Tutorials/Intermediate/Tf2/launch/turtle_tf2_fixed_frame_demo_launch.py @@ -0,0 +1,26 @@ +import os + +from ament_index_python.packages import get_package_share_directory + +from launch import LaunchDescription +from launch.actions import IncludeLaunchDescription +from launch.launch_description_sources import PythonLaunchDescriptionSource + +from launch_ros.actions import Node + + +def generate_launch_description(): + demo_nodes = IncludeLaunchDescription( + PythonLaunchDescriptionSource([os.path.join( + get_package_share_directory('learning_tf2_cpp'), 'launch'), + '/turtle_tf2_demo_launch.py']), + ) + + return LaunchDescription([ + demo_nodes, + Node( + package='learning_tf2_cpp', + executable='fixed_frame_tf2_broadcaster', + name='fixed_broadcaster', + ), + ]) diff --git a/source/Tutorials/Intermediate/Tf2/launch/turtle_tf2_sensor_message_launch.py b/source/Tutorials/Intermediate/Tf2/launch/turtle_tf2_sensor_message_launch.py new file mode 100644 index 00000000000..5b919fd302c --- /dev/null +++ b/source/Tutorials/Intermediate/Tf2/launch/turtle_tf2_sensor_message_launch.py @@ -0,0 +1,39 @@ +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument +from launch_ros.actions import Node + + +def generate_launch_description(): + return LaunchDescription([ + DeclareLaunchArgument( + 'target_frame', default_value='turtle1', + description='Target frame name.' + ), + Node( + package='turtlesim', + executable='turtlesim_node', + name='sim', + output='screen' + ), + Node( + package='turtle_tf2_py', + executable='turtle_tf2_broadcaster', + name='broadcaster1', + parameters=[ + {'turtlename': 'turtle1'} + ] + ), + Node( + package='turtle_tf2_py', + executable='turtle_tf2_broadcaster', + name='broadcaster2', + parameters=[ + {'turtlename': 'turtle3'} + ] + ), + Node( + package='turtle_tf2_py', + executable='turtle_tf2_message_broadcaster', + name='message_broadcaster', + ), + ]) diff --git a/source/Tutorials/Intermediate/URDF/Using-URDF-with-Robot-State-Publisher-cpp.rst b/source/Tutorials/Intermediate/URDF/Using-URDF-with-Robot-State-Publisher-cpp.rst index 3aef2311912..a2bda37c588 100644 --- a/source/Tutorials/Intermediate/URDF/Using-URDF-with-Robot-State-Publisher-cpp.rst +++ b/source/Tutorials/Intermediate/URDF/Using-URDF-with-Robot-State-Publisher-cpp.rst @@ -207,51 +207,8 @@ The code file will also tell ``tf2`` how to place the whole model using the ``t Create a new ``urdf_tutorial_cpp/launch`` folder. Open your editor and paste the following code, saving it as ``urdf_tutorial_cpp/launch/launch.py`` -.. code-block:: python - - import os - from ament_index_python.packages import get_package_share_directory - from launch import LaunchDescription - from launch.actions import DeclareLaunchArgument - from launch.substitutions import LaunchConfiguration - from launch_ros.actions import Node - - def generate_launch_description(): - - # ''use_sim_time'' is used to determine whether ros2 use simulation time provided by simulation environment (Gazebo). - use_sim_time = LaunchConfiguration('use_sim_time', default='false') - - urdf_file_name = 'r2d2.urdf.xml' - - # urdf is path of urdf_file_name file. we use define it as the follow due to the CMakeLists.txt file. - urdf=os.path.join( - get_package_share_directory('urdf_tutorial_cpp'), - 'urdf', - urdf_file_name - ) - - # open the whole urdf_file_name file and read it content to robot_desc - with open(urdf, 'r') as infp: - robot_desc = infp.read() - - return LaunchDescription([ - DeclareLaunchArgument( - 'use_sim_time', - default_value='false', - description='Use simulation (Gazebo) clock if true'), - Node( - package='robot_state_publisher', - executable='robot_state_publisher', - name='robot_state_publisher', - output='screen', - parameters=[{'use_sim_time': use_sim_time, 'robot_description': robot_desc}], - arguments=[urdf]), - Node( - package='urdf_tutorial_cpp', - executable='urdf_tutorial_cpp', - name='urdf_tutorial_cpp', - output='screen'), - ]) +.. literalinclude:: launch/launch.py + :language: python 5 Edit the CMakeLists.txt file diff --git a/source/Tutorials/Intermediate/URDF/Using-URDF-with-Robot-State-Publisher-py.rst b/source/Tutorials/Intermediate/URDF/Using-URDF-with-Robot-State-Publisher-py.rst index 7b87933312e..f6b0f7dab35 100644 --- a/source/Tutorials/Intermediate/URDF/Using-URDF-with-Robot-State-Publisher-py.rst +++ b/source/Tutorials/Intermediate/URDF/Using-URDF-with-Robot-State-Publisher-py.rst @@ -205,44 +205,8 @@ Fire up your favorite editor and paste the following code into ``second_ros2_ws/ Create a new ``second_ros2_ws/src/urdf_tutorial_r2d2/launch`` folder. Open your editor and paste the following code, saving it as ``second_ros2_ws/src/urdf_tutorial_r2d2/launch/demo.launch.py`` -.. code-block:: python - - import os - from ament_index_python.packages import get_package_share_directory - from launch import LaunchDescription - from launch.actions import DeclareLaunchArgument - from launch.substitutions import LaunchConfiguration - from launch_ros.actions import Node - - def generate_launch_description(): - - use_sim_time = LaunchConfiguration('use_sim_time', default='false') - - urdf_file_name = 'r2d2.urdf.xml' - urdf = os.path.join( - get_package_share_directory('urdf_tutorial_r2d2'), - urdf_file_name) - with open(urdf, 'r') as infp: - robot_desc = infp.read() - - return LaunchDescription([ - DeclareLaunchArgument( - 'use_sim_time', - default_value='false', - description='Use simulation (Gazebo) clock if true'), - Node( - package='robot_state_publisher', - executable='robot_state_publisher', - name='robot_state_publisher', - output='screen', - parameters=[{'use_sim_time': use_sim_time, 'robot_description': robot_desc}], - arguments=[urdf]), - Node( - package='urdf_tutorial_r2d2', - executable='state_publisher', - name='state_publisher', - output='screen'), - ]) +.. literalinclude:: launch/demo_launch.py + :language: python 5 Edit the setup.py file diff --git a/source/Tutorials/Intermediate/URDF/Using-Xacro-to-Clean-Up-a-URDF-File.rst b/source/Tutorials/Intermediate/URDF/Using-Xacro-to-Clean-Up-a-URDF-File.rst index 1aa906c5fdb..ba4261e2931 100644 --- a/source/Tutorials/Intermediate/URDF/Using-Xacro-to-Clean-Up-a-URDF-File.rst +++ b/source/Tutorials/Intermediate/URDF/Using-Xacro-to-Clean-Up-a-URDF-File.rst @@ -58,24 +58,8 @@ To run xacro within your launch file, you need to put the ``Command`` substituti An easier way to load the robot model is to use the `urdf_launch `_ package to automatically load the xacro/urdf. -.. code-block:: python - - from launch import LaunchDescription - from launch.actions import IncludeLaunchDescription - from launch.substitutions import PathJoinSubstitution - from launch_ros.substitutions import FindPackageShare - - - def generate_launch_description(): - ld = LaunchDescription() - - ld.add_action(IncludeLaunchDescription( - PathJoinSubstitution([FindPackageShare('urdf_launch'), 'launch', 'display.launch.py']), - launch_arguments={ - 'urdf_package': 'turtlebot3_description', - 'urdf_package_path': PathJoinSubstitution(['urdf', 'turtlebot3_burger.urdf'])}.items() - )) - return ld +.. literalinclude:: launch/urdf_display_launch.py + :language: python At the top of the URDF file, you must specify a namespace in order for the file to parse properly. For example, these are the first two lines of a valid xacro file: diff --git a/source/Tutorials/Intermediate/URDF/launch/demo_launch.py b/source/Tutorials/Intermediate/URDF/launch/demo_launch.py new file mode 100644 index 00000000000..1a11c1045b3 --- /dev/null +++ b/source/Tutorials/Intermediate/URDF/launch/demo_launch.py @@ -0,0 +1,37 @@ +import os + +from ament_index_python.packages import get_package_share_directory +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument +from launch.substitutions import LaunchConfiguration +from launch_ros.actions import Node + + +def generate_launch_description(): + use_sim_time = LaunchConfiguration('use_sim_time', default='false') + + urdf_file_name = 'r2d2.urdf.xml' + urdf = os.path.join( + get_package_share_directory('urdf_tutorial_r2d2'), + urdf_file_name) + with open(urdf, 'r') as infp: + robot_desc = infp.read() + + return LaunchDescription([ + DeclareLaunchArgument( + 'use_sim_time', + default_value='false', + description='Use simulation (Gazebo) clock if true'), + Node( + package='robot_state_publisher', + executable='robot_state_publisher', + name='robot_state_publisher', + output='screen', + parameters=[{'use_sim_time': use_sim_time, 'robot_description': robot_desc}], + arguments=[urdf]), + Node( + package='urdf_tutorial_r2d2', + executable='state_publisher', + name='state_publisher', + output='screen'), + ]) diff --git a/source/Tutorials/Intermediate/URDF/launch/launch.py b/source/Tutorials/Intermediate/URDF/launch/launch.py new file mode 100644 index 00000000000..7c664f804db --- /dev/null +++ b/source/Tutorials/Intermediate/URDF/launch/launch.py @@ -0,0 +1,45 @@ +import os + +from ament_index_python.packages import get_package_share_directory +from launch import LaunchDescription +from launch.actions import DeclareLaunchArgument +from launch.substitutions import LaunchConfiguration +from launch_ros.actions import Node + + +def generate_launch_description(): + + # ''use_sim_time'' is used to determine whether ros2 use simulation time provided by simulation environment (Gazebo). + use_sim_time = LaunchConfiguration('use_sim_time', default='false') + + urdf_file_name = 'r2d2.urdf.xml' + + # urdf is path of urdf_file_name file. we use define it as the follow due to the CMakeLists.txt file. + urdf = os.path.join( + get_package_share_directory('urdf_tutorial_cpp'), + 'urdf', + urdf_file_name + ) + + # open the whole urdf_file_name file and read it content to robot_desc + with open(urdf, 'r') as infp: + robot_desc = infp.read() + + return LaunchDescription([ + DeclareLaunchArgument( + 'use_sim_time', + default_value='false', + description='Use simulation (Gazebo) clock if true'), + Node( + package='robot_state_publisher', + executable='robot_state_publisher', + name='robot_state_publisher', + output='screen', + parameters=[{'use_sim_time': use_sim_time, 'robot_description': robot_desc}], + arguments=[urdf]), + Node( + package='urdf_tutorial_cpp', + executable='urdf_tutorial_cpp', + name='urdf_tutorial_cpp', + output='screen'), + ]) diff --git a/source/Tutorials/Intermediate/URDF/launch/urdf_display_launch.py b/source/Tutorials/Intermediate/URDF/launch/urdf_display_launch.py new file mode 100644 index 00000000000..abc54389f39 --- /dev/null +++ b/source/Tutorials/Intermediate/URDF/launch/urdf_display_launch.py @@ -0,0 +1,16 @@ +from launch import LaunchDescription +from launch.actions import IncludeLaunchDescription +from launch.substitutions import PathJoinSubstitution +from launch_ros.substitutions import FindPackageShare + + +def generate_launch_description(): + return LaunchDescription([ + IncludeLaunchDescription( + PathJoinSubstitution([FindPackageShare('urdf_launch'), 'launch', 'display.launch.py']), + launch_arguments={ + 'urdf_package': 'turtlebot3_description', + 'urdf_package_path': PathJoinSubstitution(['urdf', 'turtlebot3_burger.urdf']) + }.items() + ) + ])