ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

How to move two robots simultaneously using MultiProcessing in Python?

asked 2020-04-26 11:51:06 -0500

mkb_10062949 gravatar image

updated 2020-04-27 05:09:59 -0500

Hello I have created a launch file where I have grouped two ur5 with ns "robot1" and "robot2". I publish the joint angles in the topic "/robot1/arm_controller/command/" and "/robot2/arm_controller/command/" and both the robots move fine. Say I have made two functions which are responsible for moving publishing the joint angles in the respective topics. i.e.

script.py

class MoveRobot(object):
    def __init__(self):
          rospy.init_node('move_robot')
          pass
    def publish_angles(self):
          reset_robot = JointTrajectoryPoint()
          reset_joint_values = self.joints
          reset_robot.positions = reset_joint_values
          reset_robot.time_from_start = rospy.Duration(0.5)
          self.traj.points = [reset_robot]
          self.action_pub.publish(self.traj)  
          rospy.sleep(2)

class Robot1(MoveRobot):
    def __init__(self):
         super(Robot1, self).__init__()
         self.action_pub = rospy.Publisher("robot1/arm_controller/command", JointTrajectory, queue_size=1)
         self.joints = [1.5708,-1.5708,0, 3.14159, -1.5708,0]
class Robot2(MoveRobot):
    def __init__(self):
         super(Robot2, self).__init__()
         self.action_pub = rospy.Publisher("robot2/arm_controller/command", JointTrajectory, queue_size=1)
         self.joints = [1.5708,-1.5708,0, 3.14159, -1.5708,0]

multiProc.py

So here is where I spawn two processors to simultaneously publish joint values in the robots and move them

import multiprocessing as mp
from script import MoveRobot, Robot1, Robot2

class Workers(mp.Process):
    def __init__(self, agent):
        super(Workers, self).__init__()
        self.agent = agent
    def run(self):
        self.agent.publish_angles()

class make_vectorized_agents():
    def __init__(self, robots):
        workers = []
        for r in (robots):
            w = Workers(r)
            workers.append(r)
            w.daemon = True
            w.start()
        for w in workers:
            w.join()
r1 = Robot1()
r2 = Robot2()
m = make_vectorized_agents([r1, r2])

Unfortunately, when I do it I get error as,

Process Worker-2:
Traceback (most recent call last):
    rospy.sleep(0.01)
  File "/opt/ros/melodic/lib/python2.7/dist-packages/rospy/timer.py", line 165, in sleep
    raise rospy.exceptions.ROSInterruptException("ROS shutdown request")
ROSInterruptException: ROS shutdown request
Process Worker-1:
Traceback (most recent call last):
  File "/usr/lib/python2.7/multiprocessing/process.py", line 267, in _bootstrap
    self.run()
    raise rospy.exceptions.ROSInterruptException("ROS shutdown request")
ROSInterruptException: ROS shutdown request

It seems that rosnode is not able to work with multi processing because it gets shutdown when two process work simultaneously. Or is there something else I need to configure?

edit retag flag offensive close merge delete

Comments

I'm not an expert in the Multiprocessing library, but I imagine there is some interaction between initializing the node and spawning a new process. I would guess that if you want this to work you have to delay initializing the node until the new process is spawned, and then initialize in each new process.

But the whole approach seems cumbersome. If you want to do two things, why not have a simple node that controls one arm, without multiprocessing, and spawn two copies, one controlling each arm? You can use topic renaming to hook the two nodes up to the proper publishing topics.

A quick web search shows multiple questions on answers.ros.com related to using multiprocessing with ROS. It looks tricky to get right, so you may just be asking for trouble by trying to use it. (And do you really need it?) If you continue down ...(more)

Mark Rose gravatar image Mark Rose  ( 2020-05-02 02:14:45 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2021-08-09 09:19:19 -0500

Jaron gravatar image

If you're bound to Melodic, I would just write the two workers as separate nodes and then run them together and then they will be in their own processes. Are you trying to use some sort of IPC built into multiprocessing that is not shown here? Otherwise I don't see what your objective is in making them two process written in one node.

If you're not bound by Melodic and can use ROS2, you're looking for Executors which will allow you to write a custom way of work events being picked up.

edit flag offensive delete link more

Comments

@mkb_10062949 The rule is that you are not allowed to call rospy.init_node() more than once inside a process. Creating threads does not change this.

Mike Scheutzow gravatar image Mike Scheutzow  ( 2021-08-09 15:58:45 -0500 )edit

Question Tools

2 followers

Stats

Asked: 2020-04-26 11:51:06 -0500

Seen: 625 times

Last updated: Aug 09 '21