Metadata-Version: 2.4
Name: swarmit
Version: 0.8.0rc1
Summary: Run Your Own Robot Swarm Testbed.
Project-URL: Homepage, https://github.com/DotBots/swarmit
Project-URL: Bug Tracker, https://github.com/DotBots/swarmit/issues
Author-email: Alexandre Abadie <alexandre.abadie@inria.fr>
License: BSD
License-File: AUTHORS
License-File: LICENSE
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.7
Requires-Dist: click>=8.1.7
Requires-Dist: cryptography>=46.0.3
Requires-Dist: marilib-pkg>=0.9.0rc2
Requires-Dist: pydotbot-utils>=0.3.0
Requires-Dist: rich>=14.0.0
Requires-Dist: structlog>=24.4.0
Requires-Dist: tqdm>=4.66.5
Provides-Extra: dashboard
Requires-Dist: fastapi>=0.121.2; extra == 'dashboard'
Requires-Dist: pyjwt>=2.9.0; extra == 'dashboard'
Requires-Dist: sqlalchemy>=2.0.25; extra == 'dashboard'
Requires-Dist: uvicorn>=0.38.0; extra == 'dashboard'
Description-Content-Type: text/markdown

[![CI][ci-badge]][ci-link]
[![Coverage][codecov-badge]][codecov-link]
[![PyPI version][pypi-badge]][pypi-link]
[![License][license-badge]][license-link]

# SwarmIT

SwarmIT provides a embedded C port for nRF53 as well as Python based services to
easily build and deploy a robotic swarm infrastructure testbed.
ARM TrustZone is used to create a sandboxed user environment on each device
under test, without requiring a control co-processor attached to it.

<video src="https://github.com/user-attachments/assets/eff63b07-216a-41fb-9062-2e0e56f03c20" type="video/mp4" controls width="100%">
</video>

## Features

- Experiment management: start, stop, monitor and status check
- Deploy a custom firmware on all or on a subset of robots of a swarm testbed
- Resilient robot state: even when crashed by buggy user code, the robot can be reprogrammed remotely and wirelessly

## Usage

### Get the code

Swarmit depends on the [DotBot-libs](https://github.com/DotBots/DotBot-libs)
and [Mari](https://github.com/DotBots/mari) repositories. They are included
in the codebase as [Git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules).

Use the following command to clone the Swarmit codebase locally:

```
git clone --recurse-submodules https://github.com/DotBots/swarmit.git
```

### Embedded C code

SwarmIT embedded C code can be built using
[Segger Embedded Studio (SES)](https://www.segger.com/products/development-tools/embedded-studio/).
Use Tools > Package manager to install the CMSIS 5 CMSIS-CORE, CMSIS-DSP and nRF packages.

To provision a device, follow the following steps:
1. open [netcore.emProject](swarmit-netcore.emProject)
   and [bootloader.emProject](swarmit-bootloader-dotbot-v3.emProject)
   (or [bootloader.emProject](swarmit-bootloader-dotbot-v2.emProject) depending on
   your robot version) in SES
2. build and load the netcore application on the nRF53 network core,
3. build and load the bootloader application on the nRF53 application core.

The device is now ready.

#### Lighthouse calibration

The bootloader compiles in a Lighthouse v2 homography from
[`device/bootloader/Source/lh2_calibration.h`](device/bootloader/Source/lh2_calibration.h).
That file is auto-generated by the
[`dotbot-lh2-calibration`](https://github.com/DotBots/dotbot-lh2-calibration)
tooling — see its README for the calibration procedure. Quick recap:

```bash
# 1. Calibrate against the four reference points (-d is the square side in mm)
dotbot-calibration -p <serial-port> -d 500   # 50 cm square, ~2.5 m × 2.5 m arena

# 2. Export the calibration as a C header next to the bootloader sources
dotbot-calibration-exporter device/bootloader/Source
```

Rebuild and reflash the bootloader for the new calibration to take effect.

For **already-flashed** robots there's no need to rebuild — push the new
calibration over the air with `swarmit calibrate-lh2`, see
[Pushing an LH2 calibration over the air](#pushing-an-lh2-calibration-over-the-air)
below.

### Gateway

The communication between the computer and the swarm devices is performed via a
gateway board connected via USB to the computer.

This gateway uses the [mari](https://github.com/dotbots/mari) network stack and
must run the Mari gateway firmware.

The documentation to setup a Mari gateway is located
[here](https://github.com/DotBots/mari/wiki/Getting-started#running-mari-network-on-your-computer).

### Python CLI script

The Python CLI script provides commands for flashing, starting and stopping user
code on the device, as well as monitoring and checking the status of devices
in the swarm.

The Python CLI script connects via a virtual COM port to the gateway connected to
the computer.

The Python CLI script is available on PyPI. Install it using:

```
pip install swarmit
```

Print usage using `swarmit --help`:

```
Usage: swarmit [OPTIONS] COMMAND [ARGS]...

Options:
  -c, --config-path FILE      Path to a .toml configuration file.
  -p, --port TEXT             Serial port to use to send the bitstream to the
                              gateway. Default: /dev/ttyACM0.
  -b, --baudrate INTEGER      Serial port baudrate. Default: 1000000.
  -H, --mqtt-host TEXT        MQTT host. Default: localhost.
  -P, --mqtt-port INTEGER     MQTT port. Default: 1883.
  -T, --mqtt-use_tls          Use TLS with MQTT.
  -n, --network-id TEXT       Marilib network ID to use. Default: 0x1200
  -a, --adapter [edge|cloud]  Choose the adapter to communicate with the
                              gateway. Default: edge
  -d, --devices TEXT          Subset list of device addresses to interact with,
                              separated with ,
  -v, --verbose               Enable verbose mode.
  -V, --version               Show the version and exit.
  -h, --help                  Show this message and exit.

Commands:
  calibrate-lh2  Send LH2 calibration data to the robots.
  flash          Flash a firmware to the robots.
  message        Send a custom text message to the robots.
  monitor        Monitor running applications.
  reset          Reset robots locations.
  start          Start the user application.
  status         Print current status of the robots.
  stop           Stop the user application.
```

#### Pushing an LH2 calibration over the air

Once a robot is flashed and connected to the Mari network, you can update its
Lighthouse v2 homography without re-flashing the bootloader. The CLI pushes a
calibration file produced by
[`dotbot-lh2-calibration`](https://github.com/DotBots/dotbot-lh2-calibration)
(default location `~/.dotbot/calibration.out`) over Mari; the network core
writes it to the config page in flash and the SoC resets so the bootloader
loads the new homographies on the next boot.

```bash
# Push the most recent calibration to every ready device on network 0xA000
swarmit -n 0xA000 calibrate-lh2 ~/.dotbot/calibration.out

# Or target a subset (-d takes a comma-separated list of device addresses)
swarmit -n 0xA000 -d BC3D3C8A2A6F8E68 calibrate-lh2 ~/.dotbot/calibration.out
```

## swarmit serve

`swarmit serve` is the unified FastAPI backend. Two deployment presets,
same binary:

- **Local-dev convenience** — `swarmit serve --local`. Binds
  `127.0.0.1`, no JWT auth, no records DB. The local CLI auto-discovers
  it at `localhost:8001` and routes commands through HTTP/SSE (sub-50 ms
  cold-start) instead of building a fresh in-process Controller per
  invocation. Pass `--no-server` to force the legacy in-process path.

- **Shared service** — `swarmit serve` (default). Binds `0.0.0.0`, JWT
  required, JWT records DB on. Used on a testbed server reachable by
  operators and remote CLIs. React UI mounted on the same port.

```bash
pip install swarmit[dashboard]                # includes the serve subcommand
swarmit -n 0x1234 serve --local &             # local-dev preset

# Same CLI, now answered by the server:
swarmit status                                # live status, sub-50 ms
swarmit flash sample.bin                      # streaming OTA progress (SSE)
swarmit status -w                             # SSE-driven Rich Live table
swarmit monitor                               # streams SWARMIT_EVENT_LOG

# Override the server endpoint:
SWARMIT_SERVER_URL=http://127.0.0.1:9001 swarmit status
```

`swarmit serve --local` refuses to bind to any address other than
localhost — using `--bind-host 0.0.0.0` with `--local` is rejected.
Cross-machine deployment requires the default JWT-enabled mode.

`swarmit-server` is kept as a deprecated standalone console_script that
behaves identically to `swarmit serve`. New scripts should use
`swarmit serve`.

`python -m swarmit.dashboard.main` is kept as a deprecated alias that
forwards to `swarmit-server`.

## Control Tower Dashboard

The Control Tower is a web-based platform (backend and frontend) that enables users to manage and monitor the testbed remotely. It provides an interface for reserving timeslots, inspecting the live status of all DotBots, and supervising experiments. The platform displays each device’s position and operational state, and offers mechanisms to flash firmware, start or stop experiments, and oversee ongoing activity across the testbed.


### Setup

1. Download all requirements.
```bash
pip install swarmit[dashboard]
```

2. Generate a private and public key for the JWT
```bash
# Create the data directory
mkdir -p .data

# Generate Ed25519 private key
openssl genpkey -algorithm Ed25519 -out .data/private.pem

# Extract the public key
openssl pkey -in .data/private.pem -pubout -out .data/public.pem
```

### Running the Dashboard

After the initial setup (required only once), you can launch the dashboard. With the **edge** adapter (default — gateway over USB serial):

```bash
python3 -m swarmit.dashboard.main --http-port 8080 --open-browser
```

With the **cloud** adapter (gateway reached over an MQTT broker):

```bash
python3 -m swarmit.dashboard.main -a cloud -n 0x1234 \
    -H broker.example.com -P 8883 -T \
    --http-port 8080 --open-browser
```

Or use a TOML config file (recommended once you have one):

```bash
python3 -m swarmit.dashboard.main -c swarmit-argus.toml -n 1234 \
    --http-port 8080 --open-browser
```

Note: the dashboard opens its own gateway connection. If
`swarmit serve` is already running and owns the gateway (serial port,
especially), stop it before starting another instance.

Access the dashboard at [https://localhost:8080](https://localhost:8080)

> **__NOTE:__** Your dashboard CLI options may differ depending on your example or environment.

The map view draws a graph-paper grid (minor cells every `d` mm, major
squares every `5d` mm — one Lighthouse v2 coverage area) and marks the four
LH2 reference points used by `dotbot-calibration`. For a single-LH arena
the grid auto-infers `d` from `--map-size` (`min(width, height) / 5`). For
multi-LH arenas where the arena extends past LH0's coverage, pass it
explicitly:

```bash
# Two stacked LHs (d=200 mm), arena 1000x1800 mm with 200 mm overlap
python3 -m swarmit.dashboard.main \
    --map-size 1000x1800 --calibration-distance 200
```


[ci-badge]: https://github.com/DotBots/swarmit/workflows/CI/badge.svg
[ci-link]: https://github.com/DotBots/swarmit/actions?query=workflow%3ACI+branch%3Amain

[codecov-badge]: https://codecov.io/gh/DotBots/swarmit/branch/main/graph/badge.svg
[codecov-link]: https://codecov.io/gh/DotBots/swarmit

[pypi-badge]: https://badge.fury.io/py/swarmit.svg
[pypi-link]: https://badge.fury.io/py/swarmit

[license-badge]: https://img.shields.io/pypi/l/swarmit
[license-link]: https://github.com/DotBots/swarmit/blob/main/LICENSE
