ROS 2 rclcpp 中的 Node 类解析
目录
在 ROS 2 的rclcpp
库中,Node
类是创建发布者和订阅者的单一入口点。本文将详细解析这个类的功能和用法。
一、类概述
Node
类提供了一系列方法来管理节点的参数、创建发布者、订阅者、定时器、客户端和服务等。它继承自std::enable_shared_from_this
,以便能够安全地返回共享指针,避免出现悬空指针的情况。
二、构造函数
explicit Node(
const std::string & node_name,
const NodeOptions & options = NodeOptions());
explicit Node(
const std::string & node_name,
const std::string & namespace_,
const NodeOptions & options = NodeOptions());
- 作用:创建一个新的节点实例。可以指定节点名称和可选的命名空间以及节点选项。
- 参数解析:
node_name
:节点的名称。namespace_
:节点的命名空间。如果未指定,则使用默认的命名空间。options
:节点选项,用于控制节点的创建过程,例如是否允许未声明的参数等。
三、主要方法解析
1. 获取节点信息的方法
get_name()
:返回节点的名称。get_namespace()
:返回节点的命名空间。这个命名空间不受任何子命名空间的影响,用于获取节点的原始命名空间。get_fully_qualified_name()
:返回节点的完全限定名称,包括本地命名空间和节点名称。get_logger()
:获取节点的日志记录器。
2. 创建各种实体的方法
create_callback_group(group_type)
:创建一个回调组。回调组用于管理一组回调函数的执行方式,可以是互斥的或可重入的。create_publisher(topic_name, qos, options)
:创建一个发布者。可以指定发布的主题名称、服务质量(QoS)设置和发布者选项。create_subscription(topic_name, qos, callback, options, msg_mem_strat)
:创建一个订阅者。需要指定订阅的主题名称、QoS 设置、回调函数、订阅者选项和消息内存策略。create_timer(period, callback, group)
:创建一个定时器。定时器按照指定的时间间隔触发回调函数。可以指定时间间隔、回调函数和回调组。create_client(service_name, qos_profile, group)
:创建一个客户端。用于与服务进行交互,可以指定服务名称、QoS 配置和回调组。create_service(service_name, callback, qos_profile, group)
:创建一个服务。服务用于接收客户端的请求并提供响应,可以指定服务名称、回调函数、QoS 配置和回调组。
3. 参数管理方法
declare_parameter(name, default_value, parameter_descriptor, ignore_override)
:声明并初始化一个参数。如果在运行时用户提供了初始值,则使用该值,否则使用默认值。如果未提供参数描述符,则使用消息定义中的默认值。如果ignore_override
为true
,则忽略参数覆盖。declare_parameter<ParameterT>(name, default_value, parameter_descriptor, ignore_override)
:声明并初始化一个具有特定类型的参数。如果默认值的类型与节点选项中的初始值类型不同,可能会抛出异常。declare_parameters<ParameterT>(namespace_, parameters, ignore_overrides)
:声明并初始化多个具有相同命名空间和类型的参数。可以使用一个简单的版本,只传入参数的默认值,或者使用一个复杂的版本,传入参数的默认值和描述符。undeclare_parameter(name)
:取消声明一个先前声明的参数。如果参数未被声明或者是只读的(不可变的),则会抛出异常。has_parameter(name) const
:检查一个参数是否已经被声明。set_parameter(parameter)
:设置一个参数的值,并返回设置操作的结果。如果参数未被声明且不允许未声明的参数,则会抛出异常。set_parameters(parameters)
:设置多个参数的值,一个一个地进行设置,并返回每个设置操作的结果。如果有任何一个参数未被声明且不允许未声明的参数,则会抛出异常。set_parameters_atomically(parameters)
:原子地设置多个参数的值,如果有任何一个参数设置失败,则所有参数都不会被设置。如果有任何一个参数未被声明且不允许未声明的参数,则会抛出异常。get_parameter(name) const
:获取一个参数的值。如果参数未被声明且不允许未声明的参数,则会抛出异常。get_parameter(name, parameter) const
:获取一个参数的值,并将其存储在输出参数中。如果参数未被声明,则返回false
,否则返回true
。get_parameter<ParameterT>(name, parameter) const
:获取一个参数的值,并尝试将其转换为指定的类型。如果类型不匹配,则会抛出异常。get_parameter_or<ParameterT>(name, parameter, alternative_value) const
:获取一个参数的值,如果参数未被设置,则使用替代值。如果参数被设置,则返回true
,否则返回false
。get_parameters(names) const
:获取多个参数的值。如果有任何一个参数未被声明且不允许未声明的参数,则会抛出异常。get_parameters<prefix, values> const
:获取具有给定前缀的参数的值,并将其存储在一个映射中。如果没有找到具有该前缀的参数,则返回false
,否则返回true
。describe_parameter(name) const
:获取给定参数名称的参数描述符。如果参数未被声明且不允许未声明的参数,则会抛出异常。如果描述的参数数量多于一个,则会抛出std::runtime_error
异常。describe_parameters(names) const
:获取多个参数名称的参数描述符列表。如果有任何一个参数未被声明且不允许未声明的参数,则会抛出异常。如果描述的参数数量多于一个,则会抛出std::runtime_error
异常。get_parameter_types(names) const
:获取多个参数名称的参数类型列表。如果有任何一个参数未被声明且不允许未声明的参数,则会抛出异常。list_parameters(prefixes, depth) const
:返回具有给定前缀的参数列表,深度为给定的参数。这个方法的文档和测试还不完善。
4. 回调管理方法
add_on_set_parameters_callback(callback)
:添加一个回调函数,当参数被设置时会被调用。回调函数的签名是接收一个参数列表并返回一个SetParametersResult
,用于指示参数是否应该被设置以及设置失败的原因。remove_on_set_parameters_callback(handler)
:删除一个通过add_on_set_parameters_callback
注册的回调函数。如果处理程序不是通过add_on_set_parameters_callback
创建的,或者已经被删除,则会抛出std::runtime_error
异常。set_on_parameters_set_callback(callback)
:注册一个回调函数,当参数即将被改变时会被调用。这个方法已被弃用,应该使用add_on_set_parameters_callback
代替。
5. 其他方法
get_node_names() const
:获取所有可用节点的完全限定名称列表。get_topic_names_and_types() const
:返回一个映射,其中键是现有主题的名称,值是主题类型的列表。get_service_names_and_types() const
:返回一个映射,其中键是现有服务的名称,值是服务类型的列表。get_service_names_and_types_by_node(node_name, namespace_) const
:返回一个映射,其中键是现有服务的名称,值是服务类型的列表,仅考虑特定节点的服务。count_publishers(topic_name) const
:返回给定主题上的发布者数量。count_subscribers(topic_name) const
:返回给定主题上的订阅者数量。get_publishers_info_by_topic(topic_name, no_mangle) const
:返回给定主题上的发布者的端点信息列表。如果no_mangle
为true
,则topic_name
应该是中间件的有效主题名称;如果为false
,则topic_name
应该是有效的 ROS 主题名称。get_subscriptions_info_by_topic(topic_name, no_mangle) const
:返回给定主题上的订阅者的端点信息列表。如果no_mangle
为true
,则topic_name
应该是中间件的有效主题名称;如果为false
,则topic_name
应该是有效的 ROS 主题名称。get_graph_event()
:返回一个图形事件,当图形发生变化时会被设置。这个事件对象是一个借用,必须在使用后返回。wait_for_graph_change(event, timeout)
:等待图形事件发生,通过等待一个事件变为已设置状态。如果事件为nullptr
或者事件不是通过get_graph_event()
获取的,则会抛出异常。- **
get_clock()
**和get_clock() const
:分别获取节点管理的时钟的非 const 和 const 共享指针。 now() const
:返回当前时间,根据节点指定的时钟类型。get_node_base_interface()
、get_node_clock_interface()
、get_node_graph_interface()
、get_node_logging_interface()
、get_node_timers_interface()
、get_node_topics_interface()
、get_node_services_interface()
、get_node_waitables_interface()
、get_node_parameters_interface()
、get_node_time_source_interface()
:分别返回节点的内部接口实现,用于访问节点的不同功能,如基础接口、时钟接口、图形接口、日志接口、定时器接口、主题接口、服务接口、可等待接口、参数接口和时间源接口。get_sub_namespace() const
:返回子命名空间,如果这是一个子节点,则返回子命名空间的字符串;否则,返回一个空字符串。get_effective_namespace() const
:返回有效的命名空间,用于创建实体。这个命名空间是节点命名空间和累积的子命名空间的连接。create_sub_node(sub_namespace)
:创建一个子节点,该子节点将扩展所有使用它创建的实体的命名空间。子命名空间应该是相对的,如果是绝对的,则会抛出异常。get_node_options() const
:返回用于创建此节点的节点选项。
四、内部实现和保护成员
- 内部实现:类的实现部分在
node_impl.hpp
文件中,通过条件编译指令ifndef RCLCPP__NODE_IMPL_HPP_
来包含这个文件。 - 保护成员:
Node(const Node & other, const std::string & sub_namespace)
:用于构造子节点的保护构造函数。bool group_in_node(CallbackGroup::SharedPtr group)
:用于检查回调组是否在节点中。rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base_
、rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph_
、rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging_
、rclcpp::node_interfaces::NodeTimersInterface::SharedPtr node_timers_
、rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr node_topics_
、rclcpp::node_interfaces::NodeServicesInterface::SharedPtr node_services_
、rclcpp::node_interfaces::NodeClockInterface::SharedPtr node_clock_
、rclcpp::node_interfaces::NodeParametersInterface::SharedPtr node_parameters_
、rclcpp::node_interfaces::NodeTimeSourceInterface::SharedPtr node_time_source_
、rclcpp::node_interfaces::NodeWaitablesInterface::SharedPtr node_waitables_
:分别是节点的不同内部接口的共享指针,用于访问节点的各种功能。const rclcpp::NodeOptions node_options_
:用于存储创建节点时使用的节点选项。const std::string sub_namespace_
:存储子命名空间的字符串。const std::string effective_namespace_
:存储有效的命名空间,用于创建实体。
五、总结
rclcpp::Node
类是 ROS 2 中rclcpp
库的核心类之一,提供了丰富的功能来管理节点的参数、创建各种实体和处理回调函数。理解这个类的功能和用法对于开发 ROS 2 应用程序至关重要。通过使用Node
类,开发者可以方便地创建节点、发布消息、订阅消息、设置参数、处理回调等操作,从而实现复杂的机器人系统应用。