ROS messages outside of ROS nodes

Morten Kjaergaard and I have been working hard on refactoring core ROS code
and build system mechanisms, with the goal of facilitating use of ROS
messages outside the context of ROS nodes and the ROS build system. Please
see the README at

https://github.com/ros/ros-message-user-examples

for a first prototype, which multicasts geometry_msgs::Pose objects in 100
lines of C++ that compiles to a 220k binary.
The integration with boost::asio is passable; we'll go for a slick asio-ish
interface later.

What is most important is what is missing from this prototype, namely:

- roscpp (the roscpp_serialization library is only 12k and contains only a
single function that throws an exception)
- rosmake
- xmlrpc
- ROS_* environment variables (modulo the CMAKE_PREFIX_PATH needed to tell
cmake where to find things)
- log4cxx/apr

I'm glad to answer any questions, and would be grateful to anyone taking
the time to point out more integration scenarios... especially any where
this scheme doesn't work for some reason.

Best,

Troy Straszheim

ROS messages outside of ROS nodes

On Tuesday 06 December 2011 05:09:32 Troy Straszheim wrote:
> Orocosland:
>
> Morten Kjaergaard and I have been working hard on refactoring core ROS code
> and build system mechanisms, with the goal of facilitating use of ROS
> messages outside the context of ROS nodes and the ROS build system. Please
> see the README at
>
> https://github.com/ros/ros-message-user-examples
>
> for a first prototype, which multicasts geometry_msgs::Pose objects in 100
> lines of C++ that compiles to a 220k binary.
> The integration with boost::asio is passable; we'll go for a slick asio-ish
> interface later.
>
> What is most important is what is missing from this prototype, namely:
>
> - roscpp (the roscpp_serialization library is only 12k and contains only a
> single function that throws an exception)
> - rosmake
> - xmlrpc
> - ROS_* environment variables (modulo the CMAKE_PREFIX_PATH needed to tell
> cmake where to find things)
> - log4cxx/apr

At last, a missing feature is actually a feature :-)

>
> I'm glad to answer any questions, and would be grateful to anyone taking
> the time to point out more integration scenarios... especially any where
> this scheme doesn't work for some reason.

I think there are two issues here that touch us: serialization and cmake

What we require from an integration point of view is not ros-independent
serialization, but a generated message C++ struct which our parsers can read.
In practice this translates to typelib + orogen compatibility[1]. The current
Orocos code generators (orogen and typegen) do their serialization themselves,
but I can imagine they might use ros' serialization functions when connecting
an Orocos port to a ROS node. The current rtt_ros_integration works like that
today.
When sending ROS structs to non-ROS nodes, we use boost::serialization today
to put the data on the wire. We generate these boost::serialization stubs
ourselves. Examples are ZeroMQ or Posix queues, which need user-side
serialization.
Protocols like CORBA and DDS will never be able to use the ROS serialization,
since they have an own wire representation. For these, our tools generate the
idl from a C++ struct which we can use then to build the transport libraries.

For the cmake part, I'm really impressed. This could have saved us a lot of
trouble about a year ago. We'll have to test it in order to see if it does
what we think it does, but it certainly cleans it up.

Summarized: we did not have an immediate need for serializing ROS messages
without ros; we can use/test the cmake improvements right away.

Peter

[1] http://rock-robotics.org/documentation/orogen/type_definitions.html - See
known limitations.

ROS messages outside of ROS nodes

2011/12/6 Peter Soetens <peter [..] ...>

>
> At last, a missing feature is actually a feature :-)
>
>
Heh... can I quote you in my propaganda / promotional materials?

What we require from an integration point of view is not ros-independent
> serialization, but a generated message C++ struct which our parsers can
> read.
> In practice this translates to typelib + orogen compatibility[1]. The
> current
> Orocos code generators (orogen and typegen) do their serialization
> themselves,
> but I can imagine they might use ros' serialization functions when
> connecting
> an Orocos port to a ROS node. The current rtt_ros_integration works like
> that
> today.
> When sending ROS structs to non-ROS nodes, we use boost::serialization
> today
> to put the data on the wire. We generate these boost::serialization stubs
> ourselves. Examples are ZeroMQ or Posix queues, which need user-side
> serialization.
> Protocols like CORBA and DDS will never be able to use the ROS
> serialization,
> since they have an own wire representation. For these, our tools generate
> the
> idl from a C++ struct which we can use then to build the transport
> libraries.
>

Thanks; this is exactly the kind of thing I was looking for. Thanks.
Thoughts:

- Just to clarify, one could use CORBA, etc, if the contents of the CORBA
object were a buffer and some key (say, the md5sum) in to a set of
(de)serialization routines. Technically possible, but obviously this is a
nasty hack. Moving on...

- Would one rather generate CORBA IDL directly from the .msg format and
have it provided along with the other bindings, rather than going via an
intermediate C++ struct? I could make assorted complaints about the way
ROS code generation is currently done, but that C++ parsing is done only by
C++ compilers would not be one of them.

- Generating Boost.Serialization code would be easy, and those who don't
use it could remain blissfully ignorant. There are a few smaller
technical issues here, such as managing template instantiations. If only
"standard" archive types are used, one could provide shared libraries
containing instantiated serialization routines. This may save a
significant amount of compile time and binary space, at the cost of a small
amount of runtime due to inlining that would otherwise occur. If custom
archive types are used, it is possible to provide a way to build such
libraries, though slightly more complicated.

For the cmake part, I'm really impressed. This could have saved us a lot of
> trouble about a year ago. We'll have to test it in order to see if it does
> what we think it does, but it certainly cleans it up.
>

I'm flexible, and the interfaces are still subject to change. We've named
it 'catkin', partly to make clear a separation between the build system
infrastructure and the rest of ROS. There are non-ROS projects using it;
I'll ping here after I've put together some motivating documentation.

-t

ROS messages outside of ROS nodes

On Tue, 6 Dec 2011, Troy Straszheim wrote:

> Orocosland:
>
> Morten Kjaergaard and I have been working hard on refactoring core ROS
> code and build system mechanisms, with the goal of facilitating use of
> ROS messages outside the context of ROS nodes and the ROS build system.

Laudable goal!

> Please see the README at
>
> https://github.com/ros/ros-message-user-examples
>
> for a first prototype, which multicasts geometry_msgs::Pose objects in 100 lines of C++ that compiles to a 220k binary.
> The integration with boost::asio is passable; we'll go for a slick asio-ish interface later.
>
> What is most important is what is missing from this prototype, namely:
>
> - roscpp (the roscpp_serialization library is only 12k and contains only a single function that throws an exception)
> - rosmake
> - xmlrpc
> - ROS_* environment variables (modulo the CMAKE_PREFIX_PATH needed to tell cmake where to find things)
> - log4cxx/apr
>
> I'm glad to answer any questions, and would be grateful to anyone taking
> the time to point out more integration scenarios... especially any where
> this scheme doesn't work for some reason.

I am curious to learn why this refactoring wasn't automatically leading to
the choice of already existing communication middleware standards and
projecfs? In other words, making Communication independent from the ROS
component model (or any other component model for that matter) is
definitely a good way to go, but that path has been threaden many many
times ago in the past already. I am thinking of "message based" middleware
standards such as DDS, or ZeroMQ, etc.

I yet other words: wouldn't it be more important to go to a (ROS-agnostic,
multi-project) _standard_ to represent robotics data structures, that can
then be transported by any existing communication middleware?

> Best,
>
> Troy Straszheim

Herman

ROS messages outside of ROS nodes

On Mon, Dec 5, 2011 at 10:40 PM, Herman Bruyninckx <
Herman [dot] Bruyninckx [..] ...> wrote:

> On Tue, 6 Dec 2011, Troy Straszheim wrote:
>
> Orocosland:
>>
>> Morten Kjaergaard and I have been working hard on refactoring core ROS
>> code and build system mechanisms, with the goal of facilitating use of
>> ROS messages outside the context of ROS nodes and the ROS build system.
>>
>
> Laudable goal!
>
>
> Please see the README at
>>
>> https://github.com/ros/ros-**message-user-examples<https://github.com/ro...
>>
>> for a first prototype, which multicasts geometry_msgs::Pose objects in
>> 100 lines of C++ that compiles to a 220k binary.
>> The integration with boost::asio is passable; we'll go for a slick
>> asio-ish interface later.
>>
>> What is most important is what is missing from this prototype, namely:
>>
>> - roscpp (the roscpp_serialization library is only 12k and contains only
>> a single function that throws an exception)
>> - rosmake
>> - xmlrpc
>> - ROS_* environment variables (modulo the CMAKE_PREFIX_PATH needed to
>> tell cmake where to find things)
>> - log4cxx/apr
>>
>> I'm glad to answer any questions, and would be grateful to anyone taking
>> the time to point out more integration scenarios... especially any where
>> this scheme doesn't work for some reason.
>>
>
> I am curious to learn why this refactoring wasn't automatically leading to
> the choice of already existing communication middleware standards and
> projecfs? In other words, making Communication independent from the ROS
> component model (or any other component model for that matter) is
> definitely a good way to go, but that path has been threaden many many
> times ago in the past already. I am thinking of "message based" middleware
> standards such as DDS, or ZeroMQ, etc.
>

Hi Herman... thanks for jumping in!

You may think that I'm trying to do more than I am. The intent is to
eliminate some thorny but basic integration hassles; this should reduce
short-term pain and more readily allow the collective conscious to
determine what the standards should be. I'd like to participate in those
discussions, but there is some urgent cleanup to be done first.

Serializing these ROS message structures into buffers and then pumping them
through a socket was the simplest way I could think to demonstrate
interoperability with arbitrary messaging middleware... the socket being
the "middleware", and the simplest way to do this (in my world anyhow) is
via boost::asio. It could just as easily have been straight-C sockets or
CORBA... the important bit, from an integrator's standpoint, is to
minimize the compile- link- and run-time dependencies, i.e. not to impose
workflow or large toolsets on those who would interoperate. In other
words, if we're stuck with multiple middlewares, let's make it as painless
as possible. Note that the dependencies on CMake and boost (not just for
asio, but also for shared_ptr) make the modularity imperfect. Structures
that contain "time" objects have an additional dependency on a small
library and boost::date_time.

We could go further, though: the demo doesn't show it, but it is now
cleaner to, for example, craft one's own serialization routines for data
structures represented in .msg files. One example would be to generation
of ANSI C.

I yet other words: wouldn't it be more important to go to a (ROS-agnostic,
> multi-project) _standard_ to represent robotics data structures, that can
> then be transported by any existing communication middleware?
>

It would certainly seem so. The tools should support movement in that
direction; such a standard would emerge after a lot of prototyping, which
the tools should facilitate rather than hinder via spurious dependencies.
Example: I'd like to send associative containers over the wire. The
underlying CMake infrastructure could be taught to support code generation
from message definitions other than the ROS .msg format. At this point,
the integration hassles start to shift around: you might want to have some
common way to serialize messages that originate in either definition
language.

Thanks again,

-t

ROS messages outside of ROS nodes

On Tue, 6 Dec 2011, Troy Straszheim wrote:

>
>
> On Mon, Dec 5, 2011 at 10:40 PM, Herman Bruyninckx <Herman [dot] Bruyninckx [..] ...> wrote:
> On Tue, 6 Dec 2011, Troy Straszheim wrote:
>
> Orocosland:
>
> Morten Kjaergaard and I have been working hard on refactoring core ROS
> code and build system mechanisms, with the goal of facilitating use of
> ROS messages outside the context of ROS nodes and the ROS build system.
>
>
> Laudable goal!
>
> Please see the README at
>
>  https://github.com/ros/ros-message-user-examples
>
> for a first prototype, which multicasts geometry_msgs::Pose objects in 100 lines
> of C++ that compiles to a 220k binary.
> The integration with boost::asio is passable; we'll go for a slick asio-ish
> interface later.
>
> What is most important is what is missing from this prototype, namely:
>
> - roscpp  (the roscpp_serialization library is only 12k and contains only a
> single function that throws an exception)
> - rosmake
> - xmlrpc
> - ROS_* environment variables (modulo the CMAKE_PREFIX_PATH needed to tell cmake
> where to find things)
> - log4cxx/apr
>
> I'm glad to answer any questions, and would be grateful to anyone taking
> the time to point out more integration scenarios... especially any where
> this scheme doesn't work for some reason.
>
>
> I am curious to learn why this refactoring wasn't automatically leading to
> the choice of already existing communication middleware standards and
> projecfs? In other words, making Communication independent from the ROS
> component model (or any other component model for that matter) is
> definitely a good way to go, but that path has been threaden many many
> times ago in the past already. I am thinking of "message based" middleware
> standards such as DDS, or ZeroMQ, etc.
>
>
> Hi Herman... thanks for jumping in!
>
> You may think that I'm trying to do more than I am.  The intent is to eliminate some thorny but
> basic integration hassles;  this should reduce short-term pain and more readily allow the
> collective conscious to determine what the standards should be.   I'd like to participate in those
> discussions, but there is some urgent cleanup to be done first.

Ok, if you say so :-)

> Serializing these ROS message structures into buffers and then pumping them through a socket was
> the simplest way I could think to demonstrate interoperability with arbitrary messaging
> middleware... the socket being the "middleware", and the simplest way to do this (in my world
> anyhow) is via boost::asio.  It could just as easily have been straight-C sockets or CORBA...  
> the important bit, from an integrator's standpoint, is to minimize the compile- link- and run-time
> dependencies, i.e. not to impose workflow or large toolsets on those who would interoperate.  In
> other words, if we're stuck with multiple middlewares, let's make it as painless as possible.

The "pain" does not come from the compile time efforts (although they
exist, of course), but from the runtime interconnection problems, more in
particular the semantics of messages.

>  Note that the dependencies on CMake and boost (not just for asio, but also for shared_ptr) make
> the modularity imperfect.  Structures that contain "time" objects have an additional dependency on
> a small library and boost::date_time.

I do not have fundamental problems with such dependencies, but I have
problems identifying why your efforts are not yet another case of the "Not
Invented Here" syndrome.

> We could go further, though:  the demo doesn't show it, but it is now cleaner to, for example,
> craft one's own serialization routines for data structures represented in .msg files.  

That's exactly my point: I do no see any added value to yet another "own
serialization routine", since tons of projects (some of which mature and
well supported) do that already. The real refactoring that is needed might
be to make ROS able to work with such projects, instead of making its
transport infrastructure do similar (nice) things as these established
projects.

Maybe I am focusing on the wrong aspects of the interoperability problem
Here, so please enlighten me when that's indeed the case :-)

> One example would be to generation of ANSI C.
>
> I yet other words: wouldn't it be more important to go to a (ROS-agnostic,
> multi-project) _standard_ to represent robotics data structures, that can
> then be transported by any existing communication middleware?
>
> It would certainly seem so.  The tools should support movement in that direction;  such a standard
> would emerge after a lot of prototyping, which the tools should facilitate rather than hinder via
> spurious dependencies.  Example:  I'd like to send associative containers over the wire.  The
> underlying CMake infrastructure could be taught to support code generation from message
> definitions other than the ROS .msg format.  At this point, the integration hassles start to shift
> around:  you might want to have some common way to serialize messages that originate in either
> definition language.
>
> Thanks again,
>
> -t

Herman

ROS messages outside of ROS nodes

On Tue, Dec 6, 2011 at 12:58 AM, Herman Bruyninckx <
Herman [dot] Bruyninckx [..] ...> wrote:

> On Tue, 6 Dec 2011, Troy Straszheim wrote:
>
> On Mon, Dec 5, 2011 at 10:40 PM, Herman Bruyninckx <
>> Herman.Bruyninckx@mech.**kuleuven.be <Herman [dot] Bruyninckx [..] ...>>
>> wrote:
>> On Tue, 6 Dec 2011, Troy Straszheim wrote:
>>
>> Orocosland:
>>
>> Morten Kjaergaard and I have been working hard on refactoring
>> core ROS
>> code and build system mechanisms, with the goal of
>> facilitating use of
>> ROS messages outside the context of ROS nodes and the ROS
>> build system.
>>
>> Laudable goal!
>>
>> The "pain" does not come from the compile time efforts (although they
> exist, of course), but from the runtime interconnection problems, more in
> particular the semantics of messages.

And indeed, one can't define semantics with cmake and code generators. As
stated, the current work is "refactoring core ROS code and build system
mechanisms".

Note that the dependencies on CMake and boost (not just for asio, but also
>> for shared_ptr) make
>> the modularity imperfect. Structures that contain "time" objects have an
>> additional dependency on
>> a small library and boost::date_time.
>>
>
> I do not have fundamental problems with such dependencies, but I have
> problems identifying why your efforts are not yet another case of the "Not
> Invented Here" syndrome.

So it is either "laudable goal", or "Not Invented Here" syndrome...

We could go further, though: the demo doesn't show it, but it is now
>> cleaner to, for example,
>> craft one's own serialization routines for data structures represented in
>> .msg files.
>>
>
> That's exactly my point: I do no see any added value to yet another "own
> serialization routine", since tons of projects (some of which mature and
> well supported) do that already. The real refactoring that is needed might
> be to make ROS able to work with such projects, instead of making its
> transport infrastructure do similar (nice) things as these established
> projects.
>

> Maybe I am focusing on the wrong aspects of the interoperability problem
> Here, so please enlighten me when that's indeed the case :-)

I'm really not sure.

-t