使用发布者和订阅者编写 ros 节点?
Writing a ros node with both a publisher and subscriber?
我目前正在尝试在 Python 中创建一个同时具有订阅者和发布者的 ROS 节点。
我见过在回调中发布消息的示例,但我希望它 "constantly" 发布消息,并在这种情况下执行回调。
这是我现在的做法:
#!/usr/bin/env python
import rospy
from std_msgs.msg import Empty
from std_msgs.msg import String
import numpy as np
pub = rospy.Publisher('/status', String, queue_size=1000)
def callback(data):
print "Message received"
def listener():
rospy.init_node('control', anonymous=True)
rospy.Subscriber('control_c', Empty, callback)
rospy.spin()
if __name__ == '__main__':
print "Running"
listener()
那我应该在哪里发布呢?
好吧,我认为这里有很多解决方案,您甚至可以使用 python 过程,但我建议的是使用 ros Timer 的 ROS 方法。
我在 python 方面并没有那么高效,但这段代码可能会让您有所了解。
#!/usr/bin/env python
import rospy
from std_msgs.msg import Empty
from std_msgs.msg import String
import numpy as np
last_data = ""
started = False
pub = rospy.Publisher('/status', String, queue_size=1000)
def callback(data):
print "New message received"
global started, last_data
last_data = data
if (not started):
started = True
def timer_callback(event):
global started, pub, last_data
if (started):
pub.publish(last_data)
print "Last message published"
def listener():
rospy.init_node('control', anonymous=True)
rospy.Subscriber('control_c', String, callback)
timer = rospy.Timer(rospy.Duration(0.5), timer_callback)
rospy.spin()
timer.shutdown()
if __name__ == '__main__':
print "Running"
listener()
在这里,您的回调将更新消息,您的计时器将每 0.5 秒启动一次并发布最后收到的数据。
您可以通过每 3 秒在“/contriol_c”上发布数据并将计时器配置为 0.5 秒来测试此代码。在 /status
上开始回显
$ rostopic echo /status
您将以 2 Hz 的频率发布消息。
希望对您有所帮助!
只需将 rospy.spin()
替换为以下循环:
while not rospy.is_shutdown():
# do whatever you want here
pub.publish(foo)
rospy.sleep(1) # sleep for one second
当然,您可以将睡眠持续时间调整为您想要的任何值(甚至完全删除它)。
根据 this reference rospy 中的订阅者 运行 在一个单独的线程中,因此您不需要主动调用自旋。
请注意,在 roscpp 中(即使用 C++ 时),处理方式不同。你必须在 while 循环中调用 ros::spinOnce()
。
我目前正在尝试在 Python 中创建一个同时具有订阅者和发布者的 ROS 节点。
我见过在回调中发布消息的示例,但我希望它 "constantly" 发布消息,并在这种情况下执行回调。
这是我现在的做法:
#!/usr/bin/env python
import rospy
from std_msgs.msg import Empty
from std_msgs.msg import String
import numpy as np
pub = rospy.Publisher('/status', String, queue_size=1000)
def callback(data):
print "Message received"
def listener():
rospy.init_node('control', anonymous=True)
rospy.Subscriber('control_c', Empty, callback)
rospy.spin()
if __name__ == '__main__':
print "Running"
listener()
那我应该在哪里发布呢?
好吧,我认为这里有很多解决方案,您甚至可以使用 python 过程,但我建议的是使用 ros Timer 的 ROS 方法。
我在 python 方面并没有那么高效,但这段代码可能会让您有所了解。
#!/usr/bin/env python
import rospy
from std_msgs.msg import Empty
from std_msgs.msg import String
import numpy as np
last_data = ""
started = False
pub = rospy.Publisher('/status', String, queue_size=1000)
def callback(data):
print "New message received"
global started, last_data
last_data = data
if (not started):
started = True
def timer_callback(event):
global started, pub, last_data
if (started):
pub.publish(last_data)
print "Last message published"
def listener():
rospy.init_node('control', anonymous=True)
rospy.Subscriber('control_c', String, callback)
timer = rospy.Timer(rospy.Duration(0.5), timer_callback)
rospy.spin()
timer.shutdown()
if __name__ == '__main__':
print "Running"
listener()
在这里,您的回调将更新消息,您的计时器将每 0.5 秒启动一次并发布最后收到的数据。
您可以通过每 3 秒在“/contriol_c”上发布数据并将计时器配置为 0.5 秒来测试此代码。在 /status
上开始回显$ rostopic echo /status
您将以 2 Hz 的频率发布消息。
希望对您有所帮助!
只需将 rospy.spin()
替换为以下循环:
while not rospy.is_shutdown():
# do whatever you want here
pub.publish(foo)
rospy.sleep(1) # sleep for one second
当然,您可以将睡眠持续时间调整为您想要的任何值(甚至完全删除它)。
根据 this reference rospy 中的订阅者 运行 在一个单独的线程中,因此您不需要主动调用自旋。
请注意,在 roscpp 中(即使用 C++ 时),处理方式不同。你必须在 while 循环中调用 ros::spinOnce()
。