Ask Your Question
3

terminate & launch other node from code

asked 2011-12-07 10:30:19 -0600

130s gravatar image

updated 2011-12-08 06:00:44 -0600

Is there a ROS way to terminate and launch another node from one node's code?

For launching example in python, it's possible by doing something like this w/o using ROS:

import os
os.system('roslaunch turtlebot_navigation_ours amcl_customized.launch')

Any way to do the same in an official way in ROS?

How about terminating as well? If a node run as "respawn = true" receives "shutdown" msg/service request then shuts down itself? Better idea?


Update) I thought I'd better describe a situation when I need this...There is a node that gets to consume higher CPU in a process of time (eventually CPU load reaches 12.0 or above although it's not supposed to do so). And I found that restarting makes it stay calmer and still functions. Besides debugging that node itself, it would be nicer if I can just work around the issue for now by restarting the node.


Update-2) Found similar QA thread and roslaunch.scriptapi might be good as well for launching from python (I'm sure the argument for ROSLaunch.launch is roslaunch.core.Node instead of roslaunch.Node as in API doc).

edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted
4

answered 2011-12-07 18:58:05 -0600

Thomas gravatar image

Yes, of course, you can start a node from another node using your favorite process management API. In ROS, you also have rosspawn which will provide this kind of service.

However, it seems to me that what you want to achieve does not really fit well with the ROS framework. When using component oriented frameworks, the general idea is to start all the services at the beginning (using a roslaunch file for instance) and stating nodes relations and configurations using the ROS parameters. Then no nodes should be killed before the whole system is shutdown.

Then monitoring tools and/or interactive tools should just be launched from outside, using rosrun.

edit flag offensive delete link more

Comments

Sounds like rosspawn will do exactly what he wants. (I'm not sure I understand the comment that what he want's to do doesn't fit well.)
Asomerville gravatar imageAsomerville ( 2011-12-08 03:57:59 -0600 )edit
@Thomas thanks. rosspawn seems good and now I'm giving a shot at it. Meanwhile do you think of any source about component oriented frameworks requires all services begin at the same time? I'm just curious to know more about the concept.
130s gravatar image130s ( 2011-12-08 05:19:46 -0600 )edit
Sorry, my post probably was not clear enough: all the roslaunch files I have seen so far are launching services without having, at any moment, to restart or stop them. Having to do that proably means that your code is not reentrant which is something one should avoid, that's all ;)
Thomas gravatar imageThomas ( 2011-12-08 08:32:45 -0600 )edit
1
@Thomas, If I understand him correctly I think he just want's to periodically restart a node that is leaking resources. And if that part of his system that he's restarting is stateless/part of a pipeline (e.g. an edge detector node) there should be no ill effects other than the restart delay AFAICT.
Asomerville gravatar imageAsomerville ( 2011-12-08 09:10:09 -0600 )edit

can you tell me how it will be done in rosjava? i mean which api in rosjava is used to run another node?

vinay_kumar28 gravatar imagevinay_kumar28 ( 2017-02-20 10:34:17 -0600 )edit

@vinay_kumar28 please don't use comment section to ask a whole new question. Open a new one.

130s gravatar image130s ( 2017-02-20 13:10:15 -0600 )edit
5

answered 2011-12-08 01:36:48 -0600

DimitriProsser gravatar image

updated 2011-12-08 02:00:15 -0600

We've encountered this problem as well. On our robot, we have ROS set to autoboot on power-up. At this point, it boots into a "minimal" state in which only a few nodes are running until we receive a connection to an external network. At that point, it will launch the rest of the ROS nodes. Why we do this isn't really important, but here's HOW we do it... Just a warning, it's fairly complex.

Our whole autoboot/control system is based on a Bash/C++ interface. You are able to pipe the output of a C++ program to a Bash script and read the output. To do this, your C++ program must simply output to stdout and Bash can read it. Here's a quick example of what I mean:

control.cpp

#include <iostream>
#include <string>
#include <unistd.h>

using namespace std;

int main(int argc, char** argv)
{
    while(1)
    {
      if(guiNotConnected())
      {
        cout << "Connected" << endl;
      }
      sleep(1);
    }
}

control.bash

#!/bin/bash

function cpp_func {

    /home/robot/scripts/control

}
while read line; do
    if [ "$line" == "Connected" ]; then
        roslaunch robot_launch rest_of_ros.launch
    fi
done < <(cpp_func)

In the above example, "/home/robot/scripts/control" represents the location of the c++ executable on the filesystem. The reason it's wrapped in a Bash function is because Bash doesn't allow you to pipe an executable directly in to the function. I.E. "done << /home/robot/scripts/control" is not allowed. That's why the executable is wrapped in the Bash function cpp_func.

This allows us to execute any functions we want (start, kill, restart, etc.) on any node we want. As long as you expect an output in your Bash script, you can handle any ROS commandline processes from that one control.bash script. Just a note, you cannot send commands back to the c++ program using this method.

edit flag offensive delete link more

Comments

@DimitriProsser Wow this seems interesting, and I think it's not as complex as you mentioned. Quick question: why do you need "/home/robot/scripts/control"?
130s gravatar image130s ( 2011-12-08 01:52:53 -0600 )edit
1
I've edited my answer to also address this question.
DimitriProsser gravatar imageDimitriProsser ( 2011-12-08 01:59:01 -0600 )edit
I think you can do `/home/robot/scripts/control | while read line` and make things a little simpler.
Asomerville gravatar imageAsomerville ( 2011-12-08 03:46:46 -0600 )edit

I can't understand "/home/robot/scripts/control", is this the path where "control.cpp" locates or some other path?

zf gravatar imagezf ( 2016-01-06 15:09:10 -0600 )edit
3

answered 2014-03-17 08:05:48 -0600

Dorian Scholz gravatar image

I just had the same problem and was stunned to see how difficult it was to find a simple example for this basic task. So I added a minimal code example to the roslaunch wiki page:

http://wiki.ros.org/roslaunch/API%20U...

edit flag offensive delete link more

Comments

Is there a way not just to start a single node, instead start an whole launch file?

Johannes gravatar imageJohannes ( 2014-07-15 10:43:10 -0600 )edit

@Johannes it looks like there might be api entries for that but they aren't currently implemented: https://github.com/ros/ros_comm/blob/...

lucasw gravatar imagelucasw ( 2016-01-20 17:30:01 -0600 )edit

Though you can start a launch file bypassing the api import roslaunch; args = ['roslaunch', 'my_package', 'foo.launch']; roslaunch.main(args)- but it blocks and doesn't have the stop/is_alive methods.

lucasw gravatar imagelucasw ( 2016-01-20 17:30:44 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2011-12-07 10:30:19 -0600

Seen: 15,258 times

Last updated: Mar 17 '14