0
$\begingroup$

Rosanswers logo

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


Originally posted by 130s on ROS Answers with karma: 10937 on 2011-12-07

Post score: 3

$\endgroup$

3 Answers 3

0
$\begingroup$

Rosanswers logo

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.


Originally posted by Thomas with karma: 4478 on 2011-12-07

This answer was ACCEPTED on the original site

Post score: 4


Original comments

Comment by Asomerville on 2011-12-08:
@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.

Comment by Thomas on 2011-12-08:
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 ;)

Comment by 130s on 2011-12-08:
@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.

Comment by Asomerville on 2011-12-08:
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.)

Comment by vinay_kumar28 on 2017-02-20:
can you tell me how it will be done in rosjava? i mean which api in rosjava is used to run another node?

Comment by 130s on 2017-02-20:
@vinay_kumar28 please don't use comment section to ask a whole new question. Open a new one.

Comment by distro on 2021-12-20:
@Asomerville Does rosspawn allow for nodes(ran via launch files)to be autonomously killed and restarted when certain conditions are met?

Comment by 130s on 2021-12-20:
@distro please don't use comment section to ask a new question. To the worst, your question in the comment section doesn't get attention.

$\endgroup$
0
$\begingroup$

Rosanswers logo

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.


Originally posted by DimitriProsser with karma: 11163 on 2011-12-08

This answer was NOT ACCEPTED on the original site

Post score: 5


Original comments

Comment by Asomerville on 2011-12-08:
I think you can do /home/robot/scripts/control | while read line and make things a little simpler.

Comment by DimitriProsser on 2011-12-08:
I've edited my answer to also address this question.

Comment by 130s on 2011-12-08:
@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"?

Comment by zf on 2016-01-06:
I can't understand "/home/robot/scripts/control", is this the path where "control.cpp" locates or some other path?

Comment by distro on 2021-12-20:
@DimitriProsser Does your method allow for nodes(ran via launch files)to be autonomously killed and restarted when certain conditions are met?

$\endgroup$
0
$\begingroup$

Rosanswers logo

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%20Usage


Originally posted by Dorian Scholz with karma: 391 on 2014-03-17

This answer was NOT ACCEPTED on the original site

Post score: 3


Original comments

Comment by Johannes on 2014-07-15:
Is there a way not just to start a single node, instead start an whole launch file?

Comment by lucasw on 2016-01-20:
@Johannes it looks like there might be api entries for that but they aren't currently implemented: https://github.com/ros/ros_comm/blob/indigo-devel/tools/roslaunch/src/roslaunch/scriptapi.py#L74

Comment by lucasw on 2016-01-20:
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.

Comment by distro on 2021-12-20:
@lucasw sorry I'm still confused, does your method allow for nodes(ran via launch files)to be autonomously killed and restarted when certain conditions are met?

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.