/**
\page rostypes_tutorial_continued ROS Types in YARP: sending data to ROS

\tableofcontents

This tutorial assumes that you have completed the
steps in \ref rostypes_tutorial_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.

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.

\section rostypes_tutorial_continued_sender Making the sender program ROS-compatible

The <tt>sender</tt> program from
\ref rostypes_tutorial_portable looks like this:

\code
#include <yarp/rosidl/SharedData.h>
#include <iostream>
#include <yarp/os/Network.h>
#include <yarp/os/BufferedPort.h>
#include <yarp/os/Time.h>

using namespace std;

int main()
{
    yarp::os::Network network;

    yarp::os::Port port;

    if (!port.open("/sender"))
    {
        cerr<<"Error opening port, check your yarp network\n";
       return -1;
    }

    cout<<"Starting sender\n";
    double count=0.0;
    while(true)
    {
        yarp::rosidl::SharedData d;

        // d.text is a string
        d.text="Hello from sender";

        //d.content is a vector, let's push some data
        d.content.push_back(count++);
        d.content.push_back(count++);

        port.write(d);

        yarp::os::Time::delay(0.1);
    }

    return 0;
}
\endcode

This program was written using a <tt>yarp::os::Port</tt>, 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 <tt>yarp::os::Publisher</tt>
that is already correctly configured.  We can also add a
<tt>yarp::os::Node</tt> to make ROS even happier.

\include example/idl/rosPortable/sender2.cpp

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 <tt>receiver</tt> program from
\ref rostypes_tutorial_portable.  We're now using a topic called
`/data` so
after running the <tt>receiver</tt> you'll need to subscribe it
to the topic:

\verbatim
yarp connect topic://data /receiver
\endverbatim

We can also update the <tt>receiver</tt> code to use
the yarp::os::Subscriber helper class:

\include example/idl/rosPortable/receiver2.cpp

\section rostypes_tutorial_continued_visible Registering with ROS

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
<tt>ROS_MASTER_URI</tt> environment variable is correctly set.
Then run the yarp name server with the <tt>--ros</tt> flag:

\verbatim
$  yarpserver --ros
... start-up messages omitted ..
Using ROS with ROS_MASTER_URI=http://127.0.0.1:11311
... start-up messages omitted ..
Ok.  Ready!
\endverbatim

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:

\verbatim
$  rostopic list
...
/data
...
\endverbatim

\verbatim
$  rosnode list
...
/receiver/node
/sender/node
...
\endverbatim

\verbatim
$  rostopic info /data
Type: yarp/SharedData

Publishers:
 * /sender/node (http://192.168.1.3:10005)

Subscribers:
 * /receiver/node (http://192.168.1.3:10003)
\endverbatim

\verbatim
$  rosnode info /receiver/node
Node [/receiver/node]
Publications: None

Subscriptions:
 * /data [yarp/SharedData]

Services: None

contacting node http://192.168.1.3:10003 ...
Pid: [12432]
\endverbatim

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.

\section rostypes_tutorial_continued_msg Making the .msg file available to ROS

In \ref rostypes_tutorial_portable we defined a <tt>SharedData</tt>
structure in a <tt>SharedData.msg</tt> 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 <tt>.msg</tt> files to be in a directory called <tt>msg</tt> 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:

 + Create an empty directory, called say <tt>yarpros_tutorial</tt>.
 + Within that directory, create another empty directory called `src`.
 + Within that directory, create another empty directory that will be
   our package, called say <tt>yarp</tt>.
 + Within <tt>yarp</tt>, create an empty directory called <tt>msg</tt>.
 + Copy <tt>SharedData.msg</tt> into <tt>yarpros_tutorial/src/yarp/msg/</tt>.
 + Create a file called <tt>yarpros_tutorial/src/yarp/package.xml</tt> and place the following in it:

\code
<?xml version="1.0"?>
<package>
  <name>yarp</name>
  <version>0.0.0</version>
  <description>A test yarp package</description>
  <maintainer email="paul@robotrebuilt.com">Paul Fitzpatrick</maintainer>
  <license>BSD-3-Clause</license>
  <build_depend>message_generation</build_depend>
  <run_depend>message_runtime</run_depend>
  <buildtool_depend>catkin</buildtool_depend>
</package>
\endcode

 + Create a file called <tt>yarpros_tutorial/src/CMakeLists.txt</tt> and place the following in it:

\code
cmake_minimum_required(VERSION 3.12)
project(yarp)
find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation)
add_message_files(FILES SharedData.msg)
generate_messages(DEPENDENCIES std_msgs)
catkin_package(CATKIN_DEPENDS message_runtime)
\endcode

 + While in the `yarpros_tutorial` directory, run `catkin_make`.  You should see something like:

\verbatim
...
-- +++ processing catkin package: 'yarp'
...
Generating C++ code from yarp/SharedData.msg
[ 50%] Generating Python from MSG yarp/SharedData
...
[100%] Built target yarp_generate_messages
\endverbatim

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 `yarpros_tutorial` directory):

\verbatim
$ source devel/setup.bash
\endverbatim

At this point, the <tt>rosmsg</tt> command should be able to find
our type:

\verbatim
$  rosmsg show yarp/SharedData
string text
float64[] content
\endverbatim

And if we run the `sender` program, we can print it from ROS:

\verbatim
$  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]
---
\endverbatim

If we stop the `sender` program and run the `receiver`, we can publish to
if from ROS.  If we do this:

\verbatim
rostopic pub /data yarp/SharedData "hello from ROS" "[1.1,2.2,3.3]"
\endverbatim

The `receiver` program prints this:

\verbatim
0 Received SharedData:
hello from ROS
1.1 2.2 3.3
\endverbatim

*/
