ROS How to pass a callback variable into another file?

Viewed 22

I have a callback function in a file "color.py" that constantly recieves incoming data but updates a global variable every 3 seconds:

last_color = ""
last_calltime = datetime.strptime("00:00:00","%H:%M:%S")

def callback(data):
   global last_calltime, last_color
   cube = data.data
   t = time.localtime()
   tf = time.strftime("%H:%M:%S",t)
   current_time = datetime.strptime(tf, "%H:%M:%S")
   delta_time = current_time - last_calltime

if abs(delta_time.total_seconds()) >= 3:
    if "Red" in cube:
        last_color = "Red"
    elif "Green" in cube:
        last_color = "Green"
    else:
        last_color = "Blue"

    t = time.localtime()
    tf = time.strftime("%H:%M:%S",t)
    last_calltime = datetime.strptime(tf, "%H:%M:%S")

    return last_color



if __name__ == '__main__':

try:
    rospy.init_node('color')
    rospy.Subscriber ('/topic',String, callback)
    rospy.spin()

In another file, I need to reference this "last_color" variable that updates. So far the function I have in this file:

from color import last_color
    
    a = 0

    def observe_color(a)
       if a == 0:
         return last_color 
       else: 
         return "None"

I need this to return the updated variable from the "color.py" file but it only returns the initialized value for last_color which is "". How can I do this?

3 Answers

I don't think it's gonna work that way. How about save the value of last_color to a file and monitor it ? Because to me you run 2 separated programs, 1 with the ROS and another just to monitor last_color

while True:
    with open(filename, 'r') as f:
        color = f.readline()
    time.sleep(timesteps)

When write to file in the main, you could also append the read value and also the time, to get timeline data.

When you import something in Python, you're effectively asking it to execute everything in that module in the same runtime as your current program.

Suppose I have some module color.py with variable last_color='green'

And in a different program observer.py I have from color import last_color

The last_color that exists in color.py and the last_color that exists in observer.py are different places in computer memory - they do not reference the same string value.

A quick (and maybe dirty) solution to this is just to re-import the module every time you want to observe one of its member variables.

Since this is all done in ROS it would be easiest to simply have the separate file initialize as a ros node with a subscriber. If for some reason that's not the case you should make color.py a class and have the other file initialize an object. Take the following simplified example:

color.py

class colorPy:
    def __init__(self):
        self.last_color = None
        rospy.init_node('some_node')
        tmp = rospy.Subscriber('/some_topic', self.callback)
    def callback(self, msg):
        self.last_color = msg.data

other file

from color import colorPy
from time import sleep
local_var = colorPy()
sleep(5)
print(local_var.last_color)
Related