Giter Club home page Giter Club logo

nimbro_network's Introduction

nimbro_network - ROS transport for high-latency, low-quality networks

nimbro_network is a set of ROS packages for transporting ROS topics and services over network. It was developed for the DLR SpaceBotCup competition and performed very well during the competition. Our team was one of the few teams which did not have communication problems.

The SpaceBotCup network had a few special aspects which forced us to design our own network solution, in particular a two-second delay in each direction.

The system was also used extensively in the DARPA Robotics Challenge, in which our team NimbRo Rescue achieved the fourth place.

Why?

ROS has a network transparency layer. But it has issues, namely:

  • For subscription, a lengthy TCP handshake is required, even if you want to use the UDP transport. If you lose the connection, you have to re-do the handshake, possibly taking a long time
  • No compression
  • ROS service calls need several handshakes for each call
  • Messages are transmitted at the rate at which they are published

Our network stack offers the same functions as the ROS network transparency, but addresses each of the above issues.

Alternatives

nimbro_network offers robust transport of ROS topics and services over unreliable networks. For high-level features like auto-discovery, job scheduling etc. take a look at alternatives like rocon or multimaster_fkie.

Features

  • Topic transport:
    • TCP protocol for transmission guarantee (still with communication timeouts!)
    • UDP protocol for streaming data (data which has no meaning if it arrives late)
    • Optional transparent BZip2 compression using libbz2
    • Automatic topic discovery on the receiver side. The transmitter defines which topics get transferred
    • Optional rate-limiting for each topic
    • Experimental Forward Error Correction (FEC) for the UDP transport
  • Service transport:
    • TCP protocol with minimal latency (support for TCP Fast-Open is included)
    • UDP protocol
  • Additional nodes:
    • Special nimbro_log_transport node for transporting the ROS log over a lossy connection
    • Special tf_throttle node for creating & transferring TF snapshots at pre- defined intervals.
    • Special nimbro_cam_transport package for encoding/decoding camera images to/from H.264

Getting started

See nimbro_topic_transport/README.md and nimbro_service_transport/README.md for documentation on the topic and service transport.

State

nimbro_network is mature in the sense that it has been used extensively in the preparation and during the competition of the SpaceBotCup and in the DARPA Robotics Challenge.

In the DRC, the software was used for the high-bandwidth link. Communication over the low-bandwidth link was handled by custom, highly specific code, which is not released at this point.

License

nimbro_network is licensed under the BSD 3-clause license. This repository includes the QCustomPlot library, which is licensed under the GPLv3 license.

Authors & Contact

Max Schwarz <[email protected]>
Institute of Computer Science VI
Rheinische Friedrich-Wilhelms-Universität Bonn
Friedrich Ebert-Allee 144
53113 Bonn

nimbro_network's People

Contributors

dreuter avatar droeschel avatar fredrikbaberg avatar hfarazi avatar nimbro avatar pallgeuer avatar peci1 avatar xinyi-joffre avatar xqms avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nimbro_network's Issues

Could not create socket: Address family not supported by protocol

I am using the develop branch of this repo in order to achieve a ground station - robot communication.

The ground station is a laptop running ROS Noetic and works as a WiFi hotspot.
The robot is running ROS Melodic and is connected to the hotspot above.

I can run both receiver and sender on the robot PC and also I can launch the sender on the ground station.
However, when I run the receiver on the ground station I get the following error:

Could not create socket: Address family not supported by protocol
terminate called after throwing an instance of 'std::runtime_error'
  what():  Resource temporarily unavailable
[receiver-2] process has died 

Any ideas why is this happening?

[Feature request] Multicast UDP

In many multi-robot applications, we need few up-downlink for data to the central system and some from the central-system to all the robots which is inconvenient if we are not using Multicast/Broadcast.

[rqt] nimbro rqt-based GUI plugins not visible

Hi @xqms,

with @alaurenzi we are trying to adopt the nimbro_network framework for the communication between the pilot station and our robots.

We tried to execute the rqt-plugins you developed, but we are not able to see them inside rtq_gui.

We already tried to use the:

rqt --force-discover

with no success.

We also tried to source from install space, but the result is the same: rqt does not show up the plugins.

Any ideas?

Multimaster discovery

Would it be possible to achieve the discovery using multimaster_fkie and enable hosts on the go for the nimbro network?
Did anybody already tried that?
Do we need one node per host to synchronize?

Build issues on Jetson Nano

I am trying to build nimbro_network (develop branch) on a Jetson Nano.
All packages, except nimbro_topic_transport are completed successfully.
For the topic transport I get the following error
In file included from /home/smarthome-user/ros_projects/nimbro_ws/src/nimbro_network/nimbro_topic_transport/contrib/wirehair/WirehairTools.h:34:0, from /home/smarthome-user/ros_projects/nimbro_ws/src/nimbro_network/nimbro_topic_transport/contrib/wirehair/WirehairCodec.h:211, from /home/smarthome-user/ros_projects/nimbro_ws/src/nimbro_network/nimbro_topic_transport/contrib/wirehair/wirehair.cpp:30: /home/smarthome-user/ros_projects/nimbro_ws/src/nimbro_network/nimbro_topic_transport/contrib/wirehair/gf256.h:70:14: fatal error: tmmintrin.h: No such file or directory #include <tmmintrin.h> // SSSE3: _mm_shuffle_epi8 ^~~~~~~~~~~~~ compilation terminated.

Following the instructions from here, I tried to locate the tmmintrin.h file, but it is not installed anywhere.

Is it possible to build it on a Jetson device? Are there any modifications that should be made?

Receiver node from "develop" branch dies due to accessing nullptr

Hi @xqms

We've got an issue with the receiver node dying because of segfault (exit code -11) when using the "develop" branch.

@tomlankhorst and I tried to debug this issue and could get a backtrace using gdb (see end of the message). We were wondering if you could provide us with your feedback about this issue. This is our setup:

  • a base station runs the receiver node
  • an agent runs the sender node
  • the agent sends both tcp (sporadic messages) and udp (images and tf) topics

When the agent goes out of connection range and comes back after some minutes, we often get the receiver node dying on the base station. We suspect that Depacketizer::addPacket is called asynchronously on the same object (for example when 2 UDP packets are received) and so addPacket is called twice. But if it's called async, then it will mess up because the value of the iterator will be changing.

Do you have any hint or suggest on how we could fix this issue?

Best,
Marco

Backtrace:

#0  0x00007ffff7d6ce72 in nimbro_topic_transport::Depacketizer::handleMessagePacket (this=0x7fffffffbfb0, it=
    {id = 24190, complete = false, received_symbols = 10, packets = std::vector of length 10, capacity 10 = {std::shared_ptr<nimbro_topic_transport::Packet> (use count 1, weak count 0) = {get() = 0x7fffd48a92b0}, std::shared_ptr<nimbro_topic_transport::Packet> (use count 1, weak count 0) = {get() = 0x7fffd48b0120}, std::shared_ptr<nimbro_topic_transport::Packet> (use count 1, weak count 0) = {get() = 0x7fffd48b06f0}, std::shared_ptr<nimbro_topic_transport::Packet> (use count 1, weak count 0) = {get() = 0x7fffd48b0cc0}, std::shared_ptr<nimbro_topic_transport::Packet> (use count 2, weak count 0) = {get() = 0x7fffd48b1290}, std::shared_ptr<nimbro_topic_transport::Packet> (use count 1, weak count 0) = {get() = 0x7fffd48accd0}, std::shared_ptr<nimbro_topic_transport::Packet> (use count 1, weak count 0) = {get() = 0x7fffd48a9e50}, std::shared_ptr<nimbro_topic_transport::Packet> (use count 1, weak count 0) = {get() = 0x7fffd48a8140}, std::shared_ptr<nimbro_topic_transport::Packet> (empty) = {get() = 0x0}, std::shared_ptr<nimbro_topic_transport::Packet> (use count 1, weak count 0) = {get() = 0x7fffd48aefb0}}, decoder = std::shared_ptr<WirehairCodec_t> (empty) = {get() = 0x0}}, packet=...) at /usr/include/c++/9/bits/shared_ptr_base.h:1020
#1  0x00007ffff7d6df79 in nimbro_topic_transport::Depacketizer::addPacket (this=0x7fffffffbfb0,
    packet=std::shared_ptr<nimbro_topic_transport::Packet> (use count 2, weak count 0) = {...})
    at /home/subt/catkin_ws/src/nimbro_network/nimbro_topic_transport/src/receiver/depacketizer.cpp:44
#2  0x00007ffff7d71432 in std::function<void (std::shared_ptr<nimbro_topic_transport::Packet> const&)>::operator()(std::shared_ptr<nimbro_topic_transport::Packet> const&) const (__args#0=std::shared_ptr<nimbro_topic_transport::Packet> (use count 2, weak count 0) = {...},

License ambiguity?

First: thanks for making these pkgs available.

This is more a question than a real issue, but there is some ambiguity over how these pkgs are licensed: the readme states that they are "BSD 3 clause" (here with the QCustomPlot library as GPLv3). The nimbro_topic_transport package however has GPLv2 in its package manifest (here). Same for nimbro_service_transport.

I haven't checked the other packages, but could you clarify which statement(s) is (are) correct?

First few messages not received by receiver node

Hi @xqms

Thanks again for sharing this great collection of tools!

I've noticed one strange behavior and was wondering if it's intended to be like that.
Basically every time a topic is sent over nimbro, the first few messages are not received on the receiver side.

This is a quick example to reproduce the mentioned issue:

  1. In one terminal to simulate the first machine (sender) run
roslaunch nimbro_topic_transport tcp_sender.launch
  1. In a second terminal to simulate the second machine (receiver, running on different roscore) run:
export ROS_MASTER_URI=http://localhost:13311
roslaunch nimbro_topic_transport tcp_receiver.launch 
  1. Now in a third terminal (same rosmaster as second machine):
export ROS_MASTER_URI=http://localhost:13311
rostopic echo /recv/my_first_topic
  1. Finally we can publish a topic on the first machine in a fourth terminal (package roscpp_tutorials needs to be installed):
rosrun roscpp_tutorials talker /chatter:=/my_first_topic

As it the be noticed in the below screeshot, the received messages in the second machine start with "hello world 3", whereas the talker node on the first machine starts publishing with hello world 0.

So the question is: where are the first 3 messages? Is this an expected behavior?

Screenshot_2021-01-19_10-50-37

How to deal with "Could not bind socket: Address already in use" error & choose ports

Hi,

once again thanks for sharing this great tool!

I was wondering if there was a more systematic way to choose the TCP/UDP ports to be used in the launch files.
I saw that if the nimbro_network nodes are launched after the other ROS nodes are already running on the robot, sometimes it may happen that the TCP or UDP ports hard-coded in the launch files are already being used by some oder nodes, resulting then in the error:
[FATAL] [1570092836.939500435]: Could not bind socket: Address already in use
and then the corresponding nimbro_network node that tried to use the occupied port dies.

So far the best thing I could think of, is to: (a) launch regular launch file on the robot, (b) use the solution proposed here to scan available TCP or UDP ports in private range (49152-65535), (c) pick available ports for the nimbro nodes.

Of course this is not ideal and does not ensure that the launch files for nimbro will always have the selected ports as available. Therefore I was wondering if there's another way/method to deal with this problem.

Or maybe should I just use ports within the "registered ports" range (1024 to 49151)? I saw that the TCP Receiver/Sender example uses ports 17001 and 17002 and with these two I have never problems.

Regards,

Marco.

Build issues on Jetson Nano

I am trying to build nimbro_network (develop branch) on a Jetson Nano.
All packages, except nimbro_topic_transport are completed successfully.
For the topic transport I get the following error
In file included from /home/smarthome-user/ros_projects/nimbro_ws/src/nimbro_network/nimbro_topic_transport/contrib/wirehair/WirehairTools.h:34:0, from /home/smarthome-user/ros_projects/nimbro_ws/src/nimbro_network/nimbro_topic_transport/contrib/wirehair/WirehairCodec.h:211, from /home/smarthome-user/ros_projects/nimbro_ws/src/nimbro_network/nimbro_topic_transport/contrib/wirehair/wirehair.cpp:30: /home/smarthome-user/ros_projects/nimbro_ws/src/nimbro_network/nimbro_topic_transport/contrib/wirehair/gf256.h:70:14: fatal error: tmmintrin.h: No such file or directory #include <tmmintrin.h> // SSSE3: _mm_shuffle_epi8 ^~~~~~~~~~~~~ compilation terminated.

Following the instructions from here, I tried to locate the tmmintrin.h file, but it is not installed anywhere.

Is it possible to build it on a Jetson device? Are there any modifications that should be made?

md5sum mismatch on kinetic, between laptop and RPi3

I'm trying to setup Nimbro, but am getting errors with mismatching md5sum. The setup is as follows:

  • Laptop running Ubuntu 16.04 and ROS Kinetic
  • Raspberry Pi 3 running ubuntu-mate and ROS Kinetic
  • nimbro_network

When I try to (by hand or code) publish to a topic, e.g. /odom, from the Raspberry Pi 3 I get an error message that the md5sum does not match. For nav_msgs/Odometry:
[ERROR] [1494423321.522783000]: Client [/rostopic_31478_1494423320327] wants topic /am02/odom to have datatype/md5sum [nav_msgs/Odometry/cd5e73d190d741a2f92e81eda573aca7], but our version has [nav_msgs/Odometry/7fffffff7fffffff7fffffff7fffffff]. Dropping connection..
Similar for sensor_msgs/Image (I relaunched and published a different type of message):
[ERROR] [1494423348.232874870]: Client [/rostopic_31620_1494423344032] wants topic /am02/odom to have datatype/md5sum [sensor_msgs/Image/060021388200f6f0f447d0fcd9c64743], but our version has [sensor_msgs/Image/060021387fffffff7fffffff7fffffff]. Dropping connection.

I've checked the md5sum on both with rosmsg md5 nav_msgs/Odometry and rosmsg md5 sensor_msgs/Image, they are identical. If I export ROS_MASTER_URI and skip nimbro it works.

If I publish to /am02/cmd_vel from the laptop, I receive the message on the RPi3 without any issue. If I try the other way, it does not work.

Wrong catch_ros include dir in certain situations

As discovered in AIS-Bonn/catch_ros#15, we currently prefer the catch_ros headers from e.g. /opt/ros/noetic/include in favor of the (correct) ones from the current workspace.

The reason is this line:

include_directories(${catch_ros_INCLUDE_DIRS})

... which adds the catch_ros headers to the end. Instead, we should use catkin's list_insert_in_workspace_order() function to correctly insert the additional include path.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.