> ## Documentation Index
> Fetch the complete documentation index at: https://docs.altnautica.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Installation

> Install the Ground Agent on your SBC with a single command.

# Installation

The Ground Agent uses the same install script as the Drone Agent. One command, one SD card image, one codebase. The hardware fingerprint at first boot picks the right profile automatically.

<Note>
  Mission Control's Flash Tool surfaces this install command automatically. See [Install paths](/getting-started/install-paths) for the recommended flow per board class.
</Note>

## Prerequisites

* A Raspberry Pi 4B (or supported SBC) with a fresh Raspberry Pi OS Bookworm 64-bit image
* An RTL8812EU USB WiFi adapter plugged in
* Internet access during installation (WiFi or Ethernet)
* An SD card with at least 16 GB (32 GB recommended)
* A USB-C wall adapter or USB-C power bank that can sustain the board under radio load

<Warning>
  The install script requires internet to download packages and the DKMS driver for the RTL8812EU. After installation completes, the ground station works fully offline.
</Warning>

## One-line install

SSH into your SBC and run:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -sSL https://raw.githubusercontent.com/altnautica/ADOSDroneAgent/main/scripts/install.sh | sudo bash
```

To pair with a drone at install time, add the pairing key:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -sSL https://raw.githubusercontent.com/altnautica/ADOSDroneAgent/main/scripts/install.sh | sudo bash -s -- --pair YOUR_PAIRING_KEY
```

The install takes 5-10 minutes depending on your internet speed and SD card class.

## What the install script does

<Steps>
  <Step title="System update">
    Runs `apt update` and installs required packages: Python 3.11+, pip, systemd units, dnsmasq, hostapd, and build tools for the DKMS driver.
  </Step>

  <Step title="DKMS driver build">
    Clones the RTL8812EU kernel module source and builds it via DKMS. This is the longest step. If kernel headers are missing, the script installs them first.
  </Step>

  <Step title="Agent install">
    Installs the `ados` Python package from the GitHub release. Creates the `ados` system user, config directory at `/etc/ados/`, and runtime directory at `/run/ados/`.
  </Step>

  <Step title="Systemd units">
    Deploys all systemd service units. They are not enabled yet because the profile has not been determined.
  </Step>

  <Step title="Profile detection">
    Runs `ados.bootstrap.profile_detect` as the final step. The fingerprint checks for:

    * I2C device at `0x3C` or `0x3D` (OLED present)
    * Four GPIO pins with pull-ups (buttons wired)
    * RTL8812EU USB device
    * No flight controller on any serial port

    If the score points to ground station, the script writes `profile: ground_station` to `/etc/ados/profile.conf` and enables the ground-station systemd units. The `ados status` command displays this as `ground-station` for readability, but the on-disk value uses the underscore form.
  </Step>

  <Step title="Reboot">
    The SBC reboots once. On the second boot, the ground station is live. The WiFi AP starts, the OLED lights up, and the WFB-ng receiver begins listening.
  </Step>
</Steps>

## First boot after install

After the reboot, you should see:

1. **OLED** shows the Link screen with "No drone" (if not yet paired) or signal strength (if paired during install)
2. **WiFi AP** broadcasts `ADOS-GS-XXXX` where `XXXX` is the last four hex digits of the device ID
3. **Setup webapp** is reachable at `http://setup.ados.local/` from any device on the AP

<Note>
  The AP passphrase is printed on the case sticker for production units. For bench builds, the default passphrase is `ados-ground`. You can change it in the setup webapp or via the OLED menu.
</Note>

## Verifying the install

SSH back into the SBC and run:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
ados status
```

You should see output like:

```
ADOS Drone Agent v0.89.2
Profile: ground-station
Board: pi4b (Raspberry Pi 4B)

Services:
  ados-supervisor    active (running)
  ados-api           active (running)
  ados-wfb-rx        active (running)
  ados-hostapd       active (running)
  ados-oled          active (running)
  ados-buttons       active (running)
  ados-health        active (running)
  ados-mediamtx-gs   active (running)
```

Open the setup webapp URL shown by `ados` to check WiFi AP, WFB-ng reception,
pairing, and network status.

## Upgrading

To upgrade an existing ground station:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -sSL https://raw.githubusercontent.com/altnautica/ADOSDroneAgent/main/scripts/install.sh | sudo bash -s -- --upgrade
```

The upgrade preserves your config, pairing keys, and profile. Services restart automatically after the upgrade completes.

## Installing a specific branch

For testing pre-release features:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -sSL https://raw.githubusercontent.com/altnautica/ADOSDroneAgent/main/scripts/install.sh | sudo bash -s -- --branch ground-station-test
```

## Mesh support

Every ground-station install already pulls the mesh dependencies. There is no flag to set. On a fresh image or on `--upgrade`, the installer runs these steps:

1. apt-installs `batctl`, `avahi-daemon`, `wpasupplicant` (and tries `wpasupplicant-mesh-sae` or `wpad-mesh-wolfssl` for the 802.11s SAE backend; falls back to IBSS carrier if neither is available).
2. Creates `/etc/ados/mesh/` (mode 0755) so role-transition flows have somewhere to land mesh identity files.
3. Installs the three role-gated systemd units (`ados-batman.service`, `ados-wfb-relay.service`, `ados-wfb-receiver.service`). They stay masked until a role transition starts them. The node stays in `direct` mode by default.
4. `profile_detect` scans for a second USB-attached WiFi adapter at boot and sets `mesh_capable: true` in `/etc/ados/profile.conf` when one is present. That flag unlocks the OLED Mesh submenu, the GCS Distributed RX and Mesh tabs, and the `/api/v1/ground-station/role` REST PUT for relay/receiver targets.

To act as a `relay` or `receiver`, plug a **second RTL8812EU USB adapter** into the node (default). This matches the primary adapter one-for-one so inventory stays simple and both radios run at the same 29 dBm for matched mesh range. Any 802.11s-capable USB WiFi adapter also works; MediaTek MT7612U (mainline `mt76`) and MT7921AU (mainline `mt7921u`) are the common alternatives when an operator prefers a mainline kernel driver for the mesh carrier.

[Read the Mesh & Distributed Receive overview](/ground-agent/mesh-overview) for the full picture.

## Profile override

If auto-detection picks the wrong profile (rare, usually means ambiguous hardware), you can force it:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
sudo ados profile set ground-station
sudo reboot
```

Or edit `/etc/ados/config.yaml` directly. The on-disk value must use the underscore form. The config validator rejects the hyphenated `ground-station`:

```yaml theme={"theme":{"light":"github-light","dark":"github-dark"}}
agent:
  profile: ground_station
```

## Troubleshooting install issues

| Problem                   | Cause                    | Fix                                                                                                                                |
| ------------------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| DKMS build fails          | Missing kernel headers   | Run `sudo apt install raspberrypi-kernel-headers` and re-run the install                                                           |
| No WiFi AP after reboot   | hostapd not started      | Check `systemctl status ados-hostapd`                                                                                              |
| OLED blank                | I2C not enabled          | Run `sudo raspi-config`, enable I2C under Interface Options, reboot                                                                |
| Profile detected as "air" | Flight controller on USB | Unplug the FC, run `sudo ados profile set ground-station`, then reboot (or re-run the installer to trigger a fresh profile detect) |

## What is next

* [Setup and Pairing](/ground-agent/setup-and-pairing) for the first-time walkthrough
* [WiFi AP](/ground-agent/wifi-ap) to connect your laptop
* [USB Tether](/ground-agent/usb-tether) for a wired connection
* [Power and Runtime](/ground-agent/power-and-runtime) to size field power
