ROS python 从订阅者回调中设置全局变量
ROS python setting global variables from subscriber callbacks
我正在使用下面的代码尝试读取激光数据并确定机器人的哪一侧最靠近墙壁。
激光数据在 left 和 right 回调中成功打印,但我尝试将这两个值分配给全局变量并在第三个中使用这些变量功能。但是,变量不会在我的 运行() 函数中打印:
#!/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()
在上面的代码中,我只使用了subR_value,初始化它的值为test,重置它在 callbackRight 订阅者回调函数中,并在 运行() 函数中尝试读取新值。
但是,运行编译脚本时,我遇到了 2 个问题:
- 打印的值为 test,因此没有像预期的那样被覆盖
- 脚本不循环只输出一个对:测试输出
我找到了这个 post which is a similar problem and also this,但我似乎满足了必要的全局变量标签。
我是不是漏掉了什么?
在您的代码中 您只调用了一次 run
,它不会定期调用,因此也不会定期打印。
节点在您的 __main__
中初始化,进入 run()
例程一次,注册 /scan_right
的回调,打印 print(...)
语句并退出例程.返回主程序将由于 rospy.spin()
而停止退出。只要 ROS 每次收到关于 /scan_right
主题的新消息,就会调用 callbackRight
更新全局变量(但不打印它)。
如果您想在每次发生更新时打印变量,则必须在回调中调用 print(...)
。如果你想定期打印它(以固定速率但不是每次更新)你必须将 ros.spin()
修改为
rate = rospy.Rate(10) # Fixed update frequency of 10hz
while not rospy.is_shutdown():
# Call your print function here
rate.sleep()
我不会使用全局变量,而是将代码移动到 class 中。此外,不要将 print 与 ROS 一起使用,而是 use rospy.loginfo()
, rospy.logwarn()
and rospy.logerr()
. They have several advantages as already discussed at the bottom of .
我正在使用下面的代码尝试读取激光数据并确定机器人的哪一侧最靠近墙壁。 激光数据在 left 和 right 回调中成功打印,但我尝试将这两个值分配给全局变量并在第三个中使用这些变量功能。但是,变量不会在我的 运行() 函数中打印:
#!/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()
在上面的代码中,我只使用了subR_value,初始化它的值为test,重置它在 callbackRight 订阅者回调函数中,并在 运行() 函数中尝试读取新值。
但是,运行编译脚本时,我遇到了 2 个问题:
- 打印的值为 test,因此没有像预期的那样被覆盖
- 脚本不循环只输出一个对:测试输出
我找到了这个 post which is a similar problem and also this,但我似乎满足了必要的全局变量标签。
我是不是漏掉了什么?
在您的代码中 您只调用了一次 run
,它不会定期调用,因此也不会定期打印。
节点在您的 __main__
中初始化,进入 run()
例程一次,注册 /scan_right
的回调,打印 print(...)
语句并退出例程.返回主程序将由于 rospy.spin()
而停止退出。只要 ROS 每次收到关于 /scan_right
主题的新消息,就会调用 callbackRight
更新全局变量(但不打印它)。
如果您想在每次发生更新时打印变量,则必须在回调中调用 print(...)
。如果你想定期打印它(以固定速率但不是每次更新)你必须将 ros.spin()
修改为
rate = rospy.Rate(10) # Fixed update frequency of 10hz
while not rospy.is_shutdown():
# Call your print function here
rate.sleep()
我不会使用全局变量,而是将代码移动到 class 中。此外,不要将 print 与 ROS 一起使用,而是 use rospy.loginfo()
, rospy.logwarn()
and rospy.logerr()
. They have several advantages as already discussed at the bottom of