examples/Dual Drone Telemetry/README.md
A multi-source drone telemetry simulator that shows Serial Studio receiving and visualizing data from two independent devices at the same time, each with its own camera feed, GPS coordinates, flight dynamics, and battery monitoring.
Two simulated drones fly different flight profiles over the Swiss Alps near Zermatt, each transmitting telemetry and synthetic camera imagery over separate TCP connections.
| Drone | Port | Flight pattern | Altitude | Camera style |
|---|---|---|---|---|
| Alpha | 9001 | Circular patrol (~330 m radius) | 120 m AGL | Satellite imagery + green HUD |
| Bravo | 9002 | Figure-8 survey (~550 m radius) | 200 m AGL | Thermal/IR remap (iron-bow palette) |
Camera images are fetched from ArcGIS World Imagery satellite tiles (free, no API key required) and cached locally. Each drone's view is centered on its GPS position and rotated to match heading.
Alpha satellite. Photorealistic satellite camera view:
Bravo thermal. Thermal/IR remap of satellite imagery:
COLORMAP_INFERNO.Each drone has an output control panel on the dashboard with six interactive widgets that send commands back to the simulator.
| Control | Widget type | Range | Command sent |
|---|---|---|---|
| Throttle | Slider | 0-100% | THR <value>\r\n |
| Heading | Knob | -180° to +180° | HDG <value>\r\n |
| Camera | Toggle | ON/OFF | CAM ON\r\n / CAM OFF\r\n |
| Takeoff | Button | TKO\r\n | |
| Return to Home | Button | RTH\r\n | |
| Crash | Button | CRASH\r\n |
Throttle scales the drone's airspeed. 50% is normal cruise, 0% is idle, 100% is full speed. Heading applies a rotational offset to the flight path. Camera turns the synthetic JPEG feed on or off (telemetry keeps streaming). Takeoff launches from the helipad (only when grounded). RTH triggers return-to-home, landing, and automatic battery recharge. Crash drops the TCP link to simulate a catastrophic failure.
| Field | Units | Description |
|---|---|---|
| Latitude | deg | GPS latitude |
| Longitude | deg | GPS longitude |
| Heading | deg | Compass heading (0 to 360) |
| Altitude | m | Altitude above ground |
| Airspeed | m/s | Forward speed |
| Vertical Speed | m/s | Climb/descent rate |
| Roll | deg | Bank angle |
| Pitch | deg | Nose up/down angle |
| Battery Voltage | V | 6S LiPo (18 to 25.2 V) |
| Current Draw | A | Motor + avionics current |
| Battery % | % | Remaining charge (drains over time) |
Dual Drone Telemetry.ssproj in Serial Studio.The project includes a control loop that launches dual_drone_telemetry.py (which starts the two TCP servers) automatically just before connecting, so there is nothing to start by hand. For camera imagery, install its optional dependencies first:
pip install opencv-python numpy # for camera imagery
The simulator also works without opencv. You just won't get camera images. To run it yourself instead of letting the control loop start it, launch python3 dual_drone_telemetry.py before connecting.
| Flag | Default | Description |
|---|---|---|
--fps | 10 | Update rate in Hz (telemetry + camera) |
--host | 127.0.0.1 | TCP listen address |
Both drones use hexadecimal frame delimiters with JPEG images interleaved in the same byte stream:
A1 01 A1 01 (start) / A1 02 A1 02 (end).B2 03 B2 03 (start) / B2 04 B2 04 (end).Each cycle sends a delimited JPEG camera frame, then a delimited CSV telemetry frame. Image delimiters are separate from the CSV delimiters:
A1 CA FE 01 (start) / A1 FE ED 01 (end).B2 CA FE 02 (start) / B2 FE ED 02 (end).Serial Studio sends commands back to the simulator over the same TCP connection. Each command is a text line terminated by \r\n.
| Command | Arguments | Effect |
|---|---|---|
THR | 0 to 100 | Set throttle (scales airspeed; 50 = normal cruise) |
HDG | -180 to 180 | Apply heading offset in degrees |
CAM | ON or OFF | Enable or disable camera image transmission |
TKO | Launch from helipad (only when grounded) | |
RTH | Return to helipad, land, and recharge battery | |
CRASH | Simulate catastrophic failure — drops the TCP link with a RST. Useful for testing how Serial Studio behaves when one source goes dark in multi-device mode while the other keeps streaming. |
Commands are parsed on each simulation tick. Multiple commands can arrive per tick and are applied in order.
Each drone has eight widget groups on the dashboard.
| Widget | Type | Description |
|---|---|---|
| Camera | Image View | Live satellite (Alpha) or thermal/IR (Bravo) camera feed |
| Navigation | Map | GPS track on an interactive map |
| Heading | Compass | Compass heading indicator |
| Attitude | Gyroscope | Roll, pitch, and yaw visualization |
| Flight | Gauges + Bars | Airspeed, altitude, and vertical speed |
| Power | Gauges + Bars | Battery voltage, current draw, and charge level |
| Controls | Output Panel | Throttle, heading, camera toggle, takeoff, RTH, and crash per drone |
| State | Painter | Scripted live state visualizer driven by the telemetry datasets |
Both drones start grounded at their helipads near Zermatt. Send TKO to launch. Takeoff reaches cruise altitude in about 2 seconds so dashboard changes show up immediately during demos.
Drone Alpha, Zermatt village helipad (46.0207°N, 7.7491°E):
Drone Bravo, Trockener Steg plateau (46.0035°N, 7.7465°E):
Both drones have low-battery alarms set at 20% charge and 21 V. Send RTH to return, land, and recharge automatically for another flight.
opencv-python and numpy (optional, for camera imagery).