How can I have roslaunch manage the lifecycle of spawned nodes?
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.
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
loop should work or if you
go the asynchronous route a call to
will wait till the core goes away.
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.