# Install and enroll the collector

URL: /collect/collector/install

Install the Foxborne collector on a vehicle's companion computer and register it with your deployment using a one-time token. It then uploads journal units and process samples on its own.



The collector is optional. Foxborne works from imported files alone. Install it when you want every run's companion evidence to arrive without anyone exporting a journal by hand, and when you want process samples with clock status on every sample.

## Before you start [#before-you-start]

* You need the **Admin** role. Only admins can manage sources and collectors.
* The companion computer runs a Debian-based Linux on arm64, such as Ubuntu 22.04 on an NVIDIA Jetson module, and can install packages from your internal mirror.
* The vehicle can open an outbound HTTPS connection to your deployment while it is on the ground. Nothing needs to connect to the vehicle.
* chrony runs on the companion computer and reaches a time source. Without it the collector still uploads, but the evidence stays on the companion's own clock.

## Enroll a vehicle [#enroll-a-vehicle]

<Steps>
  <Step title="Open the vehicle's enroll drawer">
    In the console, go to **Sources** and open the **Vehicle collectors** tab. Vehicles that have never been enrolled show **Not installed** in the **Collector** column and **Not enrolled** under **State**.

    Select **Enroll** on the vehicle's row. The drawer **Enroll** *vehicle* opens with the three steps below, filled in for that vehicle and its host name. The **Enroll a vehicle** button at the top of the page opens the same drawer for the first vehicle that is not enrolled yet.
  </Step>

  <Step title="Install the package">
    On the companion computer, install the collector package from your internal package mirror. The package is signed with the Foxborne release key.

    ```bash title="On the companion computer"
    sudo apt install ./foxborne-collector_0.8.1_arm64.deb
    ```
  </Step>

  <Step title="Register with the one-time token">
    Copy the command from the drawer with **Copy command** and run it on the same computer. It carries your deployment's address, the vehicle ID and a token that works once and expires 30 minutes after the drawer shows it.

    ```bash title="On the companion computer" caption="Example values from the drawer for UGV-04"
    sudo foxborne-collector enroll \
      --server https://foxborne.hfr.internal \
      --vehicle UGV-04 \
      --token fxe_afd0de1936672610860ca702
    ```

    The collector exchanges the token for a certificate that belongs to this vehicle alone. Every later connection uses that certificate over mutual TLS.
  </Step>

  <Step title="Wait for the first upload">
    The drawer reads **Waiting for** *host* **to connect** and updates on its own. When the first segment arrives, the vehicle's row changes to **Online**, **Last upload** shows the time, and the **Clock** column shows chrony's offset, for example **Synced +0.8 ms**.
  </Step>
</Steps>

## Check the result [#check-the-result]

| Column      | What you should see            | What it means                                                                            |
| ----------- | ------------------------------ | ---------------------------------------------------------------------------------------- |
| Collector   | `0.8.1`                        | The installed version. Older versions add **No SYSTEM\_TIME**.                           |
| Clock       | **Synced +0.8 ms**             | chrony is synchronized; the value is its offset.                                         |
| Local spool | **None**                       | Nothing is waiting on the vehicle. A bar shows megabytes held against the 100 MB budget. |
| Last upload | A time within the last segment | Uploads arrive after each segment the collector closes.                                  |
| Dropped     | `0`                            | No samples were discarded.                                                               |
| State       | **Online**                     | Connected and reporting.                                                                 |

The status bar at the bottom of every screen counts collectors too: **13 of 15 collectors reporting**, with a green dot only when every enrolled collector is online.

## Troubleshoot [#troubleshoot]

**The token has expired.** Tokens work once and last 30 minutes. Open the vehicle's **Enroll** drawer again and run the new command.

**Clock shows Not synchronised.** chrony has no reachable time source. The collector keeps uploading, but the journal and process samples stay on the companion's own clock and have no position on the map. Run `chronyc tracking` on the vehicle: `Leap status : Not synchronised` confirms it. Fix the time source, or [align the clock by hand](/investigate/align-a-clock) for runs already recorded.

**State shows Buffering.** The vehicle has no uplink, for example behind terrain, and is spooling locally. Uploads resume on their own when the link returns. Nothing is lost unless the spool budget fills.

**Dropped shows a number.** The spool budget filled while the vehicle was offline. The collector discards the oldest low-priority samples first and writes a lost-data marker where they were, so the gap is visible on the timeline instead of silent. Raise the budget in the [collector policy](/collect/collector/policy) if it happens often.

## Update an older collector [#update-an-older-collector]

Rows running an older version show **Update**. Select it and confirm **Schedule update**. The vehicle downloads collector 0.8.1 from your deployment the next time it is on the ground and online. Version 0.8.1 records `SYSTEM_TIME` pairs, which give companion evidence a shared anchor with the flight log.

## What the collector cannot do [#what-the-collector-cannot-do]

* Open a port. It connects outbound only, over mutual TLS, and holds no command channel.
* Talk to the flight controller. It never sends MAVLink, and it cannot arm, move or reconfigure the vehicle.
* Change the autonomy stack. It reads the journal and `/proc`, nothing else.
* Lose data quietly. Offline samples are spooled, acknowledged before deletion, and any drop is written as a marker.

## Next [#next]

* [Set the collector policy](/collect/collector/policy) to choose the journal units, processes, sample rate, spool budget and redaction patterns.
* [Collector JSONL records](/reference/collector-jsonl) lists every field of a process sample.
