Portable MAVLink routing for drones, companion computers, GCS links, LTE, Wi-Fi, VPNs, UDP, and serial.
MAVLink Anywhere routes MAVLink data from a flight controller (Pixhawk/ArduPilot/PX4) through a companion computer to ground stations, SDKs, remote operators, local QGroundControl fallback links, and MDS Fleet Ops.
| Tool | Role |
|---|---|
| MAVLink Anywhere | companion-computer MAVLink routing and endpoint dashboard |
| MDS | fleet operations, SITL, real drone dashboard, sidecar profile status |
| Smart Wi-Fi Manager | Wi-Fi profile priority and field connectivity |
First time here? Watch the video!
Complete Setup Guide (YouTube)
git clone https://github.com/alireza787b/mavlink-anywhere.git
cd mavlink-anywhere
sudo ./install_mavlink_router.shsudo ./configure_mavlink_router.shThe script will:
- Detect your platform (Raspberry Pi, Jetson, generic Linux)
- Check serial port configuration
- Guide you through any needed setup (with auto-fix option on Raspberry Pi)
- Configure mavlink-router with your settings
Note: On Raspberry Pi, if serial port needs configuration, the script will offer to fix it automatically. This requires a reboot, after which you run the configure script again.
sudo systemctl status mavlink-routerYou should see active (running). Connect your ground station to the configured UDP ports.
The configure script automatically installs a web dashboard bound to localhost by default. On supported release architectures it downloads a prebuilt binary; if that asset is unavailable, it falls back to a local Go source build before dropping back to CLI-only mode. Minimal hosts do not need the external file(1) package for dashboard installation.
http://127.0.0.1:9070
Manage endpoints, inspect MAVLink health, view logs, and control the service from your browser. Skip with --skip-dashboard.
To expose it on the network, use --dashboard-listen 0.0.0.0:9070.
When the dashboard is exposed on a non-loopback address and no dashboard auth is
already configured, the configure script generates browser login credentials,
stores only a bcrypt password hash in /etc/mavlink-anywhere/dashboard.env, and
prints the generated password once. The default generated username is admin.
sudo ./configure_mavlink_router.sh --install-dashboard \
--dashboard-listen 0.0.0.0:9070 \
--dashboard-auth-user operator \
--dashboard-auth-password-file /root/mavlink-dashboard-passwordFor interactive setup or password rotation, use --dashboard-auth-prompt.
For MDS/Fleet Ops or other machine clients, also configure a bearer token with
--dashboard-generate-api-token or --dashboard-api-token-file.
For headless automation, use --dashboard-auth-password-stdin or
--dashboard-auth-password-file. --dashboard-auth-password PASSWORD exists
for constrained lab automation, but it is not recommended because shell history
and process listings can expose it.
If UFW is active, add --dashboard-ufw-rule to allow TCP 9070
automatically when the dashboard listens on a non-loopback address.
An unauthenticated remote dashboard is still available for isolated lab demos:
use --dashboard-open-lab-mode. Do not use that mode on a shared LAN, VPN, or
field network.
Do not expose the dashboard to a public network without VPN, firewall, reverse proxy, and dashboard browser auth.
The dashboard can also export the current effective routing profile, preview imported profiles, apply them with automatic backup, and restore the last good dashboard-managed backup. Fleet profile APIs support MDS Fleet Ops dry-run/apply workflows while preserving node-local hardware input settings by default.
The configure script handles everything - platform detection, serial setup, configuration, and dashboard.
gcs_listen on 14550/udp is enabled by default for ad-hoc field access, so QGroundControl can point to <device-ip>:14550 without pre-configuring a remote IP on the device. This follows mavlink-router UDP server semantics: the active remote is the last sender on that listener. Keep local consumers such as MAVSDK and mavlink2rest on explicit localhost endpoints, and use explicit Mode=Normal endpoints or the built-in TCP server on 5760/tcp when you need deterministic or multi-client remote access.
| Guide | Description |
|---|---|
| Web Dashboard | Dashboard access, API reference, and configuration |
| Board Setup And Dashboard Auth | New board bring-up, dashboard auth, firewall, and version drift checks |
| UART Setup Guide | Detailed serial port configuration and wiring |
| CLI Reference | All command-line options |
| Troubleshooting | Common issues and solutions |
sudo ./configure_mavlink_router.sh --auto --gcs-ip 192.168.1.100sudo ./configure_mavlink_router.sh --headless \
--uart /dev/ttyS0 \
--baud 57600 \
--endpoints "127.0.0.1:14540,127.0.0.1:14569,192.168.1.100:24550"sudo ./configure_mavlink_router.sh --auto --uart /dev/ttyUSB0sudo ./configure_mavlink_router.sh --headless \
--input-type udp \
--input-port 14550 \
--endpoints "127.0.0.1:14540,127.0.0.1:14569"# Check status
sudo systemctl status mavlink-router
# View live logs
sudo journalctl -u mavlink-router -f
# Restart service
sudo systemctl restart mavlink-router
# Stop/Start
sudo systemctl stop mavlink-router
sudo systemctl start mavlink-router# Re-run interactive config
sudo ./configure_mavlink_router.sh
# Or headless with new endpoints
sudo ./configure_mavlink_router.sh --headless \
--endpoints "127.0.0.1:14550,192.168.1.100:14550"# Edit configuration
sudo nano /etc/mavlink-router/main.conf
# Apply changes
sudo systemctl restart mavlink-router./mavlink-router-cli.sh status # Show status & config
./mavlink-router-cli.sh logs # View live logs
./mavlink-router-cli.sh endpoints # Quick endpoint edit
./mavlink-router-cli.sh help # All commandscd ~/mavlink-anywhere
git fetch --tags origin
git pull --ff-only
# Update mavlink-anywhere dashboard/service files
sudo ./configure_mavlink_router.sh --install-dashboard
# Optional: rebuild upstream mavlink-routerd as well
sudo ./install_mavlink_router.shIf your dashboard is intentionally exposed on the network, re-run the dashboard step with:
sudo ./configure_mavlink_router.sh --install-dashboard \
--dashboard-listen 0.0.0.0:9070--install-dashboard refreshes the installed dashboard binary when the host is running an older mavlink-anywhere release.
| Platform | Serial Config | Notes |
|---|---|---|
| Raspberry Pi | Auto-detected | Script offers auto-fix for serial setup |
| NVIDIA Jetson | Manual | Ensure UART is enabled |
| Generic Linux | Manual | Ensure UART device exists |
| USB Serial | None needed | Just plug in adapter |
| UDP Input | None needed | For SITL/simulation |
Dashboard release binaries are published for arm6, arm64, and amd64. On other Linux architectures, the configure script will try a local Go build if go is installed; otherwise the router still works without the dashboard.
Use dashboard profiles when you want repeatable routing layouts without editing raw INI by hand.
- Export writes the current effective routing config to JSON
- Import previews changes before apply
- Apply creates a backup and restarts
mavlink-router - Restore Last Good reverts to the latest dashboard-created backup
Profiles are intentionally limited to router configuration. They do not change firewall policy or host boot serial settings.
For fleet-managed deployments, use the dashboard profile API rather than
editing /etc/mavlink-router/main.conf directly:
GET /api/v1/profiles/summaryreports endpoint policy and the local hardware source overlay separately.POST /api/v1/profiles/importrequiresdry_run=trueand returns a confirmation token.POST /api/v1/profiles/applyapplies only a confirmed dry-run plan forfleet-mergeorfleet-strict.fleet-mergepreserves local extra endpoints and the hardware input overlay.fleet-strictcan prune local extra output endpoints only after advanced confirmation and still preserves the hardware input overlay.
Set MAVLINK_ANYWHERE_API_TOKEN before exposing mutating dashboard APIs beyond
loopback for machine clients. Browser users use
MAVLINK_ANYWHERE_DASHBOARD_USER plus
MAVLINK_ANYWHERE_DASHBOARD_PASSWORD_BCRYPT; once authenticated, dashboard
save/delete/service controls work without putting the machine token into
JavaScript. Read-only API responses can still reveal routing topology and
system metadata, so keep network exposure behind VPN/firewall controls. MDS
Fleet Ops sends the matching bearer token through MDS_SIDECAR_PROFILE_TOKEN.
For internet streaming, you need:
- Internet on companion computer (WiFi, 4G, Ethernet)
- VPN for secure access:
mavlink-anywhere is intentionally generic. It sets up a MAVLink router, a default GCS listen endpoint, and optional local service endpoints. Higher-level projects can automate it by passing explicit CLI arguments or by managing /etc/mavlink-router/main.conf.
One example integration is MAVSDK Drone Show, but this repository does not assume MDS-specific defaults.
- Video Tutorial - Most common scenarios
- Troubleshooting Guide - Common issues
- GitHub Issues - Bug reports
MIT License - Copyright (c) 2024 Alireza Ghaderi
Made with β€οΈ for the drone community
GitHub β’
Tutorial β’
Dashboard Docs
