I have written a python script that subscribes to a ROS topic and then goes into a callback function that then calls the test function that returns a list of radii in ascending order by extracting the necessary data points in the topic. This is working correctly, however I would like to access this list of radii throughout the whole class(and outside of it).
I have made it a class variable "self.radii" but the console throws an error saying the instance has no attribute "radii" unless i tell it to sleep using rospy.sleep(2)
for 2 seconds and then it returns a value. It's the same story if I try to call self.radii within the main function.
I feel as through this is a Python threading issue rather than a ROS issue as the actual subscriber is working correctly there just seems to be a long delay I do not know how to remedy.
If I instead print(self.radii)
inside the callback function it works fine, with values appearing immediately, but I want to access this variable outside of this.
The code is below. Thanks!
#!/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()
Your problem is with how ROS subscribers work. Your class variable
self.radii
will only be created once the topic which you subscribe to/line_segments
gets its very first message. After that, you can call onself.radii
from any other function in the class. When your node starts, theinit
function is the very first thing that runs, so it creates the subscriber, and moves on to your print() statement. Between that time, the topic hasn't published a message yet. When you add thesleep()
it gave the subscriber time to receive its first message.What you can do, is initialize
self.radii
to something in the init function, just like you did withradii
:Then it will be populated with the correct information as you receive messages.
To check how long it will take to receive the first message on the topic
/line_segments
you can use the following command in terminal to see the rate at which it is being published: