6

I am a developer of ROS projects. Recently I am trying using ROS(melodic) on WSL2(Windows Subsystem for Linux), and all things works just great. But I got some trouble when I want to use another PC which also in the same local area network(LAN) to communicate with. Before setting the environment variables like "ROS_MASTER_URI, ROS_IP", I know that since WSL 2 work on Hyper-V so the IP show on WSL2 is not the one in the real LAN. I have to do some command like below in order to make everyone in LAN communicate with the specific host:PORT on WSL2.

netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr

But here comes a new question:

The nodes which use TCPROS to communicate with each other have a random PORT every time I launch the file.

How can I handle this kind of problem? Or is there any information on the internet that I can have a look?

Thank you.

NotTheDr01ds
  • 15,620
  • 5
  • 44
  • 70
元哼黃
  • 87
  • 1
  • 4
  • Sorry, never noticed the edit to the question. It's usually better to ask a new question to make sure it gets noticed :-). @kraego's comment on my answer called my attention to it. Thinking about a possible solution -- Can your ROS tools (on the remote computer) be configured to use a SOCKS proxy? – NotTheDr01ds Oct 01 '21 at 19:01

1 Answers1

4

The root problem is described in WSL issue #4150. To quote from that thread,

WSL 2 seems to NAT it's virtual network, instead of making it bridged to the host NIC.

Option 1 - Port forwarding script on login

Note: From @kraego's comment (and the edited question, which I'm just seeing based on the comment), this is probably not a good option for ROS, since the port numbers are randomly assigned. This makes port forwarding something that would have to be dynamically done.

There are a number of workarounds described in that issue, for which you've already figured out the first part (the port forwarding). The primary technique seems to be to create a PowerShell script to detect the IP address and create the port forwarding rules that runs upon Windows login. This particular comment near the top of the thread seems to be the canonical go-to answer, although many people have posted their tweaks or alternatives throughout the very long thread.

One downside - I believe the script that is mentioned there needs to be run at logon since the WSL subsystem seems to only want to run when a user is logged in. I've found that attempting to run a WSL service or instance through Windows OpenSSH results in that instance/service shutting down soon after the SSH session is closed, unless the user is already logged into Windows with a WSL instance opened.

Option 2 - WSL1

I would also propose that, assuming it fits your workflow and if the ROS works on it (it may not, given the device access you need, but not sure), you can simply use WSL1 instead of WSL2 to avoid this. You can try this out by:

  1. Backing up your existing distro (from PowerShell or cmd, use wsl --export <DistroName> <FileName>
  2. Import the backup into a new WSL1 instance with wsl --import <NewDistroName> <InstallLocation> <FileNameOfBackup> --version 1

It's possible to simply change versions in place, but I tend to like to have a backup anyway before doing it, and as long as you are backing up, you may as well leave the original in place.

NotTheDr01ds
  • 15,620
  • 5
  • 44
  • 70
  • 2
    After trail and error, Option 2 is available; Option 1, since I am not that good on scripts, I need more time to learn and try it. It's a really helpful answer anyway. Thank you so much. (reference for Option2: https://winaero.com/export-import-wsl-linux-distro-windows-10/) – 元哼黃 Dec 14 '20 at 13:30
  • 1
    I've tried **Option1**, the problem with this is you can do that for the ports 80, 11311 (ROS). But as 元哼黃 mentioned: the problem is when you run roscore in WSL2 it will negotiate random ports for accessing topics (so you would have to do that for all ports). Option 2 is working for me ;-). Thank you very much. – Kraego Oct 01 '21 at 17:46
  • 1
    @kraego Good info. You are right that the use of random ports would make #1 much more challenging. I'll edit the answer with that info. Thanks! – NotTheDr01ds Oct 01 '21 at 18:44
  • @kraego I'm not familiar with ROS, but pretty good with WSL2 and networking in general. Question -- Do you know if your ROS tools on the other machine can use a SOCKS proxy? If so I might have an idea. – NotTheDr01ds Oct 01 '21 at 19:00
  • The other machine is a raspberry3 with ubuntu20.04LTS, which shares the wlan network with the windows10 machine. – Kraego Oct 01 '21 at 19:18
  • 1
    @kraego So we might tunnel or VPN the *entire* RaspberryPi over to the WSL2 instance, but it would be better if we could connect *just* specific programs (the ones you use for ROS). I did a search on *ROS socks proxy* and the [latest](https://answers.ros.org/question/159176/does-ros-support-proxy-connections-between-clientserver/) I came up with was from 7 years ago. If the tools have been updated to support SOCKS, then we could use that. If it matters, really, since you already have WSL1 working. – NotTheDr01ds Oct 01 '21 at 19:26
  • Thanks for your hints. But yes your right WSL1 is running and I’ve already spent too much time and effort in workarounds. Hopefully microsoft will implement a feature to fix this. – Kraego Oct 01 '21 at 19:46