作品
ROS 1 - 节点与 Nodelet
在 ROS 1 中,您可以将代码编写为 ROS 节点 或 ROS 节点小程序。 ROS 1 节点被编译成可执行文件。 另一方面,ROS 1 节点小程序被编译成共享库,然后在运行时由容器进程加载。
ROS 2 - 统一 API
在 ROS 2 中,编写代码的推荐方式类似于节点小程序 - 我们称之为``组件``。 这使得向现有代码添加常见概念变得容易,例如``生命周期 <https://design.ros2.org/articles/node_lifecycle.html>`__。 ROS 2 避免了使用不同的 API,这是 ROS 1 中最大的缺点,因为两种方法都使用相同的 API。
仍然可以使用类似节点的“编写自己的主程序”样式,但对于常见情况,不建议这样做。
通过将流程布局作为部署时决策,用户可以选择:
在单独的进程中运行多个节点,具有进程/故障隔离的好处,并且更容易调试单个节点和
在单个进程中运行多个节点,具有较低的开销和可选的更高效的通信(请参阅:doc:进程内通信)。
此外,ros2 launch
可用于通过专门的启动操作自动执行这些操作。
编写组件
由于组件仅内置于共享库中,因此它没有 main
函数(请参阅 Talker 源代码)。
组件通常是“rclcpp::Node”的子类。
由于它不受线程控制,因此它不应在其构造函数中执行任何长时间运行或阻塞任务。
相反,它可以使用计时器来获取定期通知。
此外,它可以创建发布者、订阅者、服务器和客户端。
将此类类设为组件的一个重要方面是,该类使用包“rclcpp_components”中的宏来注册自身(参见源代码中的最后一行)。 这使得组件在其库被加载到正在运行的进程中时可被发现 - 它充当一种入口点。
此外,一旦创建了组件,就必须使用索引进行注册,以便工具可以发现它。
add_library(talker_component SHARED src/talker_component.cpp)
rclcpp_components_register_nodes(talker_component "composition::Talker")
# 要在同一个共享库中注册多个组件,请使用多个调用
# rclcpp_components_register_nodes(talker_component "composition::Talker2")
Note
为了使 component_container 能够找到所需的组件,必须从具有相应工作区的 shell 执行或启动它。
使用组件
composition 包包含几种使用组件的不同方法。 最常见的三种方法是:
#. 启动(通用容器进程)并调用容器提供的 ROS 服务 load_node。 然后,ROS 服务将加载由传递的包名称和库名称指定的组件,并在正在运行的进程中开始执行它。 除了以编程方式调用 ROS 服务外,您还可以使用 命令行工具 通过传递的命令行参数调用 ROS 服务 #.创建一个`自定义可执行文件<https://github.com/ros2/demos/blob/rolling/composition/src/manual_composition.cpp>`__,其中包含编译时已知的多个节点。 这种方法要求每个组件都有一个头文件(第一种情况并不严格需要)。 #。创建一个启动文件并使用``ros2 launch``创建一个加载了多个组件的容器进程。