ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Get raw network data of a ros topic

asked 2018-08-06 03:15:13 -0600

Felix394 gravatar image

Hey guys,

I try to get the raw data of a topic in ros for some days now. My Problem is, that I receive a complex Message Type from a topic and I have to serialize its data to a <uint8_t>vector to fill the payload of a network package and send it to another application.

If I subscribe the topic, I only get a ConstPtr& to the specific message type and because it's a complex type which change it's size at runtime I can't use simply memcpy() to serialize the data. Of course I can serialize the data with some for loops, but this isn't a smart way to do it.

Instead of deserializing the data by the subscriber, is it possible to get the serialized raw frames directly from the topic?

So I have my subscriber:

ros::NodeHandle n;

ros::Subscriber sub = n.subscribe("topic", 1000, &callback);

and my callnack function:

void Listener::callback(SpecialDataType::ConstPtr& msg) { //should serialize data and forward it }

If it is possible to just get the raw eth frame of the topic, I'll only need copy the raw frame in my new payload and send it.

Do you have an idea how to achieve a good solution to such a problem?

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted

answered 2018-08-07 02:07:40 -0600

gvdhoorn gravatar image

updated 2018-08-07 02:33:39 -0600

It's still unclear to me why you want to do this (but then again, perhaps that is not important): but if I understand you correctly, you could take a look at ShapeShifter to create a generic subscriber. That subscriber has access to the raw data bytes.

See also the ros_type_introspection package for some examples (such as How to create a generic Topic Subscriber) and convenience classes that make this sort of thing somewhat easier to do.


If it is possible to just get the raw eth frame of the topic [..]

You're probably aware that TCP streams != ethernet frames, so what you suggest is not directly possible without some knowledge of how the network stack on the publishing side fragmented the stream.

edit flag offensive delete link more


Note also that this question has been asked multiple times. Using google fi: generic subscriber

gvdhoorn gravatar image gvdhoorn  ( 2018-08-07 02:09:51 -0600 )edit

It looks like a solution, which will fix my problem! Thanks a lot! :)

Felix394 gravatar image Felix394  ( 2018-08-08 02:21:22 -0600 )edit

answered 2018-08-06 05:19:28 -0600

but this isn't a smart way to do it

Why do you say this? It sounds perfectly reasonable to me. You're trying to break the layers of abstraction of ROS for small performance gain. There is another challenge, if you were to access the raw buffer of the message you'd also need to know how it was structured because at some point down the line you're going to have to extract the message data.

Personally I'd simply serialize the data yourself and then pass that buffer. This also means you won't have any problem de-serializing it later.

edit flag offensive delete link more



Perhaps the OP can describe why he wants to do this. There can be perfectly good reasons for wanting to access the raw bytestream, but those are not common. To avoid an xy-problem, let's see what the OP actually wants to do with it.

gvdhoorn gravatar image gvdhoorn  ( 2018-08-06 05:36:05 -0600 )edit

Because the size of the message is very big and will increase in the future and sometime it won't be just a small gain of performance. And there is no need to deserialize the message by ros, only to serialize it again. Deserialization at the destination application is enough in my opinion.

Felix394 gravatar image Felix394  ( 2018-08-06 06:17:15 -0600 )edit

That is all fine, but you still haven't told us what you are intending to do exactly. Why do you need the raw bytestream? What are you implementing? A bridge over a non-ethernet transport? Something else?

gvdhoorn gravatar image gvdhoorn  ( 2018-08-06 07:16:47 -0600 )edit

The ROS Node I want to implement should be a gateway(ROS to Ethernet). The gateway should be generic and should not care about the type which it will forward. And the receiver should not be connected directly to the master, it should receive the data via the private network

Felix394 gravatar image Felix394  ( 2018-08-06 10:07:55 -0600 )edit

Would setting up a VPN linking a computer within the private network to the computers that are running ROS now be a solution? This way you could use ROS as is.

PeteBlackerThe3rd gravatar image PeteBlackerThe3rd  ( 2018-08-06 10:56:34 -0600 )edit

I don't want to run ros on the receiver side. We try to find work arounds here, but we don't force the main question. Is it possible to get the raw data? My manual serialization is already working, but I don't like the solution because it is not the most performant way and it is not generic

Felix394 gravatar image Felix394  ( 2018-08-07 01:46:21 -0600 )edit

We're not trying to find work-arounds. It's still unclear what application level requirement you're trying to fulfil. If you're not running ROS on the other end, what good is the message content?

gvdhoorn gravatar image gvdhoorn  ( 2018-08-07 02:02:03 -0600 )edit

Question Tools



Asked: 2018-08-06 03:15:13 -0600

Seen: 871 times

Last updated: Aug 07 '18