<> <> == 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. 1. Initializing your ROS [[Nodes|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 === <> {{{{#!wiki buildsystem catkin 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. }}}} {{{{#!wiki buildsystem rosbuild ROS uses the `` listed in your [[Manifest|manifest.xml]] to configure your PYTHONPATH. To use this feature in your code, simple add this to the top of your file. {{{ #!python 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 `` tag to the `` section of your [[Manifest|manifest.xml]]. For example: {{{ .. other exports }}} }}}} === Initializing your ROS Node === See also: [[http://www.ros.org/doc/api/rospy/html/rospy-module.html#init_node|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|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 [[rospy/Overview/Logging|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|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.