Run Simulator SITL using pre-built Docker image with your GCS (MacOS/XQuartz tutorial)

UPDATE: please see @LuisVale comment about running natively within MacOS. I didn’t know this when I wrote the Docker image nor this tutorial. Hurray for better information! :slight_smile:

For MacOS we have several ground control GCS options including APM Planner 2 and QGroundControl, unfortunately neither offer in-built Simulator In The Loop (SITL) like the Windows-only Mission Planner.

Fortunately SITL can be run standalone from the ardupilot github project, and the GCS can automatically discover SITL. Unfortunately it is a relatively lengthy sequence of steps for MacOS users via Vagrant. For MacOS users I wrote up a Tutorial for running SITL Simulator on MacOS with Vagrant + XQuartz.

I wondered if it would be a nice UX for people to use Docker and a pre-built Docker image. And it sort of is nice. Except for the 3G+ size of the Docker image layers, which hopefully we can improve on in future.

To get started on MacOS, install Docker, and Xquartz.

To configure and run Xquartz, download the pre-built Docker image drnic/ardupilot-sitl, and run your favourite simulator robot:

HOST_IP=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}')
xhost + $HOST_IP

docker run -ti -e HOST_IP=$HOST_IP -e DISPLAY=$HOST_IP:0 \
  -v /tmp/.X11-unix:/tmp/.X11-unix -p 14550:14550 \
  drnic/ardupilot-sitl \
  Tools/autotest/ \
  --no-rebuild --console --map --out=$HOST_IP:14550 \
  -v APMrover2 -L Kingaroy

The first time you run docker run ... drnic/ardupilot-sitl ... it will download all the layers of the Docker image. This is currently 3G+. Sorry about that.

You should see two windows appear with the ArduRover simulator centered on Kingaroy airport. I can feel the speed already along that tarmac.

You can replace -v APMrover2 with -v ArduPlane, -v ArduCopter, -v Helicopter; and could replace -L Kingaroy with -L <location> from

Any tutorial in should “just work”.

You can pass the -h flag to the end and see the flag options, such as:


  -h, --help            show this help message and exit
  -v VEHICLE, --vehicle=VEHICLE
                        vehicle type (ArduCopter|AntennaTracker|APMrover2|Ardu
  -f FRAME, --frame=FRAME
                        set vehicle frame type
                        ArduCopter: octa-quad|cwx|singlecopter|gazebo-
                        AntennaTracker: tracker
                        APMrover2: rover|rover-
                        ArduSub: gazebo-bluerov2|vectored
                        ArduPlane: quadplane-
  -C, --sim_vehicle_sh_compatible
                        be compatible with the way works; make
                        this the first option
  -H, --hil             start HIL

SITL, whilst running inside Docker, still exposes MAVProxy to your local machine on port 14550.

This means you can now launch your GCS - APM Planner 2, QGroundControl, etc - and they should immediately connect to your simulator.

Very exciting. Our MacOS GCS has a locally running SITL.

The pre-built Docker image is currently a fork of upstream ardupilot, with the image regularly rebuilt from any changes to upstream (see Concourse CI pipeline).

Re-pull the image to get new SITL/ardupilot updates (about 300M update each time):

docker pull drnic/ardupilot-sitl

If you have any troubles with this tutorial or the Docker image please let me know below and I’ll try to resolve it or help you out. I enjoyed seeing SITL + GCS working over Docker/Xquartz and hopefully its useful to others.


You are aware that SITL runs natively on MacOS, so dispensing the need of Vagrant and XQuartz.

./Tools/autotest/ -v ArduCopter -f heli -L MyLocation

or if you want to do from master

cd ~/Ardupilot

 ./waf distclean

git submodule deinit -f. 

git clean -f-x -d 

git pull

git submodule update --init --recursive

./Tools/autotest/ -v ArduCopter -f heli -L MyLocation

which can be made on a simple script.


That is fabulous.

And I’ll acknowledge – I’m quite annoyed at myself that I never tried it over the last week just because it wasn’t explicitly mentioned in the docs. I’m quite the idiot :confused:


I went down the whole path of getting vagrant/xquartz working and then docker/xquartz. Damn.

But thank you very much for pointing this out; natively running is great.


Our bad at ArduPilot, for not keeping up documentation :slight_smile:

Reading thru it references the Tools/scripts/ -y script that I’ve seen in my Docker/Vagrant setups. I’m aware just how much stuff this script installs; and that it assumes ubuntu/debian. I didn’t seem to have to do this for MacOS. Do you know what the equivalent MacOS/homebrew dependencies are? I’ll look at writing a MacOS docs page.

All I get here on @LuisVale ./Tools commands is
Traceback (most recent call last):
File “./Tools/autotest/”, line 25, in
from MAVProxy.modules.lib import mp_util
ImportError: No module named MAVProxy.modules.lib

Are there dependancies missing or am I just missing something.

I’ll have to redo these instructions for Mojave, but you do have an equivalent script

check the script. it installs the dependencies.

Thanks for this. I hope it’s OK, I copied the first image to the top of the blog post. It means there are duplicate images but it also looks nicer when viewed from to have an image at the top.

1 Like

Have followed all this through and installed everything without error.

1 Like

I merged a patch fixing this earlier today…

the --user one ? Wasn’t required. Perhaps more important would be to move all the tools to python3 exclusively, and finish the mixed bag of required versions.

Tried following your guide, but it seems it cant find I’s that something that should be installed on the host, or am I missing something here?


$ docker run -ti -e HOST_IP=$HOST_IP -e DISPLAY=$HOST_IP:0 \
  -v /tmp/.X11-unix:/tmp/.X11-unix -p 14550:14550 \
  drnic/ardupilot-sitl \
  Tools/autotest/ \
  --no-rebuild --console --map --out=$HOST_IP:14550 \
  -v APMrover2 -L Kingaroy
SIM_VEHICLE: Killing tasks
SIM_VEHICLE: Starting up at -26.583528,151.840440,444,169 (Kingaroy)
SIM_VEHICLE: Using defaults from (/ardupilot/Tools/autotest/default_params/rover.parm)
SIM_VEHICLE: "/ardupilot/Tools/autotest/" "APMrover2" "/ardupilot/build/sitl/bin                /ardurover" "-S" "-I0" "--home" "-26.583528,151.840440,444,169" "--model" "rover" "--speedup" "1" "--defaults" "/ardupilot/Tools/autotest/default_params/rover.parm"
SIM_VEHICLE: "" "--master" "tcp:" "--sitl" "" "--out" "" "--out" "" "--out" "" "--map" "--console"
[Run MavProxy] An exception has occurred with command: ' --master tcp: --sitl --out --out --out --map --console'
[Errno 2] No such file or directory
SIM_VEHICLE: Killing tasks
RiTW: Starting APMrover2 : /ardupilot/build/sitl/bin/ardurover -S -I0 --home -26.583528,151.840440,444,169 --model rover --speedup 1 --defaults /ardupilot/Tools/autotest/default_params/rover.parm
Warning: This program is an suid-root program or is being run by the root user.
The full text of the error or warning message cannot be safely formatted
in this environment. You may get a more descriptive message by running the
program as a non-root user or by removing the suid bit on the executable.
xterm: Xt error: Can't open display: %s


To solve this error:

[Run MavProxy] An exception has occurred with command: ‘ --master tcp: --sitl --out --out --out --map --console’
[Errno 2] No such file or directory

I had to:
RUN pip install pymavlink MAVProxy
ENV PATH=$PATH:$HOME/.local/bin

To solve this problem:

xterm: Xt error: Can’t open display: %s

You should not be root to launch ArduPilot:
# Create the user “sitl”
RUN useradd --create-home --shell /bin/bash sitl && echo “sitl:sitl” | chpasswd && adduser sitl sudo && echo “sitl ALL=(ALL) NOPASSWD:ALL” >> /etc/sudoers
RUN usermod -a -G dialout sitl
USER sitl
WORKDIR /home/sitl
# Needed for

(These are Dockerfile commands)

Hello there, I’m looking for some help about using ArduPilot in Docker and simulate it with Gazebo-9 in my Jetson Nano, I couldn’t link them :confused: How should I define my ports in docker to make it able to see already working Gazebo.

TLDR: After my experimentation, this could save others some time. I would recommend ARM macs (e.g. M1, M2) to use docker to run Ardupilot SITL, instead of the native way if they need MAVProxy. If they don’t need MAVProxy, launch Ardupilot SITL natively and it will work.

I’ve tried to use ./Tools/autotest/ -v ArduCopter -f heli on an ARM Mac, but unfortunately this fails because it wants to use MAVProxy, which doesn’t install on ARM Macs. (Try pip install mavproxy)

  • I tried to install pip install libtiff and brew install libtiff, but MAVProxy still failed to build with fatal error: 'tiff.h' file not found #include "tiff.h". This is caused by WxWidgets failing to build/install.

You could disable MAVProxy: ./Tools/autotest/ -v ArduCopter -f heli --no-mavproxy, but I want to use MAVProxy :).

  • You need to pip install geocoder

Hi LuisVale, can SITL run natively on M1/M2 chip MacOS? I tried this script, doesn’t work.

Thank you