Introduction: ROS Robot With Lego EV3 and Docker

What is this robot capable of?

Using this instructable, you will be able to remote control a Lego EV3 robot using your PC keyboard. In my next instructable you will be able to move it by clicking on a 3D map. You will also be able to view a simulation of the robot on your PC.

This is the first step towards more impressive projects. ROS provides hundreds of packages for all kinds of robotics applications: SLAM (Simultaneous Localization And Mapping), speech, language / image recognition, ...

My goal it to build an autonomous robot that can fetch a ball and avoid obstables. This will be the subject of other instructables.

What is ROS?

ROS is an open-source, meta-operating system for your robot. It provides the services you would expect from an operating system, including hardware abstraction, low-level device control, implementation of commonly-used functionality, message-passing between processes, and package management.

ROS is used by researchers, hobbyists and industrials.

What is Docker?

Docker containers wrap a piece of software in a complete filesystem that contains everything needed to run: code, runtime, system tools, system libraries – anything that can be installed on a server. This guarantees that the software will always run the same, regardless of its environment.

Why Docker ?

ROS runs best on Linux, but you might not want to install linux on your computer. You can install docker on your Windows, Mac OS or Linux PC, and you will then be able to run the docker containers that I prepared for you with all the required ROS packages. This will save a lot of time, and you will be able to tweak the Dockerfiles (a kind of recipe that lists all the instructions) to suit your needs.

Step 1: What You Need

  • Lego EV3 Mindstorms 31313
  • microSD card with at least 2GB
  • Wifi dongle that can work on the EV3, such as the EDIMAX EW-7811Un
  • Wifi router - you can use your Internet provider's router
  • PC or Mac
  • Ethernet cable to connect your PC to your internet router - it won't work over Wifi
  • PC Keyboard

Step 2: Make the Robot

Use the following instructions:

You do not necessarily need to build the arms and helmet, you can stop at page 74 (step 41)

Step 3: Install ROS on the EV3 Brick


Follow these instructions until and including 'Wireless setup':

Change your Wifi router settings to make sure that the IP address of the EV3 brick will always remain the same.

  • On a Virgin Media router go to: , then 'Advanced settings', 'DHCP Reservation', select the ev3dev, click on 'Add Reservation' and 'Apply'

Apply patch

We need to apply this patch:

dpkg -i *.deb
rm *.deb

Step 4: Install Docker

docker engine

Follow the appropriate instructions depending on your platform:


Follow these instructions:

Step 5: Setup Docker Files

1) On your computer, clone or download my github repository:

2) Edit rosev3/gripp3r/docker-compose.yml

This file describes the docker containers and network that we are going to start:

  • a docker network named 'rosnet'. It uses macvlan to make the containers look as is if they were separate machines on the local network. For this to work you have to use an ethernetcable to connect to your router. Most wifi cards are incompatible with macvlan because they cannot be put in promiscuous mode. You might need to change the name of the ethernet interface. On my Ubuntu laptop it is enp0s25, but it might be different on your platform.
  • a container named 'master', which runs roscore. See for more information.
  • a container named 'robot', which runs the launch files for the robot. The launch files declare nodes that will communicate with the 'ev3_manager' program on the EV3 brick. There is one launch file for the motors and one for the infrared controller. Feel free to inspect these files and the associated config file. You can find more information about their meaning here: and here:
  • a container named 'teleop' which runs the teleop node. It will allow us to send 'Twist' messages using the keyboard. More information on topics and Twist here:

Now change the ip addresses according to your router's settings:

  • Determine your router's IP address. In most cases it will be or
  • If your router's IP is different from mine, replace everything starting with 192.168.0 with your router's prefix address, for instance 192.168.1
  • You can see that the robot node and teleop nodes have a fixed IP address. If by any chance you already have other devices with the same address you will need to change them to an unused IP to avoid clashes.

3) Edit rosev3/master/docker-compose.yml

  • Change the IP address of the master node in the same was as above.
  • Change the IP address of the EV3 brick in the 'extra_hosts' section. It was automatically allocated by your router in step 2

4) Edit /etc/hosts on the EV3 brick

Using ssh, edit the hosts file so that the EV3 brick can communicate with the other nodes using their name. The file should like this:       ev3dev.localdomain      localhost     ev3dev    master    robot

Step 6: Run

1) Run the startup script on your PC to start the master node

~/rosev3/gripp3r$ ./
Creating network "gripp3r_rosnet" with driver "macvlan"<br>Creating master
Please start ev3_manager on ev3
Press any key to continue...

2) Connect to EV3, make sure that ROS_IP is set correctly

$ ssh root@ev3dev
root@ev3dev:~# ros_ip_set wlan0
ROS_IP set to wlan0 with IP

3) Run the controller manager on the EV3

root@ev3dev:~# ev3_manager
getFilePTR opening: /sys/class/tacho-motor/motor0/position 0xb0c70<br>getFilePTR opening: /sys/class/tacho-motor/motor0/speed 0x7d688
getFilePTR opening: /sys/class/tacho-motor/motor1/position 0x13aea8
getFilePTR opening: /sys/class/tacho-motor/motor1/speed 0x13b010
getFilePTR opening: /sys/class/tacho-motor/motor2/position 0x13b178
getFilePTR opening: /sys/class/tacho-motor/motor2/speed 0x13b2e0

3) On the PC, press any key to continue running the script

The script will run the robot controller node and the teleop node

Press any key to continue... Creating robot<br>the rosdep view is empty: call 'sudo rosdep init' and 'rosdep update'

Reading from the keyboard  and Publishing to Twist!
Moving around:
   u    i    o
   j    k    l
   m    ,    .

For Holonomic mode (strafing), hold down the shift key:
   U    I    O
   J    K    L
   M    <    >

t : up (+z)
b : down (-z)

anything else : stop

q/z : increase/decrease max speeds by 10%
w/x : increase/decrease only linear speed by 10%
e/c : increase/decrease only angular speed by 10%

CTRL-C to quit

currently:    speed 0.5    turn 1

4) On the EV3, you should see the following output:

Port: in4<br>Mode: proximity
Publish rate: 10
getFilePTR opening: /sys/class/lego-sensor/sensor0/driver_name 0xb4a7b818
Str No: 0:lego-ev3-color
Str No: 1:lego-ev3-gyro
Str No: 2:lego-ev3-ir<---
Driver Name: 4
Range Mode Setup!
[ INFO] [1492105925.627802900]: Controller Change
getFilePTR opening: /sys/class/lego-sensor/sensor0/mode 0x13c818
getFilePTR opening: /sys/class/lego-sensor/sensor0/num_values 0x1277b8
getFilePTR opening: /sys/class/lego-sensor/sensor0/value0 0x127920
[ INFO] [1492105973.190347530]: Controller state will be published at 10Hz.
[ INFO] [1492105973.322766691]: Wheel separation will be multiplied by 1.
[ INFO] [1492105973.417211894]: Wheel radius will be multiplied by 1.
[ INFO] [1492105973.517104381]: Velocity commands will be considered old if they are older than 0.5s.
[ INFO] [1492105973.602212924]: Base frame_id set to base_link
[ INFO] [1492105973.656389292]: Publishing to tf is enabled
[ INFO] [1492105974.528557814]: Odometry params : wheel separation 0.148, wheel radius 0.01725
[ INFO] [1492105974.747566410]: Adding left wheel with joint name: Joint_B and right wheel with joint name: Joint_C
[ INFO] [1492105975.243133421]: Controller Change
[ INFO] [1492105975.284316193]: velocity_controllers/JointVelocityController requests Joint OutPortA Joint_A
getFilePTR opening: /sys/class/tacho-motor/motor0/command 0x129eb0
[ INFO] [1492105975.388328099]: <--------------EV3 Joint Joint_A---------------->
[ INFO] [1492105975.452792518]: Joint control mode: velocity
[ INFO] [1492105975.568053679]: P: 1000  I: 60   D: 0
[ INFO] [1492105975.594953917]: 
[ INFO] [1492105975.626518843]: ----------------------------------------------<
[ INFO] [1492105975.656511828]: PID 1000 60 0
getFilePTR opening: /sys/class/tacho-motor/motor0/speed_pid/Kp 0x12a0d0
getFilePTR opening: /sys/class/tacho-motor/motor0/speed_pid/Ki 0x129ba8
getFilePTR opening: /sys/class/tacho-motor/motor0/speed_pid/Kd 0x66500
[ INFO] [1492105975.751428230]: diff_drive_controller/DiffDriveController requests Joint diffDrv Joint_B
getFilePTR opening: /sys/class/tacho-motor/motor1/command 0x66398
[ INFO] [1492105975.838143075]: <--------------EV3 Joint Joint_B---------------->
[ INFO] [1492105975.930534411]: Joint control mode: velocity
[ INFO] [1492105976.054176139]: P: 1000  I: 60   D: 0
[ INFO] [1492105976.088151155]: 
[ INFO] [1492105976.117844438]: ----------------------------------------------<
[ INFO] [1492105976.152354831]: PID 1000 60 0
getFilePTR opening: /sys/class/tacho-motor/motor1/speed_pid/Kp 0x66668
getFilePTR opening: /sys/class/tacho-motor/motor1/speed_pid/Ki 0x667d0
getFilePTR opening: /sys/class/tacho-motor/motor1/speed_pid/Kd 0x66b88
[ INFO] [1492105976.244125969]: diff_drive_controller/DiffDriveController requests Joint diffDrv Joint_C
getFilePTR opening: /sys/class/tacho-motor/motor2/command 0x66cf0
[ INFO] [1492105976.351341620]: <--------------EV3 Joint Joint_C---------------->
[ INFO] [1492105976.423235320]: Joint control mode: velocity
[ INFO] [1492105976.610330285]: P: 1000  I: 60   D: 0
[ INFO] [1492105976.630306156]: 
[ INFO] [1492105976.674217783]: ----------------------------------------------<
[ INFO] [1492105976.707111028]: PID 1000 60 0
getFilePTR opening: /sys/class/tacho-motor/motor2/speed_pid/Kp 0x66938
getFilePTR opening: /sys/class/tacho-motor/motor2/speed_pid/Ki 0x66e58
getFilePTR opening: /sys/class/tacho-motor/motor2/speed_pid/Kd 0x129d10

4) On the PC, press the I, J, K, L keys to move the robot

Enjoy !

Step 7: Shutdown

1) On the PC, stop the docker containers

Ctrl-C, then

$ dc down
Stopping robot ... done<br>Stopping master ... done
Removing robot ... done
Removing master ... done
Removing network gripp3r_rosnet

2) On the EV3, shutdown the brick

Ctrl-C, then

root@ev3dev:~# shutdown<br>

Step 8: Next Time

In my next instructable I will show you how to use RViz to teleoperate the robot by clicking on a 3D Map.