Robotics on WSL2 using ROS, Docker and Unity 3D (Part I)
Tags: robotics, wsl, unity3d, ros
Published: 2021-03-15 18:23:04

Have you ever wanted to just be able to write code on Windows but with the familiar tools you always use at work on your Linux station? Have you ever wanted to be able to just close your Cyberpunk 2077 quest and start tinkering with your latest robot project in ROS? 

I have always developed under Linux but I recently decided to leverage my Windows laptop for my coding projects. I do occasionally game and use graphic applications so I did not really want to move to Linux and I was super lazy to partition the hard drive. Moreover lots of tools for sensors or robots are developed for Windows only and it's often inconvenient to switch back and forth.

I decided to give a try to the new Windows WSL feature. For those who don't know, [WSL](https://medium.com/r/?url=https%3A%2F%2Fdevblogs.microsoft.com%2Fcommandline%2Fannouncing-wsl-2%2F) is a Windows feature which allows you to have a running Linux image in your Windows Desktop. Yes you heard correctly! No more need to partition your drive! 
In this article I will go through how I set up my old laptop to run some cool robotics simulation. 

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a7qwfj6gynx0e6ru4p6q.png)
 
Let's dive right into it!

## Setup WSL (the right one!)
WSL is under quite some development and there are actually 2 versions around. The latest version [WLS2](https://medium.com/r/?url=https%3A%2F%2Fdevblogs.microsoft.com%2Fcommandline%2Fannouncing-wsl-2%2F) has much better support for GPU hardware and docker than its predecessor. To install WSL2 you need to have a developer preview of Windows which you can conveniently install from your Windows Update. After joining https://insider.windows.com/en-us/getting-started and updating your Windows to the latest build, follow the steps below
https://docs.microsoft.com/en-us/windows/wsl/install-win10
Once done, choose your Linux distribution and set it up the way you like. I chose Ubuntu 20.4.

Finalize by setting up your display in WSL2. Add this to your *~/.bashrc*

```
export DISPLAY="`grep nameserver /etc/resolv.conf | sed 's/nameserver //'`:0"
export LIBGL_ALWAYS_INDIRECT=1
```

*Note: In reality, I had a pretty hard time updating my outdated Windows version to the latest build. Updates kept on failing with weird reasons and I had to manually turn off several services for some updates to be installed. Good luck!*

## GPU & Docker
For the sake of this demo, having a working GPU is not necessary, however, if you have one, I strongly encourage you to setup your WSL system to use it so you will be ready to move your robot to the deep learning world. If you do not have a GPU skip to the Docker Only section. 

*Note: when installing Docker, use the same hard drive of the WSL installation or you will notice an extremely slow Docker building or running.*

### NVIDIA Docker
To setup GPU support for WSL2 follow the instructions as reported from the NVIDIA official page. https://docs.nvidia.com/cuda/wsl-user-guide/index.html. This guide will first help you to setup WSL2 for your CUDA drivers and then help you setup your Docker installation with CUDA support. You can stop at Simple CUDA Containers.

After the installation, if you are having troubles with permissions, make sure you set them up properly. Usually you have missed running this command

```sudo usermod -aG docker $USER```

*Note: This Docker installation differs from Docker Desktop which is a similar initiative from the Windows developers. If you have Docker Desktop installed you might have hard time getting the Nvidia Docker installation to work. I have tried to use Docker Desktop but did not manage to get my GPU running even though the Windows developers claim it's ready (https://www.docker.com/blog/wsl-2-gpu-support-is-here/).*

### Docker Only (No GPU)
If you do not have a GPU I strongly recommend you to install Docker Desktop as it's very simple and can be done directly from Windows with a couple of clicks. https://docs.docker.com/docker-for-windows/install/

## Last important adjustments
While setting up the rest of this tutorial I had lots of WTF moments which I listed below.

#### Firewall ([Github issue](https://github.com/microsoft/WSL/issues/5338))
WSL2 and Windows do not communicate through the same network interface but through a virtual network. WSL2 and Windows each share a different IP which you can see through the ifconfig. That said, I realized that Windows was blocking incoming connections from WSL2 and I had to add an exception to the firewall to allow ROS to communicate with Unity. [How To] (https://www.howtogeek.com/394735/how-do-i-open-a-port-on-windows-firewall/)

#### Time sync ([Github issue](https://github.com/microsoft/WSL/issues/4149))
WSL2 and Windows time will easily drift causing both systems to have different time. Some people experienced high discrepancies, however, I had only few seconds difference. Nonetheless, those few seconds were enough to cause ROS to reject the messages incoming from Unity. To fix the issue I have setup a continuous sync in WSL2.

We will go ahead and let WSL2 sync from Windows time each 10 minutes.

```sudo crontab -e ```
Then add the following line
```10 * * * * ntpdate time.windows.com```

#### Service startup
WSL2 does not support system.d or any sort of service start.  Among many different ways, I have chosen the simplest one to make it happen (https://www.how2shout.com/linux/how-to-start-wsl-services-automatically-on-ubuntu-with-windows-10-startup/)

Add the following lines to your /etc/sudoers file

```
%sudo ALL=(ALL) NOPASSWD: /usr/sbin/service docker *
%sudo ALL=(ALL) NOPASSWD: /usr/sbin/service cron *
```

Then go to your Windows search bar and type *Run* and inside it type ``` shell:startup ``` 

It will open a folder. Inside it, create a file *wslservices.bat* with this content

```
wsl.exe sudo service docker start
wsl.exe sudo service cron start
```

You can add other services if required.

## Conclusions
You are now setup to work with WSL2 and do software development using the convenience of Linux while keeping your Windows system running! I have used this setup for other projects related to deep learning and it's extremely convenient if you like me don't like swapping OS often. 

[Continue to Part II](https://dev.to/szandara/robotics-on-wsl2-using-ros-docker-and-unity-3d-part-ii-4l45) where we will setup our demo to use Unity and ROS over WSL2 and Docker.