ROS Python节点订阅回调赋值的类属性访问为空问题排查
问题原因
- 直接报错根因:索引对象错误
你在getSomeData方法中错误地使用字符串类型的区域名索引激光原始数据元组self.scans,该元组仅支持整数下标访问。你按区域拆分好的切片实际存储在self.regions字典中,把返回语句修改为return self.regions[region]即可解决类型报错。 - 回调数据未填充的两个常见原因:
- 节点启动后立即进入发布循环,此时
/scans话题的第一帧数据还未触发回调,self.scans还保留初始化时的空元组初始值。可以在发布逻辑前增加非空判断,确认已经收到激光数据后再执行后续处理:
def publish(self) : if not self.scans: return self.getSomeData('port_bow')- 订阅器对象被垃圾回收:你当前把
rospy.Subscriber的返回值赋值给了主函数的局部变量subscriber,没有绑定到FreeSpace类的实例属性上,Python的垃圾回收机制可能会销毁这个订阅器对象,导致回调永远不会被触发。建议把订阅器、发布器都绑定到实例属性:
# 主函数里的赋值修改为 spacer.subscriber = rospy.Subscriber("scans", LaserScan, spacer.callbackScans) spacer.publisher = rospy.Publisher("scans_freespace", SpaceArray, queue_size=10) - 节点启动后立即进入发布循环,此时
修复后的核心代码示例
def getSomeData(self, region) : rospy.loginfo("Checking region: %s", region) rospy.loginfo("Checking scans: %s", self.scans) # 改为从regions字典中取对应区域的切片 return self.regions.get(region, [])
内容的提问来源于stack exchange,提问作者sisko
相关产品推荐
相关产品推荐

