SICKAG / sick_safetyscanners

ROS driver for SICK safety laser scanners
https://www.sick.com/de/en/opto-electronic-protective-devices/safety-laser-scanners/c/g187225
Apache License 2.0
61 stars 59 forks source link

Issues with Ports when running inside Docker Container with Bridging #61

Closed njoye closed 4 years ago

njoye commented 4 years ago

Hi! First: Thanks for the seemingly flawless way that this project works under many conditions - that is really amazing. I have an issue that concerns the running of this project inside a Docker Container without the host network being bound directly to the container. My goal / My task (at work) is to create a container, which passes the data of the SICK laser scanners to the ROS network.

For this we have a roscore running at the IP 172.20.0.2, my container that is supposed to read the laser scanner data has the IP 172.20.0.13. The host computer has the IP 192.168.1.10 and it is able to retrieve the data and pass it to the roscore, I have already tested that. Since binding the host network to a container is no option for me, I would like to retrieve the data with a bridged network. At first I didn't quiet understand how the SICK Scanners are sending information but I'll lay it out here so that we're on the same page. It think it works like this:

The sick_safetyscanners driver starts communicating with the scanner (ours is located at 192.168.1.3) via the Cola2 Protocol. It passes the Host IP to the scanner and after succesfull communication the scanner then sends its data to the following address: host_ip:host_udp_port (as defined in the launch file).

This is all fine and in that case, the solution would be to bind my container to the 192.168.1.10:host_udp_port address which would pass through all the UDP data coming in at that port. Yet, when I define the UDP Port as 9090 and bind my container to it, I don't seem to get data in (at least nothing is passed through to the network). Upon further inspection, it seems as if the sick_safetyscanners driver not only listens to the defined host_udp_port but also to a variety of other ports which change every time the container / rosnode is restarted.

A possible solution would be to just bind all ports from 2000 to 6000 to the container, but I don't think that is a good idea, since I don't know what the other ports are needed for and if they might fall out of that port range at some point.

This is why I have a few questions about this project:

  1. Is there a way of making this project work inside a docker container ? If so all of my other questions would be obsolete.
  2. Is my understanding of the communication between the scanner and the host pc correct ? If not, which parts am I missing ?
  3. Are the ports that are listened to by the rosnode (other than the host_udp_port) for Cola2 communication or are they necessary for getting the data from the scanner to the ros network?

I think that's all the questions I can come up with for now - thank you already so much for your help! I've spent quiet a lot of time on this already, so any help is really appreciated.

lenpuc commented 4 years ago

Hi there, first of i am not an big user of docker, so there might be some parts I am not that sure of. However i'll try to highlight the functionality of the sensor. The sensor once set up should only need the Host_udp_port. However on startup there will be some TCP connections to the sensor transferring the current setting to the sensor. This might be where the other ports might appear. The connections are established using boost::asio, there might be functionality, that the same port is used for establishing the connection on the host system, but this is not used in the current driver. The TCP comminciation is done in the follwoing cpp: https://github.com/SICKAG/sick_safetyscanners/blob/master/src/communication/AsyncTCPClient.cpp While looking at wireshark, i couldn't see any different ports used for the udp communication, only the ports for the tcp communication. So if you experience anything different please let me know. For the communciation it can be said, that the UDP data from the sensor is listenting to the continuous datastream, which is a different protocol from cola2. Which instead is the TCP communication between sensor and driver.

Hope this clarifies already a bit

njoye commented 4 years ago

Thanks for the quick answer!

Maybe I didn't propery work that into the threads first post, but that's pretty much what I expected - mulitple TCP from the driver to the scanner for the setup and then a continuous UDP datastream from the scanner to the host_udp_port. That sounds good, because the setup part of the communication seems to have worked from inside the container.

I'll have to figure out why my container couldn't receive the datastream when I listened to the correct port then. I'll do some more investigation tomorrow and come back with more quesetions or an answer in that case.

njoye commented 4 years ago

I just did some research and I realized that when running containers with Docker one needs to pass /udp as ending of -p *port*:*port* (like this: -p *port*:*port*/udp) to bind the UDP port to the container since without the /udp only the TCP port is used. Will also check that tomorrow.

EDIT: This information comes from the Docker Documentation

lenpuc commented 4 years ago

Alright, let me know if that solves your problem.

lenpuc commented 4 years ago

Is this resolved?

njoye commented 4 years ago

Dang sorry - yes it did! The issue was that Docker assumes that /udp is added to the port binding if you want a UDP bind. Issue resolved, thanks for your help. Best regards.