Advanced Ground Control System for real-time drone telemetry, visualization, and calibration
SkySync GCS is a powerful, modern ground control system designed for professional drone operations. Built for real-time data visualization and calibration using the MAVLink protocol, SkySync seamlessly integrates with Pixhawk and Jetson-based systems. Our platform features:
- Immersive 3D Data Visualization π
- Advanced TypeScript & React-based UI π¨
- Real-time MAVLink telemetry processing β³
- Professional-grade sensor calibration π°οΈ
- Responsive design for all devices π»π±
-
Real-time Telemetry Dashboard
- Live battery status monitoring
- GPS positioning with visual mapping
- Attitude and orientation visualization
- System health analytics
-
π‘οΈ Dynamic Drone Arena Visualization
- Complete dynamic system - No hardcoded coordinates
- Real-time SCP data fetching from Jetson device
- Dynamic arena boundaries from GPS coordinates
- Live safe spot detection with pulsing animations
- Auto-refresh every 30 seconds from Jetson device
- GPS-to-field coordinate conversion system
- Real-time drone position tracking with trail effects
- Safe spot proximity alerts with distance calculations
-
Professional Calibration Suite
- Gyroscope calibration
- Accelerometer calibration
- Magnetometer calibration
- Level horizon calibration
- Radio calibration
-
Advanced Visualization
- Interactive 3D drone model
- Real-time attitude representation
- Position tracking and history
- Data-rich telemetry charts
-
Optimized Architecture
- Websocket-based communications
- Efficient data processing
- Modular component design
- Cross-platform compatibility
- The SkySync backend utilizes Python-based MAVLink integration to capture real-time telemetry data
- Advanced data processing transforms raw MAVLink messages into structured JSON formats
- The frontend consumes this processed data through efficient pull/push mechanisms for real-time display
- Configurable data rates and filtering options optimize performance across different network conditions
- WebSocket-based communication provides low-latency calibration command handling
- Bi-directional data flow enables real-time feedback during calibration procedures
- Step-by-step guided calibration workflow with visual indicators and progress tracking
- Support for all standard drone calibration procedures with advanced error detection
- Built with Next.js and React for optimal performance and SEO capabilities
- Three.js-powered 3D visualizations for immersive drone attitude representation
- Tailwind CSS implementation for responsive design across all device sizes
- Component-based architecture enabling easy customization and extension
- Python-based microservices handling different aspects of drone communication
- Robust error handling and recovery mechanisms for connection disruptions
- Data persistence layer for telemetry logging and analysis
- Configurable communication parameters to support various drone hardware
-
Hardware Requirements
- Pixhawk-compatible flight controller
- USB or telemetry connection to drone
- Computer with internet connection
-
Software Requirements
- Node.js 16+ and npm/pnpm
- Python 3.8+
- MAVProxy (optional but recommended)
# Clone the SkySync repository
git clone https://github.com/your-username/skysync-gcs.git
cd skysync-gcs
# Install frontend dependencies
pnpm install
# or with npm
npm install
# Install Python dependencies
pip install pymavlink websockets asyncio pyserialCreate a .env.local file in the project root:
NEXT_PUBLIC_WEBSOCKET_URL=ws://localhost:8765
NEXT_PUBLIC_MAVLINK_CONNECTION=/dev/tty.usbserial-XXXX
NEXT_PUBLIC_BAUD_RATE=57600
Adjust the serial port to match your system configuration:
- macOS:
/dev/tty.usbserial-XXXX - Linux:
/dev/ttyUSB0or/dev/ttyACM0 - Windows:
COM3(or other COM port)
IMPORTANT: We use MAVProxy as a bridge to avoid port conflicts between multiple applications:
graph LR
A[Drone Hardware<br/>/dev/tty.usbserial-XXXX] --> B[MAVProxy<br/>Master Connection]
B --> C[UDP:14550<br/>listen.py]
B --> D[UDP:14551<br/>Other Apps]
B --> E[Console<br/>Commands]
style A fill:#ff6b6b
style B fill:#4ecdc4
style C fill:#45b7d1
style D fill:#96ceb4
style E fill:#feca57
Setup Commands:
# Terminal 1: Start MAVProxy with UDP forwarding (REQUIRED FIRST)
mavproxy.py --master=/dev/tty.usbserial-XXXX --baud=115200 --out=udp:localhost:14550 --out=udp:localhost:14551 --console
# You should see:
# "Connecting to /dev/tty.usbserial-XXXX"
# "Received heartbeat from APM"Data Flow Architecture:
sequenceDiagram
participant D as Drone Hardware
participant M as MAVProxy
participant L as listen.py
participant J as Jetson Device
participant F as Frontend
D->>M: MAVLink Messages
M->>L: UDP Stream (14550)
L->>L: Parse & Save JSON
F->>L: Fetch JSON Files
J->>J: Update safe_zone_data.txt
F->>J: SCP Fetch (30s interval)
F->>F: Combine Telemetry + Arena Data
Start all services in order:
# Terminal 1: MAVProxy (Hardware Bridge)
mavproxy.py --master=/dev/tty.usbserial-XXXX --baud=115200 --out=udp:localhost:14550 --console
# Terminal 2: Telemetry Listener (via UDP)
python3 listen.py --connection=udp:localhost:14550
# Terminal 3: Calibration Server
python3 calibrating/calibration_server.py
# Terminal 4: Next.js Web Interface
npm run devSystem Status Check:
# Verify MAVProxy connection
# Should show: "heartbeat from system X component Y"
# Check JSON files being created
ls -la public/params/
# Should show: ATTITUDE.json, GLOBAL_POSITION_INT.json, etc.
# Test Jetson connection
curl http://localhost:3000/api/jetson-dataNavigate to http://localhost:3000 in your browser to access the SkySync GCS interface.
SkySync GCS provides comprehensive drone telemetry monitoring:
- Attitude Data: Real-time roll, pitch, yaw with 3D visualization
- Position Tracking: GPS coordinates with map overlay and flight path
- System Health: Battery status, signal strength, and system diagnostics
- Sensor Data: IMU readings, magnetometer data, and barometric information
The calibration interface guides you through each procedure with clear instructions:
-
Gyroscope Calibration
- Automatically detects and corrects gyro bias
- Visual indicators for calibration quality
-
Accelerometer Calibration
- Six-position guided calibration workflow
- Real-time feedback for each position
-
Magnetometer Calibration
- Interactive compass calibration with visual guidance
- Interference detection and correction
-
Radio Calibration
- Channel mapping and endpoint configuration
- Failsafe testing and configuration
SkySync GCS features a completely dynamic drone arena visualization system that fetches real-time arena boundaries and safe spots from a Jetson device via SCP. No coordinates are hardcoded - everything is dynamically fetched and updated in real-time.
graph TD
A[Jetson Device<br/>10.0.2.219] --> B[SCP Fetch<br/>Every 30s]
B --> C[Backend API<br/>/api/jetson-data]
C --> D[Frontend UI<br/>/safe-spots]
D --> E[Live Visualization<br/>Arena + Safe Spots]
F[Drone Telemetry] --> G[MAVProxy<br/>UDP Bridge]
G --> H[listen.py<br/>JSON Writer]
H --> I[Position Updates<br/>250ms]
I --> D
J[GPS Coordinates] --> K[Field Coordinate<br/>Conversion]
K --> E
style A fill:#ffd93d
style B fill:#6bcf7f
style C fill:#4d96ff
style D fill:#ff6b9d
style E fill:#c44536
style F fill:#ff8c42
style G fill:#6c5ce7
style H fill:#a29bfe
style I fill:#fd79a8
Complete System Integration:
flowchart TB
subgraph HW["π§ Hardware Layer"]
DRONE[Pixhawk/Drone<br/>MAVLink Protocol]
JETSON[Jetson Device<br/>10.0.2.219]
end
subgraph BRIDGE["π Communication Bridge"]
MAVPROXY[MAVProxy<br/>UDP Forwarding]
SCP[SCP Protocol<br/>File Transfer]
end
subgraph BACKEND["βοΈ Backend Services"]
LISTEN[listen.py<br/>Telemetry Parser]
API[Jetson API<br/>Route Handler]
CALIB[Calibration<br/>WebSocket Server]
end
subgraph FRONTEND["π¨ Frontend Interface"]
REACT[Next.js/React<br/>Components]
SAFESPOTS[Safe Spots<br/>Detection UI]
ARENA[3D Arena<br/>Visualization]
TELEMETRY[Real-time<br/>Dashboard]
end
subgraph DATA["π Data Layer"]
JSON[Telemetry JSON<br/>Files]
TEMP[Temporary<br/>SCP Cache]
end
DRONE --> MAVPROXY
JETSON --> SCP
MAVPROXY --> LISTEN
SCP --> API
LISTEN --> JSON
API --> TEMP
JSON --> REACT
TEMP --> REACT
REACT --> SAFESPOTS
REACT --> ARENA
REACT --> TELEMETRY
CALIB --> REACT
style HW fill:#ff7675
style BRIDGE fill:#74b9ff
style BACKEND fill:#00b894
style FRONTEND fill:#fdcb6e
style DATA fill:#e17055
π Jetson Device ([email protected])
βββ /home/nvidia/safe_zone_data.txt β UPDATE THIS FILE FOR LIVE DATA
File Format:
Arena:
Corner1: [12.0345, 77.1234]
Corner2: [12.0345, 77.1265]
Corner3: [12.0315, 77.1265]
Corner4: [12.0315, 77.1234]
Detected Safe Spots
SafeSpots:
Spot1: [12.0331, 77.1245]
Spot2: [12.0320, 77.1255]
Spot3: [12.0330, 77.1239]π app/api/jetson-data/route.ts
- Automatically connects to Jetson via SCP
- Downloads /home/nvidia/safe_zone_data.txt
- Parses GPS coordinates
- Returns structured JSON data
π app/safe-spots/page.tsx β Safe Spots Detection UI
π app/arena/page.tsx β 3D Arena Visualization
- Jetson Device updates
/home/nvidia/safe_zone_data.txtwith live GPS coordinates - Backend API fetches data via SCP every 30 seconds
- Frontend receives JSON data and converts GPS to field coordinates
- Visualization renders dynamic arena polygon and safe spots
- Real-time Updates show drone position and safe spot detection
# SSH to Jetson device
ssh [email protected]
# Edit the safe zone file
nano /home/nvidia/safe_zone_data.txt
# Update coordinates and save
# System automatically fetches updates every 30 secondsCreate this script on the Jetson device for continuous updates:
# /home/nvidia/update_safe_zones.py
import time
import random
import json
from datetime import datetime
def update_safe_zone_data():
# Base coordinates (adjust for your location)
base_lat = 12.0330
base_lng = 77.1250
# Define arena corners (fixed rectangle)
arena_data = f"""Arena:
Corner1: [{base_lat + 0.0015:.6f}, {base_lng - 0.0016:.6f}]
Corner2: [{base_lat + 0.0015:.6f}, {base_lng + 0.0015:.6f}]
Corner3: [{base_lat - 0.0015:.6f}, {base_lng + 0.0015:.6f}]
Corner4: [{base_lat - 0.0015:.6f}, {base_lng - 0.0016:.6f}]
Detected Safe Spots
SafeSpots:"""
# Generate dynamic safe spots (example: 3 random spots within arena)
safe_spots = []
for i in range(1, 4):
lat = base_lat + random.uniform(-0.001, 0.001)
lng = base_lng + random.uniform(-0.001, 0.001)
safe_spots.append(f"Spot{i}: [{lat:.6f}, {lng:.6f}]")
content = arena_data + "\n" + "\n".join(safe_spots)
# Write to file
with open('/home/nvidia/safe_zone_data.txt', 'w') as f:
f.write(content)
print(f"β
Updated safe zone data at {time.ctime()}")
# Run continuously
if __name__ == "__main__":
while True:
update_safe_zone_data()
time.sleep(10) # Update every 10 secondsAdvanced Jetson Integration Flow:
stateDiagram-v2
[*] --> Detecting
Detecting --> ProcessingGPS: GPS Lock Acquired
ProcessingGPS --> CalculatingSpots: Arena Boundaries Set
CalculatingSpots --> WritingFile: Safe Spots Identified
WritingFile --> WaitingUpdate: File Written
WaitingUpdate --> Detecting: Timer Expires (10s)
ProcessingGPS --> ErrorState: GPS Signal Lost
CalculatingSpots --> ErrorState: Invalid Coordinates
WritingFile --> ErrorState: File Write Failed
ErrorState --> Detecting: Retry After Delay
Jetson Data Processing Pipeline:
flowchart LR
subgraph JETSON["π€ Jetson Device"]
GPS[GPS Module<br/>Coordinate Input]
PROCESS[Data Processing<br/>Safe Spot Detection]
FILE[File Writer<br/>safe_zone_data.txt]
end
subgraph NETWORK["π Network Transfer"]
SCP[SCP Protocol<br/>SSH File Transfer]
CACHE[Temp Cache<br/>Local Storage]
end
subgraph WEBAPP["π₯οΈ Web Application"]
API[API Endpoint<br/>/api/jetson-data]
PARSE[Data Parser<br/>GPS β Local Coords]
UI[React UI<br/>Live Visualization]
end
GPS --> PROCESS
PROCESS --> FILE
FILE --> SCP
SCP --> CACHE
CACHE --> API
API --> PARSE
PARSE --> UI
style JETSON fill:#e74c3c
style NETWORK fill:#3498db
style WEBAPP fill:#2ecc71
Run on Jetson:
python3 /home/nvidia/update_safe_zones.pyComplete System Testing Flow:
graph TB
subgraph TEST["π§ͺ Testing Workflow"]
START[Start Testing] --> MOCK[Test Mock Data]
MOCK --> JETSON[Test Jetson SCP]
JETSON --> INTEGRATION[Test Full Integration]
INTEGRATION --> VALIDATION[Validate Real-time Updates]
end
subgraph COMMANDS["π» Test Commands"]
CMD1[curl -X POST<br/>Mock Data Test]
CMD2[curl -X GET<br/>Real SCP Test]
CMD3[Browser Test<br/>Live Visualization]
CMD4[SSH Test<br/>Jetson Connection]
end
MOCK --> CMD1
JETSON --> CMD2
INTEGRATION --> CMD3
VALIDATION --> CMD4
style TEST fill:#f39c12
style COMMANDS fill:#9b59b6
# Test with mock data (no Jetson required)
curl -X POST http://localhost:3000/api/jetson-data
# Test with real Jetson SCP connection
curl http://localhost:3000/api/jetson-data
# Test Jetson SSH connectivity
ssh [email protected] "echo 'Connection successful'"
# Test file exists on Jetson
ssh [email protected] "cat /home/nvidia/safe_zone_data.txt"# Start the development server
npm run dev
# Open in browser:
# http://localhost:3000/safe-spots β Safe Spots Detection
# http://localhost:3000/arena β 3D Arena VisualizationReal-time Data Monitoring:
sequenceDiagram
participant U as User Browser
participant F as Frontend
participant A as API Route
participant J as Jetson Device
participant D as Drone
loop Every 30 seconds
F->>A: Fetch Jetson Data
A->>J: SCP Request
J-->>A: safe_zone_data.txt
A-->>F: Parsed JSON
F-->>U: Update Arena UI
end
loop Every 250ms
F->>F: Fetch Telemetry JSON
D->>F: Position Data
F-->>U: Update Drone Position
end
Note over F,U: Real-time Safe Spot Detection
F->>F: Calculate Distance
F-->>U: Proximity Alert
- π Auto-Refresh: Fetches new data every 30 seconds
- π GPS Conversion: Converts GPS coordinates to field coordinates
- π― Safe Spot Detection: Real-time proximity detection with 0.5m threshold
- β¨ Visual Effects: Pulsing animations for detected safe spots
- π Live Status: Connection status and data freshness indicators
- πΊοΈ Dynamic Arena: Arena boundaries render from fetched GPS corners
- π Position Trail: Shows drone movement history
β οΈ Alerts: Pop-up notifications when entering safe spots
const JETSON_CONFIG = {
ip: '10.0.2.219', // Jetson IP address
username: 'jetson123', // SSH username
remotePath: '/home/nvidia/safe_zone_data.txt', // File path on Jetson
localPath: path.join(process.cwd(), 'temp', 'safe_zone_data.txt') // Local temp file
}const DETECTION_THRESHOLD = 0.5 // Detection radius in meters
const UPDATE_INTERVAL = 30000 // SCP fetch interval (30 seconds)
const POSITION_UPDATE = 250 // Drone position update (250ms)- SCP Fetch: 30-second intervals to avoid overloading Jetson
- Position Updates: 250ms (4Hz) for smooth drone tracking
- GPS Conversion: Real-time coordinate transformation
- Visual Rendering: 60fps smooth animations with Three.js
- Memory Efficient: Automatic cleanup of temporary SCP files
System Diagnostics Flow:
flowchart TD
START[System Issue] --> IDENTIFY{Identify Component}
IDENTIFY -->|Telemetry| TEL[Telemetry Issues]
IDENTIFY -->|Jetson| JET[Jetson Connection]
IDENTIFY -->|Frontend| FE[Frontend Problems]
IDENTIFY -->|MAVProxy| MAV[MAVProxy Issues]
TEL --> TEL1[Check MAVProxy Status]
TEL --> TEL2[Verify listen.py Running]
TEL --> TEL3[Check JSON Files]
JET --> JET1[Test SSH Connection]
JET --> JET2[Verify File Exists]
JET --> JET3[Check SCP Permissions]
FE --> FE1[Clear Browser Cache]
FE --> FE2[Check Console Errors]
FE --> FE3[Verify API Responses]
MAV --> MAV1[Check Port Conflicts]
MAV --> MAV2[Verify Hardware Connection]
MAV --> MAV3[Test Different Baud Rates]
style START fill:#e74c3c
style TEL fill:#3498db
style JET fill:#f39c12
style FE fill:#2ecc71
style MAV fill:#9b59b6
# Test SSH connection to Jetson
ssh [email protected]
# Check if file exists
ls -la /home/nvidia/safe_zone_data.txt
# Test SCP manually
scp [email protected]:/home/nvidia/safe_zone_data.txt ./test_file.txt
# Check MAVProxy UDP ports
netstat -an | grep 14550
netstat -an | grep 14551
# Test listen.py connection
python3 listen.py --connection=udp:localhost:14550 --baud=115200Port Conflict Resolution:
graph LR
A[Port Conflict Detected] --> B{Check Running Processes}
B --> C[Kill MAVProxy: pkill -f mavproxy]
B --> D[Kill listen.py: pkill -f listen.py]
B --> E[Kill Other Apps: lsof -i :14550]
C --> F[Restart in Correct Order]
D --> F
E --> F
F --> G[1. MAVProxy First]
G --> H[2. listen.py Second]
H --> I[3. Web App Last]
style A fill:#e74c3c
style F fill:#f39c12
style I fill:#27ae60
- Ensure Jetson device is connected to network
- Verify SSH key authentication is set up
- Check firewall settings on both devices
- Confirm file permissions on Jetson device
- Restart MAVProxy if UDP ports are busy
- Clear browser cache for frontend issues
SkySync GCS works seamlessly across all devices:
- Desktop: Full-featured interface with expanded data visualization
- Tablet: Optimized touch controls and readable data displays
- Mobile: Essential controls and telemetry for field operations
Fetches live arena and safe spot data from Jetson device via SCP.
// Response Format
{
"arena": [
{ "lat": 12.0345, "lng": 77.1234 },
{ "lat": 12.0345, "lng": 77.1265 },
{ "lat": 12.0315, "lng": 77.1265 },
{ "lat": 12.0315, "lng": 77.1234 }
],
"safeSpots": [
{ "id": "Spot1", "lat": 12.0331, "lng": 77.1245 },
{ "id": "Spot2", "lat": 12.0320, "lng": 77.1255 },
{ "id": "Spot3", "lat": 12.0330, "lng": 77.1239 }
],
"timestamp": "2025-06-07T10:30:45.123Z",
"status": "success"
}Error Response:
{
"arena": [],
"safeSpots": [],
"timestamp": "2025-06-07T10:30:45.123Z",
"status": "error",
"error": "Failed to fetch data from Jetson"
}Returns mock data for testing purposes (no Jetson connection required).
# Example Usage
curl -X GET http://localhost:3000/api/jetson-data
curl -X POST http://localhost:3000/api/jetson-data # Mock data# Local Position (NED coordinates)
GET /params/local_position_ned.json
# Global Position (GPS coordinates)
GET /params/global_position_int.json
# Attitude Data
GET /params/attitude.json
# Battery Status
GET /params/battery_status.jsonExample Response:
// local_position_ned.json
{
"x": 2.45,
"y": -1.23,
"z": -0.15,
"vx": 0.1,
"vy": -0.05,
"vz": 0.02,
"time_boot_ms": 45678
}// Connect to live telemetry WebSocket
const ws = new WebSocket('ws://localhost:8765/telemetry')
ws.onmessage = (event) => {
const data = JSON.parse(event.data)
// Handle real-time telemetry data
}// Calibration WebSocket
const calibWs = new WebSocket('ws://localhost:8765/calibration')
// Send calibration command
calibWs.send(JSON.stringify({
command: 'start_gyro_calibration',
parameters: {}
}))We're continuously improving SkySync GCS with new features:
- Q3 2025: Advanced mission planning with waypoint management
- Q4 2025: AI-powered anomaly detection for preventive maintenance
- Q1 2026: Enhanced 3D mapping with LiDAR and SLAM integration
- Q2 2026: Multi-vehicle control and fleet management capabilities
We welcome contributions to SkySync GCS:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the proprietary license. All rights reserved.
For support, feature requests, or inquiries:
- Website: Upcoming
- Email: [email protected]
- Twitter: Upcoming
- GitHub Issues: For bug reports and feature requests
SkySync GCS is optimized for real-time drone operations:
- Update Rate: Up to 50Hz telemetry updates
- Latency: <100ms typical end-to-end latency
- Resource Usage: <200MB memory footprint
- Compatibility: Works with MAVLink 1.0 and 2.0
- SCP Data Fetch: 30-second intervals from Jetson device
- Position Updates: 250ms (4Hz) for smooth drone tracking
- GPS Conversion: Real-time coordinate transformation (<5ms)
- Visual Rendering: 60fps smooth animations with Three.js
- Memory Efficiency: Auto-cleanup of temporary SCP files
- Detection Accuracy: 0.5m threshold for safe spot proximity
- Connection Timeout: 10-second SCP timeout with fallback
Connect to your drone using multiple methods:
- Serial Connection: Direct USB to Pixhawk (FTDI)
- Telemetry Radio: Support for SiK radios (433/915MHz)
- Wi-Fi: ESP8266/ESP32-based telemetry bridges
- Bluetooth: Experimental support for HC-05/HC-06
- SCP/SSH: Jetson device integration for arena data
SkySync GCS monitors comprehensive drone metrics:
- Attitude: Roll, pitch, yaw (degrees and quaternions)
- Position: Latitude, longitude, altitude (GPS and barometric)
- Velocity: Ground speed and 3D velocity vector (m/s)
- RC Input: All channel values and control positions
- Arena Boundaries: GPS coordinates converted to field coordinates
- Safe Spots: Real-time GPS positions with detection zones
- Proximity Detection: Distance calculation and alert system
- Data Freshness: Timestamp tracking for Jetson data updates
- Connection Status: Live monitoring of Jetson device connectivity
- Battery: Voltage, current, remaining capacity, cells
- Connection: Signal strength, packet loss, round-trip time
- System: CPU usage, storage, temperature, uptime
- Sensors: Gyroscope, accelerometer, magnetometer, barometer health
- Jetson Status: SCP connection health and data validation
# Start MAVProxy with UDP forwarding (FIRST - Master connection)
mavproxy.py --master=/dev/tty.usbserial-XXXX --baud=115200 --out=udp:localhost:14550 --out=udp:localhost:14551 --console
# Start telemetry listener (SECOND - Connects via UDP to MAVProxy)
python3 listen.py --connection=udp:localhost:14550
# Start calibration server (THIRD - Independent WebSocket server)
python3 calibrating/calibration_server.py
# Start web interface (FOURTH - Frontend application)
npm run dev
# Test dynamic arena system
curl -X GET http://localhost:3000/api/jetson-data # Real SCP fetch
curl -X POST http://localhost:3000/api/jetson-data # Mock data test
# Jetson connection tests
ssh [email protected] "echo 'Jetson connected'"
scp [email protected]:/home/nvidia/safe_zone_data.txt ./test.txtService Startup Sequence:
gantt
title SkySync GCS Startup Sequence
dateFormat X
axisFormat %M:%S
section Hardware
Connect Drone Hardware :done, hardware, 0, 30s
section Communication
Start MAVProxy Bridge :active, mavproxy, after hardware, 45s
Establish UDP Streams :udp, after mavproxy, 15s
section Data Processing
Start listen.py :listen, after udp, 30s
Start Calibration Server :calib, after listen, 30s
section Frontend
Start Next.js App :frontend, after calib, 60s
Load Web Interface :ui, after frontend, 30s
section Integration
Test Jetson Connection :jetson, after ui, 45s
Verify Full System :verify, after jetson, 30s
SkySync GCS/
βββ app/
β βββ api/jetson-data/route.ts # π‘οΈ Dynamic arena SCP API
β βββ safe-spots/page.tsx # π‘οΈ Safe spots detection UI
β βββ arena/page.tsx # π‘οΈ 3D arena visualization
β βββ telemetry/page.tsx # π‘ Real-time telemetry
β βββ calibration/page.tsx # π οΈ Sensor calibration
β βββ layout.tsx # π¨ Main layout
βββ components/
β βββ ui/ # π¨ Reusable UI components
β βββ telemetry-chart.tsx # π Data visualization
β βββ navigation.tsx # π§ Navigation components
βββ public/params/ # π Live telemetry JSON files
βββ temp/safe_zone_data.txt # π‘οΈ Jetson data cache
βββ calibrating/ # π οΈ Python calibration scripts
βββ listen.py # π‘ MAVLink β JSON converter
βββ public/ # πΌοΈ Static assets
Data Flow Through Project Structure:
flowchart LR
subgraph INPUT["π₯ Input Sources"]
DRONE[Drone<br/>MAVLink Data]
JETSON[Jetson Device<br/>GPS Coordinates]
end
subgraph PROCESSING["βοΈ Processing Layer"]
MAVPROXY[MAVProxy<br/>UDP Bridge]
LISTEN[listen.py<br/>JSON Writer]
SCPAPI[SCP API<br/>route.ts]
end
subgraph STORAGE["πΎ Data Storage"]
PARAMS[public/params/<br/>Telemetry Files]
TEMP[temp/<br/>Arena Cache]
end
subgraph OUTPUT["π₯οΈ Output Interface"]
SAFESPOTS[Safe Spots<br/>page.tsx]
ARENA[3D Arena<br/>page.tsx]
TELEMETRY[Telemetry<br/>page.tsx]
end
DRONE --> MAVPROXY
MAVPROXY --> LISTEN
LISTEN --> PARAMS
JETSON --> SCPAPI
SCPAPI --> TEMP
PARAMS --> SAFESPOTS
PARAMS --> TELEMETRY
TEMP --> SAFESPOTS
TEMP --> ARENA
style INPUT fill:#ff7675
style PROCESSING fill:#74b9ff
style STORAGE fill:#00b894
style OUTPUT fill:#fdcb6e
File Dependencies Map:
graph TD
subgraph CORE["π― Core Files"]
LISTEN[listen.py<br/>Telemetry Processor]
ROUTE[route.ts<br/>Jetson API]
LAYOUT[layout.tsx<br/>App Structure]
end
subgraph PAGES["π Page Components"]
SAFE[safe-spots/page.tsx]
ARENA[arena/page.tsx]
TELEM[telemetry/page.tsx]
CALIB[calibration/page.tsx]
end
subgraph DATA["π Data Files"]
JSON[params/*.json]
CACHE[temp/safe_zone_data.txt]
STATIC[public/assets]
end
subgraph UTILS["π§ Utilities"]
COMPONENTS[components/ui/*]
HOOKS[hooks/*]
LIB[lib/utils.ts]
end
LISTEN --> JSON
ROUTE --> CACHE
JSON --> SAFE
JSON --> TELEM
CACHE --> SAFE
CACHE --> ARENA
COMPONENTS --> SAFE
COMPONENTS --> ARENA
COMPONENTS --> TELEM
COMPONENTS --> CALIB
HOOKS --> SAFE
HOOKS --> ARENA
LIB --> SAFE
LAYOUT --> SAFE
LAYOUT --> ARENA
LAYOUT --> TELEM
LAYOUT --> CALIB
style CORE fill:#e74c3c
style PAGES fill:#3498db
style DATA fill:#f39c12
style UTILS fill:#27ae60
Hardware Requirements:
mindmap
root((SkySync GCS<br/>Requirements))
Minimum Hardware
2 GHz dual-core processor
4 GB RAM
1 GB storage
USB 2.0 port
Recommended Hardware
2.5 GHz quad-core processor
8 GB RAM
2 GB storage
USB 3.0 port
Network Requirements
Ethernet/WiFi connection
SSH access to Jetson
Internet for dependencies
Drone Hardware
Pixhawk compatible FC
MAVLink 1.0/2.0 support
USB or telemetry radio
GPS module (recommended)
Software Compatibility Matrix:
graph TB
subgraph OS["π» Operating Systems"]
MACOS[macOS 11+<br/>β
Fully Supported]
UBUNTU[Ubuntu 20.04+<br/>β
Fully Supported]
WINDOWS[Windows 10/11<br/>β
Fully Supported]
RASPI[Raspberry Pi OS<br/>β οΈ Limited Support]
end
subgraph RUNTIME["π§ Runtime Requirements"]
NODE[Node.js 16+<br/>Required]
PYTHON[Python 3.8+<br/>Required]
MAVPROXY[MAVProxy<br/>Recommended]
GIT[Git<br/>Required for setup]
end
subgraph OPTIONAL["π¦ Optional Components"]
DOCKER[Docker<br/>For containerization]
VSCODE[VS Code<br/>Development]
CHROME[Chrome/Firefox<br/>Web interface]
end
OS --> RUNTIME
RUNTIME --> OPTIONAL
style OS fill:#3498db
style RUNTIME fill:#e74c3c
style OPTIONAL fill:#f39c12
-
Minimum Hardware
- 2 GHz dual-core processor
- 4 GB RAM
- 1 GB available storage
- USB port for drone connection
-
Recommended Hardware
- 2.5 GHz quad-core processor
- 8 GB RAM
- 2 GB available storage
- USB 3.0 port
-
Supported Operating Systems
- Windows 10/11
- macOS 11+
- Ubuntu 20.04+
- Raspberry Pi OS (64-bit)
Special thanks to:
- ArduPilot Team for MAVLink protocol development
- QGroundControl and Mission Planner for inspiration
SkySync GCS - Professional Ground Control System
Β© 2025 Arnav Angarkar . All Rights Reserved.
- Install Node.js (LTS version) from nodejs.org
- Install Python 3.8+ from python.org
- Install MAVProxy:
# On macOS
brew install mavproxy
# On Ubuntu/Debian
sudo apt-get install python3-pip python3-dev
pip3 install MAVProxy
# On Windows
pip install MAVProxy# 1. Clone the repository
git clone https://github.com/ArnavBallinCode/Drone_Web_9009.git
cd Drone_Web_9009
# 2. Install Python dependencies
pip install pymavlink websockets asyncio pyserial
# 3. Install Node.js dependencies
npm install
# or if using pnpm
pnpm install- Connect your Pixhawk/drone via USB
- Identify the correct port:
# On macOS/Linux
ls /dev/tty.*
# Look for something like /dev/tty.usbserial-D30JKVZM
# On Windows
# Check Device Manager under "Ports (COM & LPT)"
# Look for something like COM3# On macOS/Linux
mavproxy.py --master=/dev/tty.usbserial-D30JKVZM --baud=57600 --out=udp:localhost:14550 --out=udp:localhost:14551
# On Windows
mavproxy.py --master=COM3 --baud=57600 --out=udp:localhost:14550 --out=udp:localhost:14551
# You should see:
# "Connecting to SITL on TCP port 5760"
# "Received heartbeat from APM"Open a new terminal and run:
# On macOS/Linux
python3 listen.py --connection /dev/tty.usbserial-D30JKVZM --baud 57600
# On Windows
python listen.py --connection COM3 --baud 57600
# You should see:
# "Connected to drone"
# "Writing telemetry data..."Open another new terminal and run:
# On macOS/Linux
python3 caliberating/calibration_server.py
# On Windows
python caliberating/calibration_server.py
# You should see:
# "Starting WebSocket server..."
# "Calibration WebSocket server started on ws://localhost:8765"Open another new terminal and run:
# Using npm
npm run dev
# Using pnpm
pnpm dev
# You should see:
# "ready - started server on 0.0.0.0:3000"- Open your browser and go to:
- Main interface: http://localhost:3000
- Calibration page: http://localhost:3000/calibration
-
Gyroscope Calibration
- Keep the drone completely still on a level surface
- Click "Start Gyro Calibration"
- Wait for completion (about 30 seconds)
-
Accelerometer Calibration
- Click "Start Accelerometer Calibration"
- Follow the orientation instructions:
- Place vehicle level
- On right side
- On left side
- Nose down
- Nose up
- On its back
- Hold each position until you see "Position detected"
- Wait for "Position calibrated successfully" before moving to next position
-
Magnetometer Calibration
- Click "Start Magnetometer Calibration"
- Rotate the drone around all axes
- Continue rotation for at least 30 seconds
- Keep away from metal objects
- Wait for completion message
-
Barometer Calibration
- Keep the drone still
- Click "Start Barometer Calibration"
- Wait for completion (about 30 seconds)
-
No Serial Port Connection
# List all serial ports python3 -m serial.tools.list_ports -
MAVProxy Connection Issues
- Ensure no other program is using the serial port
- Try different baud rates: 57600, 115200, 921600
- Check USB connection
-
Calibration Server Issues
- Ensure MAVProxy is running first
- Check if port 8765 is free:
# On macOS/Linux lsof -i :8765 # On Windows netstat -ano | findstr :8765
-
Web Interface Issues
- Clear browser cache
- Check console for errors (F12)
- Ensure all servers are running
- MAVProxy UDP outputs: 14550, 14551
- Calibration WebSocket: 8765
- Web Interface: 3000 (or 3001)
# All commands needed (in order):
mavproxy.py --master=/dev/tty.usbserial-D30JKVZM --baud=57600 --out=udp:localhost:14550 --out=udp:localhost:14551
python3 listen.py --connection /dev/tty.usbserial-D30JKVZM --baud 57600
python3 caliberating/calibration_server.py
pnpm dev # or npm run dev- Python 3.8+
- Node.js 16+
- Modern web browser (Chrome, Firefox, Safari)
- USB port for drone connection
- 2GB RAM minimum
- 1GB free disk space
Drone_Web_9009/
βββ caliberating/
β βββ calibration_server.py # WebSocket calibration server
βββ public/
β βββ params/ # Telemetry JSON files
βββ app/
β βββ calibration/ # Calibration UI components
βββ lib/
β βββ mavlink/ # MAVLink utilities
βββ listen.py # Telemetry listener
βββ package.json # Node.js dependencies
-
Connection Settings
# For PX4, use these MAVProxy settings: mavproxy.py --master=/dev/tty.usbserial-D30JKVZM --baud=921600 --out=udp:localhost:14550 --out=udp:localhost:14551Note: PX4 typically uses 921600 baud rate by default
-
Calibration Commands
- PX4 uses slightly different calibration parameters:
# Gyroscope params = [1, 0, 0, 0, 0, 0, 0] # Same as ArduPilot # Accelerometer params = [0, 0, 0, 0, 4, 0, 0] # Note: Uses 4 instead of 1 for simple calibration # Magnetometer params = [0, 1, 0, 0, 0, 0, 0] # Same as ArduPilot # Level Horizon params = [0, 0, 0, 0, 2, 0, 0] # Note: Uses 2 for level calibration
- PX4 uses slightly different calibration parameters:
-
Status Messages
- PX4 uses different status message formats:
- "[cal] progress "
- "[cal] orientation detected"
- "[cal] calibration done: "
- "CAL FAILED" for failures
- PX4 uses different status message formats:
-
Additional PX4 Parameters
# Set calibration auto-save (optional) param set CAL_AUTO_SAVE 1 # Set QGC core as remote (recommended) param set MAV_COMP_ID 190 param set MAV_SYS_ID 255
-
Troubleshooting PX4
- If calibration fails immediately:
# Check if the drone is armed # PX4 requires disarming for calibration commander disarm
- If no messages appear:
# Enable verbose output param set SYS_MC_EST_GROUP 2 param set SENS_BOARD_ROT 0
- If calibration fails immediately:
| Feature | ArduPilot | PX4 |
|---|---|---|
| Default Baud Rate | 57600 | 921600 |
| Calibration Messages | [cal] prefix | Various formats |
| Auto-save Calibration | Always | Configurable |
| Level Calibration | Part of Accel | Separate command |
| Simple Accel Cal | Value: 1 | Value: 4 |
| Status Updates | Frequent | On state change |
| UDP Forwarding | Optional | Recommended |
-
No Calibration Response
- Ensure drone is disarmed
- Check parameter
CAL_AUTO_SAVE - Verify
SYS_MC_EST_GROUPsetting
-
Connection Issues
# For PX4, try these settings: mavproxy.py --master=/dev/tty.usbserial-D30JKVZM --baud=921600 --source-system=255 --source-component=190 --out=udp:localhost:14550 --out=udp:localhost:14551 -
Calibration Timeouts
- PX4 may need longer timeouts:
CALIBRATION_TIMEOUT = 180 # Increase from 120 to 180 seconds
- PX4 may need longer timeouts:
