rospy overview: Initialization and Shutdown | Messages | Publishers and Subscribers | Services | Parameter Server | Logging | Names and Node Information | Time | Exceptions | tf/Overview | tf/Tutorials | Python Style Guide

Initialization

There are two parts to initializing your Python code to work in ROS:

  1. Configuring your PYTHONPATH: if you use other ROS Packages in your code, you'll need to dynamically load their libraries onto your path so that you can import them.

  2. Initializing your ROS Node: every node has a name, so your code cannot communicate with other nodes until you have provided this information.

Each of these steps is described in detail below.

Configuring your PYTHONPATH

ROS catkin packages containing python code should use a setup.py file as described here:

http://docs.ros.org/hydro/api/catkin/html/user_guide/setup_dot_py.html

This setup.py defines which Python packages and scripts should be installed. Installed packages are added to the PYTHONPATH automatically when you source the devel or install space in which the package was built or installed to.

ROS uses the <depends> listed in your manifest.xml to configure your PYTHONPATH. To use this feature in your code, simple add this to the top of your file.

   1 import roslib; roslib.load_manifest('YOUR_PACKAGE_NAME')

By default, this will add the src and lib directory for each of your dependencies to your PYTHONPATH.

NOTE: If you wish to export a different PYTHONPATH for your package, you can add a <python> tag to the <export> section of your manifest.xml. For example:

<export>
 <python path="${prefix}/different_dir"/>
 .. other exports
</export>

Initializing your ROS Node

See also: rospy.init_node() Code API

One of the first calls you will likely execute in a rospy program is the call to rospy.init_node(), which initializes the ROS node for the process. You can only have one node in a rospy process, so you can only call rospy.init_node() once.

The two most common invocations for init_node() are:

rospy.init_node('my_node_name')

and

rospy.init_node('my_node_name', anonymous=True)

As part of the init_node() call, you will pass in the default name of your node. When you run your code, this is the name that your node will appear as online unless it's overridden by remapping arguments. Names have important properties in ROS. Most importantly, they must be unique. In cases where you don't care about unique names for a particular node, you may wish to initialize the node with an anonymous name.

rospy.init_node(name, anonymous=False, log_level=rospy.INFO, disable_signals=False)

  • Create a new node with the specified name. There are several optional keyword arguments that you may wish to set:
    • anonymous=True

      • The anonymous keyword argument is mainly used for nodes where you normally expect many of them to be running and don't care about their names (e.g. tools, GUIs). It adds a random number to the end of your node's name, to make it unique. Unique names are more important for nodes like drivers, where it is an error if more than one is running. If two nodes with the same name are detected on a ROS graph, the older node is shutdown.

      log_level=rospy.INFO

      • Set the default log level for publishing log messages to rosout. See Logging.

      disable_signals=False

      • By default, rospy registers signal handlers so that it can exit on Ctrl-C. In some code, you may wish to disable this, including:

        • You're not calling init_node() from the Python Main thread. Python only allows signals to be registered from the Main thread.

        • You're running rospy within Qt, wxPython or any other GUI toolkit that has its own exit handlers.
        • You wish to have your own signal handlers by default.

Accessing your command-line arguments

ROS passes in additional command-line arguments to your program to initialize remapping arguments. While these are easy to filter out on your own, rospy provides a convenience function for stripping these out.

rospy.myargv(argv=sys.argv)

  • Return a copy of sys.argv with remapping arguments removed. You can optionally pass in your own argv array to have that filtered instead.

Shutting down

Testing for shutdown

The most common usage patterns for testing for shutdown in rospy are:

while not rospy.is_shutdown():
   do some work

and

... setup callbacks
rospy.spin()

The spin() code simply sleeps until the is_shutdown() flag is True. It is mainly used to prevent your Python Main thread from exiting.

There are multiple ways in which a node can receive a shutdown request, so it is important that you use one of the two methods above for ensuring your program terminates properly.

Registering shutdown hooks

rospy.on_shutdown(h)

  • Register handler to be called when rospy process begins shutdown. h is a function that takes no arguments.

You can request a callback using rospy.on_shutdown() when your node is about to begin shutdown. This will be invoked before actual shutdown occurs, so you can perform service and parameter server calls safely. Messages are not guaranteed to be published.

def myhook():
  print "shutdown time!"

rospy.on_shutdown(myhook)

Manual shutdown (Advanced)

If you are overriding rospy's signal handling (the disable_signals option to init_node()), you will need to manually invoke the correct shutdown routines to cleanup properly.

rospy.signal_shutdown(reason)

  • Initiate node shutdown. reason is a human-readable string that documents why a node is being shutdown.

Wiki: rospy/Overview/Initialization and Shutdown (last edited 2017-03-23 19:10:10 by IsaacSaito)