When you work with an Unmanned Surface Vessel (USV) (our little boats for example), the part that actually drives it is a piece of software called the autopilot. On our boats that software is ArduPilot, a mature open-source project with almost twenty years of development behind it and the most widely used autopilot software in the world. It normally runs on a small dedicated board called a flight controller, tucked inside the vessel. The usual choice is a Pixhawk; that name is a whole family of these boards rather than a single product, and ours are the common Pixhawk 2.4.8. Some sensors are built into the board itself, an accelerometer and a gyroscope that sense acceleration and turning, while others plug in around it, mainly a GPS unit (a u-blox NEO-M8N) that fixes the boat's position and also carries the compass that gives its heading.
ArduPilot's job is everything between what you ask for and what the motors do. At its heart is a fast loop that repeats many times per second: read the sensors, combine their readings into a best estimate of where the boat is, which way it is pointing, and how fast it is moving, compare that estimate with what it has been asked to do (hold a heading, reach a point on the map, follow a planned route), and adjust the motor and rudder outputs to close the gap. On top of that loop sit the operational rules you will spend most of this lab meeting: driving modes, missions, arming, and failsafes, the automatic reactions to trouble such as a lost connection or a low battery.
Software In The Loop, almost always shortened to SITL, is ArduPilot's simulation build: the same software, compiled not as firmware for a flight controller but as an ordinary program that runs on your laptop. The trick is where the simulation is spliced in. The program contains the whole autopilot, unchanged, plus a small physics model that stands in for the real world. Instead of reading real sensors, ArduPilot is fed readings invented by that model, and instead of turning real motors, its outputs push the model's virtual boat around; the boat's new position then produces the next round of invented sensor readings. The control loop closes entirely inside software, which is exactly what the name means.
Everything above that swap is the real thing: the same code that runs on the Pixhawk in your kit, making the same decisions, with the same driving modes, missions, and failsafes, commanded through the same MAVLink protocol, just on a network port instead of a cable. Nothing you connect to it, Mission Planner or your own Python, can tell whether the boat behind the messages is real or simulated. And since a simulated boat is just a program, you can start several of them at once; we will do exactly that near the end of this lab. (SITL exists, by the way, because of the automated-testing culture you just read about: the developers needed a way to exercise every change on virtual vehicles before it went anywhere near a real one.)
One honest caveat before we move on. "The same code" does not mean that moving from the simulator to a real boat is a blind copy. On real water your commands travel over a wireless link that can lag or drop, sensors are noisy, batteries drain, and a mistake costs more than a restart. The logic you build and test in SITL genuinely carries over, that is the whole point of it, but the step onto a real vessel is taken deliberately: failsafes checked, imperfect communications expected, safety margins added. Keep that in the back of your mind for when the real boats come out.
Before we install it, ArduPilot's origin story is worth two minutes, because it is a genuinely great one.
In 2007, a 20-year-old Mexican immigrant named Jordi Muñoz was stuck at home in Riverside, California. He was waiting months for his green card, so he could not legally work or enroll in college. To fight the boredom, he started tinkering with radio-controlled helicopters in his garage. He wanted an autopilot to stabilize them but could not afford one, so he cracked open a Nintendo Wii controller, salvaged its motion sensors, wired them to an Arduino (a cheap hobbyist microcontroller board), and wrote the code to make his toy helicopter fly itself.
He posted his progress, code and videos included, on a brand-new forum called DIY Drones. The forum's founder turned out to be Chris Anderson, at the time the editor-in-chief of Wired magazine. Anderson was so impressed that he mailed a $500 check to a young man he had never met, with no conditions attached, just to keep him building. The project became known as ArduPilot (Arduino + autopilot), and in 2009 the two co-founded the drone company 3D Robotics, Jordi handling the engineering (at first literally baking circuit boards in a toaster oven) and Anderson the business. The company went on to raise over $100 million and was for a while the largest consumer drone maker in North America.
Through all of that, the software itself stayed open source, and that is the part that matters for us. Developers around the world grew it far beyond its hobby roots, into the family you can pick from today: ArduCopter, ArduPlane, ArduSub, and the ArduRover flavor you will run on your boats. One of those contributors, Andrew Tridgell (already famous as the author of rsync and Samba, tools most Linux machines carry to this day), brought serious automated testing to the project, and out of that work came the SITL simulator you are about to install. 3D Robotics eventually moved on to enterprise software, but ArduPilot lives on as an independent open-source project, and today it drives, flies, and sails more than a million vehicles.
So the autopilot you are installing is not a stripped-down teaching tool. It is the real thing, born in a garage, raised by a worldwide community, and it is yours for free.
Whatever you use to drive the boat, you are talking to the same autopilot underneath, and there are a few different ways to do that. You will meet most of them across these labs:
arm or
mode GUIDED.We lean on the console here because it is direct, it makes what is happening easy to see, and it comes with the simulator with nothing extra to install. The boat does not care which tool a command comes from, so the skills carry in every direction: what arming means, what each driving mode does, and how a mission is built are the same whether you click them in Mission Planner, type them in the console, or send them from Python. Only the buttons differ.
Under the hood, all of these tools talk to the autopilot in the same digital language, a protocol called MAVLink. You do not need to know its details yet, but the name will keep coming up. If you have written networked software before, the shape is familiar: the autopilot acts like a server, and every tool above is just another client sending it requests.
Running on your laptop instead of on the water buys you a lot:
This matters even more for boats than for most vehicles. Sea trials are expensive and depend on the weather, and a boat that misbehaves in open water can be genuinely hard to recover. Practicing in simulation first means you arrive at the water already knowing how the autopilot reacts.
This lab is short and ArduPilot can do far more than we could cover in one sitting. That is on purpose. The goal is not to teach you everything; it is to get SITL installed and working on your laptop, give you a confident first tour, and leave you with a tool that is now yours. Once it is set up it stays on your machine for the rest of the summer school and well beyond, ready whenever you want to experiment further at your own pace, with no hardware required.
One last thing: treat these notes as a tested, best-effort guide rather than the final word. We have walked through them step by step to verify and correct them, but SITL is a big field and the exact behaviour can shift with your operating system, software versions, and hardware, so the odd small difference or rough edge is possible. If something does not match what you read here, it is usually a difference in your setup rather than a mistake on your part. This page also gets updated over time, so you can always come back for the latest version.
On the real boats, the autopilot does not work alone. A small companion computer, a Raspberry Pi, rides alongside it running Python code that talks to the autopilot: reading its telemetry (the live data the boat reports back, such as position, speed, heading, and battery; the word means "measurement from a distance"), sending it commands, and coordinating with other boats or a shore station over a network. SITL lets you develop and test that kind of Python code on a single laptop, with the simulator standing in for the whole boat. That is exactly what Lab04 does, and it builds directly on the SITL environment you set up here. In short, this lab lays the foundation, and the next one puts code on top of it.
SITL simulates the autopilot, its navigation sensors, and the boat's motion, and it does this faithfully. It does not simulate everything. There is no simulated camera and no computer vision, for example, so something like visual obstacle detection cannot be tested here directly. For this lab that is no limitation at all: you will be driving the boat and running missions, which SITL models well. (Other simulators such as Gazebo or AirSim can add visual detail, at the cost of a much heavier setup; ArduPilot's SITL is the simplest and most direct way in, which is why we use it.)
Over the next few hours you will:
By the end you will have a working simulator you understand and own, ready to carry into the rest of the summer school.
The goal of this section is to get a Linux environment ready on your machine, because ArduPilot's SITL is built and run on Linux. What you do depends on your operating system. Most of you are on Windows, so that is the path we cover in most detail.
Windows cannot build SITL directly, so you run a real Ubuntu Linux inside Windows using a built-in feature called WSL2 (Windows Subsystem for Linux, version 2). Your Ubuntu lives alongside Windows and shares its files and network, and that is where everything in this lab happens. The full official instructions are here if you ever need them: https://ardupilot.org/dev/docs/building-setup-windows.html.
On an up-to-date Windows 10 or Windows 11 with administrator rights (the normal case for a personal laptop), installation is straightforward:
Open Windows Terminal (or PowerShell) as administrator: right click it in the Start menu and choose "Run as administrator".
Run:
wsl --install -d Ubuntu-24.04This turns on the needed Windows features and installs Ubuntu 24.04. Reboot when it asks you to.
[Jun26 note]: We name the version on purpose. A
plain wsl --install now installs the newest Ubuntu (26.04
stable, published two months ago), which is so fresh that some of the
tools this lab needs are not ready for it yet, so the install takes
longer and hits avoidable snags. Ubuntu 24.04 is the tested, smooth
path, so we ask for it by name.
After the reboot, Ubuntu usually finishes setting itself up on its own and asks you to create a Linux username and password.
On some machines nothing opens after the reboot: that first command only turned on the Windows features, and Ubuntu itself still needs to be installed. If that happens (for example, the Start menu shows no Ubuntu app), open Windows Terminal as administrator again and run the same command once more:
wsl --install -d Ubuntu-24.04This time it downloads and installs Ubuntu, then asks for the username and password.
When prompted, create a Linux username and
password. Pick any you like. This password is for Linux's
sudo (the command that runs admin tasks inside Ubuntu); it
is separate from your Windows login. You will not see anything on screen
as you type it, which is normal.
You now have an Ubuntu terminal. From here on, unless we say otherwise, commands are typed in Ubuntu, not in Windows.
No administrator rights? Rare on a personal laptop, but if the one-command install is blocked, someone with admin rights has to enable the WSL features first. The official guide linked above covers that case step by step.
SITL opens a map and a status window, so your Ubuntu needs to be able to show graphical (GUI) programs on your Windows desktop. On Windows 11 this works out of the box through a feature called WSLg; on some setups, most often Windows 10, it needs one extra tool. Rather than guess from your Windows version, just test it.
In the Ubuntu terminal, install a tiny test program and run it:
sudo apt update && sudo apt install x11-apps
xeyes(Enter your Linux password when asked, and press Y to
approve the install.)
If a small window with a pair of eyes that follow your mouse
pointer appears on your desktop, graphical apps work. Close it
and move on to the next section. If nothing appears after a few seconds
(most common on Windows 10), do the one-time setup just below, then run
xeyes again to confirm.
This step is almost always Windows 10 only; if xeyes
already worked, skip it.
The piece that lets Linux draw windows on your screen is called an X server. Windows 11's WSLg already includes one; older setups do not, so you add one called VcXsrv.
~/.bashrc file (the file that runs each time you open
an Ubuntu terminal):
export DISPLAY=$(grep -m 1 nameserver /etc/resolv.conf | awk '{print $2}'):0source ~/.bashrc, or just close and
reopen the Ubuntu terminal.xeyes again. The window should now appear.You only add the ~/.bashrc line once, but VcXsrv
has to be running whenever you launch SITL, so start it
(through XLaunch) at the beginning of each session.
SITL builds and runs on macOS too, but the setup is different: it uses the Homebrew package manager and a few extra steps. Follow ArduPilot's official macOS guide: https://ardupilot.org/dev/docs/building-setup-mac.html. Once SITL is built, the running and driving parts of this lab are exactly the same.
If your computer already runs Ubuntu (or a similar Linux), you do not need WSL2 or an X server; you are ready for the next section. We tested on Ubuntu; other distributions work too but may need small adjustments.
Now you get ArduPilot's source code and compile SITL from it. This is the longest part of the setup. The download is around 2 GB and the build works your processor hard for several minutes, so before you start: make sure your laptop has plenty of battery (use a power plug if one is within reach, but above all do not start this on a nearly empty charge) and use a stable internet connection. Then let it work; it is normal for this part to take a while.
Everything here is typed in the Ubuntu terminal.
First make sure git (the tool that downloads the code) is installed, then clone the ArduPilot repository into your home folder:
sudo apt update
sudo apt install git
cd ~
git clone --recurse-submodules https://github.com/ArduPilot/ardupilot.git
cd ~/ardupilot--recurse-submodules matters: ArduPilot is split across
many smaller sub-libraries, and this pulls them all in together. The
download is sizeable and can take a few minutes on a slow connection.
(You may also see guides mention an apt upgrade or some
optional GUI tools. Neither is needed for this lab; only git is
essential, and the next script installs the rest.)
A fresh clone leaves you on the master branch, which is
the latest development code and can be unstable. For the lab we pin a
tested, stable release instead.
git describe --tagsThis shows where you are. On master it prints a long
string like ArduPilot-4.6.0-beta1-7164-gc3a03439be, which
just means "far ahead of the last release." Now switch to the stable
Rover release and re-sync the sub-libraries:
git checkout Rover-4.6.3
git submodule update --init --recursiveRover-4.6.3 was the latest stable version as of
mid-2026; to check whether a newer one exists, run
git tag -l 'Rover-4.*' | sort -V | tail. After the
checkout, git warns that you are in a "detached HEAD" state: that is
normal and just means you are sitting exactly on a release rather than
on a branch.
The second command is important. Switching the main code does not automatically move the sub-libraries, so this re-syncs them to the exact versions that shipped with Rover-4.6.3. Skipping it is a common cause of strange build errors later.
Confirm the switch:
git describe --tagsYou should now see a short tag rather than the long development
string. Do not be thrown if it reads
APMrover2-stable instead of
Rover-4.6.3: ArduPilot keeps a moving "stable" tag that
sits on the very same commit, and git just happens to report that name.
You are on the right code either way.
ArduPilot ships a script that installs everything else the build needs, both system packages and Python tools. Run it, then reload your shell settings so the new tools are available:
Tools/environment_install/install-prereqs-ubuntu.sh -y
source ~/.profileThis is the step that takes a while and works the computer hardest.
The -y answers "yes" to its prompts. (It also installs a
toolchain for building real flight-controller hardware, which SITL does
not need but which does no harm.)
Only on very recent Linux (Ubuntu 25.04 or newer, including 26.04): the script bundled with the 4.6.x release does not recognise these brand-new Ubuntu versions and fails, with errors like
Unable to locate package python-argparseor a "PEP 668 externally-managed-environment" pip error. If that happens, replace just that one script with the up-to-date version from ArduPilot's development branch, then re-run the two commands above:git checkout origin/master -- Tools/environment_install/install-prereqs-ubuntu.shWindows students will not hit this. The command above installs Ubuntu 24.04, which the bundled script already supports. This only affects very recent native-Linux installs.
When it finishes, your terminal prompt should start with
(venv-ardupilot). That is a Python virtual environment (an
isolated set of Python tools) the script created for ArduPilot, and
SITL's launch command and its Python libraries live inside it. The
script also arranges for this environment to activate automatically each
time you open a new Ubuntu terminal, so normally you do not have to
think about it: if the prompt starts with (venv-ardupilot),
you are ready.
If you ever open a terminal where that prefix is missing, or a later
command such as sim_vehicle.py comes back as "command not
found", it just means the environment was not loaded. The simplest fix
is to close that terminal and open a fresh one; if you would rather
reload it in place, run source ~/.profile. And if you ever
want to step out of the environment on purpose, type
deactivate.
Run these from inside ~/ardupilot (the folder you cloned
into), with the (venv-ardupilot) prefix showing. If you
opened a new terminal since the prereq step, the prefix comes back on
its own, but new terminals start in your home folder, so
cd ~/ardupilot first.
Two commands: the first sets up the build for the simulator, the second compiles the Rover code.
./waf configure --board sitl
./waf roverconfigure is quick and ends with
Configure finished successfully. The build itself takes
several minutes and ends with
'rover' finished successfully. While it runs you will see a
long stream of yellow warnings scroll past; those are not errors, so let
them be and watch the [ n/1299 ] counter climb. The
finished simulator lands at build/sitl/bin/ardurover.
| After running | You should see |
|---|---|
git describe --tags (after the checkout) |
a short tag such as APMrover2-stable |
source ~/.profile |
the prompt now starts with (venv-ardupilot), and
which sim_vehicle.py finds it |
./waf rover |
'rover' finished successfully, and the file
build/sitl/bin/ardurover exists |
With the build finished and the environment loaded, you are ready to start the simulator for the first time.
Once the build has finished, you are almost ready to start the simulator. First we set up two things the launch command needs, a boat-specific settings file and a named starting location, and then we make a folder to run from. The setup you only do once.
Boat settings file. Make a working folder and create a parameter file inside it:
mkdir -p ~/maritime26/custom-parms
cd ~/maritime26/custom-parms
nano boat.parmnano is a simple text editor in the terminal; use any
editor you like. Put these two lines in the file:
FRAME_CLASS 2
BATT_CAPACITY 30000
FRAME_CLASS 2 is the important one: it tells Rover to
behave as a boat rather than a car. BATT_CAPACITY 30000
sets the simulated battery to a large 30,000 mAh. We are not testing
battery life in the simulator, so we make it deliberately large: the
battery then stays comfortably full through a long run, instead of
draining down and nagging you with low-battery warnings part way through
a mission. (A "parameter" is just one of ArduPilot's many settings; this
file holds the few we want to change, and the launch command loads them
on top of Rover's defaults.) In nano, save and exit with Ctrl-O, Enter,
then Ctrl-X.
Starting location. ArduPilot keeps a list of named
places in a file called locations.txt. Open it and add our
spots at the very end, leaving everything already in the file
untouched:
nano ~/ardupilot/Tools/autotest/locations.txtAppend:
# Syros, Nisaki area
Syros=37.439322,24.945616,0.1,180
# Piraeus, port of Athens (a second example; the format works for any place)
Piraeus=37.9435,23.6472,0.1,90
Each line is name=latitude,longitude,altitude,heading.
Syros is the one we launch with next; Piraeus
is just a second example to show the format works for any place. The
heading is the compass direction the boat faces at start, in degrees,
where 0 is north and 90 is east. (We add a few more points near Syros
later, in the multi-vehicle section.)
Why the altitude is 0.1 and not 0. Our boats sit at
sea level, so you would expect 0. But there is a known bug in the firmware:
when the home altitude is exactly 0, ArduPilot keeps
re-setting its ground-height reference to 0 about once a second and
floods the console with Field Elevation Set: 0m messages
the whole time the boat is disarmed. It is harmless, but it buries every
other message. Giving the home a tiny non-zero altitude like
0.1 (ten centimetres, far too small to matter) sidesteps
it: you see the Field Elevation Set message once at
startup, then quiet. (Other ArduRover users have run into the same thing
in SITL; see this ArduPilot forum
thread.)
Make a separate folder to run the simulator from and move into it:
mkdir -p ~/maritime26/sitl-test
cd ~/maritime26/sitl-testThis matters more than it looks. When SITL runs, it drops several working files into whatever folder you start it from, so a dedicated folder keeps them in one place you can clear out between runs, instead of scattering them through the ArduPilot source code. After a session the folder typically holds:
eeprom.bin: the boat's memory; the settings you have
changed and the mission you uploaded live here (more on this one just
below).logs/: the autopilot's own flight logs, the same "black
box" recordings a real boat keeps.mav.parm: a plain text snapshot of all the boat's
settings, written by MAVProxy; handy to search when you wonder what a
value is.mav.tlog and mav.tlog.raw: recordings of
all the telemetry that flowed between the boat and MAVProxy. Mission
Planner can replay a .tlog later, like a video of the
session.All of them are safe to delete when you want a truly clean start; the
simulator recreates what it needs. Deleting eeprom.bin, or
launching with the -w flag described below, is exactly how
you reset a boat that keeps remembering old settings.
Now start it:
sim_vehicle.py -v Rover -L Syros --out=udp:127.0.0.1:14550 \
--add-param-file=$HOME/maritime26/custom-parms/boat.parm \
--map --consoleThe very first launch builds the vehicle code if it has not been built already, so it can take a while. After that it starts quickly. You may see some red text scroll past as it comes up; the troubleshooting section covers which of those messages are harmless. When it is ready, two windows open: a map, and a console showing the boat's status.
The map downloads its satellite imagery online as you look around. If a few tiles read "unavailable" at first, zoom out a little or pan the map and they fill in. That is just the imagery service catching up, not a problem with the boat or your setup.
sim_vehicle.py: the script that starts
everything. It builds the autopilot if needed, launches the simulator,
and connects MAVProxy to it. (MAVProxy is the command line ground
station that the simulator starts for you; it is the program you type
commands into.) You can run this script from any folder, because the
installer added its location to your PATH, the list of folders your
shell searches for programs. You do not need to be inside the ArduPilot
folder.
-v Rover: the vehicle type to simulate.
ArduPilot comes in several versions, one each for multirotors (Copter),
planes (Plane), underwater vehicles (Sub), and ground vehicles and boats
(Rover). Rover is the one we want, and this flag is what
makes the simulator build and run the ardurover program and
load Rover's baseline settings.
If you leave -v out, the script tries to guess the
vehicle from the name of the folder you are standing in. That is why
some older instructions had you move into the Rover source
folder first and then skip this flag. Since we run from our own
sitl-test folder instead, that guess would fail, so
-v Rover has to be given here. Writing it out also makes
the command clearer to read.
-L Syros: the starting location.
ArduPilot keeps a list of named places with their coordinates, and
Syros is one we added for this course. The name is case
sensitive, so -L syros in lower case will not be found. The
boat appears at this spot on the map when the simulator starts.
--out=udp:127.0.0.1:14550: sends a copy
of the boat's live data to a ground station on this same computer
(127.0.0.1 means "this same computer"). MAVProxy's own map
and console do not need it, but Lab04's Python reads the boat here, so
we include it from the start. How other ground stations like Mission
Planner connect, including the WSL case, is covered just below.
--add-param-file=$HOME/maritime26/custom-parms/boat.parm:
loads an extra settings file on top of Rover's defaults. This
is where the boat specific settings live, such as the one that tells
Rover to behave as a boat (FRAME_CLASS=2). Use
$HOME here rather than the ~ shortcut. The
~ is not expanded inside this option and would give you a
"file not found" error, while $HOME works.
--map: opens a map window showing the
boat's position, the path it has travelled, and any waypoints (points
along a planned route). You can also right click on the map to send the
boat somewhere, which we use in the next section.
--console: opens a separate status
window showing the boat's mode, whether it is armed (ready to move), its
GPS fix, its battery, and a running list of messages. You still get a
text command prompt in the terminal you launched from either way; this
window just adds a cleaner view of the boat's state next to it.
The boat remembers, and -w resets it.
Between runs the simulated boat keeps its state in a small file called
eeprom.bin, saved in the folder you launch from: every
setting you change from the console or a ground station, and any mission
you upload, survive a restart. Mostly that is convenient, but the
remembered values also win over the settings files in the launch
command, so if a setting refuses to change no matter what you edit, an
old remembered value is usually the reason. The fix is simple: add
-w to any launch command in this lab, with or without the
weather file or -f motorboat, to wipe that memory and start
the boat fresh from the settings files. Launch with it once, then leave
it out again.
The map and console MAVProxy gives you are enough for everything in this lab, so you can begin with those. If you want a fuller ground station, connect one now. On Windows, including when the simulator runs in WSL, use Mission Planner, the tool from Labs 01 and 02. On native Linux or macOS, where Mission Planner is not available, use QGroundControl instead, which supports Rover.
How the boat reaches a ground station. A ground
station listens on port 14550, and SITL sends the boat's
live data to that port. The only question is which computer it
goes to, and SITL handles most of this for you. On native Linux or macOS
it sends to 127.0.0.1, which just means "this same
computer", so a ground station on the same machine finds the boat on its
own. Inside WSL it detects WSL and also forwards the data across to the
Windows side, so Mission Planner finds it with no Windows address to
look up, as long as WSL is in its normal networking mode. (The
--out=udp:127.0.0.1:14550 in your launch command adds one
more copy on "this same computer"; that is the copy Lab04's Python reads
later, so it does no harm to keep it in from the start.)
Mission Planner (Windows or WSL). Install it first if you have not; the install note is in section 7. Then open Mission Planner, set the connection box at the top right to UDP, click Connect, and accept port 14550. (Recent versions may do this step for you: Mission Planner starts listening on port 14550 on its own, so if the boat is already on the map when you open it, it has connected by itself and there is nothing more to click.) The first time, Windows Firewall asks whether to let Mission Planner use your networks; allow it and tick both Private and Public (the data arrives over a virtual network adapter Windows may treat as either kind, so allowing only one can silently block it). The parameters load and the boat appears on the map.
If the boat does not appear: check the firewall first, the usual
culprit (Control Panel → Windows Defender Firewall → Allow an
app through firewall → find Mission Planner
and tick both Private and Public);
make sure the connection really is UDP on port
14550, not serial or TCP; and as a last resort send the
data to Windows by hand. Find your Windows address with
ip route show default | awk '{print $3}', then at the
simulator's console prompt add it as an extra output, no restart
needed:
output add <that-address>:14550
This keeps the 127.0.0.1:14550 copy that Lab04 reads and
adds the path to Windows alongside it.
QGroundControl (native Linux or macOS). It usually
connects on its own: start the simulator, open QGroundControl, and it
finds the boat on port 14550. If it stays on
"Disconnected", add the link by hand: click the
Disconnected text at the top, open Comm
Links, choose Add, set the Type to
UDP and the Port to 14550, give it a
name, Save, then select it and
Connect. The boat appears on the map.
You have already driven the real boat by hand: the joystick paired to its receiver, the thrusters turning, maybe a first run in the pool. SITL is the same idea on screen. It lets you rehearse how the boat behaves and try commands out safely, before trusting them on the water. The part it is especially good for is the part that is hardest to do by hand: telling the boat to go to a point on its own, and later running a whole route by itself. That is where we spend our time here, and it carries straight into Lab04, where Python sends the boat these same commands.
The console is the text window where you type commands to the boat. (It is part of MAVProxy, the small ground station the simulator started for you.) Two commands you will use constantly:
arm throttle: arms the boat, meaning
it is now allowed to move. Nothing drives until the boat is armed.disarm: disarms it again, so it is
safe and will not move.You switch between modes by typing mode
followed by the mode name, for example mode GUIDED. A mode
is just a way of driving: who is in control, and how. The next part puts
this to use.
GUIDED mode is the one to start with. In GUIDED you point at a spot and the boat works out how to get there on its own. You do not need a joystick, which is why it makes the best first test in the simulator.
Type these in the console, one line at a time:
mode GUIDED
arm throttle
If arming is refused, wait a few seconds for the simulated GPS to
settle, then try arm throttle again.
Now right-click on the map at a spot near the boat and choose
Fly to. It will ask for an altitude; type
1 and press Enter. (The "Fly to" wording and the altitude
question are there because the same map is also used for flying drones.
A boat ignores altitude entirely, so the value does not matter; we use
1 because it is the one value every ground station accepts,
Mission Planner included, whose altitude box refuses 0 and
decimals like 0.1.)
The boat should turn towards the point and drive to it, drawing its path on the map as it goes. When you are done, send it home and disarm:
mode RTL
disarm
RTL means Return To Launch: the boat drives back to where it started.
On a boat it does not stop dead on arrival; it gently holds or circles
around the launch point (more on that below). If disarm is
refused because the boat is still moving, wait until it has settled,
then try again.
That is the whole loop you will repeat through the lab: pick a mode, arm, command the boat, watch it on the map, return and disarm.
To read the boat's live numbers at any time, type
status VFR_HUD in the console. On a boat, watch
groundspeed for speed, heading for
direction, and throttle for motor effort; the
airspeed field just mirrors groundspeed (a boat has no
airspeed sensor), and alt and climb
stay near zero on the surface.
ArduPilot has many modes; you only need a handful here. The
boat-specific behaviour below depends on one setting we already loaded,
FRAME_CLASS=2, which tells ArduPilot it is driving a boat
rather than a land vehicle.
| Mode | What it does | For a boat |
|---|---|---|
| GUIDED | Go to a point you give it, in real time | The main mode we use; also how Python commands it in Lab04 |
| AUTO | Run a saved mission of waypoints by itself | Covered in section 7 |
| RTL | Return to the launch point | Holds or circles around home instead of stopping |
| LOITER | Actively hold position | Works the motors to stay put against wind and current |
| HOLD | Stop and let the motors idle | The boat drifts with wind and current; rarely useful at sea |
| MANUAL | Direct stick control | The sim version of the hand-driving you already did; see below |
| ACRO | Stick sets turn rate, holds heading when centred | Advanced hand-driving; not needed here |
| STEERING | Autopilot holds heading, you set the speed | Occasional assisted driving |
| CIRCLE | Drive a circle around a point | Survey or station-keeping patterns |
| SMART_RTL | Return home by retracing the path it came | Useful in harbours to dodge obstacles; advanced |
Three of these are worth a closer look, because a boat behaves differently from a land rover:
GUIDED is the workhorse. You give it a destination and it drives there, correcting for drift along the way. Right-clicking the map uses GUIDED, and so does Lab04: its Python drives the boat by sending one destination after another in GUIDED. Running a whole pre-planned route on its own is the job of a different mode, AUTO, which we meet with missions in section 7.
LOITER versus HOLD is the key maritime difference. HOLD just stops the boat and lets the motors go idle. On land a rover then sits still, but a boat with idle motors drifts off with the wind, waves, and current. LOITER instead keeps the motors working to hold the boat on its spot, so it stays where you left it even in a current. To hold position on the water, use LOITER, not HOLD.
RTL brings the boat back to where it started. A land rover would simply stop there, but a boat would drift, so instead it holds or circles around the launch point to stay put. This "keep your position after you arrive" behaviour is automatic once the vehicle is set up as a boat, and it applies in AUTO, GUIDED, and Smart RTL as well (see the ArduPilot RTL mode and Loiter mode docs).
You will notice we never drive manually in the simulator. That is on purpose. Manual driving needs a joystick, and the radio link from a joystick to the boat is its own kind of signal, separate from MAVLink, the digital language the simulator and your Python scripts speak. There is a way to fake stick input over MAVLink in SITL, but it is fiddly and we do not use it. You have already done the real manual driving on the actual boat with its joystick, so in the simulator we focus on the digital commands instead. (If there is time later, connecting a real joystick to a ground station on the PC is something we can experiment with, but it is not part of the lab.)
Two quick checks confirm the setup is sound, which matters because Lab04's Python will rely on both.
Confirm the data link Python will use is open:
output list
This should list 127.0.0.1:14550, the address we send
the boat's data to in the launch command. On WSL you will also
see a second line for your Windows host; that is SITL
forwarding the data across to Windows, and it is normal.
Confirm the boat settings loaded:
param show FRAME_CLASS
param show BATT_CAPACITY
FRAME_CLASS should read 2 (the boat
setting) and BATT_CAPACITY should read 30000
(the large battery we set so the sim does not nag about low charge). You
can check any other parameter the same way.
Once the boat launches with its map and console, drives where you send it, and shows these settings, your simulation environment is fully installed and ready for the rest of the lab.
In section 5 the water was calm: the boat went exactly where you pointed it. Real sea trials will not be so kind. Around Syros and the rest of the Cyclades, summer brings the Meltemi, a strong, dry wind out of the north that kicks up steep waves and drags a surface current along with it. (It is also called the Etesian wind; see Wikipedia for the meteorology and this sailing guide for what it feels like on the water.) In this section we let the simulator fake those conditions, so you can watch the modes from section 5 work against weather before you ever put a real boat in the water.
Up to now we launched with the plain Rover model. It is light and
predictable, which is exactly what you want while learning the modes,
but it has one limit: it knows nothing about water, so wind, waves, and
currents do not touch it. For this section we switch to the simulator's
motor boat model, which floats, rocks on the waves, and
gets carried by a current. You turn it on by adding
-f motorboat to the launch command, shown below. This is
the only part of the lab that needs the water physics; everywhere else
we stay on the plain model.
One honest point about the wind itself. A motor boat has no sail, so in the simulator the wind does not push the boat directly. What a small powerboat actually feels in a Meltemi is the current the wind drives, which carries the boat, and the waves it raises, which rock it. So we recreate the Meltemi through those two effects rather than as a wind force.
Make a second parameter file next to boat.parm:
nano ~/maritime26/custom-parms/meltemi.parmPut these lines in it:
# The Meltemi, recreated as the two things a motor boat actually feels:
# a surface current that carries the boat, and waves that rock it.
# Surface current: about 1.5 m/s (3 knots), setting from the north, so flowing south.
SIM_TIDE_SPEED 1.5
SIM_TIDE_DIR 0
# Sea state: rocks the boat for realism; it does not move the boat anywhere.
SIM_WAVE_ENABLE 1 # turn wave simulation on
SIM_WAVE_AMP 1.5 # 1.5 m wave height
SIM_WAVE_LENGTH 20 # 20 m between crests
SIM_WAVE_SPEED 6 # waves travel at 6 m/s
SIM_WAVE_DIR 0 # waves coming from the north
Every line starts with SIM_, which means it lives only
inside the simulator; a real autopilot on a real boat has no such
settings and ignores them. The current is the part that moves the boat:
SIM_TIDE_DIR 0 means it sets from the north, so the water,
and anything floating in it, drifts south at
SIM_TIDE_SPEED, here 1.5 m/s. The waves only rock the boat;
they make the sim feel like a real sea but do not carry the boat. Both
the current and the waves take effect only once the boat is
armed.
(For the curious: the simulator does have a wind setting,
SIM_WIND_*, but on this motor boat it does nothing, because
there is no sail for the wind to act on. We leave it out so it does not
look like the wind is moving the boat; the current is what does
that.)
A note on realism: the 1.5 m/s current here is on the strong side, picked so the drift and the crabbing are easy to see rather than a barely noticeable nudge. A current driven purely by wind is only a small fraction of the wind speed, so even a strong Meltemi would move the open-sea surface at maybe half a metre per second, not 1.5. Currents this strong are real in the region, though: the narrow channels between the islands squeeze and speed up the flow. The Kafireas Strait off southeastern Evia, which sailors call the Cavo d'Oro, is notorious for its fierce wind and water, and closer to Syros the straits around Tinos and Mykonos and the Paros to Naxos channel can run strong too. So think of our 1.5 m/s as a busy strait on a rough day, not the calm open sea off Syros.
Start the simulator as in section 4, but add
-f motorboat to switch to the boat model, and a second
--add-param-file line for the weather:
sim_vehicle.py -v Rover -f motorboat -L Syros --out=udp:127.0.0.1:14550 \
--add-param-file=$HOME/maritime26/custom-parms/boat.parm \
--add-param-file=$HOME/maritime26/custom-parms/meltemi.parm \
--map --consoleThe files stack: boat.parm carries the boat settings
from before, and meltemi.parm adds the weather on top. To
go back to flat calm, launch without the meltemi.parm line;
to go back to the plain, weather-free boat, drop the
-f motorboat part as well.
Arm the boat, then run the same modes from section 5 and watch them work harder. (Remember that the current and waves only act once the boat is armed.)
The motor boat also rocks on the waves, which shows up nicely on the Mission Planner attitude display and makes the whole thing feel much closer to a real boat at sea. The rocking is for realism; it does not move the boat.
This is the closest the simulator gets to a real day on the water in the Cyclades, and it is a safe place to learn how each mode copes before a real sea trial.
So far you have driven the boat one move at a time: in GUIDED you pointed at a spot and it went there, and you did the same by hand on the real boat. A mission is the next step up. Instead of commanding one point at a time, you plan a whole route in advance, a list of points the boat should visit in order, and then hand it over: the boat drives the route on its own, from start to finish, with no further input from you. This is the autonomous part of the lab, and it is the same idea Lab04 builds on when Python sends the boat its instructions.
The mode that runs a saved route is called AUTO. The boat needs two things before it will go: a mission loaded into it, and to be armed and switched to AUTO. With both in place, it sets off immediately.
So everyone starts from the same route, we give you a ready-made
mission, simple_nisaki.txt. You create it the same way you
made the parameter files earlier. Open a new file in your missions
folder:
nano ~/maritime26/missions/simple_nisaki.txtPaste in these lines exactly, then save with Ctrl-O and exit with Ctrl-X:
QGC WPL 110
0 1 0 16 0 0 0 0 37.439322 24.945616 0 1
1 0 3 16 0 0 0 0 37.438300 24.945386 0 1
2 0 3 16 0 0 0 0 37.437200 24.945046 0 1
3 0 3 16 0 0 0 0 37.436100 24.944596 0 1
The first line is a required label, and each line after it is one point in the route. Do not worry about what the numbers mean yet; we break the format down just below. The columns can be separated by spaces or tabs, so an ordinary copy and paste is fine.
Start the simulator the usual way from your run folder
(~/maritime26/sitl-test), then load the mission in the
console:
wp load ../missions/simple_nisaki.txt
wp is the console's mission command, and
wp load reads a mission from a file. The
../missions/ part is a relative path: you launched from
sitl-test, so .. steps up one level to
maritime26, then down into missions. We keep
mission files in their own folder, separate from the run folder, so the
run folder's throwaway files do not mix with routes you want to
keep.
Check it loaded:
wp list
You should see 4 items, numbered 0 to 3. Item 0 is the home point and items 1 to 3 are the places the boat will visit. Now run it:
mode AUTO
arm throttle
The moment it is armed in AUTO with a mission loaded, the boat sets off to the first point on its own. Watch the map: it drives out to point 1, turns and continues to point 2, then point 3, each a little further from the start, then holds its position at the final point. Holding rather than stopping is the maritime behaviour from sections 5 and 6: a boat with idle motors would drift, so it keeps station instead. If arming is refused, wait a few seconds for the GPS to settle and try again.
When you have watched it finish, bring it home and stop:
mode RTL
disarm
One handy detail: disarming resets the mission back to the start, so to run it again you just arm once more in AUTO. You do not need to reload the file.
A few console commands cover everything you need:
| Command | What it does |
|---|---|
wp load <file> |
Load a mission from a file |
wp list |
Show the mission currently loaded |
wp clear |
Remove all waypoints (use with care) |
You do not need to understand the file to run the mission, but it is
worth a quick look so you are not copying numbers blindly. Open
simple_nisaki.txt in a text editor. The first line is
always:
QGC WPL 110
This is a label that says "this is a QGroundControl waypoint list, file format version 110." It has to be the first line. After it, each line is one point in the route, written as 12 values separated by tabs, always in the same order:
| Column | Field | Meaning |
|---|---|---|
| 1 | Index | Order number: 0, 1, 2, and so on |
| 2 | Current | 1 marks the active point, 0 the rest (handled for you) |
| 3 | Frame | Height reference: 0 is absolute, 3 is relative to home |
| 4 | Command | What to do here: 16 means "go to this point" |
| 5 | Param1 | Hold time at the point, in seconds (0 means do not wait) |
| 6 to 8 | Param2 to 4 | Extra options a boat ignores for a plain point |
| 9 | Latitude | How far north or south |
| 10 | Longitude | How far east or west |
| 11 | Altitude | Height relative to home; 0 for a boat on the surface |
| 12 | Autocontinue | 1 to roll straight on to the next point, 0 to stop and wait |
Apart from the sample you just pasted in, you will not normally write these by hand. A ground station writes the file for you when you click points on a map (more on that just below); we show the format so you can read a mission file and make small edits with confidence. For a simple "visit these points" route like ours, the only columns you would ever change are the command (16), the latitude, and the longitude, with hold time and autocontinue as occasional extras. Everything else stays as you see it.
Two small things you may notice. Item 0 is the home point, but the autopilot ignores its coordinates and uses your real launch position instead, so its latitude and longitude are only a placeholder. And the altitude column is 0 on every line: a boat drives on the surface, so height does not apply, and 0 here means "the same level as home."
If you want the full detail, these are the authoritative references:
Loading a ready-made file is fine for a first run, but the skill you actually want is building a route yourself, and the easiest way to do that is to draw it on a map. We use Mission Planner for this, the Windows ground station you met in Labs 01 and 02. It is also the tool you will use to plan missions on the real boats, so the practice here carries straight over.
Installing it. When you install Mission Planner it
asks permission to install some device drivers; allow this, it is safe
and expected (those drivers let it talk to real autopilots over USB).
The first time you open it, it may also offer aviation extras like an
Altitude Angel airspace and air-traffic service, or a
Remote ID / Drone ID plugin (a regulatory "license
plate" broadcast for real drones). We only use Mission Planner with
simulated boats, so you can skip or disable both; Ctrl-P
manages plugins.
Connect Mission Planner. Connect it to the simulator exactly as in section 4: set the connection to UDP and accept port 14550, allowing it through Windows Firewall the first time (both Private and Public). The boat appears on the map and you are ready to plan. If it does not show up, see the connection troubleshooting in section 4.
Draw the route. Click the PLAN tab. Left-click on the water to drop waypoints one after another; each appears as a numbered marker and as a row in the table below. The table's altitude defaults to 100 and the frame to Relative; a boat ignores altitude, so leave both as they are. To finish with the boat returning home, right-click the map and choose RTL, which adds a return-to-launch as the final step. When the route looks right, click Write to upload it to the boat. (Save File writes the mission to a file you can reuse, and Load File reads one back in.)
Run it. Switch to the DATA tab and open the Actions sub-tab at the bottom. Click Arm/Disarm to arm, then click Auto. The boat sets off through your waypoints on the map. RTL brings it home, and Restart Mission runs the route again from the start.
Use one tool at a time. Mission Planner and the
console window are two separate ground stations. Each keeps its own copy
of the mission, and they only match up when you push or pull:
Write sends Mission Planner's mission to the boat, and
Read pulls the boat's mission back into Mission
Planner. So do not plan in one and check in the other. If you build a
mission in Mission Planner, run the whole loop there. As an example of
the trap: clearing the mission with wp clear in the console
does not update Mission Planner's map until you press
Read. To clear a mission inside Mission Planner,
right-click the map and choose Clear Mission.
You can also draw a mission in the console itself, by right-clicking its map and choosing Mission then Draw, but it is fiddlier and the points only reach the boat after a final click, so for building missions we recommend Mission Planner. On native Linux or macOS, where Mission Planner is not available, QGroundControl's Plan view builds and runs missions in the same way.
Everything above ran in calm water. You can put a mission through the
Meltemi weather from section 6 just as easily: launch with the
meltemi.parm line added, then load and run the same
mission. Watch it work harder. The boat angles into the current to stay
on the line between points, takes longer to get there, and holds the
final point more actively against the drift. It is the same route, now
tested against the kind of conditions a real sea trial would throw at
it.
Sending a mission from your own Python code, rather than loading it in the console, is exactly what Lab04 is about. The route you just ran by hand is the same thing your companion-computer code will build and command there.
The companion-computer projects in Lab04 coordinate several boats at once, ending with a worked example of a coordinated formation: boats following others on their own. Those projects are exactly that, examples. Their job is to give you a basic understanding and a working setup to build on, so you can then run your own experiments, trying ideas like holding a formation or splitting an area between the boats to survey it faster. To rehearse running more than one boat here, we start two or more SITL boats at the same time and watch them together on one map.
More starting points. In section 4 we added
Syros to locations.txt. So the boats do not
all spawn on the exact same spot, add three more points just south-west
of it (each about 20 m further along the shore). Open the file
again:
nano ~/ardupilot/Tools/autotest/locations.txtAppend:
Syros2=37.439142,24.945389,0.1,180
Syros3=37.438962,24.945162,0.1,180
Syros4=37.438782,24.944935,0.1,180
Each boat is a separate copy of the simulator, run from its own terminal and its own folder, just like the single boat in section 4 but with a few extra flags so the copies do not clash.
You already made a sitl-test folder for the first boat.
Make a second one for the second boat:
mkdir -p ~/maritime26/sitl-test2Each boat needs its own folder, because the simulator writes its memory file and logs into the folder it starts from, and two boats sharing one folder would overwrite each other's files.
We also run the boats this time without the
--map and --console windows. Each boat's own
map works perfectly well, but you get a separate window for every boat,
and none of them can show more than its own boat. Mission Planner
instead puts every boat on one map at once, which is what we want for
watching several boats together. You still get a text command prompt in
each terminal for sending that boat its own commands.
Boat 1, in the first terminal, is just the section 4 command with the two window flags removed:
cd ~/maritime26/sitl-test
sim_vehicle.py -v Rover -L Syros \
--add-param-file=$HOME/maritime26/custom-parms/boat.parm \
--out=udp:127.0.0.1:14550Boat 2 needs four changes, which we explain here and then put together with the networking part in the next section:
--instance 1: run this as a second, separate simulator.
Without it, the second boat would try to grab the same network ports as
the first and fail to start. Each instance moves its ports up by ten, so
instance 0 uses 14550, instance 1 uses 14560, and so on.--sysid 2: give this boat the identity number 2. Every
boat on the network needs a different system id so Mission Planner can
tell them apart. The first boat is 1 by default; without a different id
here, both boats would claim to be boat 1 and Mission Planner would
merge them.-L Syros2: start it at the second location you added,
so it does not appear on top of boat 1.--out: the line that actually gets boat 2
into Mission Planner, covered next.In section 4 you saw that inside WSL the simulator sends the first boat across to Windows by itself, so Mission Planner finds it on port 14550 with no setup. It does the same for every extra boat, but with a catch: each instance is sent to its own port. Instance 0 goes to 14550, instance 1 to 14560, instance 2 to 14570, and so on. Mission Planner listens on only one port, 14550, so only the first boat lands there by itself. The others arrive on ports nothing is listening on.
The fix is to send each extra boat a second time, explicitly, to
Windows on port 14550, so it reaches Mission Planner alongside boat 1.
That is the extra --out on boat 2.
Which address you aim it at depends on your WSL networking:
ip route show default | awk '{print $3}'172.20.160.1. (Do not use the address from
/etc/resolv.conf; on recent WSL that is an internal DNS
helper, not your Windows machine.)127.0.0.1
and skip the lookup. It is not on by default; you only have it if you
switched it on yourself in .wslconfig. If you did not, use
the NAT option above.So boat 2's full launch, on a default WSL2 setup, is (put
your own address in place of 172.20.160.1):
cd ~/maritime26/sitl-test2
sim_vehicle.py -v Rover --instance 1 --sysid 2 -L Syros2 \
--add-param-file=$HOME/maritime26/custom-parms/boat.parm \
--out=udp:127.0.0.1:14560 --out=udp:172.20.160.1:14550The first output, 127.0.0.1:14560, keeps a copy on this
computer for your Lab04 Python to read later. The second,
172.20.160.1:14550, is the one aimed at Windows so Mission
Planner sees the boat.
Check it before opening Mission Planner. In boat 2's
terminal, type output at the prompt. Your Windows address
on port 14550 should be in the list. If instead you see a line ending in
:14550 with no address in front, the address did not fill
in; add it on the spot without restarting:
output add 172.20.160.1:14550
Now connect Mission Planner, once. Set the
connection to UDP, connect on port 14550, and both boats appear, listed
by their system ids 1 and 2, with a selector to switch the view between
them. You do not open a second connection: both boats share the one port
and Mission Planner separates them by id. (You may also see a third
entry in the selector ending in 255-ALL. That is not a
boat; 255 is the identity number ground stations themselves use on the
network. Ignore it and pick the boats by their ids.)
For a third boat, repeat the pattern with a new folder,
--instance 2, --sysid 3,
-L Syros3, and the same explicit
--out=udp:<your-windows-address>:14550.
With several boats running you will want to command one at a time. There are two ways in: point-and-go driving on a map, and mission or mode commands in each boat's own console.
Driving a specific boat. Point-and-go means clicking
a map, and there are two ways to do it. You can give a boat its own
MAVProxy map by adding --map when you launch it, then
right-click that map to send just that boat; for two or three boats this
is perfectly workable, it is only one more window each. Or you can drive
from Mission Planner: the selector at its top right sets which boat your
commands go to, so pick a boat by its system id, right-click the map,
choose Fly to, and that boat drives to the point while the others stay
put.
One quirk worth repeating here, because it looks like a failure when
it is not: use 1 for the Fly-to altitude, as in section 5.
Mission Planner's altitude box is fussy on a boat: a 0
makes it quietly send nothing, so the boat sits there and looks like it
is refusing the command, and a decimal like 0.1 is rejected
outright. Any whole number of at least 1 works, and the value itself
does not matter, since a boat ignores altitude. The box is extra easy to
get wrong because it shows the frame as "Relative", which makes
0 feel like the natural answer for a boat that should stay
where the water is; 0 is exactly the value that quietly
does nothing. Note also that Mission Planner stops asking once it has a
value it accepts: later Fly-tos reuse that value without showing the
question again, which is fine once the value is 1.
Why Mission Planner is our main window. Its real strength with several boats is that it shows them all on one map at once. That single shared view is what makes a multi-boat run easy to follow, and it is exactly what you want for watching a formation, the kind the later Lab04 projects build toward. Separate MAVProxy maps, one per boat, cannot give you that combined picture, and they pile up as boats are added. That is why we launched the boats without their own maps and let Mission Planner be the one window onto the whole group.
Missions and mode changes go in the boat's own console. Each boat has its own command prompt, in the terminal you launched it from, and anything you type there reaches only that boat, so there is no way to command the wrong one by accident. (Mission Planner can do these too, from its Actions tab, on whichever boat the selector holds; the console is simply the surer path with several boats running, and it reads your mission file directly from the Linux side.) This is the place for arming, switching modes, and running a saved mission. For example, to run a mission on boat 2, type these at boat 2's prompt (any mission file works; the one from section 7 is fine):
wp load ~/simple_nisaki.txt
mode auto
arm throttle
Boat 2 sets off through the waypoints while boat 1 stays where it is. That independence is the whole point, and it is exactly how the Lab04 Python projects drive several boats at once: each script talks to its own boat on its own port, the same idea as each boat having its own console here.
One thing to avoid: MAVProxy has a form of output that filters by
system id (output sysid ...). It has a long-standing bug
that can cut off control of all the boats at once, so do not use it. The
plain second --out we used above is the reliable way.
Most of what looks like an error in SITL is not one. This section sorts the harmless noise from the real problems and points you to the fix for each, and it covers how to stop the simulator cleanly.
To stop the simulator, press Ctrl-C in the
terminal where you launched it. That is the normal way to shut
it down. You may see a short red error traceback as it exits; that is
harmless, just the program tearing itself down.
If you are running several boats (section 8), press
Ctrl-C in each boat's own terminal the same way.
Rarely, a simulator is left running in the background even after that, and a later launch complains that an address or port is already in use. Only then do you need to clear the leftover by force:
pkill -f arduroverA running simulator prints a lot of text, and some of it looks alarming without being a problem. The common harmless ones:
Failed to download /SRTM3/filelist_python ... at
startup. The simulator is trying to fetch terrain elevation data (SRTM
is a global map of ground heights). Our boat is on the sea, where ground
height does not matter, so this is safe to ignore.Field Elevation Set: 0m printed over and over, about
once a second, while the boat is disarmed. This is the firmware quirk
from section 4. Seeing it once at startup is normal. If it keeps
repeating, your starting location's altitude is set to 0;
change it to 0.1 (see section 4) and it stops.got COMMAND_ACK: REQUEST_AUTOPILOT_CAPABILITIES: FAILED,
repeating every 20 seconds or so while Mission Planner is connected.
Mission Planner keeps asking the boat for its version details in a
slightly out-of-spec way, and the boat declines each time. Nothing is
affected; ignore it.finished successfully, you are fine.| Symptom | What is happening | What to do |
|---|---|---|
The map and console windows never open (and the xeyes
test did not work either) |
Your system cannot display Linux graphical apps yet | Set up the display first; see section 2 (the xeyes
test, and VcXsrv on Windows 10) |
The map window opens, then crashes with an error mentioning
cv2 or numpy |
OpenCV and NumPy are out of step, on some older setups only | See "If the map will not open" below |
arm throttle is refused |
The autopilot's pre-arm safety checks have not passed yet, often the simulated GPS still settling | Wait a few seconds and try again. In the simulator only, you can
switch the checks off with param set ARMING_CHECK 0 (never
on a real boat). See section 5 |
| The boat never shows up in Mission Planner or QGroundControl | The ground station is not receiving the boat's data | Check the connection; see section 4: UDP on port 14550, the Windows host address on default WSL, and the firewall allowed on both Private and Public |
sim_vehicle.py: command not found, or a Python module
is reported missing, or the build failed |
The build environment is incomplete or not loaded | Run source ~/.profile; your prompt should then show
(venv-ardupilot). If it still fails, re-run the
prerequisites and rebuild; see section 3 |
| A launch complains an address or port is already in use | An earlier simulator is still running | Run pkill -f ardurover (see "Stopping the simulator"
above) |
| Downloads time out or crawl during install | The clone, the prerequisites, and the map tiles all need internet | Check your connection and retry. Map tiles that read "unavailable" fill in when you pan or zoom; see section 4 |
Permission denied when the simulator writes its
files |
You are running from a folder you do not own | Run from a folder under your home directory, such as
~/maritime26/sitl-test as section 4 sets up |
| The MAVProxy map window freezes, especially with several boats running | A known fragility of the MAVProxy map on WSL's graphics, mostly with more than one simulator | Run multi-vehicle headless, with one Mission Planner as the single viewer; see section 8. A single boat's map is fine |
On some older setups the map window crashes on startup with an error
mentioning OpenCV and NumPy. These are two helper libraries the map
viewer uses, one for images (OpenCV, imported in Python as
cv2) and one for maths (NumPy). The crash happens when the
versions of the two are out of step with each other. On current setups
this almost never happens, so do not touch anything unless you actually
see it.
If, and only if, your map fails to open and the error names
cv2 or numpy, pin them to a known-good
pair:
pip install opencv-python==4.9.0.80 numpy==1.26.4If that command refuses to install, with pip saying there is no matching version, your Python is newer than those old releases support, which also means it is new enough not to need this fix. Leave the libraries alone; your map problem is something else, most likely the display setup in section 2.
A one-page reminder of the commands from this lab; each block points back to the section with the full explanation. Everything in the console blocks is typed into the MAVProxy console, the text window you launched the simulator from.
cd ~/maritime26/sitl-test
sim_vehicle.py -v Rover -L Syros --out=udp:127.0.0.1:14550 \
--add-param-file=$HOME/maritime26/custom-parms/boat.parm \
--map --consoleTo run it in the Meltemi weather (section 6), add a second parameter file to the command:
--add-param-file=$HOME/maritime26/custom-parms/meltemi.parm| Command | What it does |
|---|---|
arm throttle |
Allow the boat to move |
disarm |
Lock the motors, safe |
mode GUIDED |
Go where you point: right-click the map, choose Fly
to, altitude 1 |
mode RTL |
Return to the launch point |
mode AUTO |
Run the loaded mission |
mode LOITER |
Hold position against wind and current |
status VFR_HUD |
Show live numbers: read groundspeed, heading, throttle (airspeed mirrors groundspeed on a boat) |
wp load ../missions/simple_nisaki.txt # load a route from a file
wp list # show the loaded route
mode AUTO # then arm to set it off
arm throttle
wp clear # remove all waypoints
output list # data links; should include 127.0.0.1:14550
param show FRAME_CLASS # 2 means the boat settings loaded
param set ARMING_CHECK 0 # turn off pre-arm checks: SIMULATOR ONLY
Press Ctrl-C in the terminal. If a leftover process then blocks the next launch:
pkill -f arduroverSet the connection to UDP, port
14550. On a default WSL setup, point the launch
command's --out at your Windows address, found with:
ip route show default | awk '{print $3}' # your Windows host addresscd ~/maritime26/sitl-test2
sim_vehicle.py -v Rover --instance 1 --sysid 2 -L Syros2 \
--add-param-file=$HOME/maritime26/custom-parms/boat.parm \
--out=udp:127.0.0.1:14560 --out=udp:<windows-address>:14550A third boat repeats the pattern with
--instance 2 --sysid 3 -L Syros3, ports going up by ten
again.