UP | HOME

Rospy and Naming

The python ROS client library rospy allows your python programs to interact with other ROS processes running on your system. ROS uses a special naming convention to allow multiple ROS clients to communicate.

rospy

How to use

Rospy is just like any other python library.

  1. import rospy
  2. Create classes and call functions in rospy
  3. Calling rospy.init_node(name) is what makes your code a ROS node, with a given name.
  4. Calling rospy.logXXX functions is how to use the ROS logging system
  5. rospy.Subscriber is how to subscribe to messages
  6. rospy.Publisher is how to publish messages
  7. rospy.Service is how to offer a service
  8. rospy.ServiceProxy is how to call a service.
  9. rospy.get_param gets a parameter from the server.
  10. rospy.Rate sleeps for a duration such that the time between sleep() calls matches a specified period.
  11. There are many other ROS functions available in rospy.

Messages and Services in Python

When a package uses a custom .msg or .srv file, catkin generates python classes that encapsulates the data types used by the service. The python package that is created is stored in devel/lib/python3/dist-packages/<pkg>

To use the message type MType defined in msg/MType.msg in package pkg:

  1. from pkg.msg import Mtype
  2. Mtype.field is to access a field in the message type
  3. Mtype(field1 = x, field2 =y) let's you construct the message.

To use a service type SType defined in srv/SType.srv with request type STypeRequest and response type STypeResponse in package pkg:

  1. from pkg.srv import SType, STypeResponse
  2. SType is the service type, this is needed when registering the service.
  3. STypeResponse is the type of the response.
    • The response type corresponds to the part of the service after the --- in the .srv file
    • Service callback handlers should explicitly return an object of STypeResponse.
    • Returning None from a service callback triggers an error. To return an empty response use STypeResponse()
    • Its constructor and members work follow the same convention as a message type.
  4. STypeRequest is the type of the request (i.e., the type of the parameter passed to your service handler).
    • You usually don't need to declare STypeRequest explicitly, but you can import it if you want
    • Its fields and constructor follow the same convention as a message type.

ROS API

  1. The collection of services, publishers, subscribers, and parameters of a node is its ROS API
  2. These ROS inter-process communication mechanisms are how you link nodes together, much like how modules, functions, and classes are used from within python.
  3. The ROS name mechanism are essential for connecting multiple packages together

Naming in ROS

What's in a name?

  1. Every item in the ROS Computation Graph has a Graph Resource Name
  2. You manipulate names in ROS using Remapping, which enables you to re-wire the computation graph and connect otherwise unrelated components
  3. ROS's name system is the source of much of its flexibility, and you will use it in every ROS program you write.
  4. Important Reading: Graph Resource Name and Remapping

Understanding Names

  1. In ROS, every topic, parameter, and service has a Graph Resource Name
  2. Message Types, Service Types, and Node Types also have names that can be referred to by a similar mechanism:
    • For example turtlesim/Color refers to /path/to/turtlesim/msg/Color.msg
  3. You pass strings to rospy API calls to access a resource by its name.
    • When you initialize a node, you provide a name
    • When you subscribe to a topic, you provide a name
    • When you publish to a topic, you provide a name
    • When you offer a service, you provide a name
    • When you call a service, you provide a name
  4. Names work in a manner similar to paths on Linux:
    • namespaces are like directories.
      • The global namespace is called /
      • Namespaces can be nested. For example, /ns1/ns2/ns3
      • Every node exists in a namespace (analogous to the current directory). By default, the namespace is /
      • Multiple nodes can be grouped into the same namespace.
    • base names are like files: they are what the actual resource is called, without any preceding namespaces
      • Essentially, any name without a / in it is a base name. For example node1 is a base name.
      • Base names are resolved relative to the namespace of the node
    • relative names are like relative paths: they are namespaces that resolve relative to a given node's namespace
      • relative names are any name that doesn't start with / or ~, for example =ns1/ns2/bname.
      • A base name can be thought of as a relative name without any preceding namespace.
    • global names are like absolute paths: they are names that start with a / to indicate they begin from the global namespace
      • Most of the time, you use relative names within nodes, which allows all the names referenced by a node to be moved into a different namespace more easily
    • private names start with a ~ (i.e. ~name).
      • The ~ expands to the global namespace of the node, followed by the name of the node.
      • Anyone can access private names but you shouldn't do it.
  5. Parameters in the parameter server also use namespaces for access.
    • Private parameters are useful for constants that only a single node instance needs.
    • If you run multiple instances of a node with private parameters, it will get multiple instances of those parameters
  6. Nodes can be launched in any namespace
    • The change can be done in a launchfile or by setting the ROS_NAMESPACE environment variable
      • For example: ROS_NAMESPACE=mynamespace rosrun mypkg mynode will run mynode in the mynamespace namespace
    • If your node uses relative names, you can then change the node namespace to group everything from a given node.
    • This is useful, for example, if you have two nodes from different packages that publish on the same topics but you don't want to connect them.

Remapping

  1. Resources can be remapped to any name that you want
    • This is like a mv operation in the Linux filesystem
    • It enables multiple copies of a node to run with different names for the topics they subscribe to
  2. Remapping can occur by passing arguments to rosrun, roslaunch or in a launchfile
    • The basic syntax is passed as a command-line argument: oldname:=newname (see Remapping Arguments)
    • a preceding underscore (_) on the command-line becomes a ~ to indicate a private name
    • You can change the name of a node by remapping __name
  3. In practice, ROS nodes are written with remapping in mind
    • By default, nodes are created directly under /. You can change the namespace with environment variables or a launchfile
    • Use simple, base names for ROS nodes, the services they offer, and the topics they publish and subscribe to
    • Document these names as part of the node's ROS API
    • Users of the node then remap these topics and services as needed
    • By using base or relative names enables easy remapping of all the topics/services used by a node.
    • Typically, you should not use a global name in a ROS node, as this makes it impossible for a user to move your node and all its topics under a desired namespace
  4. Names should start with a lower case letter, and then can contain letters, or underscores.

Example

Suppose we are referring to names from node1, which is in the namespace ns1.

  1. /ns1/node1 is the global name of node1
  2. node1 is the base name of node1
  3. From within node1, topic1, resolves to /ns1/topic1
  4. /topic1, resolves to /topic1
  5. From within node1, ~topic1, resolves to /ns1/node1/topic1
  6. If within node1 you subscribe topic2 then the node is connected to /ns1/topic2
  7. If within node1 you subscribe to /topic2 then the node is connected to /topic2

Author: Matthew Elwin.