Skip to content

rclcpp::Node 类 API 速查 ​

rclcpp::Node 是写 ROS 2 节点代码的核心类:通信实体(publisher/subscription/service/client/timer)、参数、图查询、回调组全部从它创建。本文按功能域整理其公开 API,每个接口附签名与注意事项,作为写节点代码时的速查表。基于 rclcpp 当前主线接口,未逐一区分发行版差异。

1) 构造 / 析构 / 基本信息 ​

构造函数 ​

cpp
Node(const std::string& node_name, const NodeOptions& options = NodeOptions());
Node(const std::string& node_name, const std::string& namespace_, const NodeOptions& options = NodeOptions());
virtual ~Node();

说明:构造器接受节点名、可选命名空间和 NodeOptions(例如参数覆盖、自动初始化上下文等)。构造期间会配置内部 node interface 实例,可能抛出名称/命名空间校验异常(例如 InvalidNamespaceError、NameValidationError)。

基本信息获取 ​

cpp
const char* get_name() const;
const char* get_namespace() const;
const char* get_fully_qualified_name() const;

说明:返回节点名 / 命名空间 / 完整限定名(const char* 指向内部存储,注意生命周期)。

cpp
const std::string& get_sub_namespace() const;
const std::string& get_effective_namespace() const;

说明:

  • get_sub_namespace():如果是 sub-node 则返回累积的子命名空间
  • get_effective_namespace():实体创建时实际使用的 namespace(node namespace + sub-namespace),以 "/" 前缀形式返回
cpp
const rclcpp::NodeOptions& get_node_options() const;

说明:返回创建时传入的 NodeOptions。

2) Logging / Clock / Time ​

cpp
rclcpp::Logger get_logger() const;

返回与 node 关联的 logger(用于日志记录)。

cpp
rclcpp::Clock::SharedPtr get_clock();
rclcpp::Clock::ConstSharedPtr get_clock() const;
Time now() const;

获取 node 管理的时钟(可用于仿真/系统时钟);now() 返回基于 node 时钟的当前时间。

3) Callback Group 管理 ​

cpp
rclcpp::CallbackGroup::SharedPtr create_callback_group(
    rclcpp::CallbackGroupType group_type, 
    bool automatically_add_to_executor_with_node = true
);

说明:创建 callback group,用于把回调分组以便 executor 管理或隔离;参数决定是否自动将 group 注册到 executor。

cpp
void for_each_callback_group(
    const node_interfaces::NodeBaseInterface::CallbackGroupFunction& func
);

说明:以线程安全方式遍历 node 中的 callback groups,对每个仍有效的 group 调用给定函数。

注意:callback group 与 executor 的交互决定了回调调度行为(并发/串行等)。

4) 发布 / 订阅 / 泛型接口(模板) ​

发布器创建 ​

cpp
template<typename MessageT, typename AllocatorT, typename PublisherT>
typename rclcpp::Publisher<MessageT, AllocatorT>::SharedPtr create_publisher(
    const std::string& topic_name, 
    const rclcpp::QoS& qos,
    const PublisherOptionsWithAllocator<AllocatorT>& options = ...
);

说明:创建并返回 rclcpp::Publisher 的 shared_ptr。支持 QoS 快捷构造(如直接传 size_t)。第三个参数可定制 publisher 选项(event callbacks、callback_group 等)。

关键注意:

  • 主题名相对/绝对均可,内部会扩展(相对名用 effective namespace)
  • 可能抛出异常(例如底层 rcl/rmw 失败时)

订阅器创建 ​

cpp
template<typename MessageT, typename CallbackT, typename AllocatorT, typename SubscriptionT>
typename rclcpp::Subscription<MessageT, AllocatorT>::SharedPtr create_subscription(
    const std::string& topic_name,
    const rclcpp::QoS& qos,
    CallbackT&& callback,
    const SubscriptionOptionsWithAllocator<AllocatorT>& options = ...,
    typename rclcpp::message_memory_strategy::MessageMemoryStrategy<MessageT, AllocatorT>::SharedPtr message_memory_strategy = ...
);

说明:创建并返回 Subscription。允许传入消息内存策略(message memory strategy)和订阅选项(event callbacks、ignore_local_publications、callback_group 等)。

泛型接口 ​

cpp
template<typename... Args>
typename rclcpp::GenericPublisher::SharedPtr create_generic_publisher(...);

template<typename... Args>
typename rclcpp::GenericSubscription::SharedPtr create_generic_subscription(...);

说明:用于运行时按字符串类型名创建泛型(序列化)发布/订阅,适用于不在编译期拥有消息类型的场景。

注意:泛型接口在缺少消息包(AMENT 前缀路径)或类型解析失败时会抛出异常;并非所有选项都被支持(以官方头文件注释列出的字段为准)。

5) 服务与客户端 ​

客户端创建 ​

cpp
template<typename ServiceT>
typename rclcpp::Client<ServiceT>::SharedPtr create_client(
    const std::string& service_name,
    const rmw_qos_profile_t& qos_profile = ...,
    rclcpp::CallbackGroup::SharedPtr group = nullptr
);

说明:创建一个 client 对象用于调用服务,默认 QoS 为服务默认。

服务端创建 ​

cpp
template<typename ServiceT, typename CallbackT>
typename rclcpp::Service<ServiceT>::SharedPtr create_service(
    const std::string& service_name,
    CallbackT&& callback,
    const rmw_qos_profile_t& qos_profile = ...,
    rclcpp::CallbackGroup::SharedPtr group = nullptr
);

说明:创建服务端并注册回调。service 名称与 remapping 语义同 topic;底层错误同样可能抛出。

6) Timers ​

cpp
template<typename DurationRepT, typename DurationT, typename CallbackT>
typename rclcpp::WallTimer<CallbackT>::SharedPtr create_wall_timer(
    std::chrono::duration<DurationRepT, DurationT> period,
    CallbackT callback,
    rclcpp::CallbackGroup::SharedPtr group = nullptr
);

说明:创建 wall-time 定时器,定期调用 callback,返回值可用于取消/管理定时器。

注意:计时器调度受 executor 与 callback_group 的影响;使用 node 管理的 rclcpp::Clock 可切换仿真时间等。

7) 参数(声明 / 获取 / 设置 / 回调) ​

参数声明 ​

cpp
// 多重重载版本
declare_parameter(const std::string& name, const rclcpp::ParameterValue& default_value, 
                 const ParameterDescriptor& descriptor = ..., bool ignore_override = false)
declare_parameter(const std::string& name, rclcpp::ParameterType type, 
                 const ParameterDescriptor& descriptor = ..., bool ignore_override = false)
// 模板版本(返回具体类型)
template<typename T>
T declare_parameter(const std::string& name, const T& default_value, 
                   const ParameterDescriptor& descriptor = ..., bool ignore_override = false)
// 批量声明
void declare_parameters(const std::string& namespace_, 
                       const std::map<std::string, rclcpp::ParameterValue>& parameters, 
                       bool ignore_overrides = false)

说明:声明参数并返回其有效值;如果运行时有参数覆盖,则覆盖被应用(除非 ignore_override=true)。声明会触发已注册的 on_set_parameters 回调;回调可拒绝初始值(抛出 InvalidParameterValueException)。

参数取消声明 ​

cpp
void undeclare_parameter(const std::string& name);

说明:取消声明参数(不会触发 on_set callback)。

参数检查与操作 ​

cpp
bool has_parameter(const std::string& name) const;

// 参数设置
std::vector<rcl_interfaces::msg::SetParametersResult> 
set_parameters(const std::vector<rclcpp::Parameter>& parameters);

rcl_interfaces::msg::SetParametersResult 
set_parameters_atomically(const std::vector<rclcpp::Parameter>& parameters);

// 参数获取
template<typename T>
bool get_parameter(const std::string& name, T& parameter) const;

template<typename T>
T get_parameter(const std::string& name) const;

template<typename T>
T get_parameter_or(const std::string& name, const T& alternative_value) const;

说明:设置参数(逐个或全部原子设置),会触发 on_set 回调;回调拒绝会反映在返回的 SetParametersResult 中。set_parameters_atomically 要么全部成功,要么全部失败。

参数查询与描述 ​

cpp
rcl_interfaces::msg::ParameterDescriptor describe_parameter(const std::string& name) const;
std::vector<rcl_interfaces::msg::ParameterDescriptor> describe_parameters(const std::vector<std::string>& names) const;

std::vector<rclcpp::ParameterType> get_parameter_types(const std::vector<std::string>& names) const;

rcl_interfaces::msg::ListParametersResult list_parameters(
    const std::vector<std::string>& prefixes, uint64_t depth) const;

说明:用于参数描述、类型查询与按前缀列举参数。

参数回调管理 ​

cpp
OnSetParametersCallbackHandle::SharedPtr 
add_on_set_parameters_callback(OnParametersSetCallbackType callback);

void remove_on_set_parameters_callback(const OnSetParametersCallbackHandle* handler);

说明:注册/移除参数被设置时调用的回调,签名返回 rcl_interfaces::msg::SetParametersResult。回调顺序:某个回调返回失败后,后续回调不会被调用;多个回调的执行顺序是注册顺序的逆序(最近注册的先被调用)。回调内不允许修改参数(否则抛 ParameterModifiedInCallbackException)。

重要注意:

  • declare/set 时都会触发回调,回调可以拒绝修改
  • 当参数未声明且 NodeOptions.allow_undeclared_parameters=false 时,部分接口会抛 ParameterNotDeclaredException

8) 图(Graph)与拓扑查询 ​

节点查询 ​

cpp
std::vector<std::string> get_node_names() const;

返回当前可见节点的 fully-qualified 名称列表。

主题查询 ​

cpp
std::map<std::string, std::vector<std::string>> get_topic_names_and_types() const;

返回 topic 名称到类型列表的映射(快照)。

服务查询 ​

cpp
std::map<std::string, std::vector<std::string>> get_service_names_and_types() const;

返回 service 名称到类型列表的映射(快照),属于全局查询(所有节点的服务)。

cpp
std::map<std::string, std::vector<std::string>> 
get_service_names_and_types_by_node(const std::string& node_name, const std::string& namespace_) const;

只列出某个节点创建的服务(不含 clients)。返回的名称是实际使用的名字、不应用 remap 规则。

计数统计 ​

cpp
size_t count_publishers(const std::string& topic_name) const;
size_t count_subscribers(const std::string& topic_name) const;

返回给定 topic 实际已创建的 publishers/subscribers 数量(以实际 topic 名为准,不自动 remap),可能抛出 runtime_error。

端点信息查询 ​

cpp
std::vector<rclcpp::TopicEndpointInfo> 
get_publishers_info_by_topic(const std::string& topic_name, bool no_mangle = false) const;

std::vector<rclcpp::TopicEndpointInfo> 
get_subscriptions_info_by_topic(const std::string& topic_name, bool no_mangle = false) const;

返回 topic 端点信息数组,每条包含 node 名、namespace、topic type、endpoint 类型、GID、QoS 等。no_mangle 控制传入名是中间件有效名(true)还是 ROS 名(false);查询不会 remap,relative/private 名按 node 的 effective namespace 扩展。

图变化监听 ​

cpp
rclcpp::Event::SharedPtr get_graph_event();
void wait_for_graph_change(rclcpp::Event::SharedPtr event, std::chrono::nanoseconds timeout);

说明:获取一个 graph change 事件对象(借用性质,不用时让其超出作用域以归还),再用 wait_for_graph_change 在超时时间内等待触发。传入的事件对象不是通过 get_graph_event() 获取时会抛 InvalidEventError 或 EventNotRegisteredError。

注意:

  • 查询接口可能抛出 std::runtime_error(底层 rcl 错误)或 InvalidTopicNameError、NameValidationError 等
  • get_*_by_node 系列返回不应用 remap 的「实际」名称,适合判断某个节点本身有哪些主题/服务;在包含 remap 的运行环境中要注意与 ROS 名称空间的差异

9) NodeInterfaces 访问(内部接口句柄) ​

cpp
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()

说明:返回对应的 NodeXXXInterface::SharedPtr,允许外部代码直接调用更底层的接口(由 node 实现类包装真实 rcl/rmw 行为),对扩展或测试(mocking、自定义功能)非常有用。

10) Sub-node(从属节点)相关 ​

cpp
rclcpp::Node::SharedPtr create_sub_node(const std::string& sub_namespace);

protected:
Node(const Node& other, const std::string& sub_namespace);

说明:创建 sub-node(继承原 node 的上下文但扩展 sub-namespace),所有用相对名创建的实体都基于 effective namespace 扩展。sub_namespace 必须是相对名(不能以 '/' 开头),否则抛 NameValidationError。

常见使用示例 ​

创建 publisher / subscription ​

cpp
auto pub = node->create_publisher<std_msgs::msg::String>("chatter", 10);
auto sub = node->create_subscription<std_msgs::msg::String>(
    "chatter", 10,
    [&node](std_msgs::msg::String::SharedPtr msg) {
        RCLCPP_INFO(node->get_logger(), "got: %s", msg->data.c_str());
    }
);

声明参数并读取 ​

cpp
node->declare_parameter("speed", 1.0);
double speed = node->get_parameter("speed").as_double();
node->set_parameter(rclcpp::Parameter("speed", 2.0));

列出服务类型 ​

cpp
auto services = node->get_service_names_and_types();
for (auto& [name, types] : services) {
    for (auto& t : types) {
        RCLCPP_INFO(node->get_logger(), "service %s : %s", name.c_str(), t.c_str());
    }
}

等待图变化 ​

cpp
auto evt = node->get_graph_event();
// 等待最多 1s
node->wait_for_graph_change(evt, std::chrono::seconds(1));

重要边界与陷阱 ​

  1. 名称/主题 remap:get_*_by_node 系列不应用 remap;get_publishers_info_by_topic 传入相对名会用 effective namespace 扩展但并不 remap——写监控/诊断代码时先确认想查的是 ROS 名还是实际名
  2. 指针/引用生命周期:不要缓存 get_name() 返回的 const char* 超过 node 生命周期
  3. 参数回调副作用限制:on_set_parameters 回调里禁止修改参数或注册/移除回调(会抛异常);多个回调按注册逆序执行
  4. 线程安全:部分访问(如 for_each_callback_group)标注线程安全;对 node 内部状态的复杂并发操作应谨慎,优先使用官方线程安全接口与 callback_group/executor 模型
  5. 异常语义:很多查询/创建操作会在底层 rcl/rmw 失败时抛 std::runtime_error 或更专门的异常;客户端代码应准备捕获或让异常冒泡到合适位置
  6. 泛型 API:create_generic_* 在运行时解析类型,消息包不在 AMENT 前缀路径或解析失败会抛异常;适合运行时插件或类型无编译期依赖的场景
最近更新

基于 VitePress 构建