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

Revision history [back]

click to hide/show revision 1
initial version

First, the obligatory link to the wiki page: wiki/roscpp/Overview/Publishers and Subscribers - Transport_Hints, and the C++ API docs linked in that section: ros::TransportHints Class Reference.

what are the differences between:

  • reliable, tcp and tcpNoDelay?

From the linked docs:

  • reliable: Specifies a reliable transport. Currently this means TCP.
  • tcp: Explicitly specifies the TCP transport.
  • tcpNoDelay: If a TCP transport is used, specifies whether or not to use TCP_NODELAY to provide a potentially lower-latency connection.

So both reliable and tcp currently result in TCP/IP being used. It says currently in the documentation, as specifying reliable could actually mean different things based on which underlying transports are available (it's just a hint).

  • udp and unreliable?

This is going to be similar:

  • unreliable: Specifies an unreliable transport. Currently this means UDP.
  • udp: Explicitly specifies a UDP transport.

So again: both result in UDP being used, but unreliable could result in some other transport getting selected which could be considered unreliable.

As an example: consider a roscpp modified to be aware of the physical layer. reliable could mean it would try (or make sure) to always route messages over a wired connection for subscribers which have set that transport hint. For subscribers which haven't done this, it could choose between wireless or wired, and for unreliable it could always route over a wireless connection (assuming the wireless connection is less reliable here of course).

None of this is currently supported by the vanilla roscpp, but that's partly what the idea behind the transport hints was/is.

Also, if tcpNoDelay() is much better in terms of performance, why wouldn't you always want tcpNoDelay() then? If there are some downsides, could you explain what they are?

This is not actually a ROS-specific question. The generic form would be: if TCP_NODELAY results in lower latency, why don't we enable it for all connections?

TCP_NODELAY controls whether or not Nagle's algorithm is enabled for that particular TCP connection. I'll not go into too much detail about how it works, as there are too many (very good) resources about it available (any book on networking at least mentions it, as do countless web pages).

But Nagle's algorithm comes with a drawback: it (almost) trades bandwidth efficiency for latency. Efficiency comes from the fact that it delays sending data until it has a "full" packet (whatever that means for the connection). This (typically) results in fewer, but larger, packets getting transmitted. For topics which carry larg(ish) messages at a high rate, this can be important to reach saturation of the link.

But for topics which carry smal(lish) messages, the batching behaviour of Nagle's will actually introduce additional latency (as data has to "wait" in a buffer more). So disabling the algorithm can be beneficial in that case.

In essence, (dis|en)abling Nagle's is a trade-off, and the decision cannot be made by the infrastructure, as it requires knowledge about the data which will be transmitted (volume, frequency, etc), which is not available to the roscpp developers.

Only you, as a user of roscpp know these characteristics of your topics. Hence the need for the transport hints, and why you need to do this yourself.

A comment on something in your table:

TransportHint   Avg comm. time (ms)
reliable        7.5
unreliable      0.4
udp             0.4

You state:

I've tried sending a fairly large custom message with the following transport hints

I'd recommend to make sure how large, as the results you show here for UDP (and unreliable) could be misleading: there is no support for fragmentation/reassembly in UDPROS, so if the message becomes too large, data may be corrupted or not arrive at all.

First, the obligatory link to the wiki page: wiki/roscpp/Overview/Publishers and Subscribers - Transport_Hints, and the C++ API docs linked in that section: ros::TransportHints Class Reference.

what are the differences between:

  • reliable, tcp and tcpNoDelay?

From the linked docs:

  • reliable: Specifies a reliable transport. Currently this means TCP.
  • tcp: Explicitly specifies the TCP transport.
  • tcpNoDelay: If a TCP transport is used, specifies whether or not to use TCP_NODELAY to provide a potentially lower-latency connection.

So both reliable and tcp currently result in TCP/IP being used. It says currently in the documentation, as specifying reliable could actually mean different things based on which underlying transports are available (it's just a hint).

  • udp and unreliable?

This is going to be similar:

  • unreliable: Specifies an unreliable transport. Currently this means UDP.
  • udp: Explicitly specifies a UDP transport.

So again: both result in UDP being used, but unreliable could result in some other transport getting selected which could be considered unreliable.

As an example: consider a roscpp modified to be aware of the physical layer. reliable could mean it would try (or make sure) to always route messages over a wired connection for subscribers which have set that transport hint. For subscribers which haven't done this, it could choose between wireless or wired, and for unreliable it could always route over a wireless connection (assuming the wireless connection is less reliable here of course).

None of this is currently supported by the vanilla roscpp, but that's partly what the idea behind the transport hints was/is.

Also, if tcpNoDelay() is much better in terms of performance, why wouldn't you always want tcpNoDelay() then? If there are some downsides, could you explain what they are?

This is not actually a ROS-specific question. The generic form would be: if TCP_NODELAY results in lower latency, why don't we enable it for all connections?

TCP_NODELAY controls whether or not Nagle's algorithm is enabled for that particular TCP connection. I'll not go into too much detail about how it works, as there are too many (very good) resources about it available (any book on networking at least mentions it, as do countless web pages).

But Nagle's algorithm comes with a drawback: it (almost) trades bandwidth efficiency for latency. Efficiency comes from the fact that it delays sending data until it has a "full" packet (whatever that means for the connection). This (typically) results in fewer, but larger, packets getting transmitted. For topics which carry larg(ish) messages at a high rate, this can be important to reach saturation of the link.

But for topics which carry smal(lish) messages, the batching behaviour of Nagle's will actually introduce additional latency (as data has to "wait" in a buffer more). So disabling the algorithm can be beneficial in that case.

In essence, (dis|en)abling Nagle's is a trade-off, and the decision cannot be made by the infrastructure, as it requires knowledge about the data which will be transmitted (volume, frequency, etc), which is not available to the roscpp developers.

Only you, as a user of roscpp know these characteristics of your topics. Hence the need for the transport hints, and why you need to do this yourself.

A comment on something in your table:

TransportHint   Avg comm. time (ms)
reliable        7.5
unreliable      0.4
udp             0.4

You state:

I've tried sending a fairly large custom message with the following transport hints

I'd recommend to make sure how large, as the results you show here for UDP (and unreliable) could be misleading: there is no support for fragmentation/reassembly in UDPROS, so if the message becomes too large, data may be corrupted or not arrive at all.

First, the obligatory link to the wiki page: wiki/roscpp/Overview/Publishers and Subscribers - Transport_Hints, and the C++ API docs linked in that section: ros::TransportHints Class Reference.

what are the differences between:

  • reliable, tcp and tcpNoDelay?

From the linked docs:

  • reliable: Specifies a reliable transport. Currently this means TCP.
  • tcp: Explicitly specifies the TCP transport.
  • tcpNoDelay: If a TCP transport is used, specifies whether or not to use TCP_NODELAY to provide a potentially lower-latency connection.

So both reliable and tcp currently result in TCP/IP being used. It says currently in the documentation, as specifying reliable could actually mean different things based on which underlying transports are available (it's just a hint).

  • udp and unreliable?

This is going to be similar:

  • unreliable: Specifies an unreliable transport. Currently this means UDP.
  • udp: Explicitly specifies a UDP transport.

So again: both result in UDP being used, but unreliable could result in some other transport getting selected which could be considered unreliable.

As an example: consider a roscpp modified to be aware of the physical layer. reliable could mean it would try (or make sure) to always route messages over a wired connection for subscribers which have set that transport hint. For subscribers which haven't done this, it could choose between wireless or wired, and for unreliable it could always route over a wireless connection (assuming the wireless connection is less reliable here of course).

None of this is currently supported by the vanilla roscpp, but that's partly what the idea behind the transport hints was/is.

Also, if tcpNoDelay() is much better in terms of performance, why wouldn't you always want tcpNoDelay() then? If there are some downsides, could you explain what they are?

This is not actually a ROS-specific question. The generic form would be: if TCP_NODELAY results in lower latency, why don't we enable it for all connections?

TCP_NODELAY controls whether or not Nagle's algorithm is enabled for that particular TCP connection. I'll not go into too much detail about how it works, as there are too many (very good) resources about it available (any book on networking at least mentions it, as do countless web pages).

But Nagle's algorithm comes with a drawback: it (almost) trades bandwidth efficiency for latency. Efficiency comes from the fact that it delays sending data until it has a "full" packet (whatever that means for the connection). This (typically) results in fewer, but larger, packets getting transmitted. For topics which carry larg(ish) messages at a high rate, this can be important to reach saturation of the link.

But for topics which carry smal(lish) messages, the batching behaviour of Nagle's will actually introduce additional latency (as data has to "wait" in a buffer more). So disabling the algorithm can be beneficial in that case.

In essence, (dis|en)abling Nagle's is a trade-off, and the decision cannot be made by the infrastructure, as it requires knowledge about the data which will be transmitted (volume, frequency, etc), which is not available to the roscpp developers.

Only you, as a user of roscpp know these characteristics of your topics. Hence the need for the transport hints, and why you need to do this yourself.

A comment on something in your table:

TransportHint   Avg comm. time (ms)
reliable        7.5
unreliable      0.4
udp             0.4

You state:

I've tried sending a fairly large custom message with the following transport hints

I'd recommend to make sure how large, as the results you show here for UDP (and unreliable) could be misleading: there is no support for fragmentation/reassembly in UDPROS, so if the message becomes too large, data may be corrupted or not arrive at all.