【ROS2】launch启动文件如何集成到ROS2(Python版本)

一、简单实操

1.创建/打开一个功能包

复制代码
mkdir -p my_ws/src
cd my_ws/src
ros2 pkg create my_pkg_example --build-type ament_python

2.创建Launch文件的存放目录

将所有启动文件都存储在launch包内的目录中。

复制代码
目录结构如下所示:
src/
  my_pkg_example/
    launch/
    package.xml
    py_launch_example/
    resource/
    setup.cfg
    setup.py
    test/

3.修改setup.py文件

为了让 colcon 找到启动文件,我们需要使用 参数告知 Python 的安装工具我们的启动data_files文件setup。

python 复制代码
import os
from glob import glob
from setuptools import setup

package_name = 'my_pkg_example'

setup(
    # Other parameters ...
    data_files=[
        # ... Other data files
        # Include all launch files.
        (os.path.join('share', package_name, 'launch'), glob(os.path.join('launch', '*launch.[pxy][yma]*')))
    ]
)

4.编写Launch文件

在launch目录中,创建一个名为my_test.launch.py文件

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'),
  ])

5.最后就可以构建并运行啦!

python 复制代码
colcon build
python 复制代码
ros2 launch my_pkg_example my_test.launch.py

二、大型项目中的使用技巧

1.完整代码示例

在/launch文件夹中创建一个文件launch_turtlesim.launch.py 内容如下:

python 复制代码
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'])
      )

   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,
      broadcaster_listener_nodes,
      mimic_node,
      fixed_frame_node,
      rviz_node
   ])

2.内包含turtlesim_world_1.launch.py文件

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]
      )
   ])

3.参数设置

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]
      )
   ])

现我们在 /config 文件夹中创建一个配置文件turtlesim.yaml ,它将由我们的启动文件加载。

python 复制代码
/turtlesim2/sim:
   ros__parameters:
      background_b: 255
      background_g: 86
      background_r: 150

/turtlesim3/sim:
   background_b
   background_g
   background_r

我们可以使用通配符语法,而不是为使用相同参数的同一节点创建新配置
/**:
   ros__parameters:
      background_b: 255
      background_g: 86
      background_r: 150

加载相同的 YAML 文件不会影响第三个turtlesim 世界的外观。原因是它的参数存储在另一个命名空间下。

4.ROS2节点复用

现在创建一个broadcaster_listener.launch.py文件

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')}
         ]
      ),
   ])

在此文件中,我们声明了target_frame默认值为 的启动参数turtle1。默认值意味着启动文件可以接收参数以转发到其节点,或者如果未提供参数,它将传递默认值到其节点。

之后,我们turtle_tf2_broadcaster在启动期间使用不同的名称和参数两次使用该节点。这允许我们复制相同的节点而不会发生冲突。

我们还启动一个turtle_tf2_listener节点并设置target_frame上面声明和获取的参数。

5.参数覆盖

我们broadcaster_listener.launch.py在顶级启动文件中调用了该文件。除此之外,我们还传递了它的target_frame启动参数,如下所示:

python 复制代码
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(),
   )

此语法允许我们将默认目标目标框架更改为carrot1。如果您想turtle2跟随turtle1而不是跟随carrot1,只需删除定义的行即可launch_arguments。这将分配target_frame其默认值,即turtle1

6.重新映射

现在创建一个mimic.launch.py文件

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'),
         ]
      )
   ])

该启动文件将启动mimic节点,该节点将向一个turtlesim发出命令以跟随另一个。

该节点旨在接收主题上的目标姿势/input/pose。

在我们的例子中,我们想要从/turtle2/pose主题重新映射目标姿势。

最后,我们将/output/cmd_vel主题重新映射到/turtlesim2/turtle1/cmd_vel。

7.千万记住更新setup.py

python 复制代码
import os
from glob import glob
from setuptools import setup
...

data_files=[
      ...
      (os.path.join('share', package_name, 'launch'),
         glob(os.path.join('launch', '*.launch.py'))),
      (os.path.join('share', package_name, 'config'),
         glob(os.path.join('config', '*.yaml'))),
   ],

8.最后就可以构建并运行啦!

相关推荐
XiaoMu_00121 分钟前
基于Python+Streamlit的旅游数据分析与预测系统:从数据可视化到机器学习预测的完整实现
python·信息可视化·旅游
tan180°23 分钟前
Boost搜索引擎 网络库与前端(4)
linux·网络·c++·搜索引擎
THMAIL24 分钟前
深度学习从入门到精通 - 生成对抗网络(GAN)实战:创造逼真图像的魔法艺术
人工智能·python·深度学习·神经网络·机器学习·生成对抗网络·cnn
Mr. Cao code1 小时前
Docker:颠覆传统虚拟化的轻量级革命
linux·运维·ubuntu·docker·容器
抓饼先生1 小时前
Linux control group笔记
linux·笔记·bash
我没想到原来他们都是一堆坏人2 小时前
(未完待续...)如何编写一个用于构建python web项目镜像的dockerfile文件
java·前端·python
挺6的还2 小时前
25.线程概念和控制(二)
linux
您的通讯录好友2 小时前
conda环境导出
linux·windows·conda
总有刁民想爱朕ha2 小时前
车牌模拟生成器:Python3.8+Opencv代码实现与商业应用前景(C#、python 开发包SDK)
开发语言·python·数据挖掘
代码AC不AC3 小时前
【Linux】vim工具篇
linux·vim·工具详解