ros c++发布者需先初始化节点并创建ros::publisher对象,关键注意话题名须带前缀斜杠(如"/chatter")、消息类型严格匹配、queue_size设为1–100;必须在while(ros::ok())循环中调用publish()和ros::spinonce(),且正确配置cmakelists.txt的target_link_libraries。

ROS C++ 发布者怎么写,ros::Publisher 初始化要注意什么
发布者核心是创建 ros::Publisher 对象并调用 publish()。关键不在“能发”,而在初始化时是否正确关联了话题名、消息类型和队列长度。
常见错误:话题名漏写斜杠(如写成 "chatter" 而非 "/chatter"),导致发布到匿名命名空间,订阅者收不到;或队列长度设为 0,造成消息直接丢弃(queue_size=0 在 ROS 1 中是非法值,会静默失败)。
-
nh.advertise<:string>("/chatter", 10)</:string>—— 第二个参数是输出队列大小,建议设为 1–100 之间,太大会吃内存,太小(如 1)在高频率下易丢帧 - 必须在
ros::spin()或循环中调用pub.publish(msg),不能只初始化就退出 - 如果节点需要动态重映射话题名,优先用
nh.resolveName("chatter")替代硬编码路径
ROS C++ 订阅者回调函数为什么没触发,ros::Subscriber 常见失效原因
订阅者不进回调,90% 和节点生命周期或通信状态有关,不是代码逻辑错。
典型现象:编译运行无报错,但 ROS_INFO 一句都不打印;rostopic list 看得到话题,rostopic echo /chatter 却空——说明发布端可能根本没连上,或发布频率低于订阅端的连接建立速度。
- 确保
ros::Subscriber sub = nh.subscribe("/chatter", 10, chatterCallback)的话题名、消息类型、回调签名完全匹配发布者(例如发布std_msgs::String,就不能用std_msgs::Int32的回调) - 回调函数必须是
void chatterCallback(const std_msgs::String::ConstPtr& msg)这种带ConstPtr&引用的形式,传值或裸指针会编译失败 - 不要在回调里调用阻塞操作(如
sleep、文件 IO),否则会卡住整个ros::spin()循环
如何让发布者和订阅者跑在同一节点里,ros::spinOnce() 怎么用才安全
单节点内同时发布+订阅很常见(比如传感器数据处理后立刻发控制指令),但不能混用 ros::spin() 和手动循环——前者会阻塞,后者需主动驱动回调。
如果用了 ros::spin(),节点就只能做订阅;想边发布边处理,必须改用 ros::spinOnce() 配合 while 循环,并加 ros::Rate 控制频率,否则 CPU 占满且时间不可控。
- 发布频率由
ros::Rate loop_rate(10)控制(单位 Hz),每次循环末尾调用loop_rate.sleep() - 每个循环内必须调用一次
ros::spinOnce(),否则订阅回调永远不会执行 - 注意
ros::ok()检查,避免在 roscore 关闭后继续循环(while (ros::ok()) { ... })
编译报错 undefined reference to ros::NodeHandle::NodeHandle 怎么快速定位
这是链接阶段失败,说明 CMakeLists.txt 没正确导出依赖,和头文件包含无关。
最常被忽略的是:只加了 find_package(catkin REQUIRED COMPONENTS roscpp std_msgs),却漏了 catkin_package() 或 target_link_libraries() 配置。
- 确认
add_executable()后紧跟target_link_libraries(your_node ${catkin_LIBRARIES}),缺了这句必然报这个错 -
catkin_package()中的DEPENDS不影响链接,只影响下游包;真正决定链接库的是target_link_libraries - 如果用了自定义消息,还必须把生成的消息库(如
your_pkg_generate_messages_cpp)加进target_link_libraries
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











