process escalates to SIGTERM before running rospy.on_shutdown()
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.
Asked by davidem on 2019-11-17 11:28:33 UTC
Answers
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.
Asked by Delb on 2019-11-18 11:10:56 UTC
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
Asked by davidem on 2019-11-18 12:26:35 UTC
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.
Asked by Delb on 2019-11-19 04:07:05 UTC
Comments