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
- The python client library for ROS.
- Overview of Rospy
- Go beyond the tutorials and read the Code API documentation.
- Documentation for noetic has not been generated as of this writing but should be substantially the same
How to use
Rospy is just like any other python library.
import rospy
- Create classes and call functions in rospy
- Calling
rospy.init_node(name)
is what makes your code a ROS node, with a givenname
. - Calling
rospy.logXXX
functions is how to use the ROS logging system rospy.Subscriber
is how to subscribe to messagesrospy.Publisher
is how to publish messagesrospy.Service
is how to offer a servicerospy.ServiceProxy
is how to call a service.rospy.get_param
gets a parameter from the server.rospy.Rate
sleeps for a duration such that the time betweensleep()
calls matches a specified period.- 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
:
from pkg.msg import Mtype
Mtype.field
is to access a field in the message typeMtype(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
:
from pkg.srv import SType, STypeResponse
SType
is the service type, this is needed when registering the service.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 useSTypeResponse()
- Its constructor and members work follow the same convention as a message type.
- The response type corresponds to the part of the service after the
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.
- You usually don't need to declare
ROS API
- The collection of services, publishers, subscribers, and parameters of a node is its ROS API
- These ROS inter-process communication mechanisms are how you link nodes together, much like how modules, functions, and classes are used from within python.
- The ROS name mechanism are essential for connecting multiple packages together
Naming in ROS
What's in a name?
- Every item in the ROS Computation Graph has a Graph Resource Name
- You manipulate names in ROS using Remapping, which enables you to re-wire the computation graph and connect otherwise unrelated components
- ROS's name system is the source of much of its flexibility, and you will use it in every ROS program you write.
- Important Reading: Graph Resource Name and Remapping
Understanding Names
- In ROS, every topic, parameter, and service has a Graph Resource Name
- 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
- For example
- 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
- 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.
- The global namespace is called
- 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 examplenode1
is a base name. - Base names are resolved relative to the namespace of the node
- Essentially, any
- 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.
- relative names are any name that doesn't start with
- 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.
- namespaces are like directories.
- 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
- 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
- For example:
- 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.
- The change can be done in a launchfile or by setting the
Remapping
- 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
- This is like a
- Remapping can occur by passing arguments to
rosrun
,roslaunch
or in alaunchfile
- 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
- The basic syntax is passed as a command-line argument:
- 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
- By default, nodes are created directly under
- 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
.
/ns1/node1
is the global name ofnode1
node1
is the base name ofnode1
- From within
node1
,topic1
, resolves to/ns1/topic1
/topic1
, resolves to/topic1
- From within
node1
,~topic1
, resolves to/ns1/node1/topic1
- If within
node1
you subscribetopic2
then the node is connected to/ns1/topic2
- If within
node1
you subscribe to/topic2
then the node is connected to/topic2