/**
\page rostypes_tutorial_portable ROS Types in YARP: writing a portable

\tableofcontents

YARP built-in types can be sent through Ports. Sometimes you need to send custom
datatypes, in YARP objects that can be sent through ports are called
\em portable objects. \ref port_expert shows how you can manually implement a
portable object.

For ROS interoperability YARP supports ROS msg types. In this tutorial we see
how you can automatically generate YARP portable objects using ROS syntax.
The advantage in this case is that your type is compatible with ROS and can be
directly read from a topic.

\section rostypes_intro Introduction

Suppose we have two modules that wish to share a \em SharedData \m struct that
contains a string and a vector.
Normally you would define the data in a C++ header file and write
serialization/deserialization methods to allow it to be sent and received
to/from a port (this process is called marshalling/demarshalling).
This process requires some YARP specific expertise, is error-prone and tedious.
The idea here is that instead of manually writing the class you define the
structure using the ROS syntax, then you ask a compiler (called
\em yarpidl_rosmsg) to generate the class for you, including all the required
code.
Because you use the ROS syntax this type is also compatible with ROS and can be
read from a topic.

Let's see how to do it.

\section rostypes_ros_defintion ROS definition for SharedData

We start by defining our \em ShareData structure. Open a text editor and type
the following:

\code
string text
float64[] content
\endcode

name this file \em SharedData.msg save and close it.

In ROS this specifies that SharedData is a struct that contains a \em text field
of type \em string and a \em content field which type is a \em vector of double
precision floating point numbers. ROS in fact supports much more options, see
http://wiki.ros.org/msg.

Now you can convert the ROS type in a YARP compatible type.

Type:

\code
yarpidl_rosmsg SharedData.msg
\endcode

This is the output you shuld get:
\code
[type] BEGIN SharedData.msg
[type]   string text []
[type]   float64[] content []
[type] END SharedData.msg
Generating SharedData.h
\endcode

This will generate one file: \em yarp/rosidl/SharedData.h

In case you are interested you can inspect it to see that it defines a C++ class
with some extra code. The good thing is that you don't actually need to bother
about the details, but you can readily use the class in your code.

Now we can use these files in your YARP programs. We now write a sender and a
receiver.

\section rostypes_code Code

This code is straightforward. We define a sender executable that opens a port
and periodically writes a \em yarp::rosidl::SharedData object and a receiver
that opens a port and receives the same message type.

As usual we start with the CMake code, write your CMakeLists.txt:

\code

cmake_minimum_required(VERSION 3.12)

find_package(YARP COMPONENTS os REQUIRED)

add_executable(sender)
target_sources(sender PRIVATE sender.cpp)
target_include_directories(sender PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(sender PRIVATE YARP::YARP_os
                                     YARP::YARP_init)

\endcode
Now we write the code for the sender in \em sender.cpp:

\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

Now compile the code
\code
mkdir build
cd build
cmake ../
make

./sender
\endcode

Now you can run yarp read on a separate console to inspect the content that is
being transmitted on the port, the output should be something like this (you'll
need a very recent version of YARP for this to work - if it doesn't just skip
it):
\code
~$ yarp read ... /sender
yarp: Port /tmp/port/1 active at tcp://127.0.0.1:10003
yarp: Receiving input from /sender to /tmp/port/1 using tcp
"Hello from sender" (276.0 277.0)
"Hello from sender" (278.0 279.0)
\endcode

It is simple to write a receiver:

Append the following to the CMakeLists.txt

\code
add_executable(receiver)
target_sources(receiver PRIVATE receiver.cpp)
target_link_libraries(receiver YARP::YARP_os
                               YARP::YARP_init)
\endcode

Now we write the code for the receiver in \em receiver.cpp:

\code

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

using namespace std;

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

    cout<<"Starting receiver\n";

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

    network.connect("/sender", "/receiver");

    int count=0;
    while(true)
    {
        yarp::rosidl::SharedData d;
        port.read(d);

        //access d
        cout << count << " Received SharedData:\n";
        cout << d.text << "\n";
        for (int i=0; i<d.content.size(); i++)
        {
            cout<<d.content[i]<<" ";
        }
        cout<<"\n";
        count++;
    }

    return 0;
}
\endcode

Compile, and start the receiver, with the sender running:
\code
$ ./receiver
Starting receiver
yarp: Port /receiver active at tcp://192.168.59.129:10003
yarp: Receiving input from /sender to /receiver using tcp
0 Received SharedData:
Hello from sender
396 397
1 Received SharedData:
Hello from sender
398 399
2 Received SharedData:
Hello from sender
400 401
3 Received SharedData:
Hello from sender
402 403
...
\endcode

\section rostypes_using_cmake Using CMake

YARP provides CMake supports to automate the invocation of yarpidl_rosmsg. This
is convenient in large projects when we generate several files and we do not
want to keep track of all of them individually.

Edit the file CMakeLists.txt:

\code

cmake_minimum_required(VERSION 3.12)

#find YARP
find_package(YARP REQUIRED)

\endcode

We now tell CMake to parse SharedData.msg with the rosmsg compiler.
All generated files will be placed in separate \em include and \em src
directories.

\code

#compile definition file to generate source code into the desired directory
set(generated_libs_dir "${CMAKE_CURRENT_SOURCE_DIR}")
yarp_idl_to_dir(SharedData.msg ${generated_libs_dir})

\endcode

The first time you run CMake it will produce a file SharedData_msg.cmake that
contains all generated files. This file can be used to compile our executables,
i.e.:

\code
#include files generated previously
include(SharedData_msg.cmake)
include_directories(${generated_libs_dir}/include)

# create the sender
add_executable(sender)
target_sources(sender PRIVATE sender.cpp
                              ${headers}
                              ${sources})
target_link_libraries(sender PRIVATE YARP::YARP_os
                                     YARP::YARP_init)

# create the receiver
add_executable(receiver)
target_sources(receiver PRIVATE receiver.cpp
                                ${headers}
                                ${sources})
target_link_libraries(receiver PRIVATE YARP::YARP_os
                                       YARP::YARP_init)
\endcode

Now you just have to execute CMake. The variable ALLOW_IDL_GENERATION controls
if the rosmsg compiler is executed to generate SharedData.h or not. Notice that
the first time you run cmake you \em have to enable this flag otherwise
compilation will fail because SharedData.h will be missing.

\code
cd build
cmake ../ -DALLOW_IDL_GENERATION=TRUE
\endcode

The code generation step is required only when \em SharedData.msg is modified.

\section rostypes_related_tutorials Related Tutorials

This tutorial continues with:
\li \ref rostypes_tutorial_continued

More information on interoperatiblity with ROS can be found here:
\ref yarp_with_ros

The Thrift IDL allows defining portable objects and modules interfaces with YARP
native types:
\li \ref thrift_tutorial_portable
\li \ref thrift_tutorial_simple
\li \ref thrift_tutorial


Code for this tutorial can be found here: `example/idl/rosportable`

*/
