[英]How to keep ROS publisher publishing while executing a subprocess callback?
How can I keep the ROS Publisher publishing the messages while calling a sub-process:如何让 ROS Publisher 在调用子流程时发布消息:
import subprocess
import rospy
class Pub():
def __init__(self):
pass
def updateState(self, msg):
cmd = ['python3', planner_path, "--alias", search_options, "--plan-file", plan_path, domain_path, problem_path]
subprocess.run(cmd, shell=False, stdout=subprocess.PIPE)
self.plan_pub.publish(msg)
def myPub(self):
rospy.init_node('problem_formulator', anonymous=True)
self.plan_pub = rospy.Publisher("plan", String, queue_size=10)
rate = rospy.Rate(10) # 10hz
rospy.Subscriber('model', String, updateState)
rospy.sleep(1)
rospy.spin()
if __name__ == "__main__":
p_ = Pub()
p_.myPub()
Since subprocess.call
is a blocking call your subscription callback may take a long time.由于subprocess.call
是阻塞调用,您的订阅回调可能需要很长时间。
Run the command described by args.运行 args 描述的命令。 Wait for command to complete, then return the returncode attribute.等待命令完成,然后返回 returncode 属性。
ROS itself will not call the callback again while it is executed already. ROS 本身不会在已经执行的情况下再次调用回调。 This means you are blocking this and potentially also other callbacks to be called in time.这意味着您正在阻止此回调,并且可能还会及时调用其他回调。
The most simple solution would be to replace subprocess.call
by subprocess.Popen
which最简单的解决方案是用subprocess.Popen
替换subprocess.call
Execute a child program in a new process在新进程中执行子程序
nonblocking.非阻塞。
But keep in mind that this potentially starts the process multiple times quite fast.但请记住,这可能会非常快地多次启动该过程。
Think about starting the process only conditionally if not already running.如果尚未运行,请考虑仅有条件地启动该过程。 This can be achieved by checking the process to be finished in another thread.这可以通过检查要在另一个线程中完成的过程来实现。 Simple but effective, use boolean flag.简单但有效,使用 boolean 标志。 Here is a small prototype:这是一个小原型:
def updateState(self, msg):
#Start the process if not already running
if not self._process_running:
p = subprocess.Popen(...)
self._process_running = True
def wait_process():
while p.poll() is None:
time.sleep(0.1)
self._process_running = False
threading.Thread(target=wait_process).start()
#Other callback code
self.plan_pub.publish(msg)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.