This tutorial assumes that you have completed the steps in ROS Types in YARP: writing a portable. That tutorial showed how to use types defined in a ROS-style .msg file within YARP. Now, we will work on sending data from YARP to ROS.
Make sure you have the latest version of YARP from github. Make sure you run the latest version of the yarp name server, there have been important fixes.
At the beginning of this tutorial, we assume you have a YARP server running, without any special configuration. During the tutorial, we will reconfigure the name server to communicate with ROS.
sender program from ROS Types in YARP: writing a portable looks like this:
This program was written using a
yarp::os::Port, a very flexible creature. It can communicate with ROS, if we tame it a little bit to fit in with ROS's expectations that promise to never change the type of data sent, and promise to always send data in a particular direction. We can make those promises by calls to yarp::os::Port::setWriteOnly and yarp::os::Port::promiseType, or we can switch to using the helper class
yarp::os::Publisher that is already correctly configured. We can also add a
yarp::os::Node to make ROS even happier.
Great, at this point our port is nice and tame by ROS standards. And the code will still work just fine without ROS. For example, we can run our existing
receiver program from ROS Types in YARP: writing a portable. We're now using a topic called
/data so after running the
receiver you'll need to subscribe it to the topic:
yarp connect topic://data /receiver
We can also update the
receiver code to use the yarp::os::Subscriber helper class:
Now let's make our programs visible with ROS. Stop running them, and then also stop the yarp name server. Make sure you have a ROS name server running ("roscore"/"rosmaster"), and that the
ROS_MASTER_URI environment variable is correctly set. Then run the yarp name server with the
$ yarpserver --ros ... start-up messages omitted .. Using ROS with ROS_MASTER_URI=http://127.0.0.1:11311 ... start-up messages omitted .. Ok. Ready!
Done! Now, if we rerun the sender and receiver programs, they should work as before. The (invisible) difference is that they are being connected by ROS rather than YARP. A visible difference is that the programs are now visible within ROS. Try:
$ rostopic list ... /data ...
$ rosnode list ... /receiver/node /sender/node ...
$ rostopic info /data Type: yarp/SharedData Publishers: * /sender/node (http://192.168.1.3:10005) Subscribers: * /receiver/node (http://192.168.1.3:10003)
$ rosnode info /receiver/node Node [/receiver/node] Publications: None Subscriptions: * /data [yarp/SharedData] Services: None contacting node http://192.168.1.3:10003 ... Pid: 
Notice that ROS is reporting the topic
/data as having the type
yarp/SharedData. ROS needs types to include a "package" name, and we haven't specified one yet, so YARP has added a fake one. To get full interoperation, we now need to add our
SharedData type in ROS (not just YARP), and as part of that process we'll end up making a real ROS package.
In ROS Types in YARP: writing a portable we defined a
SharedData structure in a
SharedData.msg file and used it to communicate between sender and receiver programs written using YARP. Now we need to make that file visible to ROS. ROS expects
.msg files to be in a directory called
msg within a ROS "package". If you already have a package set up for your work, you can just use that. For completeness, we give a very minimal ROS package here, just enough to experiment with, but you can also just follow ROS tutorials, there's nothing YARP-specific here. Do the following:
yarp, create an empty directory called
yarpros_tutorial/src/yarp/package.xmland place the following in it:
yarpros_tutorial/src/CMakeLists.txtand place the following in it:
catkin_make. You should see something like:
... -- +++ processing catkin package: 'yarp' ... Generating C++ code from yarp/SharedData.msg [ 50%] Generating Python from MSG yarp/SharedData ... [100%] Built target yarp_generate_messages
Now we need to tell ROS about the existence of yarpros_tutorial. There are many ways to do that. In a bash shell, the simplest is to do (from the
$ source devel/setup.bash
At this point, the
rosmsg command should be able to find our type:
$ rosmsg show yarp/SharedData string text float64 content
And if we run the
sender program, we can print it from ROS:
$ rostopic echo /data text: Hello from sender content: [4794.0, 4795.0] --- text: Hello from sender content: [4796.0, 4797.0] --- text: Hello from sender content: [4798.0, 4799.0] --- text: Hello from sender content: [4800.0, 4801.0] ---
If we stop the
sender program and run the
receiver, we can publish to if from ROS. If we do this:
rostopic pub /data yarp/SharedData "hello from ROS" "[1.1,2.2,3.3]"
receiver program prints this:
0 Received SharedData: hello from ROS 1.1 2.2 3.3