Search code examples
bashros

Automatically terminate all nodes after calling roslaunch


I am trying to run several roslaunch files, one after the other, from a bash script. However, when the nodes complete execution, they hang with the message:

[grem_node-1] process has finished cleanly
log file: /home/user/.ros/log/956b5e54-75f5-11e9-94f8-a08cfdc04927/grem_node-1*.log

Then I need to Ctrl-C to get killing on exit for all of the nodes launched from the launch file. Is there some way of causing nodes to automatically kill themselves on exit? Because at the moment I need to Ctrl-C every time a node terminates.

My bash script looks like this, by the way:

python /home/user/git/segmentation_plots/scripts/generate_grem_launch.py /home/user/Data2/Coco 0 /home/user/git/Async_CNN/config.txt
source ~/setupgremsim.sh
roslaunch grem_ros grem.launch config:=/home/user/git/Async_CNN/config.txt
source /home/user/catkin_ws/devel/setup.bash
roslaunch rpg_async_cnn_generator conf_coco.launch

The script setupgremsim.sh sources another catkin workspace.

Many thanks!


Solution

  • Thanks all for your advice. What I ended up doing was this; I launched my ROS Nodes from separate python scripts, which I then called from the bash script. In python you are able to terminate child processes with shutdown. So to provide an example for anyone else with this issue:

    bash script:

    #!/bin/bash
    for i in {0..100}
    do
       echo "========================================================\n"
       echo "This is the $i th run\n"
       echo "========================================================\n"
       source /home/timo/catkin_ws/devel/setup.bash
       python planar_launch_generator.py
    done
    

    and then inside planar_launch_generator.py:

    import roslaunch
    import rospy
    
    process_generate_running = True
    
    class ProcessListener(roslaunch.pmon.ProcessListener):
        global process_generate_running
    
        def process_died(self, name, exit_code):
            global process_generate_running
            process_generate_running = False
            rospy.logwarn("%s died with code %s", name, exit_code)
    
    
    def init_launch(launchfile, process_listener):
        uuid = roslaunch.rlutil.get_or_generate_uuid(None, False)
        roslaunch.configure_logging(uuid)
        launch = roslaunch.parent.ROSLaunchParent(
            uuid,
            [launchfile],
            process_listeners=[process_listener],
        )
        return launch
    
    
    rospy.init_node("async_cnn_generator")
    launch_file = "/home/user/catkin_ws/src/async_cnn_generator/launch/conf_coco.launch"
    launch = init_launch(launch_file, ProcessListener())
    launch.start()
    
    while process_generate_running:
            rospy.sleep(0.05)
    
    launch.shutdown()
    

    Using this method you could source any number of different catkin workspaces and launch any number of launchfiles.