ROS2学习

前言

ros2与ros1的不同有以下几点:

  1. 取消了roscore,各节点直接互相通信
  2. ros2的命令于ros2基本一致,但为区别于ros1,ros1中的命令被拆分开,如:rosrun --> ros2 runroslaunch --> ros2 launchrostopic --> ros2 topic等等;
  3. 放弃使用catkin工具转而使用colcon进行编译;
  4. ros2的launch文件增加了python与yaml格式,保留了xml格式但后缀也从.launch变为.xml
  5. 相比于ros1中的ros noderos nodelet,ros2中推荐使用component
    下文将会介绍以下几点:
    launch.py文件的执行原理
    component的构造与使用方法

Python Launch文件

参考:
ROS2 BASICS IN 5 DAYS

示例

# example.launch.py

import os

from ament_index_python import get_package_share_directory

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.actions import IncludeLaunchDescription
from launch.actions import GroupAction
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


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_ns_launch_arg = DeclareLaunchArgument(
        "chatter_ns", default_value=TextSubstitution(text="my/chatter/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 another launch file in the chatter_ns namespace
    launch_include_with_namespace = GroupAction(
        actions=[
            # push-ros-namespace to set namespace of included nodes
            PushRosNamespace(LaunchConfiguration('chatter_ns')),
            IncludeLaunchDescription(
                PythonLaunchDescriptionSource(
                    os.path.join(
                        get_package_share_directory('demo_nodes_cpp'),
                        'launch/topics/talker_listener.launch.py'))
            ),
        ]
    )

    # 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_ns_launch_arg,
        launch_include,
        launch_include_with_namespace,
        turtlesim_node,
        turtlesim_node_with_parameters,
        forward_turtlesim_commands_to_second_turtlesim_node,
    ])

由以上示例,launch.py文件目的就是返回一个launchdescription对象,构造这个对象的参数是一个列表,其中可以包含 参数、其他launch文件和ros节点。

LaunchConfiguration()
ComposableNode()
ComposableNodeContainer()
LoadComposableNodes()
IfCondition()
UnlessCondition()
DeclareLaunchArgument()
SetLaunchConfiguration()
OpaqueFunction()

Architecture of launch

launch设计意图为提供类似 行为描述、事件生成、launch描述自检、和执行launch描述等的核心功能。同时,它提供一些扩展点,以便可以使用其他包来扩展上述核心功能可操作或与之集成的事物集。

Launch Entities和Launch Descriptions

launch中的主要对象是launch.LaunchDescriptionEntityclass,其他实体为其派生。从此类派生的类,负责捕获用户关于“如何启动系统”的意图,以及launch本身应如何在启动期间对系统中的异步事件做出反应。launch描述实体在启动期间会调用其launch.LaunchDescriptionEntity.visitmethod,并在自检期间调用“describe” method。如果在visit返回后具有持续的异步活动,它还可能提供一个有launch.LaunchDescriptionEntity.get_asyncio_futuremethod的asyncio.Futureclass。

执行visit后,实体可产生额外要visit的实体,这种模式从launch的root使用,在那里launch.LaunchDescriptionclass启动launch进程

launch.LaunchDescriptionclass将用户的意图封装为离散的launch.Actionclass列表,这些launch.Action也派生自launch.LaunchDescriptionEntity。作为“launch description entities”本身,通常,为了响应启动系统中的事件,这些“actions”可以在无副作用的情况下,进行自检分析,或者被执行。

另外,launch描述和其它们包含的actions可查询其中的launch.Substitutionclass内容。这些Substitution可在launch期间运算,并可做各种事情,如获取launch configuration,获取变量、或运行python表达式。

launch描述和其所包含的actions可直接自检或由launch.LaunchService类启动。launch service用于处理事件循环并调度actions,为长期运行的活动。

Actions

上述actions允许用户表达不同的意图,并且,对于用户可用的actions集也可以由其他包扩展,从而允许针对特定域的actions。

actions可产生直接的副作用(如运行进程或设置配置变量),并且它们还可以产生其他额外的actions。后者可用于创建"syntactic sugar" actions,而它们以会产生更详尽的actions。

actions也可以有参数,这些参数可以影响actions的行为。这些参数就是应用launch.Substitution的地方,以在描述可重用launch描述时提供更多的灵活性。

Basic Actions

launch提供一些基础actions,其他更复杂的actions可以在此基础上进行构建。以下为launch提供的部分actions列表:

  • launch.actions.IncludeLaunchDescription
    包含另一个launch description,相当于将其粘贴到该include action位置。

  • launch.actions.SetLaunchConfiguration
    This action will set a launch.LaunchConfiguration to a specified value, creating it if it doesn’t already exist.
    launch.LaunchConfiguration设置值,若其不存在,则创建它;
    任何action都可以通过substitution访问这些launch configurations,但默认情况下有作用域。

  • launch.actions.DeclareLaunchDescriptionArgument
    此action将声明一个launch description参数,该参数可以具有一个名字,默认值和文档。
    该参数将通过一个命令行选项对root launch描述公开,或作为“include launch description”的“include launch description action”的action配置公开。

  • launch.actions.SetEnvironmentVariable
    使用名字设置一个环境变量。

  • launch.actions.GroupAction
    此action将生成其他action,但也可与条件关联(以允许对组action使用条件而不必对单个的子action执行),并可选择launch configuration的限定范围。

  • launch.actions.TimerAction
    在不取消的情况下经过一段时间后产生其他action

  • launch.actions.ExecuteProcess
    此action将在给定其路径、参数和其他可选内容(如工作目录或环境变量)的情况下执行一个进程。

  • launch.actions.RegisterEventHandler
    This action will register an launch.EventHandler class, which takes a user defined lambda to handle some event.
    此action将注册一个launchEventHandler类,该类采用用户定义的lambda来处理事件。可以是任何事件,事件的子集或一个特定事件。

  • launch.actions.UnregisterEventHandler
    该action将会移除一个已注册的事件。

  • launch.actions.EmitEvent
    该action将会发出一个基于launch.Event的类,这将会调用所有与其匹配的已注册的事件处理程序。

  • launch.actions.LogInfo:
    此action会将用户定义的消息记录到logger(也可能是logger的变体。如LogWarn)。

  • launch.actions.RaiseError
    This action will stop execution of the launch system and provide a user defined error message.
    该action将会停止执行launch系统并提供一个用户定义的error message。

Base Action

所有action都需要从launch.Action基类继承,以便在与外部包定义的action交互时,launch系统可以使用一些通用接口。由于基操作类是launch描述中的第一个类元素,因此它还继承自launch.LaunchDescriptionEntity,这是迭代launch描述中的元素时使用的多态类型。

此外,基本actions具有所有action共有的一些功能,例如一些自检实用程序,以及与单个launch.Condition(如launch.IfCondition类或launch.UnlessCondition类)相关联的能力。

action配置是在用户使用action时提供的,可用于将“参数”传递给action以影响其行为,例如,在执行进程action中将路径传递给可执行文件的方式。

如果action与条件相关联,则会评估该条件以确定是否执行该action。即使关联的action计算结果为 false,该action也可用于内省。

Composition

composition是

CmakeLists.txt

rclcpp_components_register_node()
rclcpp_components_register_nodes()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值