ROS回调函数失效:自定义话题/mobile_base/sensors/switch1无数据输出
ROS话题/mobile_base/sensors/switch1无数据输出问题排查
问题描述
创建ROS话题/mobile_base/sensors/switch1后,已配置发布者、订阅者及回调函数,但执行rostopic echo /mobile_base/sensors/switch1无法获取数据。执行rostopic list能看到该话题,rostopic info /mobile_base/sensors/switch1输出如下:
发布者:
- /mobile_base_nodelet_manager(http:192.168.66.20:41251)
订阅者:- /mobile_base_nodelet_manager(http:192.168.66.20:41251)
代码错误点分析
用户提供的代码片段:
ros::Publisher stop_switch_state_publisher; stop_switch_state_publisher = nh.advertise<robot_msgs::StopSwitch>("sensors/switch1",100); ros::Subscriber stop_switch_state_subscriber; stop_switch_state_subscriber = nh.subscribe("swnsors/switch1",10,&BaseRos::subScribeStopSwitchState,this); void subscribeStopSwitchState(const robot_msgs::StopSwitchPtr &msgs); void BaseRos::subscribStopSwitchState(const robot_msgs::StopSwitchPtr &msg){ ROS_INFO("subscribeStopSwitchState worked!"); if(ros::ok()){ ROS_INFO("getting into if..."); BaseState::Data = mobile_base.getBaseStateData(); msg.state = data.hard_stop; stop_switch_publisher.publishing(msg); } return; }
1. 订阅话题名称拼写错误
订阅的话题名写成了swnsors/switch1,正确应为sensors/switch1(少了一个'e'),导致订阅者监听错误话题,无法触发回调。
2. 回调函数名不一致
- 声明的函数名是
subscribeStopSwitchState - 类成员函数定义成了
subscribStopSwitchState(少一个'e') - 订阅者注册时用的是
&BaseRos::subScribeStopSwitchState(大写S)
三者名称不匹配,导致回调函数无法正确绑定,永远不会执行。
3. 语法与变量错误
BaseState::Data使用了中文全角冒号,应改为英文半角::- 赋值用
BaseState::Data,后续却用data.hard_stop,变量名大小写不一致 - 回调中使用的发布者变量是
stop_switch_publisher,但声明的是stop_switch_state_publisher,变量名不匹配
4. 消息发布方法错误
ROS发布消息的方法是publish(),而非publishing(),调用错误方法导致无法发布消息。
5. 消息指针使用问题
直接修改订阅到的StopSwitchPtr消息对象,可能因消息只读引发问题,建议创建新消息实例发布。
修正后的代码示例
ros::Publisher stop_switch_state_publisher; stop_switch_state_publisher = nh.advertise<robot_msgs::StopSwitch>("sensors/switch1", 100); ros::Subscriber stop_switch_state_subscriber; // 修正话题名与回调函数名 stop_switch_state_subscriber = nh.subscribe("sensors/switch1", 10, &BaseRos::subscribeStopSwitchState, this); // 保持声明与定义一致 void BaseRos::subscribeStopSwitchState(const robot_msgs::StopSwitchConstPtr &msg){ ROS_INFO("subscribeStopSwitchState worked!"); if(ros::ok()){ ROS_INFO("getting into if..."); // 修正语法与变量名 BaseState::Data data = mobile_base.getBaseStateData(); // 创建新消息实例 robot_msgs::StopSwitch publish_msg; publish_msg.state = data.hard_stop; // 使用正确的发布者与方法 stop_switch_state_publisher.publish(publish_msg); } }
额外排查建议
- 检查节点命名空间:确保节点运行在
/mobile_base命名空间下,保证话题完整名称正确 - 查看节点日志:用
rosout或rqt_console检查是否有编译错误、未定义变量等日志 - 验证消息类型:确认
robot_msgs::StopSwitch已正确编译,发布者与订阅者使用的消息类型完全一致 - 确认回调触发:在回调开头添加
ROS_INFO,运行节点后查看是否有输出,验证回调是否执行
内容的提问来源于stack exchange,提问作者SmileJay
相关产品推荐
相关产品推荐

