简体   繁体   中英

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:

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.

Run the command described by args. Wait for command to complete, then return the returncode attribute.

ROS itself will not call the callback again while it is executed already. 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

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. 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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM