最简稳定 ROS2 C++ Publisher 需在 Node 派生类构造函数中调用 create_publisher,显式指定消息类型与 QoS(如 rclcpp::QoS(10).reliable()),发布前建议检查订阅数,并确保 topic 名、QoS 与 subscriber 严格一致。

ROS2 C++ 节点里怎么写一个最简 publisher
直接用 rclcpp::Node::create_publisher 创建,但关键不是“能发”,而是发得稳、不崩溃。常见错误是节点生命周期管理没对齐——比如在构造函数里创建 publisher,但 rclcpp::spin 还没开始,或者节点对象提前析构了。
- 必须在
rclcpp::Node派生类的构造函数里调用create_publisher,不能拖到某个回调里才建 - 消息类型必须显式指定模板参数,比如
create_publisher<:msg::string>,漏掉<:msg::string>会编译失败 - QoS 配置别直接用默认值:局域网内发 sensor 数据建议用
rclcpp::QoS(10).reliable(),发诊断日志可用best_effort()节省带宽 - 发布前务必检查
publisher_->get_subscription_count() > 0(可选但推荐),避免无人订阅时盲目发数据占 CPU
auto publisher_ = this->create_publisher<:msg::string>("topic_name", 10);
auto msg = std::make_unique<:msg::string>();
msg->data = "hello";
publisher_->publish(std::move(msg));
</:msg::string></:msg::string>
subscriber 收不到消息?先查这三件事
90% 的收不到问题和 topic 名称、QoS、线程模型有关,不是代码逻辑错。ROS2 默认用 intra-process 优化,但跨节点通信时如果 QoS 不匹配,会静默丢弃消息,连 warning 都不打。
- 确认 subscriber 和 publisher 的 QoS profile 完全一致:比如 publisher 用
reliable(),subscriber 也得用reliable();best_effort()对best_effort(),混用必收不到 - topic 名称要严格一致,包括前导斜杠——ROS2 默认不自动补前缀,
"chatter"和"/chatter"是两个 topic - callback 函数必须是
void(const std_msgs::msg::String::SharedPtr)形式,传值或传引用都会编译失败;用SharedPtr是为了零拷贝共享所有权
auto subscription_ = this->create_subscription<:msg::string>(
"topic_name", 10,
[this](const std_msgs::msg::String::SharedPtr msg) {
RCLCPP_INFO(this->get_logger(), "I heard: '%s'", msg->data.c_str());
});
</:msg::string>
main() 里 spin 怎么写才不卡死也不漏消息
别手写 while 循环 + rclcpp::spin_some(),那是 ROS1 习惯。ROS2 推荐用 rclcpp::spin() 配合多线程或定时器,否则 callback 可能永远不触发。
- 单线程场景直接
rclcpp::spin(node),它会阻塞并处理所有注册的 callback,适合简单节点 - 需要同时做非 ROS 工作(比如读串口、跑算法)时,用
rclcpp::executors::MultiThreadedExecutor,但注意:多个 callback 可能并发执行,共享变量要加锁 - 绝对不要在 callback 里调用
sleep或阻塞 IO,会拖慢整个 executor;该用 timer 就用this->create_wall_timer()
编译报错找不到 std_msgs::msg::String 或链接失败
不是头文件没 include,是 CMakeLists.txt 没配对。ROS2 的 message 依赖必须显式声明,且顺序敏感。
- 在
find_package里加上std_msgs和你用到的所有接口包,比如sensor_msgs -
ament_target_dependencies必须包含对应包名,漏一个就会提示 “no member named ‘data’” 这类误导性错误 - 如果用了自定义 msg,确保
add_message_files和generate_messages正确配置,且package.xml里有rosidl_default_generators
最容易被忽略的是:CMakeLists.txt 里 add_executable 后必须跟 ament_target_dependencies,只写 target_link_libraries 不够。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











