前言
ros2与ros1的不同有以下几点:
- 取消了roscore,各节点直接互相通信
- ros2的命令于ros2基本一致,但为区别于ros1,ros1中的命令被拆分开,如:
rosrun --> ros2 run
,roslaunch --> ros2 launch
,rostopic --> ros2 topic
等等; - 放弃使用catkin工具转而使用colcon进行编译;
- ros2的launch文件增加了python与yaml格式,保留了xml格式但后缀也从
.launch
变为.xml
; - 相比于ros1中的
ros node
与ros nodelet
,ros2中推荐使用component
下文将会介绍以下几点:
launch.py
文件的执行原理
component的构造与使用方法
Python Launch文件
示例:
# 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.LaunchDescriptionEntity
class,其他实体为其派生。从此类派生的类,负责捕获用户关于“如何启动系统”的意图,以及launch本身应如何在启动期间对系统中的异步事件做出反应。launch描述实体在启动期间会调用其launch.LaunchDescriptionEntity.visit
method,并在自检期间调用“describe” method。如果在visit返回后具有持续的异步活动,它还可能提供一个有launch.LaunchDescriptionEntity.get_asyncio_future
method的asyncio.Future
class。
执行visit后,实体可产生额外要visit的实体,这种模式从launch的root
使用,在那里由launch.LaunchDescription
class启动launch进程。
launch.LaunchDescription
class将用户的意图封装为离散的launch.Action
class列表,这些launch.Action
也派生自launch.LaunchDescriptionEntity
。作为“launch description entities”本身,通常,为了响应启动系统中的事件,这些“actions”可以在无副作用的情况下,进行自检分析,或者被执行。
另外,launch描述和其它们包含的actions可查询其中的launch.Substitution
class内容。这些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 alaunch.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 anlaunch.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()