# Get Started (Standalone Mode / pymavlink)
This guide provides a step-by-step walkthrough for testing the UAV Vision Analytics application in standalone mode (pymavlink) and running the demo with a simulated UAV camera feed/RealSense cameras.
## How It Works
A self-contained stack. PX4 SITL, MAVLink router, MQTT broker, and Metrics Manager are all started together (`docker-compose-pymavlink.yml`). Telemetry flows from PX4 SITL through `mavlink-router` to the DL Streamer container, where `pymavlink` reads it directly over UDP.

**Telemetry flow:**
```mermaid
sequenceDiagram
participant PX4 as PX4 SITL
participant RTR as mavlink-router
participant OVL as gvapython (MavlinkReceiver)
participant Frame as Video Frame
PX4->>RTR: MAVLink stream (UDP :14550)
RTR->>OVL: broadcast UDP :14541
Note over OVL: background thread parses
GLOBAL_POSITION_INT, VFR_HUD,
GPS_RAW_INT into latest_data
Frame->>OVL: process_frame() per frame
OVL->>Frame: ROI labels (ALT · SPD · HDG · LAT · LON · SATS)
```
**Services:**
| Service | Image | Ports | Role |
|---|---|---|---|
| `dlstreamer-pipeline-server` | `intel/dlstreamer-pipeline-server` + pymavlink | `8081`, `8555` | AI inference, RTSP output |
| `px4` | `px4io/px4-sitl` | `14550` | Flight controller simulator |
| `mavlink-router` | custom build | `14551` | MAVLink UDP routing (:14550 → :14541) |
| `metrics-manager` | `intel/metrics-manager` | `9090` | CPU/GPU/NPU/power metrics |
---
## Steps to Test the Application
### System Requirements
See [System Requirements](./system-requirements.md) for the full list of software and hardware prerequisites.
### 1. Configure environment
Clone the repo and Get into the directory:
```bash
git clone https://github.com/open-edge-platform/edge-ai-suites.git --branch release-2026.2.0
cd edge-ai-suites/federal-and-aerospace-ai-suite/uav-vision-analytics
```
```bash
make init
```
`make init` creates `.env` from the template and **auto-detects your Intel GPU device paths** (`GPU_DEVICE`, `GPU_RENDER_DEVICE`), **Intel NPU** (`NPU_DEVICE`), and **Intel RealSense / USB camera** (`REALSENSE_DEVICE`). It skips if `.env` already exists.
Then set your host IP address in `.env`:
```bash
nano .env # set HOST_IP=
```
### 2. Prepare the model
Download and export the YOLOv8n-VisDrone model to OpenVINO FP16 IR:
```bash
make model
```
> See the [AI Model guide](../how-to-guides/model.md) for model details.
### 3. Standalone mode (pymavlink)
```bash
make pymav-up
```
### 4. Start inference pipelines
Two options are available depending on your use case:
#### Option A — Managed RTSP output (recommended)
Runs `pipeline_manager.py` inside the DLSPS container. It monitors the drone's ARMED/DISARMED state and automatically starts and stops inference pipelines. Annotated frames are served as RTSP on port `8555`.
`make start-rtsp` starts **one device pipeline at a time** (default: GPU). Pass `DEVICE=cpu|gpu|npu|all` to choose:
```bash
make start-rtsp # GPU only (default)
make start-rtsp DEVICE=cpu # CPU only
make start-rtsp DEVICE=npu # NPU only
make start-rtsp DEVICE=all # CPU + GPU + NPU simultaneously
```
> **Note:** Open QGroundControl (QGC) to connect and press takeoff, which arms the UAV (Only arming will automatically disarm the UAV after a few seconds). The pipeline manager will automatically start the selected pipeline and serve annotated RTSP streams.
>
> `DEVICE=npu` requires `NPU_DEVICE` to have been detected during `make init` — falls back to GPU otherwise.
>
> Refer to the [QGroundControl guide](../how-to-guides/qgroundcontrol.md#rtsp-stream) for instructions on connecting to the RTSP stream.
**pymavlink mode** — output streams (only the selected `DEVICE` is active, unless `DEVICE=all`):
```
rtsp://:8555/uav-mavlink-cpu (CPU pipeline)
rtsp://:8555/uav-mavlink-gpu (GPU pipeline)
rtsp://:8555/uav-mavlink-npu (NPU pipeline) # If NPU Device is available
```
**File-source pipelines** (started via REST API or benchmark script) — output path is set in the POST request body (e.g. `uav-mavlink-cpu` for the `uav_object_detection_cpu` pipeline).
#### Option B — Manual REST API
Start a single pipeline directly without the pipeline manager. Useful for testing individual pipelines or custom configurations.
```bash
# CPU pipeline
INSTANCE_ID=$(curl -s -X POST \
http://localhost:8081/pipelines/user_defined_pipelines/uav_object_detection_cpu \
-H "Content-Type: application/json" \
-d '{
"destination": {
"metadata": {
"type": "file",
"path": "/tmp/results.jsonl",
"format": "json-lines"
},
"frame": {
"type": "rtsp",
"path": "uav-mavlink-cpu"
}
},
"parameters": {
"detection-properties": {
"model": "/home/pipeline-server/resources/models/yolov8n-visdrone/best_openvino_model/best.xml",
"device": "CPU"
}
}
}' | tr -d '"')
echo "Instance ID: $INSTANCE_ID"
```
Change following **three values** to switch between CPU / GPU / NPU:
1. **Pipeline name** in the URL path (`uav_object_detection_cpu` → `_gpu` / `_npu`)
2. **RTSP path** in the request body (`uav-mavlink-cpu` → `uav-mavlink-gpu` / `uav-mavlink-npu`)
3. **Device** in `detection-properties` (`CPU` → `GPU` / `NPU`)
View the annotated stream immediately after posting:
```bash
ffplay rtsp://:8555/uav-mavlink-cpu # or uav-mavlink-gpu / uav-mavlink-npu
```
Stop a pipeline:
```bash
curl -X DELETE http://localhost:8081/pipelines/${INSTANCE_ID}
```
### 5. View the output stream
```bash
# Install ffmpeg if not present, then view any device stream
ffplay rtsp://:8555/uav-mavlink-cpu # CPU
ffplay rtsp://:8555/uav-mavlink-gpu # GPU
ffplay rtsp://:8555/uav-mavlink-npu # NPU
```
The annotated stream includes bounding boxes for detected objects (person, car, bus, truck, van, bicycle, tricycle, awning-tricycle, motor, others) and a live telemetry overlay (GPS, altitude, speed, heading).
### 6. Stop all services
Stop and remove the standalone pymavlink stack (also removes named volumes):
```bash
make pymav-down
```
---
## Pipelines
### pymavlink mode (`config-pymavlink.json`)
| Pipeline | Device | Source | Output |
|---|---|---|---|
| `uav_object_detection_cpu` | CPU | Looped video file (`uav_sample.avi`) | RTSP `:8555` |
| `uav_object_detection_gpu` | GPU | Looped video file (`uav_sample.avi`) | RTSP `:8555` |
| `uav_object_detection_npu` | NPU | Looped video file (`uav_sample.avi`) | RTSP `:8555` |
| `uav_realsense_cpu` | CPU | Intel RealSense camera (v4l2src) | RTSP `:8555` |
| `uav_realsense_gpu` | GPU | Intel RealSense camera (v4l2src) | RTSP `:8555` |
| `uav_realsense_npu` | NPU | Intel RealSense camera (v4l2src) | RTSP `:8555` |
---
## Telemetry Overlay Fields
Each output frame carries these overlaid fields in the upper-left corner:
| Field | Source MAVLink message | Description |
|---|---|---|
| `Name` | — | Name passed as argument to the gvapython |
| `Frame` | — | Running frame counter |
| `ALT` | `GLOBAL_POSITION_INT.relative_alt` | Relative altitude (m) |
| `SPD` | `VFR_HUD.groundspeed` | Ground speed (m/s) |
| `HDG` | `GLOBAL_POSITION_INT.hdg` | Heading (degrees) |
| `LAT` | `GPS_RAW_INT.lat` | Latitude |
| `LON` | `GPS_RAW_INT.lon` | Longitude |
| `SATS` | `GPS_RAW_INT.satellites_visible` | GPS satellites visible |
---
## Port Reference
| Port | Protocol | Service | Mode |
|---|---|---|---|
| `8081` | HTTP | DL Streamer REST API | All modes |
| `8555` | RTSP | Annotated video output | All modes |
| `14541` | UDP | MAVLink broadcast (mavlink-router) | pymavlink modes |
| `9090` | HTTP | metrics-manager (HW metrics) | pymavlink modes |
---
## RealSense Camera Support
Intel RealSense camera setup and pipelines details are provided in the [RealSense guide](../how-to-guides/realsense-guide.md).
## Documentation
| Document | Description |
|---|---|
| [index.md](../index.md) | Application overview and component block diagrams |
| [benchmark.md](../how-to-guides/benchmark.md) | Performance benchmarking guide (`calc_stream_density.sh`) |
| [makefile.md](../how-to-guides/makefile.md) | Makefile target reference |
| [troubleshooting.md](../how-to-guides/troubleshooting.md) | Known issues and resolutions |