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

How can I have roslaunch manage the lifecycle of spawned nodes?

asked 2017-05-04 13:45:41 -0600

BJP gravatar image

When I run roslaunch without an existing core, it starts up a core and starts the requested node(s) as separate processes. When I hit ctrl-c, roslaunch seems smart enough to know that it needs to kill the core it started as well as all the node processes it spawned. Great.

I have a set of USB cameras in a pseudo database and some subset of those cameras are connected to the computer in some unknown configuration (which is /dev/video0, etc). I wrote a node to spawn a bunch of usb_cam nodes to serve all USB cameras connected to the computer according to database information about all cameras and the runtime-polled information about what is actually connected. This also is pretty good*.

The issue is that when I ctrl-c the roslaunch that starts my spawner node, the spawned usb_cam node processes don't die because roslaunch wasn't the one that started them. One way I could solve this is to keep my spawner node running until killed, and then kill all spawned nodes in its shutdown process. But, there's no other good reason to keep the spawner node process running all that time and I'd rather let it complete after it has spawned all its child nodes. What I'd really like to do is "attach" the spawned nodes to roslaunch (let roslaunch know that those are nodes it should control the lifecycle of). Is there an existing mechanism to do this? If not, is there a reason why not apart from "nobody has added that feature yet"? Like, for instance, am I misinterpreting some part of the ROS philosophy by doing things this way?

*The way I did this from C++ was to capture the output from a 'which rosrun' popen operation, and then fork and exec that rosrun executable with appropriate arguments to spawn the desired node. This seems unfortunately complex/ugly and it would be much nicer if spawning new nodes according to package and executable name were part of the ROS API.

edit retag flag offensive close merge delete

Comments

Can you just ctl-c the core?

The spinner you use will have functionality to monitor the state of the roscore as documented here. Placing your usb_cam node code within a

while (ros::ok())
{
}

loop should work or if you

BrettHemes gravatar image BrettHemes  ( 2017-05-04 15:30:56 -0600 )edit

go the asynchronous route a call to

ros::waitForShutdown();

will wait till the core goes away.

BrettHemes gravatar image BrettHemes  ( 2017-05-04 15:31:24 -0600 )edit

Surprisingly, ctrl-c'ing roscore does NOT seem to affect ros::ok() of connected nodes, at least in Kinetic. Same with ctrl-c'ing roslaunch, if the node wasn't started by roslaunch. Same result with waitForShutdown. So, unfortunately the approach in the comments above won't work.

BJP gravatar image BJP  ( 2017-05-04 16:32:48 -0600 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2017-05-10 16:51:22 -0600

BJP gravatar image

I decided there was apparently no good way to do this in ROS, and there also was no good way to spawn nodes at runtime. To solve both problems, I created a package called node_director: https://github.com/MisoRobotics/node_... A node_director node allows runtime spawning of nodes ROS is aware of (accessible via rosrun), keeps track of those child processes, and terminates all managed child processes/nodes when the parent node_director dies.

To answer the specific original question, I just instruct node_director (via a ROS service) to spawn the usb_cam nodes rather than starting the processes directly from the spawner process.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2017-05-04 13:45:41 -0600

Seen: 874 times

Last updated: May 10 '17