Port forward settings for QGC+SITL+Docker

I’m trying to connect an ardupilot SITL setup to QGroundControl (but this problem is pretty generic to any ground station). I can run this on the host machine:

cd ArduCoputer
sim_vehicle.py -w

...

SIM_VEHICLE: "mavproxy.py" "--master" "tcp:127.0.0.1:5760" "--sitl" "127.0.0.1:5501" "--out" "127.0.0.1:14550" "--out" "127.0.0.1:14551"
...

and QGC connects instantly (on UDP 14550). I can see packets being sent with sudo tcpdump -i lo -n udp port 14550 without the ground station connected.

I’ve now set this up to run in Docker, and I can get sim_vehicle running, but I’m struggling to figure out the port settings.

For example, if I run docker run -it -p 14550:14550/udp ardupilot (with an entrypoint to sim vehicle), SITL starts. If I try and connect, QGS complains:

"UDP Link Error" "Error binding UDP port: The bound address is already in use"

Similar error using pymavlink. I also can’t see any traffic using tcpdump.

I tested with a jupyter notebook server to check that I could port forward something (eg -p 8888:8888).

So I’m guessing this is something to do with how I’m forwarding UDP, but no idea why I’m not getting any traffic out. I’m running Kubuntu 19.04. Any advice is much appreciated, thanks!

This is the container, FYI:

FROM ubuntu:16.04
WORKDIR /ardupilot

RUN useradd -U -d /ardupilot ardupilot && \
    usermod -G users ardupilot

ENV USER=ardupilot

RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install --no-install-recommends -y \
    lsb-release \
    sudo \
    software-properties-common \
    git \
    python-software-properties && \
    apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# Passwordless sudo for ardupilot user
RUN echo "ardupilot ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/ardupilot \
    && chmod 0440 /etc/sudoers.d/ardupilot

RUN git clone https://github.com/ArduPilot/ardupilot $(pwd)
RUN cd /ardupilot && git submodule update --init --recursive

RUN chown -R ardupilot:ardupilot /ardupilot

# Assumes fixed install script
RUN bash -c "Tools/environment_install/install-prereqs-ubuntu.sh -y && apt-get install gcc-arm-none-eabi -y" && \
    apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

USER ardupilot

ENV CCACHE_MAXSIZE=1G
ENV PATH /usr/lib/ccache:/ardupilot/Tools:${PATH}
ENV PATH /usr/lib/ccache:/ardupilot/Tools/autotest:${PATH}
ENV PATH /ardupilot/.local/bin:$PATH

# Build SITL/Copter
RUN ./waf configure --board sitl
RUN ./waf -j8 copter

EXPOSE 14550/udp
EXPOSE 14551/udp
EXPOSE 5760

ENTRYPOINT cd /ardupilot/ArduCopter && sim_vehicle.py -w --no-rebuild --console

Seems like one fix[1] is to use --no-mavproxy, port forward 5760, and then connect using mavproxy on the host:

Terminal 1: mavproxy.py --master=tcp:127.0.0.1:5760 --out=udp:0.0.0.0:14550
Terminal 2: docker run -it -p 5760:5760 ardupilot
Terminal 3: launch QGC

Maybe I’m misunderstanding how mavproxy works, but I still don’t understand why forwarding UDP from the container directly is failing. The SITL is publishing mavlink messages on tcp:5760, and nominally mavproxy connects to that (--master) and republishes over UDP?

[1] https://github.com/radarku/sitl-swarm/blob/master/startArdu.sh