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

Generic adapter for TCP / UDP / serial communications?

asked 2020-04-03 14:24:55 -0500

rgov gravatar image

I am writing driver nodes that control various sensors attached to my CPU. For instance, NMEA messages come from a GPS-enabled device over UDP, while temperature readings are reported over serial.

I could write the thermometer driver node to specifically listen for messages over serial, but this seems like a separation-of-concerns violation.

Instead I think I'd rather have a generic serial driver, and a generic UDP driver, and a generic TCP driver, which all publish a generic line message type, then my thermometer driver could be configured to subscribe to the appropriate topic where these lines are coming in, without caring what communication method is being used upstream.

Is there an existing standard package that would offer this? It's not hard to write myself of course, but I'd like to not reinvent the wheel.

(To emphasize one point, this isn't about sending serialized ROS messages over serial or UDP or whatever.)

edit retag flag offensive close merge delete


At least for serial there have been some, and the velodyne_driver package follows a similar design pattern (ie: dedicated nodelet handles network traffic and (initial) deserialisation, other nodelet(s) convert to ROS msgs).

I'm not aware of anything that would be a standard "goto implementation" you could reuse (but that doesn't mean there aren't any of course).

Three reasons why I believe node authors often decide to not separate these concerns:

  1. the effort needed to write good networking code is often underestimated
  2. if using something like asio for C++ or pyserial for Python, it takes only a few lines of code to get something to work
  3. unless you take care (by using nodelets fi), interposing an intermediary node to handle the conversion to and from your external comms infrastructure/transport will introduce latency and jitter, and will add one more component which can fail.

Finally: network and ...(more)

gvdhoorn gravatar image gvdhoorn  ( 2020-04-04 04:49:19 -0500 )edit

.. typically not examples of shared resources, and require specific interaction patterns to function correctly. Both at the level of the transport, and at the level of communication with whatever is "on the other side".

While that does seem like a responsibility/concern which could be nicely separated -- and some packages that bridge systems like CAN(open)/Ethercat/etc do just that -- it also has a tendency to couple nodes (ie: the bridge and the nodes talking to the bridge), as now two nodes need to work together to maintain proper ordering of messages (fi). This is especially true if the transport/comms channel being wrapped/bridged has no or a different concept of addressing, or doesn't support asynchronous messaging.

Note: I'm not saying your idea is not a good one. I just wanted to discuss it a bit.

That's also why this is not an answer.

I ...(more)

gvdhoorn gravatar image gvdhoorn  ( 2020-04-04 04:53:53 -0500 )edit

3 Answers

Sort by ยป oldest newest most voted

answered 2021-07-20 12:31:10 -0500

Months ago I stumbled upon this thread when I searched for a ethernet bridging node. As I have not been able to find any suitable one, I have created one:

Perhaps you (or anyone coming across this thread from Google) can also benefit from it. However, it does not come with serial communication nodes.

edit flag offensive delete link more

answered 2020-06-08 16:08:58 -0500

borgcons gravatar image

updated 2020-06-08 16:14:56 -0500


What we have done is to create a serial node and publish to a string topic. We have done the same for a tcp and udp node as well.

For serial node you have to decide is you want to publish from a read or publish on a terminator. For ASCII protocols its usually done by ending with a terminator. So your serial node should be of type ASCII or BINARY. For ASCII it would send on a parameterized terminator. For BINARY it would send whatever the read returns. It would be the responsibility of the high node receiving the BINARY data to assemble the data into a packet.

BTW you will have to you assign to move the data from the serial port to the string topic.

Hope all that helps.

Separating in serial into a string topic also makes testing, and debugging easier. An extra feature is that if you have the same type of device, like a GNSS/GPS, that returns apacket of UDP instead of serial your GNSS/GPS node does not have to change. We actually ran into this situation and all that was required was to change a launch file.

edit flag offensive delete link more

answered 2020-04-04 04:56:56 -0500

gvdhoorn gravatar image

updated 2020-04-04 04:58:02 -0500

For ROS 1 I believe there are a few packages that go in this direction, but nothing I could really point you to as being "standard".

For ROS 2 (but you tagged this melodic, so that may not really help you), there is ros-drivers/transport_drivers. Note: these are more libraries than ROS nodes, but it's not entirely clear from your question text whether that would be a problem.

And for NMEA devices specifically, you could look at ros-drivers/nmea_comms.

edit flag offensive delete link more

Question Tools



Asked: 2020-04-03 14:24:55 -0500

Seen: 846 times

Last updated: Jun 08 '20