Chapter 13
Urbi for ROS Users

This chapter extends the ROS official tutorials ( Make sure to complete this tutorial before reading this document.

 13.1 Communication on topics
  13.1.1 Starting a process from Urbi
  13.1.2 Listening to Topics
  13.1.3 Advertising on Topics
 13.2 Using Services

13.1 Communication on topics

First we will take back examples from topics, make sure talker and listener in ‘beginner_tutorial’ package are compiled. You can recompile it with the following command:

$ rosmake beginner_tutorial  

13.1.1 Starting a process from Urbi

To communicate with ROS components, you need to launch them. You can do it without Urbi, or ask Urbi to start them for you. To launch new processes through Urbi, we will use the class Process (Section 20.45).

Let’s say we want to start roscore, and the talker of the beginner tutorial. Open an Urbi shell by typing the command ‘rlwrap urbi -i’. Here rlwrap makes ‘urbi -i’ acts like a shell prompt, with features like line editing, history, …

var core ="roscore", []); 
[00000001] Process roscore 
var talker ="rosrun", ["beginner_tutorial", "talker"]); 
[00000002] Process rosrun;;  

At this point, the processes are launched. The first argument of is the name of the command to launch, the second is a list of arguments.

Then you can check the status of the processes, get their stdout/stderr buffers, kill them in urbiscript (see Process (Section 20.45)).

13.1.2 Listening to Topics

First you need to make sure that roscore is running, and the Ros module is loaded correctly:

[00016931] true  

Then we can get the list of nodes launched through:


This returns a Dictionary (Section 20.11), with the name of the node as key, and a dictionary with topics subscribed, topics advertised, topics advertised as value.

We can check that our talker is registered, and on which channel it advertises:

// Get the structure (|; makes the instruction quiet). 
var nodes = Ros.nodes|; 
// List of nodes (keys). 
[00000002] ["/rosout", "/urbi_1273060422295250703", "/talker"] 
// Details of the node "talker". 
[00000003] ["/rosout", "/chatter"]  

Here we see that this node advertises ‘/rosout’ and ‘/chatter’. Let’s subscribe to ‘/chatter’:

// Initialize the subscription object. 
var chatter ="/chatter")|; 
// Subscribe. 
// This is the way we are called on new message. 
chatTag: at(chatter.onMessage?(var e)) { 
  // This will be executed on each message. 

In this code, e is a dictionary that follows the structure of the ROS message. Here is an example of what this code produces:

[00000004] *** ["data" => "Hello there! This is message [4]"] 
[00000005] *** ["data" => "Hello there! This is message [5]"] 
[00000006] *** ["data" => "Hello there! This is message [6]"]  

We can also get a template for the message structure on this channel with:

[00000007] ["data" => ""]  

To stop temporarily the echo, we take advantages of tags, by doing chatTag.freeze. Same thing goes with unfreeze. Of course you could also call chatter.unsubscribe, which unsubscribes you completely from this channel.

13.1.3 Advertising on Topics

To advertise a topic, this is roughly the same procedure. Simple Talker

Here is a quick example:

// Initialize our object. 
var talker ="/chatter")|; 
// Advertise (providing the ROS Type of this topic). 
// Get a template of our structure. 
var msg =; 
msg["data"] = "Hello ROS world"|; 
talker << msg;  

We have just sent our first message to ROS, here if you launch the chatter, you will be able to get the message we have just sent.

The << operator is an convenient alias for Ros.Topic.publish. Turtle Simulation

Now we are going to move the turtle with Urbi. First let’s launch the turtle node:

var turtle ="rosrun", ["turtlesim", "turtlesim_node"])|;;  

With the help of Ros.topics, we can see that this turtle subscribes to a topic ‘/turtle1/command_velocity’. Let’s advertise on it:

var velocity ="/turtle1/command_velocity")|; 
[00000001] ["linear" => 0, "angular" => 0]  

Now we want to have it moving in circle with a small sinusoid wave. Here is the code:

// Get our template structure 
var m = |; 
m["linear"] = 0.8 |; 
var angular = 0 |; 
// Every time angular is changed, we send a message. 
angTag: { 
  at(angular->changed?) { 
    m["angular"] = angular; 
    velocity << m 
  // Generates a trajectory updated each System.period (default 20ms). 
  angular = 0.3 sin: 2s ampli: 2 
},; // Put this in background since the instruction above is blocking. 

We won’t cover this code in details, but the general principle is that angular is updated every 20ms with the values of a sinusoid wave trajectory with 0.3 as average value, 2 seconds for the period and 2 for the amplitude. See TrajectoryGenerator (Section 20.63) for more information.

Every time angular is changed, a new message is sent on the Topic ‘/turtle1/command_velocity’, thus updating the position of the turtle. After 20 seconds the tag is frozen, pausing the trajectory generation and the at.


13.2 Using Services

Services work the same way topics do, with minor differences.

Let’s take back the turtle simulation example (Section Then we can list the services available, and filter out loggers:

var r ="(get|set)_logger") |; 
var services = |; 
services.filter(closure (var item) { !r.match(item) }); 
[00000001] ["/clear", "/kill", "/turtle1/teleport_absolute", "/turtle1/teleport_relative", "/turtle1/set_pen", "/reset", "/spawn"]  

The use the closure construct allows us to keep the current “scope”, and thus, to keep our variable r.

Now we see that there is a service called ‘/spawn’. Here is the code to initialize its use:

var spawn ="/spawn", false) |; 

The new function takes the service name as first argument, and whether or not the connection should be kept alive as second argument.

Since the creation of this object checks the service name, you should wait until initialized is true to use this service. You can also see the structure of the request through spawn.reqStruct, and the structure of the response by doing spawn.resStruct.

Now let’s spawn a turtle called Jenny, at position (4, 4).

var req = |; 
req["x"] = 4 | 
req["y"] = 4 | 
req["name"] = "Jenny" |; 
[00000001] ["name" => "Jenny"]