【问题标题】:Python global variables not available in functionPython 全局变量在函数中不可用
【发布时间】:2021-08-24 19:47:33
【问题描述】:

我正在使用以下代码读取传感器数据,对其进行处理并将一些反馈发布到不同的主题,/scans_freespace

#!/usr/bin/env python

import rospy
from rospy.core import is_shutdown
from sensor_msgs.msg import LaserScan
from sweep_bot.msg import Space
from sweep_bot.msg import SpaceArray

class FreeSpace :

    def __init__(self) :
        rospy.loginfo('starting')
        self.scans = ()
        self.regions = {}
        self.publisher = self.subscriber = ''
        
    def callbackScans(self, data) :
        self.scans = data.ranges
        self.regions = {
            'starboard_aft' : self.scans[0:135],
            'starboard_abeam_aft' : self.scans[136:271],
            'starboard_abeam_bow' : self.scans[272:407],
            'starboard_bow' : self.scans[408:543],
            'port_aft' : self.scans[949:1084],
            'port_abeam_aft' : self.scans[814:949],
            'port_abeam_bow' : self.scans[679:814],
            'port_bow' : self.scans[544:679],
        }

    def publish(self) :
        self.getSomeData('port_bow')

    def getSomeData(self, region) :
        rospy.loginfo("Checking region: %s", region)
        rospy.loginfo("Checking scans: %s", self.scans)

        return self.scans[region]
        
    
if __name__ == '__main__' :
    rospy.init_node('space_identifier')
    rate = rospy.Rate(10)
    spacer = FreeSpace()

    subscriber = rospy.Subscriber("scans", LaserScan, spacer.callbackScans)
    publisher  = rospy.Publisher("scans_freespace", SpaceArray, queue_size=10)

    while not rospy.is_shutdown() :
        spacer.publish()
        rate.sleep()

正如代码所示,我从 publish() 函数中调用 getSomeData() 函数并传递一个字符串参数。 getSomeData() 按预期接收参数callbackScan() 函数填充的全局变量为空。

脚本的输出如下:

[INFO] [1629830370.246796, 0.000000]: starting
[INFO] [1629830370.253719, 0.000000]: Checking region: port_bow
[INFO] [1629830370.256151, 0.000000]: Checking scans: ()
Traceback (most recent call last):
  File "/home/sisko/catkin_ws/src/sweepbot/Sweeper/sweep_bot/src/freespace.py", line 49, in <module>
    spacer.publish()
  File "/home/sisko/catkin_ws/src/sweepbot/Sweeper/sweep_bot/src/freespace.py", line 31, in publish
    self.getSomeData('port_bow')
  File "/home/sisko/catkin_ws/src/sweepbot/Sweeper/sweep_bot/src/freespace.py", line 37, in getSomeData
    return self.scans[region]
TypeError: tuple indices must be integers, not str

具有讽刺意味的是,在我尝试更新输出之前,代码确实有效。

我错过了什么?

【问题讨论】:

  • 什么全局变量? data.ranges 显然是一个元组(一个空的),你正试图用字符串port_bow 来索引它。是谁打电话给callbackScans 或以什么论据并不是很明显。

标签: python-2.7 ros publisher subscriber


【解决方案1】:

这里有一些问题。但是,您的错误是因为您没有正确初始化消息字段。当在接收到 LaserScan 消息之前调用 publish() 时,这反过来会导致问题。同样,rangesstd_msg/Float32[],因此即使在回调中正确分配了它,在尝试使用字符串索引浮点列表时也会出现另一个错误。你想做什么有点不清楚,但看看键名getSomeData() 应该看起来更像这样:

def getSomeData(self, region) :
    rospy.loginfo("Checking region: %s", region)
    rospy.loginfo("Checking scans: %s", self.scans)

    return self.regions[region] if region in self.regions else None

要说明的另一点是,如果您希望通过 publish() 函数发布此函数的结果,您需要在您的类中实际定义一个具有正确类型的发布者。

【讨论】:

  • 感谢 BTables。我真的很感谢你的回答。因为代码之前一直在工作,所以我没有想到 publish() 函数在订阅者之前触发。我在订阅者 i:e rospy.sleep(1) 和脚本按预期执行之后添加了延迟。
  • 我以前也被这样的东西咬过,如果你不知道要寻找什么,这可能并不明显。需要注意的是,依靠延迟不是解决此问题的正确方法,永远不能保证在那个时间内会收到数据。相反,在尝试使用/发布信息之前,您应该验证订阅者是否已收到某些内容;例如我是如何使用if region in self.regions
猜你喜欢
  • 1970-01-01
  • 2012-05-22
  • 2015-05-11
  • 1970-01-01
  • 2021-05-31
  • 2013-05-06
  • 1970-01-01
相关资源
最近更新 更多