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

process escalates to SIGTERM before running rospy.on_shutdown()

asked 2019-11-17 10:28:33 -0600

davidem gravatar image

updated 2019-11-18 08:31:25 -0600

I am running ROS Melodic.
I have wrote a script that is supposed to launch a param-configured gmapping node and, when it receives a shutdown signal from roscore, it launches the map_saver and quits. The script looks like this:

#!/usr/bin/env python

import rospy
import subprocess


def save_map():
    subprocess.Popen(['rosrun', 'map_server', 'map_saver', '-f', 'mymap']).communicate()


if __name__ == '__main__':
    rospy.init_node('gmapping_and_mapsaver')
    rospy.on_shutdown(save_map)

    pop = subprocess.Popen(['roslaunch', 'foo_pkg', 'gmapping_configured.launch'])

    try:
        pop.communicate()
    except rospy.ROSInterruptException:
        pop.terminate()
        save_map()

This node is launched from a .launch file that also spawns the robot, launches the keyboard teleop and so on.

The issue is that even if I send a CTRL-C command, all the nodes get shutdown correctely but this node escaletes directely to SIGTERM, without launching the save_map() function, nor calling the rospy.on_shutdown() method, that is the same thing.

I have also tried catching a KeyboardInterrupt exception, but with no effects.

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2019-11-18 10:10:56 -0600

Delb gravatar image

I've tried your script and it does call the save_map method after pressing CTRL-C. When you press CTRL-C, the signal SIGINT is sent to end all the running nodes.

Your problem is that you have redirected what should happen when this signal is sent with rospy.on_shutdown(save_map). You manually define how to exit the node BUT you launch a new process within this method. The process launched is map_server which is waiting indefinitely to receive something on the topic /map to exit itself. Since the map_server is called during the ros shutdown, all your previous nodes have been exited, meaning there is no node publishing to /map anymore. The map_server will never get a map so you never exit the method save_map. When the SIGINT signal is sent, if all the nodes aren't closed after a defined timeout (15 seconds by default) the signal SIGTERM is sent to kill all the remaining running nodes, including your current node.

edit flag offensive delete link more

Comments

Is there any way I can prevent this behaviour for this purpose only? I do understand that it sounds irrational, but it's unbelievable to me that a mapping node doesn't save the map it has worked to create and instead I must remember to separately run an additional node before shutting down everything... That's at least how I see things atm

davidem gravatar image davidem  ( 2019-11-18 11:26:35 -0600 )edit

I tried to find a workaround using signal handlers or changing your shutting down method but all the nodes always exit before the call to it. One "solution" if you forgot to save the map is to add in your launch file this :

<node name="record" pkg="rosbag" type="record" args="/map -o PATH_TO_YOUR_FOLDER""/>

With this you will get a bagfile with your map topic saved that you could play back to run map_saver after.

Delb gravatar image Delb  ( 2019-11-19 03:07:05 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2019-11-17 10:28:33 -0600

Seen: 1,527 times

Last updated: Nov 18 '19