ROS Communication Wrapper Classes

From the beginning, we hoped to make a product useful to future researchers. We structured our code to follow object-oriented principles by capsuling related functions and variables into methods and attributes. Our goal was to make our code more sustainable without becoming bloated.

The key idea to model was how components may communicate. To represent communications over ROS, we kept four primary parent classes, paired up to match to their mode of communication:

  • ROSPublisher
  • ROSSubscriber
  • ROSServiceServer
  • ROSServiceClient

These parent classes have been designed as wrappers. The intention is for developers to extend these with their own functionality. Below is an outline of the functionality provided by these wrappers. It is assumed that the reader is already familiar with ROS publishers/subscribers and servers/clients.

ROSPublisher

Creating a publisher ROSPublisher(topic, ROS msg, queue_size=1, rate=10)

from std_msgs.msg import String
my_string = String()
pub = ROSPublisher('/mytopic', my_string, 1, 10)

To publish publish(data=None)

pub.publish()

ROSSubscriber

Creating a subscriber ROSSubscriber(string topic, ROS/msg message_type)

from std_msgs.msg import String
my_string = String()
sub = ROSSubscriber('/mytopic', my_string)

Each subscriber has a callback function callback(data=None), which is implicitly called whenever something is published on the subscribed topic. This simply prints "Received message on topic <topic>".

ROSServiceServer

Creating a server :code:ROSServiceServer(string service_name, ROS/srv service_type)

# Custom service type
server = ROSServiceServer('`my_service'``, CustomServiceType)

Each server has a callback function to deal with a service request :code:callback(request), where request is a ROS service type.

ROSServiceClient

Creating a client :code:`ROSServiceClient(string service_name, ROS/srv service_type)

# Custom service type
client = ROSServiceClient('my_service', CustomServiceType)

A request can be sent using the make_request(request=None) method. This returns the server response or None if there is an error.

# Custom service type
request = CustomServiceType()
client.make_request(request)

The next 2 pages contain examples on how to create custom publishers/subscribers and servers/clients.

Class hierarchy

We used these wrapper classes in order to implement all component classes which are outlines in the components section further. The following UML class diagram shows extract from the full class hierarchy, focussing on the most important attributes and methods. The full class diagram is given in our report.

_images/class_transp_extract.png