kellil-uav1 / index.html
nkellil's picture
Add 3 files
be78e49 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PV Plant Surveillance Drone Control</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<style>
#map { height: 100%; width: 100%; }
.waypoint-marker { background-color: #3b82f6; width: 12px; height: 12px; border-radius: 50%; border: 2px solid white; }
.home-marker { background-color: #ef4444; width: 14px; height: 14px; border-radius: 50%; border: 2px solid white; }
.drone-marker { background-color: #10b981; width: 16px; height: 16px; border-radius: 50%; border: 2px solid white; }
.custom-scrollbar::-webkit-scrollbar {
width: 6px;
}
.custom-scrollbar::-webkit-scrollbar-track {
background: #f1f1f1;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background: #888;
border-radius: 3px;
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
background: #555;
}
.telemetry-value {
font-family: 'Courier New', monospace;
font-size: 0.9rem;
}
.gauge {
width: 100%;
height: 8px;
background: #e5e7eb;
border-radius: 4px;
overflow: hidden;
}
.gauge-fill {
height: 100%;
background: linear-gradient(90deg, #10b981, #3b82f6);
border-radius: 4px;
}
</style>
</head>
<body class="bg-gray-100 text-gray-800 h-screen flex flex-col">
<!-- Header -->
<header class="bg-blue-600 text-white p-4 shadow-md">
<div class="container mx-auto flex justify-between items-center">
<div class="flex items-center space-x-3">
<i class="fas fa-solar-panel text-2xl"></i>
<h1 class="text-xl font-bold">PV Plant Surveillance Drone Control</h1>
</div>
<div class="flex items-center space-x-4">
<div class="flex items-center space-x-2">
<div class="w-3 h-3 rounded-full bg-green-500 animate-pulse"></div>
<span class="text-sm">MAVLINK Connected</span>
</div>
<button class="bg-red-500 hover:bg-red-600 px-3 py-1 rounded text-sm">
<i class="fas fa-power-off mr-1"></i> Emergency Stop
</button>
</div>
</div>
</header>
<!-- Main Content -->
<div class="flex flex-1 overflow-hidden">
<!-- Sidebar -->
<div class="w-80 bg-white border-r border-gray-200 flex flex-col">
<!-- Connection Panel -->
<div class="p-4 border-b border-gray-200">
<h2 class="font-semibold text-lg mb-3 flex items-center">
<i class="fas fa-plug mr-2 text-blue-500"></i> Connection
</h2>
<div class="space-y-3">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Connection Type</label>
<select class="w-full p-2 border border-gray-300 rounded">
<option>UDP</option>
<option>TCP</option>
<option>Serial</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Address</label>
<input type="text" class="w-full p-2 border border-gray-300 rounded" value="192.168.1.100">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Port</label>
<input type="text" class="w-full p-2 border border-gray-300 rounded" value="14550">
</div>
<button class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 rounded flex items-center justify-center">
<i class="fas fa-link mr-2"></i> Connect
</button>
</div>
</div>
<!-- Telemetry Panel -->
<div class="p-4 border-b border-gray-200 flex-1 overflow-y-auto custom-scrollbar">
<h2 class="font-semibold text-lg mb-3 flex items-center">
<i class="fas fa-chart-line mr-2 text-green-500"></i> Telemetry
</h2>
<div class="space-y-4">
<div class="bg-gray-50 p-3 rounded">
<div class="flex justify-between items-center mb-1">
<span class="text-sm font-medium">Battery</span>
<span class="text-sm font-bold">78%</span>
</div>
<div class="gauge">
<div class="gauge-fill" style="width: 78%"></div>
</div>
</div>
<div class="grid grid-cols-2 gap-3">
<div class="bg-gray-50 p-2 rounded">
<div class="text-xs text-gray-500">Altitude</div>
<div class="telemetry-value">120.5 m</div>
</div>
<div class="bg-gray-50 p-2 rounded">
<div class="text-xs text-gray-500">Speed</div>
<div class="telemetry-value">8.2 m/s</div>
</div>
<div class="bg-gray-50 p-2 rounded">
<div class="text-xs text-gray-500">Satellites</div>
<div class="telemetry-value">12</div>
</div>
<div class="bg-gray-50 p-2 rounded">
<div class="text-xs text-gray-500">HDOP</div>
<div class="telemetry-value">1.2</div>
</div>
<div class="bg-gray-50 p-2 rounded">
<div class="text-xs text-gray-500">Latitude</div>
<div class="telemetry-value">48.8566°</div>
</div>
<div class="bg-gray-50 p-2 rounded">
<div class="text-xs text-gray-500">Longitude</div>
<div class="telemetry-value">2.3522°</div>
</div>
</div>
<div>
<h3 class="font-medium text-sm mb-2">Flight Mode</h3>
<div class="flex space-x-2">
<button class="px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-xs">GUIDED</button>
<button class="px-3 py-1 bg-gray-100 text-gray-800 rounded-full text-xs">AUTO</button>
<button class="px-3 py-1 bg-gray-100 text-gray-800 rounded-full text-xs">RTL</button>
<button class="px-3 py-1 bg-gray-100 text-gray-800 rounded-full text-xs">LOITER</button>
</div>
</div>
<div>
<h3 class="font-medium text-sm mb-2">Camera Control</h3>
<div class="grid grid-cols-3 gap-2">
<button class="p-2 bg-gray-100 rounded hover:bg-gray-200">
<i class="fas fa-camera"></i>
</button>
<button class="p-2 bg-gray-100 rounded hover:bg-gray-200">
<i class="fas fa-video"></i>
</button>
<button class="p-2 bg-gray-100 rounded hover:bg-gray-200">
<i class="fas fa-expand"></i>
</button>
<button class="p-2 bg-gray-100 rounded hover:bg-gray-200">
<i class="fas fa-arrow-up"></i>
</button>
<button class="p-2 bg-gray-100 rounded hover:bg-gray-200">
<i class="fas fa-arrow-down"></i>
</button>
<button class="p-2 bg-gray-100 rounded hover:bg-gray-200">
<i class="fas fa-thermometer-half"></i>
</button>
</div>
</div>
</div>
</div>
<!-- Mission Control -->
<div class="p-4 border-b border-gray-200">
<h2 class="font-semibold text-lg mb-3 flex items-center">
<i class="fas fa-map-marked-alt mr-2 text-purple-500"></i> Mission Control
</h2>
<div class="space-y-3">
<button class="w-full bg-green-600 hover:bg-green-700 text-white py-2 rounded flex items-center justify-center">
<i class="fas fa-play mr-2"></i> Start Mission
</button>
<button class="w-full bg-yellow-500 hover:bg-yellow-600 text-white py-2 rounded flex items-center justify-center">
<i class="fas fa-pause mr-2"></i> Pause Mission
</button>
<button class="w-full bg-red-500 hover:bg-red-600 text-white py-2 rounded flex items-center justify-center">
<i class="fas fa-undo mr-2"></i> Return to Launch
</button>
</div>
</div>
</div>
<!-- Main Map Area -->
<div class="flex-1 flex flex-col">
<!-- Map Tabs -->
<div class="bg-white border-b border-gray-200">
<div class="flex">
<button class="px-4 py-2 border-b-2 border-blue-500 text-blue-600 font-medium">Google Earth</button>
<button class="px-4 py-2 text-gray-600 hover:text-gray-800">Satellite</button>
<button class="px-4 py-2 text-gray-600 hover:text-gray-800">Topographic</button>
<button class="px-4 py-2 text-gray-600 hover:text-gray-800">PV Layout</button>
</div>
</div>
<!-- Map Container -->
<div id="map" class="flex-1"></div>
<!-- Mission Planning Panel -->
<div class="bg-white border-t border-gray-200 p-4">
<div class="flex justify-between items-center mb-3">
<h2 class="font-semibold text-lg flex items-center">
<i class="fas fa-route mr-2 text-purple-500"></i> Mission Planning
</h2>
<div class="flex space-x-2">
<button class="px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm flex items-center">
<i class="fas fa-plus mr-1"></i> Add Waypoint
</button>
<button class="px-3 py-1 bg-green-100 text-green-800 rounded-full text-sm flex items-center">
<i class="fas fa-save mr-1"></i> Save Mission
</button>
<button class="px-3 py-1 bg-gray-100 text-gray-800 rounded-full text-sm flex items-center">
<i class="fas fa-trash mr-1"></i> Clear
</button>
</div>
</div>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">#</th>
<th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Latitude</th>
<th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Longitude</th>
<th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Altitude</th>
<th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Speed</th>
<th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Action</th>
<th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase"></th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
<tr>
<td class="px-4 py-2 whitespace-nowrap text-sm font-medium text-gray-900">1</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">48.856612</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">2.352222</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">
<input type="number" class="w-20 p-1 border border-gray-300 rounded" value="100">
</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">
<input type="number" class="w-20 p-1 border border-gray-300 rounded" value="5">
</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">
<select class="p-1 border border-gray-300 rounded text-xs">
<option>Waypoint</option>
<option>Take Photo</option>
<option>Start Video</option>
<option>Thermal Scan</option>
</select>
</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">
<button class="text-red-500 hover:text-red-700">
<i class="fas fa-times"></i>
</button>
</td>
</tr>
<tr>
<td class="px-4 py-2 whitespace-nowrap text-sm font-medium text-gray-900">2</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">48.856712</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">2.353222</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">
<input type="number" class="w-20 p-1 border border-gray-300 rounded" value="100">
</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">
<input type="number" class="w-20 p-1 border border-gray-300 rounded" value="5">
</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">
<select class="p-1 border border-gray-300 rounded text-xs">
<option>Waypoint</option>
<option selected>Take Photo</option>
<option>Start Video</option>
<option>Thermal Scan</option>
</select>
</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">
<button class="text-red-500 hover:text-red-700">
<i class="fas fa-times"></i>
</button>
</td>
</tr>
<tr>
<td class="px-4 py-2 whitespace-nowrap text-sm font-medium text-gray-900">3</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">48.857612</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">2.354222</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">
<input type="number" class="w-20 p-1 border border-gray-300 rounded" value="100">
</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">
<input type="number" class="w-20 p-1 border border-gray-300 rounded" value="5">
</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">
<select class="p-1 border border-gray-300 rounded text-xs">
<option>Waypoint</option>
<option>Take Photo</option>
<option>Start Video</option>
<option selected>Thermal Scan</option>
</select>
</td>
<td class="px-4 py-2 whitespace-nowrap text-sm text-gray-500">
<button class="text-red-500 hover:text-red-700">
<i class="fas fa-times"></i>
</button>
</td>
</tr>
</tbody>
</table>
</div>
<div class="mt-4 flex justify-between">
<div class="flex items-center space-x-2">
<button class="px-3 py-1 bg-blue-600 text-white rounded text-sm">
<i class="fas fa-upload mr-1"></i> Import Mission
</button>
<button class="px-3 py-1 bg-gray-200 text-gray-800 rounded text-sm">
<i class="fas fa-download mr-1"></i> Export Mission
</button>
</div>
<div class="text-sm text-gray-600">
Total Distance: 1.2 km | Estimated Duration: 8 min 24 sec
</div>
</div>
</div>
</div>
</div>
<!-- Status Bar -->
<footer class="bg-gray-800 text-white p-2 text-sm">
<div class="container mx-auto flex justify-between items-center">
<div class="flex items-center space-x-4">
<span><i class="fas fa-satellite-dish mr-1 text-green-400"></i> GPS: 12 satellites</span>
<span><i class="fas fa-battery-three-quarters mr-1 text-yellow-400"></i> Battery: 78% (24.3V)</span>
<span><i class="fas fa-signal mr-1 text-blue-400"></i> RSSI: -65dBm</span>
</div>
<div>
<span><i class="fas fa-clock mr-1"></i> Flight Time: 00:12:45</span>
</div>
</div>
</footer>
<script>
// Initialize the map
const map = L.map('map').setView([48.8566, 2.3522], 15);
// Add Google Earth layer (this is a placeholder - in reality you'd need Google Earth API)
L.tileLayer('https://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}', {
maxZoom: 20,
subdomains: ['mt0', 'mt1', 'mt2', 'mt3'],
attribution: 'Google Earth'
}).addTo(map);
// Add PV plant area (polygon)
const pvPlant = L.polygon([
[48.8560, 2.3515],
[48.8560, 2.3535],
[48.8575, 2.3535],
[48.8575, 2.3515]
], {color: '#3b82f6', fillOpacity: 0.2}).addTo(map);
pvPlant.bindPopup("PV Plant Area");
// Add home position
const home = L.marker([48.8566, 2.3522], {
icon: L.divIcon({className: 'home-marker', html: ''})
}).addTo(map);
home.bindPopup("Home Position");
// Add drone position (would update in real application)
const drone = L.marker([48.8566, 2.3522], {
icon: L.divIcon({className: 'drone-marker', html: ''})
}).addTo(map);
drone.bindPopup("Drone Position");
// Add waypoints
const waypoints = [
{lat: 48.856612, lng: 2.352222, alt: 100},
{lat: 48.856712, lng: 2.353222, alt: 100},
{lat: 48.857612, lng: 2.354222, alt: 100}
];
const waypointMarkers = [];
waypoints.forEach((wp, i) => {
const marker = L.marker([wp.lat, wp.lng], {
icon: L.divIcon({className: 'waypoint-marker', html: ''})
}).addTo(map);
marker.bindPopup(`Waypoint ${i+1}<br>Altitude: ${wp.alt}m`);
waypointMarkers.push(marker);
});
// Draw lines between waypoints
const waypointLine = L.polyline(
waypoints.map(wp => [wp.lat, wp.lng]),
{color: '#3b82f6', dashArray: '5,5'}
).addTo(map);
// Simulate drone movement (for demo purposes)
let currentWp = 0;
function simulateDroneMovement() {
if (currentWp >= waypoints.length) {
currentWp = 0;
}
const target = waypoints[currentWp];
const currentPos = drone.getLatLng();
// Move drone slightly toward target
const newLat = currentPos.lat + (target.lat - currentPos.lat) * 0.1;
const newLng = currentPos.lng + (target.lng - currentPos.lng) * 0.1;
drone.setLatLng([newLat, newLng]);
// If close to waypoint, move to next
if (Math.abs(newLat - target.lat) < 0.0001 && Math.abs(newLng - target.lng) < 0.0001) {
currentWp++;
}
setTimeout(simulateDroneMovement, 500);
}
// Start simulation
simulateDroneMovement();
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=nkellil/kellil-uav1" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>