Rock

the Robot Construction Kit

Example

In this page, we will detail – as an example – how the ROS prosilica camera output can be displayed using vizkit. (To use the camera with ROS check the tutorials at http://ros.org/wiki/prosilica_camera/Tutorials/)

To be able to use Rock’s visualization tools, add the following to the layout section of autoproj manifest (autoproj/manifest):

 - gui/vizkit

Now, update and build.

Step 1: Data Type Convertion

We want to be able to convert the ROS image message into its Rock equivalent, the base::samples::frame::Frame type.

Since base::samples::frame::Frame is declared in the base/orogen/types oroGen project, we go there (base/orogen/types/base.orogen) and add the necessary ROS-to-Rock mapping declaration (if not yet present):

typekit.ros_mappings '/base/samples/frame/Frame' => 'sensor_msgs/Image'

And run amake once

amake

For the conversion between ROS and Rock to work we then have to fill in conversion functions. Stubs for the conversion functions are automatically generated, i.e. if there was no ROS mappings in the package before, just edit typekit/ROSConvertions.cpp. Otherwise, we have to copy the relevant signatures from templates/typekit/ROSConvertions.hpp and .cpp into the corresponding files in the typekit/ subfolder.

namespace ros_convertions {
    ...
    void toROS( sensor_msgs::Image& ros, 
           ::base::samples::frame::Frame const& value );

    void fromROS( ::base::samples::frame::Frame& value,
            sensor_msgs::Image const& ros );
}

Once the functions are filled in, simply build with

amake

Step 2: Runtime Setup via Topics

At the setup level, getting hold on a topic is as simple as getting hold on a port. For instance, the equivalent of the “rostopic echo” command would be:

require 'orocos'
Orocos.initialize

topic = Orocos::ROS.topic ARGV.first
reader = topic.reader :type => :buffer, :size => 10
while true
  while value = reader.read_new
    pp value
    sleep 0.01
  end
end

Using the connection API as if it was a Rock component, one can then connect the nodes to the task contexts.

Assuming we have one ROS-driven camera (/prosilica_driver), you can use vizkit to display the image using the ROS node’s topic:

require 'vizkit'
require 'orocos'
Orocos.initialize

image_raw = Orocos::ROS.topic '/prosilica/image_raw'

Vizkit.display image_raw
Vizkit.exec

Step 3: Using the Rock tooling

The ROS integration allow you to use ROS nodes similarly to TaskContexts, i.e. it maintains the same user experience for ROS nodes and oroGen tasks. For the tooling to work, the orocos.rb library maps the ROS graph into a structure that maps the Rock component structure. In other words, a given ROS node will have “input ports” and “output ports”. The former are the topics it is subscribed to and the latter the topics that it is publishing.

First of all use rock-display (comes with gui/vizkit) to check for available ROS services:

rock-display

Rock display

Correspondingly, in a Ruby script, one can get hold of a ROS node object through the standard name service interface:

camera = Orocos.name_service.get '/prosilica_driver'

and give that to APIs that expect Orocos task, e.g. assuming that we have a stereo task which relies on image data from one ROS-driven camera (/prosilica_driver) and one Rock-driven one:

require 'orocos'
Orocos.initialize

Orocos.run 'camera_prosilica::Task' => 'right_camera', 'stereo::Task' => 'stereo' do
  left_camera  = Orocos.name_service.get '/prosilica_driver'
  right_camera = Orocos.name_service.get 'right_camera'
  stereo       = Orocos.name_service.get 'stereo'

  left_camera_frame = left_camera.find_output_port('/prosilica/image_raw')
  right_camera.frame.connect_to stereo.right_frame
  left_camera_frame.connect_to stereo.left_frame

  right_camera.configure
  stereo.configure
  right_camera.start
  stereo.start
  Orocos.watch(stereo, right_camera) # Cannot watch a ROS node
end

All the Orocos connection policies can be applied when connecting a ROS node with a Rock component.