4.1 启动文件 launch 简介

场景

如前所述,在机器人操作系统中,节点是程序的基本构成单元,一个完整的、系统性的功能模块是由若干节点组成的,启动某个功能模块时可能需要依次启动这些节点,比如:

以机器人的导航功能为例,涉及的节点主要有:

  • 底盘驱动;
  • 雷达驱动;
  • 摄像头驱动;
  • imu驱动;
  • 地图服务;
  • 路径规划;
  • 运动控制;
  • 环境感知;
  • 定位;
  • ......

并且不同节点启动时,可以还会涉及到各种参数的导入、节点间执行逻辑的处理等。

如果使用 ros2 run指令逐一执行节点的话,显然效率低下,基于此,ROS2中提供了launch模块用于实现节点的批量启动。

概念

launch 字面意为“启动”、“发射”,在ROS2中主要用于启动程序。launch模块由launch文件与 ros2 launch命令组成,前者用于打包并配置节点,后者用于执行launch文件。

作用

简化节点的配置与启动,提高程序的启动效率。

准备工作

1.新建工作空间ws02_tools,本章后续编码实现都基于此工作空间;

2.终端下进入工作空间的src目录,调用如下两条命令分别创建C++功能包和Python功能包。

ros2 pkg create cpp01_launch --build-type ament_cmake --dependencies rclcpp
ros2 pkg create py01_launch --build-type ament_python --dependencies rclpy

3.在使用Python版的launch文件时,涉及的API众多,为了提高编码效率,可以在VScode中设置launch文件的代码模板,将VScode的配置文件python.json修改为为如下内容:

{
    // Place your snippets for python here. Each snippet is defined under a snippet name and has a prefix, body and 
    // description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
    // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the 
    // same ids are connected.
    // Example:
    // "Print to console": {
    //     "prefix": "log",
    //     "body": [
    //         "console.log('$1');",
    //         "$2"
    //     ],
    //     "description": "Log output to console"
    // }

    "ros2 node": {
        "prefix": "ros2_node_py",
        "body": [
            "\"\"\"  ",
            "    需求:",
            "    流程:",
            "        1.导包;",
            "        2.初始化ROS2客户端;",
            "        3.自定义节点类;",
            "                        ",          
            "        4.调用spain函数,并传入节点对象;",
            "        5.资源释放。 ",
            "",
            "",
            "\"\"\"",
            "# 1.导包;",
            "import rclpy",
            "from rclpy.node import Node",
            "",
            "# 3.自定义节点类;",
            "class MyNode(Node):",
            "    def __init__(self):",
            "        super().__init__(\"mynode_node_py\")",
            "",
            "def main():",
            "    # 2.初始化ROS2客户端;",
            "    rclpy.init()",
            "    # 4.调用spain函数,并传入节点对象;",
            "    rclpy.spin(MyNode())",
            "    # 5.资源释放。 ",
            "    rclpy.shutdown()",
            "",
            "if __name__ == '__main__':",
            "    main()",
        ],
        "description": "ros2 node"
    },
    "ros2 launch py": {
        "prefix": "ros2_launch_py",
        "body": [
            "from launch import LaunchDescription",
            "from launch_ros.actions import Node",
            "# 封装终端指令相关类--------------",
            "# from launch.actions import ExecuteProcess",
            "# from launch.substitutions import FindExecutable",
            "# 参数声明与获取-----------------",
            "# from launch.actions import DeclareLaunchArgument",
            "# from launch.substitutions import LaunchConfiguration",
            "# 文件包含相关-------------------",
            "# from launch.actions import IncludeLaunchDescription",
            "# from launch.launch_description_sources import PythonLaunchDescriptionSource",
            "# 分组相关----------------------",
            "# from launch_ros.actions import PushRosNamespace",
            "# from launch.actions import GroupAction",
            "# 事件相关----------------------",
            "# from launch.event_handlers import OnProcessStart, OnProcessExit",
            "# from launch.actions import ExecuteProcess, RegisterEventHandler,LogInfo",
            "# 获取功能包下share目录路径-------",
            "# from ament_index_python.packages import get_package_share_directory",
            "",
            "def generate_launch_description():",
            "    ",    
            "    return LaunchDescription([])"
        ],
        "description": "ros2 launch"
    }
}

results matching ""

    No results matching ""