I'm using the code below in an attempt to read laser data and determine which side of my robot is closest to a wall. The laser data is successfully being printed in the left and right callbacks but I try to assign both values to global variables and use those varibles in a third function. However, the varibales DO NOT print in my run() function:
#!/usr/bin/env python
import rospy
import math
from sensor_msgs.msg import LaserScan
from geometry_msgs.msg import Twist
from nav_msgs.msg import Odometry
from tf import transformations
from sensor_msgs.msg import LaserScan
subL_value = ''
subR_value = 'test'
def callbackLeft(msg) :
subL_value = min(msg.ranges[0:49])
def callbackRight(msg) :
global subR_value
subR_value = min(msg.ranges[0:49])
def run() :
# rospy.Subscriber('/scan_left', LaserScan, callbackLeft)
rospy.Subscriber('/scan_right', LaserScan, callbackRight)
# print('\tLeft: '),
# print(subL_value)
print('\tRight: '),
global subR_value
print(subR_value)
if __name__ == "__main__":
rospy.init_node('wall_detector')
run()
rospy.spin()
In the code above, I am only using the subR_value, Initiating it to a value of test, resetting it in the callbackRight subscriber callback function and attemoting to read the new value in the run() function.
However, running the script, I have 2 problems:
I found this post which is a similar problem and also this one but I seem to be satisfying the necessary global variable labelling.
Am I missing something ?
In your code you are only calling run
once, it is not called periodically and therefore also does not print periodically.
The node is initialised inside your __main__
, enters once into the run()
routine, registers the callback for /scan_right
, prints the print(...)
statements and exits the routine. Returned to the main the program will be stopped from exiting due to rospy.spin()
. As long as ROS is alive every single time a new message on the /scan_right
topic is received the callbackRight
will be called which updates the global variable (but does not print it).
If you wanted to print the variable every single time an update occurs you would have to call the print(...)
inside the callback. If you wanted to print it periodically (with a fixed rate but not on every update) you would have to modify ros.spin()
to something like
rate = rospy.Rate(10) # Fixed update frequency of 10hz
while not rospy.is_shutdown():
# Call your print function here
rate.sleep()
Instead of using global variables I would move the code inside a class. Furthermore do not use print with ROS but instead use rospy.loginfo()
, rospy.logwarn()
and rospy.logerr()
. They have several advantages as already discussed at the bottom of this post.