| 
							
								 | 
							
							<!DOCTYPE html>
 | 
						
						
						
						
							 | 
							
								 | 
							
							<html lang="zh-CN">
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							<head>
 | 
						
						
						
						
							 | 
							
								 | 
							
							    <meta charset="UTF-8">
 | 
						
						
						
						
							 | 
							
								 | 
							
							    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
						
						
						
						
							 | 
							
								 | 
							
							    <title>无人机控制 - 距离判断系统</title>
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    <!-- 内联Bootstrap CSS - 避免CDN依赖 -->
 | 
						
						
						
						
							 | 
							
								 | 
							
							    <style>
 | 
						
						
						
						
							 | 
							
								 | 
							
							        /* Bootstrap 5.1.3 基础样式 - 简化版 */
 | 
						
						
						
						
							 | 
							
								 | 
							
							        *,
 | 
						
						
						
						
							 | 
							
								 | 
							
							        *::before,
 | 
						
						
						
						
							 | 
							
								 | 
							
							        *::after {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            box-sizing: border-box;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        body {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            margin: 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            font-size: 1rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            font-weight: 400;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            line-height: 1.5;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #212529;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #f8f9fa;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .container-fluid {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            width: 100%;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            padding-right: 0.75rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            padding-left: 0.75rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            margin-right: auto;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            margin-left: auto;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .row {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            display: flex;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            flex-wrap: wrap;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            margin-right: -0.75rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            margin-left: -0.75rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .col-12 {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            flex: 0 0 auto;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            width: 100%;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .col-lg-6 {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            flex: 0 0 auto;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            width: 50%;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        @media (max-width: 991.98px) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            .col-lg-6 {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                width: 100%;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .py-4 {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            padding-top: 1.5rem !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            padding-bottom: 1.5rem !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .mb-4 {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            margin-bottom: 1.5rem !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .mb-3 {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            margin-bottom: 1rem !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .mb-0 {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            margin-bottom: 0 !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .me-2 {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            margin-right: 0.5rem !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .me-3 {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            margin-right: 1rem !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .ms-auto {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            margin-left: auto !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .text-center {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            text-align: center !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .text-muted {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #6c757d !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .d-flex {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            display: flex !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .d-block {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            display: block !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .align-items-center {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            align-items: center !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .justify-content-center {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            justify-content: center !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            display: inline-block;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            padding: 0.375rem 0.75rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            margin-bottom: 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            font-size: 1rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            font-weight: 400;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            line-height: 1.5;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #212529;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            text-align: center;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            text-decoration: none;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            vertical-align: middle;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            cursor: pointer;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border: 1px solid transparent;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-radius: 0.25rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn:hover {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            text-decoration: none;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn:disabled {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            pointer-events: none;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            opacity: 0.65;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn-primary {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #fff;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #0d6efd;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #0d6efd;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn-primary:hover {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #0b5ed7;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #0a58ca;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn-success {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #fff;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #198754;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #198754;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn-success:hover {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #157347;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #146c43;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn-danger {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #fff;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #dc3545;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #dc3545;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn-danger:hover {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #bb2d3b;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #b02a37;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn-warning {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #000;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #ffc107;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #ffc107;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn-warning:hover {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #ffca2c;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #ffc720;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn-info {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #000;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #0dcaf0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #0dcaf0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn-info:hover {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #31d2f2;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #25cff2;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn-light {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #000;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #f8f9fa;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #f8f9fa;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn-light:hover {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #f9fafb;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #f9fafb;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn-outline-light {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #f8f9fa;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #f8f9fa;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn-outline-light:hover {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #000;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #f8f9fa;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #f8f9fa;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn-outline-warning {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #ffc107;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #ffc107;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn-outline-warning:hover {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #000;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #ffc107;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #ffc107;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn-lg {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            padding: 0.5rem 1rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            font-size: 1.25rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .badge {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            display: inline-block;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            padding: 0.35em 0.65em;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            font-size: 0.75em;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            font-weight: 700;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            line-height: 1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #fff;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            text-align: center;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            white-space: nowrap;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            vertical-align: baseline;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-radius: 0.25rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .bg-danger {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #dc3545 !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .bg-success {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #198754 !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .bg-warning {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #ffc107 !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #000 !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fs-6 {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            font-size: 1rem !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fs-5 {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            font-size: 1.25rem !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .display-5 {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            font-size: 2.5rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            font-weight: 300;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            line-height: 1.2;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .alert {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            position: relative;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            padding: 0.75rem 1.25rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            margin-bottom: 1rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border: 1px solid transparent;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-radius: 0.25rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .alert-info {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #055160;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #d1ecf1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #bee5eb;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .alert-success {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #0f5132;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #d1e7dd;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #badbcc;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .alert-warning {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #664d03;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #fff3cd;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #ffecb5;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .alert-danger {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #721c24;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #f8d7da;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #f5c6cb;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .alert-secondary {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #383d41;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #e2e3e5;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: #d6d8db;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .form-range {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            width: 100%;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            height: 1.5rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            padding: 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: transparent;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            appearance: none;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            -webkit-appearance: none;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .form-range::-webkit-slider-track {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            width: 100%;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            height: 0.5rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: transparent;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            cursor: pointer;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #dee2e6;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-color: transparent;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-radius: 1rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .form-range::-webkit-slider-thumb {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            width: 1rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            height: 1rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            margin-top: -0.25rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background-color: #0d6efd;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border: 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-radius: 1rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            -webkit-appearance: none;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            appearance: none;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .form-label {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            margin-bottom: 0.5rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            font-weight: 500;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .img-fluid {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            max-width: 100%;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            height: auto;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .rounded {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-radius: 0.25rem !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        /* 自定义样式 */
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .video-container {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background: #000;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            min-height: 300px;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            display: flex;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            align-items: center;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            justify-content: center;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-radius: 0.375rem;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn-grid {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            display: grid;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            grid-template-columns: repeat(3, 1fr);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            gap: 10px;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            max-width: 300px;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            margin: 0 auto;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .btn-grid .btn {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            min-height: 50px;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            font-size: 14px;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .status-badge {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            position: fixed;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            top: 20px;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            right: 20px;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            z-index: 1000;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .control-panel {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: white;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-radius: 15px;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            padding: 20px;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            margin-bottom: 20px;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .video-panel {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: white;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-radius: 15px;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            padding: 20px;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .status-panel {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: white;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            border-radius: 15px;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            padding: 15px;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        /* Font Awesome图标替换为文字符号 */
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-wifi::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "📶";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-play::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "▶";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-stop::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "⏹";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-paper-plane::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "✈";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-rocket::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "🚀";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-arrow-up::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "↑";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-arrow-down::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "↓";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-arrow-left::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "←";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-arrow-right::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "→";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-undo::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "↶";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-redo::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "↷";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-video::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "📹";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-camera::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "📷";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-ruler::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "📏";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-sync-alt::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "🔄";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-tachometer-alt::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "⚡";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-home::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "🏠";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-cog::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "⚙";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-info-circle::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "ℹ";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-check-circle::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "✅";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-exclamation-triangle::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "⚠";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-times-circle::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "❌";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-minus-circle::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "⊖";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .fa-circle::before {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            content: "●";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .text-success {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #198754 !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .text-secondary {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #6c757d !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .text-dark {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #212529 !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        .text-white {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            color: #fff !important;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    </style>
 | 
						
						
						
						
							 | 
							
								 | 
							
							</head>
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							<body class="bg-light">
 | 
						
						
						
						
							 | 
							
								 | 
							
							    <div class="container-fluid py-4">
 | 
						
						
						
						
							 | 
							
								 | 
							
							        <!-- 状态指示器 -->
 | 
						
						
						
						
							 | 
							
								 | 
							
							        <div class="status-badge">
 | 
						
						
						
						
							 | 
							
								 | 
							
							            <span id="connectionBadge" class="badge bg-danger fs-6">未连接</span>
 | 
						
						
						
						
							 | 
							
								 | 
							
							        </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        <!-- 页面标题 -->
 | 
						
						
						
						
							 | 
							
								 | 
							
							        <div class="row mb-4">
 | 
						
						
						
						
							 | 
							
								 | 
							
							            <div class="col-12 text-center">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                <h1 class="display-5">🚁 RoboMaster TT 无人机控制系统</h1>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                <p class="text-muted fs-5">基于距离判断系统的无人机实时视频传输控制</p>
 | 
						
						
						
						
							 | 
							
								 | 
							
							            </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							        </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        <div class="row">
 | 
						
						
						
						
							 | 
							
								 | 
							
							            <!-- 左侧控制面板 -->
 | 
						
						
						
						
							 | 
							
								 | 
							
							            <div class="col-lg-6">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                <!-- 连接控制 -->
 | 
						
						
						
						
							 | 
							
								 | 
							
							                <div class="control-panel">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    <h5 class="mb-3"><i class="fa-wifi me-2"></i>连接控制</h5>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    <div class="d-flex mb-3 align-items-center">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <button id="connectBtn" class="btn btn-light me-2">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <i class="fa-play me-1"></i>连接无人机
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </button>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <button id="disconnectBtn" class="btn btn-danger me-2" disabled>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <i class="fa-stop me-1"></i>断开连接
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </button>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <button id="diagnoseBtn" class="btn btn-info me-2">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            🔍 诊断连接
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </button>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <div class="ms-auto">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <span id="batteryStatus" class="badge bg-warning text-dark fs-6">电量: --</span>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    <div class="alert alert-info mb-0" id="connectionStatus">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <i class="fa-info-circle me-2"></i>未连接到无人机,请确保已连接到无人机WiFi (TELLO-xxxxxx)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                <!-- 飞行控制 -->
 | 
						
						
						
						
							 | 
							
								 | 
							
							                <div class="control-panel">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    <h5 class="mb-3"><i class="fa-paper-plane me-2"></i>飞行控制</h5>
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    <!-- 起飞降落 -->
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    <div class="d-flex justify-content-center mb-4">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <button id="takeoffBtn" class="btn btn-success btn-lg me-3" disabled>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <i class="fa-rocket me-1"></i>起飞
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </button>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <button id="landBtn" class="btn btn-warning btn-lg" disabled>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <i class="fa-arrow-down me-1"></i>降落
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </button>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    <!-- 移动控制网格 -->
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    <div class="btn-grid mb-4">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <div></div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <button id="upBtn" class="btn btn-outline-light" disabled>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <i class="fa-arrow-up d-block mb-1"></i>上升
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </button>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <div></div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <button id="leftBtn" class="btn btn-outline-light" disabled>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <i class="fa-arrow-left d-block mb-1"></i>左移
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </button>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <button id="forwardBtn" class="btn btn-outline-light" disabled>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <i class="fa-arrow-up d-block mb-1"></i>前进
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </button>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <button id="rightBtn" class="btn btn-outline-light" disabled>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <i class="fa-arrow-right d-block mb-1"></i>右移
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </button>
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <button id="rotateLeftBtn" class="btn btn-outline-warning" disabled>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <i class="fa-undo d-block mb-1"></i>左转
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </button>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <button id="backBtn" class="btn btn-outline-light" disabled>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <i class="fa-arrow-down d-block mb-1"></i>后退
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </button>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <button id="rotateRightBtn" class="btn btn-outline-warning" disabled>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <i class="fa-redo d-block mb-1"></i>右转
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </button>
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <div></div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <button id="downBtn" class="btn btn-outline-light" disabled>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <i class="fa-arrow-down d-block mb-1"></i>下降
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </button>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <div></div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    <!-- 参数控制 -->
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    <div class="row">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <div class="col-md-6">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <label for="moveDistance" class="form-label">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                <i class="fa-ruler me-1"></i>移动距离 (厘米)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            </label>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <input type="range" class="form-range" id="moveDistance" min="20" max="100" step="10"
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                value="30">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <div class="text-center"><span id="distanceValue">30</span> 厘米</div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <div class="col-md-6">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <label for="rotateAngle" class="form-label">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                <i class="fa-sync-alt me-1"></i>旋转角度 (度)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            </label>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <input type="range" class="form-range" id="rotateAngle" min="15" max="360" step="15"
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                value="90">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <div class="text-center"><span id="angleValue">90</span> 度</div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							            </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            <!-- 右侧视频面板 -->
 | 
						
						
						
						
							 | 
							
								 | 
							
							            <div class="col-lg-6">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                <!-- 视频流控制 -->
 | 
						
						
						
						
							 | 
							
								 | 
							
							                <div class="video-panel mb-3">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    <h5 class="mb-3"><i class="fa-video me-2"></i>实时视频流</h5>
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    <div class="d-flex mb-3">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <button id="startVideoBtn" class="btn btn-light me-2" disabled>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <i class="fa-play me-1"></i>开始视频流
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </button>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <button id="stopVideoBtn" class="btn btn-danger me-2" disabled>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <i class="fa-stop me-1"></i>停止视频流
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </button>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <button id="captureBtn" class="btn btn-info" disabled>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <i class="fa-camera me-1"></i>捕获图像
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </button>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    <div class="video-container mb-3">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <img id="videoStream" class="img-fluid rounded" style="max-width: 100%; max-height: 350px;"
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjQwIiBoZWlnaHQ9IjQ4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjMzMzIi8+PHRleHQgeD0iNTAlIiB5PSI1MCUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIyMCIgZmlsbD0iI2ZmZiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZHk9Ii4zZW0iPuaXoOinhumikea1gTwvdGV4dD48L3N2Zz4="
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            alt="无视频流">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    <div id="videoStatus" class="text-center">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <small><i class="fa-circle text-secondary me-1"></i>视频流状态: 未启动</small>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                <!-- 无人机状态 -->
 | 
						
						
						
						
							 | 
							
								 | 
							
							                <div class="status-panel">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    <h6 class="mb-3"><i class="fa-tachometer-alt me-2"></i>无人机状态</h6>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    <div class="row text-center">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <div class="col-3">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <div class="h4 mb-0" id="batteryLevel">--</div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <small>电量</small>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <div class="col-3">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <div class="h4 mb-0" id="heightLevel">--</div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <small>高度</small>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <div class="col-3">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <div class="h4 mb-0" id="speedLevel">--</div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <small>速度</small>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <div class="col-3">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <div class="h4 mb-0" id="signalLevel">--</div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            <small>信号</small>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							            </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							        </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        <!-- 快速访问链接 -->
 | 
						
						
						
						
							 | 
							
								 | 
							
							        <div class="row mt-4">
 | 
						
						
						
						
							 | 
							
								 | 
							
							            <div class="col-12 text-center">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                <div class="btn-group" role="group">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    <a href="/" class="btn btn-outline-primary">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <i class="fa-home me-1"></i>返回主页
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    </a>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    <a href="/test_device_selector.html" class="btn btn-outline-info">
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <i class="fa-cog me-1"></i>设备测试
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    </a>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							            </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							        </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							    </div>
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    <script>
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // 全局变量
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let isConnected = false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let isVideoStreaming = false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        let videoUpdateInterval = null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // DOM元素
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const connectBtn = document.getElementById('connectBtn');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const disconnectBtn = document.getElementById('disconnectBtn');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const diagnoseBtn = document.getElementById('diagnoseBtn');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const connectionStatus = document.getElementById('connectionStatus');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const connectionBadge = document.getElementById('connectionBadge');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const batteryStatus = document.getElementById('batteryStatus');
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const takeoffBtn = document.getElementById('takeoffBtn');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const landBtn = document.getElementById('landBtn');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const upBtn = document.getElementById('upBtn');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const downBtn = document.getElementById('downBtn');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const leftBtn = document.getElementById('leftBtn');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const rightBtn = document.getElementById('rightBtn');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const forwardBtn = document.getElementById('forwardBtn');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const backBtn = document.getElementById('backBtn');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const rotateLeftBtn = document.getElementById('rotateLeftBtn');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const rotateRightBtn = document.getElementById('rotateRightBtn');
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const startVideoBtn = document.getElementById('startVideoBtn');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const stopVideoBtn = document.getElementById('stopVideoBtn');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const captureBtn = document.getElementById('captureBtn');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const videoStream = document.getElementById('videoStream');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const videoStatus = document.getElementById('videoStatus');
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const moveDistance = document.getElementById('moveDistance');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const rotateAngle = document.getElementById('rotateAngle');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const distanceValue = document.getElementById('distanceValue');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        const angleValue = document.getElementById('angleValue');
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // 初始化
 | 
						
						
						
						
							 | 
							
								 | 
							
							        document.addEventListener('DOMContentLoaded', function () {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            setupEventListeners();
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            // 🔧 确保状态变量正确初始化
 | 
						
						
						
						
							 | 
							
								 | 
							
							            isConnected = false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            isVideoStreaming = false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            videoUpdateInterval = null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            // 更新界面状态
 | 
						
						
						
						
							 | 
							
								 | 
							
							            updateConnectionState(false);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            updateStatus('未连接到无人机,请确保已连接到无人机WiFi (TELLO-xxxxxx)', 'info');
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            console.log('🚁 无人机控制界面已加载');
 | 
						
						
						
						
							 | 
							
								 | 
							
							            console.log('📊 初始状态 - 连接:', isConnected, '视频流:', isVideoStreaming);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        });
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // 设置事件监听器
 | 
						
						
						
						
							 | 
							
								 | 
							
							        function setupEventListeners() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            connectBtn.addEventListener('click', connectDrone);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            disconnectBtn.addEventListener('click', disconnectDrone);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            diagnoseBtn.addEventListener('click', diagnoseDroneConnection);
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            takeoffBtn.addEventListener('click', () => sendCommand('takeoff'));
 | 
						
						
						
						
							 | 
							
								 | 
							
							            landBtn.addEventListener('click', () => sendCommand('land'));
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            upBtn.addEventListener('click', () => sendMoveCommand('up'));
 | 
						
						
						
						
							 | 
							
								 | 
							
							            downBtn.addEventListener('click', () => sendMoveCommand('down'));
 | 
						
						
						
						
							 | 
							
								 | 
							
							            leftBtn.addEventListener('click', () => sendMoveCommand('left'));
 | 
						
						
						
						
							 | 
							
								 | 
							
							            rightBtn.addEventListener('click', () => sendMoveCommand('right'));
 | 
						
						
						
						
							 | 
							
								 | 
							
							            forwardBtn.addEventListener('click', () => sendMoveCommand('forward'));
 | 
						
						
						
						
							 | 
							
								 | 
							
							            backBtn.addEventListener('click', () => sendMoveCommand('back'));
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            rotateLeftBtn.addEventListener('click', () => sendRotateCommand('ccw'));
 | 
						
						
						
						
							 | 
							
								 | 
							
							            rotateRightBtn.addEventListener('click', () => sendRotateCommand('cw'));
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            startVideoBtn.addEventListener('click', startVideo);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            stopVideoBtn.addEventListener('click', stopVideo);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            captureBtn.addEventListener('click', captureImage);
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            moveDistance.addEventListener('input', () => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                distanceValue.textContent = moveDistance.value;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            });
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            rotateAngle.addEventListener('input', () => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                angleValue.textContent = rotateAngle.value;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            });
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // 连接无人机
 | 
						
						
						
						
							 | 
							
								 | 
							
							        async function connectDrone() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            try {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                connectBtn.disabled = true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                updateStatus('正在连接无人机...', 'warning');
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                const response = await fetch('/api/drone/connect', {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    method: 'POST',
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    headers: {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        'Content-Type': 'application/json'
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    },
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    body: JSON.stringify({
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        drone_ip: '192.168.10.1'
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    })
 | 
						
						
						
						
							 | 
							
								 | 
							
							                });
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                const result = await response.json();
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (result.status === 'success') {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    isConnected = true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    updateStatus('无人机连接成功!', 'success');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    updateConnectionState(true);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    updateDroneStatus(result.drone_info);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    showToast('✅ 无人机连接成功!', 'success');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                } else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    updateStatus('连接失败: ' + result.message, 'danger');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    showToast('❌ 连接失败: ' + result.message, 'error');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            } catch (error) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                updateStatus('连接错误: ' + error.message, 'danger');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                showToast('🔥 连接错误: ' + error.message, 'error');
 | 
						
						
						
						
							 | 
							
								 | 
							
							            } finally {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                connectBtn.disabled = false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // 断开无人机
 | 
						
						
						
						
							 | 
							
								 | 
							
							        async function disconnectDrone() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            try {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                const response = await fetch('/api/drone/disconnect', {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    method: 'POST'
 | 
						
						
						
						
							 | 
							
								 | 
							
							                });
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                const result = await response.json();
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                // 🔧 强制清理所有状态
 | 
						
						
						
						
							 | 
							
								 | 
							
							                isConnected = false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                isVideoStreaming = false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                // 停止视频帧更新
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (videoUpdateInterval) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    clearInterval(videoUpdateInterval);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    videoUpdateInterval = null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    console.log('⏹️ 已停止视频帧更新定时器');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                // 重置视频显示
 | 
						
						
						
						
							 | 
							
								 | 
							
							                videoStream.src = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjQwIiBoZWlnaHQ9IjQ4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjMzMzIi8+PHRleHQgeD0iNTAlIiB5PSI1MCUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIyMCIgZmlsbD0iI2ZmZiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZHk9Ii4zZW0iPuaXoOinhumikea1gTwvdGV4dD48L3N2Zz4=";
 | 
						
						
						
						
							 | 
							
								 | 
							
							                videoStatus.innerHTML = '<small><i class="fa-circle text-secondary me-1"></i>视频流状态: 未启动</small>';
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                // 重置按钮状态
 | 
						
						
						
						
							 | 
							
								 | 
							
							                startVideoBtn.disabled = true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                stopVideoBtn.disabled = true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                captureBtn.disabled = true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                updateStatus('无人机已断开连接', 'secondary');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                updateConnectionState(false);
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                showToast('📡 无人机已断开连接', 'info');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                console.log('📊 断开后状态 - 连接:', isConnected, '视频流:', isVideoStreaming);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            } catch (error) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                updateStatus('断开连接错误: ' + error.message, 'danger');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                showToast('❌ 断开连接错误: ' + error.message, 'error');
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                // 即使出错也要清理状态
 | 
						
						
						
						
							 | 
							
								 | 
							
							                isConnected = false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                isVideoStreaming = false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (videoUpdateInterval) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    clearInterval(videoUpdateInterval);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    videoUpdateInterval = null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                updateConnectionState(false);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // 发送控制命令
 | 
						
						
						
						
							 | 
							
								 | 
							
							        async function sendCommand(command, params = {}) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!isConnected) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                showToast('⚠️ 请先连接无人机', 'warning');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            try {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                showToast('📡 正在发送命令: ' + command, 'info');
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                const response = await fetch('/api/drone/control', {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    method: 'POST',
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    headers: {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        'Content-Type': 'application/json'
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    },
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    body: JSON.stringify({
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        command: command,
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        params: params
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    })
 | 
						
						
						
						
							 | 
							
								 | 
							
							                });
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                const result = await response.json();
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (result.status === 'success') {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    showToast('✅ 命令执行成功: ' + command, 'success');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                } else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    showToast('❌ 命令执行失败: ' + result.message, 'error');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            } catch (error) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                showToast('🔥 命令发送错误: ' + error.message, 'error');
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // 发送移动命令
 | 
						
						
						
						
							 | 
							
								 | 
							
							        function sendMoveCommand(direction) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            const distance = parseInt(moveDistance.value);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            sendCommand('move', { direction: direction, distance: distance });
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // 发送旋转命令
 | 
						
						
						
						
							 | 
							
								 | 
							
							        function sendRotateCommand(direction) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            const angle = parseInt(rotateAngle.value);
 | 
						
						
						
						
							 | 
							
								 | 
							
							            sendCommand('rotate', { direction: direction, angle: angle });
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // 开始视频流
 | 
						
						
						
						
							 | 
							
								 | 
							
							        async function startVideo() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!isConnected) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                showToast('⚠️ 请先连接无人机', 'warning');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            try {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                const response = await fetch('/api/drone/start_video', {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    method: 'POST'
 | 
						
						
						
						
							 | 
							
								 | 
							
							                });
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                const result = await response.json();
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (result.status === 'success') {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    isVideoStreaming = true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    videoStatus.innerHTML = '<small><i class="fa-circle text-success me-1"></i>视频流状态: 正在接收</small>';
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    startVideoBtn.disabled = true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    stopVideoBtn.disabled = false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    captureBtn.disabled = false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    // 开始更新视频帧
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    videoUpdateInterval = setInterval(updateVideoFrame, 200); // 5 FPS
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    showToast('📹 视频流已启动', 'success');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                } else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    showToast('❌ 视频流启动失败: ' + result.message, 'error');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            } catch (error) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                showToast('🔥 视频流启动错误: ' + error.message, 'error');
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // 停止视频流
 | 
						
						
						
						
							 | 
							
								 | 
							
							        async function stopVideo() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            try {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                const response = await fetch('/api/drone/stop_video', {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    method: 'POST'
 | 
						
						
						
						
							 | 
							
								 | 
							
							                });
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                isVideoStreaming = false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                videoStatus.innerHTML = '<small><i class="fa-circle text-secondary me-1"></i>视频流状态: 已停止</small>';
 | 
						
						
						
						
							 | 
							
								 | 
							
							                startVideoBtn.disabled = false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                stopVideoBtn.disabled = true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                captureBtn.disabled = true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (videoUpdateInterval) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    clearInterval(videoUpdateInterval);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    videoUpdateInterval = null;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                // 重置视频显示
 | 
						
						
						
						
							 | 
							
								 | 
							
							                videoStream.src = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjQwIiBoZWlnaHQ9IjQ4MCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjMzMzIi8+PHRleHQgeD0iNTAlIiB5PSI1MCUiIGZvbnQtZmFtaWx5PSJBcmlhbCIgZm9udC1zaXplPSIyMCIgZmlsbD0iI2ZmZiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZHk9Ii4zZW0iPuaXoOinhumikea1gTwvdGV4dD48L3N2Zz4=";
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                showToast('⏹️ 视频流已停止', 'info');
 | 
						
						
						
						
							 | 
							
								 | 
							
							            } catch (error) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                showToast('❌ 停止视频流错误: ' + error.message, 'error');
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // 更新视频帧
 | 
						
						
						
						
							 | 
							
								 | 
							
							        async function updateVideoFrame() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            // 双重检查确保视频流已启动
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!isVideoStreaming || !isConnected) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                console.log('⚠️ 视频流未启动或无人机未连接,跳过帧更新');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            try {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                const response = await fetch('/api/drone/video_frame');
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                // 检查HTTP响应状态
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (!response.ok) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (response.status === 404) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        // 没有视频帧可用,这是正常的,不显示错误
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        console.log('📹 等待视频帧...');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        return;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                const result = await response.json();
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (result.status === 'success') {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    videoStream.src = result.frame;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    const fps = result.stats?.fps || 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    videoStatus.innerHTML = `<small><i class="fa-circle text-success me-1"></i>视频流状态: 正在接收 (${fps.toFixed(1)} FPS)</small>`;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                } else if (result.status === 'no_frame') {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    // 暂时没有帧,这是正常的
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    console.log('📹 等待视频帧数据...');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                } else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    console.warn('视频帧响应异常:', result.message);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            } catch (error) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                // 只在非预期错误时显示日志
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (!error.message.includes('404')) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    console.log('获取视频帧失败:', error.message);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // 捕获图像
 | 
						
						
						
						
							 | 
							
								 | 
							
							        function captureImage() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!isVideoStreaming) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                showToast('⚠️ 请先启动视频流', 'warning');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                return;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            showToast('📸 图像捕获功能开发中...', 'info');
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // 🔍 诊断无人机连接
 | 
						
						
						
						
							 | 
							
								 | 
							
							        async function diagnoseDroneConnection() {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            try {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                diagnoseBtn.disabled = true;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                diagnoseBtn.innerHTML = '🔄 诊断中...';
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                showToast('🔍 正在诊断无人机连接状态...', 'info');
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                const response = await fetch('/api/drone/diagnose');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                const result = await response.json();
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (result.status === 'success') {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    const diagnosis = result.diagnosis;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    // 🔧 显示诊断结果
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    let diagnosticHtml = '<div class="diagnostic-results">';
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    diagnosticHtml += '<h6>🔍 诊断结果:</h6>';
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    // 显示建议
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    diagnosis.recommendations.forEach(rec => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        diagnosticHtml += `<div class="mb-1">${rec}</div>`;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    });
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    // 显示详细信息
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    diagnosticHtml += '<hr>';
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    diagnosticHtml += '<h6>📊 详细信息:</h6>';
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (diagnosis.network.ping_success !== undefined) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        diagnosticHtml += `<div>网络连通性: ${diagnosis.network.ping_success ? '✅ 正常' : '❌ 失败'}</div>`;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (diagnosis.network.port_11111_available !== undefined) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        diagnosticHtml += `<div>UDP端口11111: ${diagnosis.network.port_11111_available ? '✅ 可用' : '❌ 被占用'}</div>`;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (diagnosis.tello.connected !== undefined) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        diagnosticHtml += `<div>Tello连接: ${diagnosis.tello.connected ? '✅ 已连接' : '❌ 未连接'}</div>`;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        if (diagnosis.tello.battery) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            diagnosticHtml += `<div>电池电量: ${diagnosis.tello.battery}%</div>`;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (diagnosis.video_stream.receiver_exists !== undefined) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        diagnosticHtml += `<div>视频接收器: ${diagnosis.video_stream.receiver_exists ? '✅ 已创建' : '❌ 未创建'}</div>`;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        if (diagnosis.video_stream.running !== undefined) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            diagnosticHtml += `<div>视频流状态: ${diagnosis.video_stream.running ? '🟢 运行中' : '⚪ 已停止'}</div>`;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        if (diagnosis.video_stream.has_frames !== undefined) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            diagnosticHtml += `<div>视频帧接收: ${diagnosis.video_stream.has_frames ? '✅ 正常' : '⚠️ 无数据'}</div>`;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    diagnosticHtml += `<div>系统平台: ${diagnosis.system.platform}</div>`;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    diagnosticHtml += `<div>OpenCV版本: ${diagnosis.system.opencv_version}</div>`;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    diagnosticHtml += '</div>';
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    // 创建诊断结果弹窗
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    const alertDiv = document.createElement('div');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    alertDiv.className = 'alert alert-info alert-dismissible fade show position-fixed';
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    alertDiv.style.cssText = 'top: 100px; right: 20px; z-index: 1060; max-width: 450px; max-height: 400px; overflow-y: auto; box-shadow: 0 4px 6px rgba(0,0,0,0.1);';
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    alertDiv.innerHTML = `
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        ${diagnosticHtml}
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        <button type="button" class="btn-close" onclick="this.parentElement.remove()"></button>
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    `;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    document.body.appendChild(alertDiv);
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    // 10秒后自动删除
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    setTimeout(() => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        if (alertDiv.parentNode) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            alertDiv.parentNode.removeChild(alertDiv);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    }, 10000);
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    showToast('✅ 诊断完成,请查看右侧详细信息', 'success');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                } else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    showToast('❌ 诊断失败: ' + result.message, 'error');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            } catch (error) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                showToast('🔥 诊断过程出错: ' + error.message, 'error');
 | 
						
						
						
						
							 | 
							
								 | 
							
							            } finally {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                diagnoseBtn.disabled = false;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                diagnoseBtn.innerHTML = '🔍 诊断连接';
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // 更新连接状态
 | 
						
						
						
						
							 | 
							
								 | 
							
							        function updateConnectionState(connected) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            isConnected = connected;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            connectBtn.disabled = connected;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            disconnectBtn.disabled = !connected;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            // 更新所有控制按钮
 | 
						
						
						
						
							 | 
							
								 | 
							
							            const controlButtons = [
 | 
						
						
						
						
							 | 
							
								 | 
							
							                takeoffBtn, landBtn, upBtn, downBtn, leftBtn, rightBtn,
 | 
						
						
						
						
							 | 
							
								 | 
							
							                forwardBtn, backBtn, rotateLeftBtn, rotateRightBtn, startVideoBtn
 | 
						
						
						
						
							 | 
							
								 | 
							
							            ];
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            controlButtons.forEach(btn => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                btn.disabled = !connected;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            });
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            connectionBadge.textContent = connected ? '已连接' : '未连接';
 | 
						
						
						
						
							 | 
							
								 | 
							
							            connectionBadge.className = connected ? 'badge bg-success fs-6' : 'badge bg-danger fs-6';
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // 更新状态显示
 | 
						
						
						
						
							 | 
							
								 | 
							
							        function updateStatus(message, type = 'info') {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            const iconMap = {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                'info': 'fa-info-circle',
 | 
						
						
						
						
							 | 
							
								 | 
							
							                'success': 'fa-check-circle',
 | 
						
						
						
						
							 | 
							
								 | 
							
							                'warning': 'fa-exclamation-triangle',
 | 
						
						
						
						
							 | 
							
								 | 
							
							                'danger': 'fa-times-circle',
 | 
						
						
						
						
							 | 
							
								 | 
							
							                'secondary': 'fa-minus-circle'
 | 
						
						
						
						
							 | 
							
								 | 
							
							            };
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            connectionStatus.innerHTML = `<i class="${iconMap[type] || iconMap.info} me-2"></i>${message}`;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            connectionStatus.className = `alert alert-${type} mb-0`;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // 更新无人机状态
 | 
						
						
						
						
							 | 
							
								 | 
							
							        function updateDroneStatus(droneInfo) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (droneInfo) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                const battery = droneInfo.battery || 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                const height = droneInfo.height || 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                const speed = droneInfo.speed || 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                const signal = droneInfo.signal_strength || 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                batteryStatus.textContent = `电量: ${battery}%`;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                batteryStatus.className = battery > 30 ? 'badge bg-success text-white fs-6' :
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    battery > 15 ? 'badge bg-warning text-dark fs-6' :
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        'badge bg-danger text-white fs-6';
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                document.getElementById('batteryLevel').textContent = `${battery}%`;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                document.getElementById('heightLevel').textContent = `${height}cm`;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                document.getElementById('speedLevel').textContent = `${speed}km/h`;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                document.getElementById('signalLevel').textContent = `${signal}%`;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // 显示提示信息
 | 
						
						
						
						
							 | 
							
								 | 
							
							        function showToast(message, type = 'info') {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            const typeMap = {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                'success': 'success',
 | 
						
						
						
						
							 | 
							
								 | 
							
							                'error': 'danger',
 | 
						
						
						
						
							 | 
							
								 | 
							
							                'warning': 'warning',
 | 
						
						
						
						
							 | 
							
								 | 
							
							                'info': 'info'
 | 
						
						
						
						
							 | 
							
								 | 
							
							            };
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            const alertDiv = document.createElement('div');
 | 
						
						
						
						
							 | 
							
								 | 
							
							            alertDiv.className = `alert alert-${typeMap[type] || 'info'} alert-dismissible fade show position-fixed`;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            alertDiv.style.cssText = 'top: 80px; right: 20px; z-index: 1050; max-width: 350px; box-shadow: 0 4px 6px rgba(0,0,0,0.1);';
 | 
						
						
						
						
							 | 
							
								 | 
							
							            alertDiv.innerHTML = `
 | 
						
						
						
						
							 | 
							
								 | 
							
							                ${message}
 | 
						
						
						
						
							 | 
							
								 | 
							
							                <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
 | 
						
						
						
						
							 | 
							
								 | 
							
							            `;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            document.body.appendChild(alertDiv);
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            // 3秒后自动删除
 | 
						
						
						
						
							 | 
							
								 | 
							
							            setTimeout(() => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (alertDiv.parentNode) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    alertDiv.parentNode.removeChild(alertDiv);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }, 3000);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // 定期更新无人机状态
 | 
						
						
						
						
							 | 
							
								 | 
							
							        setInterval(async () => {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (isConnected) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                try {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    const response = await fetch('/api/drone/status');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    const result = await response.json();
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (result.status === 'success') {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        updateDroneStatus(result.drone_state);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                } catch (error) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    console.log('获取无人机状态失败:', error);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }, 2000); // 每2秒更新一次状态
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // 简单的Bootstrap替代功能
 | 
						
						
						
						
							 | 
							
								 | 
							
							        document.addEventListener('click', function (e) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            // 处理alert关闭按钮
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (e.target.classList.contains('btn-close')) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                const alert = e.target.closest('.alert');
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (alert) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    alert.remove();
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        });
 | 
						
						
						
						
							 | 
							
								 | 
							
							    </script>
 | 
						
						
						
						
							 | 
							
								 | 
							
							</body>
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							</html> |