1

我编写了一个订阅 ROS 主题的 python 脚本,然后进入一个回调函数,然后调用测试函数,该函数通过提取主题中的必要数据点以升序返回半径列表。这工作正常,但是我想在整个班级(以及班级之外)访问这个半径列表。

我已将其设为类变量“self.radii”,但控制台会抛出一个错误,指出实例没有属性“radii”,除非我告诉它使用rospy.sleep(2)2 秒睡眠,然后它返回一个值。如果我尝试在 main 函数中调用 self.radii,情况也是如此。

我觉得这是一个 Python 线程问题而不是 ROS 问题,因为实际订阅者工作正常,似乎有很长的延迟,我不知道如何补救。

如果我改为print(self.radii)在回调函数中工作正常,值会立即出现,但我想在此之外访问此变量。

代码如下。谢谢!

#!/usr/bin/env python
import rospy
import numpy as np
from laser_line_extraction.msg import LineSegmentList

class z_laser_filter():
    def __init__(self):
        self.sub_ = rospy.Subscriber("/line_segments",
                                     LineSegmentList,
                                     self.callback)
        rospy.sleep(2)
        print(self.radii)

    def callback(self, line_segments):
        self.radii = self.test(line_segments)
        print(self.radii)

    def test(self, line_segments):  
        number_of_lines = ((len(line_segments.line_segments)) - 1)
        i = 0
        radii = list()
        while (i!=number_of_lines):
            radii.append(line_segments.line_segments[i].radius)
            radii = sorted(radii, key=float)
            i = i + 1
        return radii

if __name__ == '__main__':
    rospy.init_node('line_extraction_filter', anonymous=True)
    node = z_laser_filter()
    rospy.spin()
4

1 回答 1

0

您的问题在于 ROS 订阅者的工作方式。self.radii只有在您订阅的主题/line_segments收到第一条消息后,才会创建您的类变量。之后,您可以self.radii从类中的任何其他函数调用。当您的节点启动时,该init函数是最先运行的,因此它会创建订阅者,然后继续执行您的 print() 语句。在此期间,该主题尚未发布消息。当你添加它时,sleep()它给了订阅者时间来接收它的第一条消息。

您可以做的是初始化self.radiiinit 函数中的某些内容,就像您对以下内容所做的那样radii

 def __init__(self):

    self.sub_ = rospy.Subscriber("/line_segments", LineSegmentList, self.callback)
    self.radii = list()
    print(self.radii)

然后,当您收到消息时,它将填充正确的信息。

要检查接收关于该主题的第一条消息需要多长时间,/line_segments您可以在终端中使用以下命令来查看它的发布速率:

rostopic hz /line_segments
于 2018-09-20T23:09:48.367 回答