You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Software_Architecture/distance-judgement/trajectory_simulation_test....

470 lines
15 KiB

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>🛤️ 无人机轨迹模拟测试</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Microsoft YaHei', sans-serif;
background: linear-gradient(135deg, #1e3c72, #2a5298);
color: white;
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 800px;
margin: 0 auto;
background: rgba(255, 255, 255, 0.1);
border-radius: 20px;
padding: 30px;
backdrop-filter: blur(10px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
}
.header {
text-align: center;
margin-bottom: 30px;
}
.header h1 {
font-size: 2.5em;
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
.header p {
font-size: 1.1em;
opacity: 0.8;
}
.control-panel {
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
padding: 25px;
margin-bottom: 20px;
}
.control-group {
margin-bottom: 20px;
}
.control-group h3 {
color: #00aaff;
margin-bottom: 15px;
font-size: 1.2em;
border-bottom: 2px solid rgba(0, 170, 255, 0.3);
padding-bottom: 8px;
}
.button-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
gap: 15px;
margin-bottom: 15px;
}
.btn {
padding: 12px 20px;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 14px;
font-weight: bold;
color: white;
transition: all 0.3s ease;
text-align: center;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
.btn-circle {
background: linear-gradient(135deg, #9C27B0, #7B1FA2);
}
.btn-line {
background: linear-gradient(135deg, #FF9800, #F57C00);
}
.btn-random {
background: linear-gradient(135deg, #607D8B, #455A64);
}
.btn-stop {
background: linear-gradient(135deg, #F44336, #D32F2F);
}
.btn-clear {
background: linear-gradient(135deg, #FF5722, #D32F2F);
}
.input-group {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 10px;
}
.input-group label {
min-width: 100px;
font-weight: bold;
}
.input-group input,
.input-group select {
flex: 1;
padding: 8px 12px;
border: none;
border-radius: 6px;
background: rgba(255, 255, 255, 0.2);
color: white;
font-size: 14px;
}
.input-group input::placeholder {
color: rgba(255, 255, 255, 0.6);
}
.status-panel {
background: rgba(0, 0, 0, 0.3);
border-radius: 10px;
padding: 20px;
margin-bottom: 20px;
}
.status-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.status-item:last-child {
border-bottom: none;
}
.status-value {
font-weight: bold;
color: #4CAF50;
}
.alert {
padding: 12px 15px;
border-radius: 8px;
margin-bottom: 15px;
display: none;
}
.alert.success {
background: rgba(76, 175, 80, 0.2);
border-left: 4px solid #4CAF50;
}
.alert.error {
background: rgba(244, 67, 54, 0.2);
border-left: 4px solid #F44336;
}
.alert.info {
background: rgba(33, 150, 243, 0.2);
border-left: 4px solid #2196F3;
}
.drone-list {
max-height: 200px;
overflow-y: auto;
background: rgba(0, 0, 0, 0.2);
border-radius: 8px;
padding: 10px;
}
.drone-item {
padding: 8px 10px;
margin-bottom: 5px;
background: rgba(255, 255, 255, 0.1);
border-radius: 6px;
font-size: 12px;
}
.link-section {
text-align: center;
margin-top: 20px;
}
.link-section a {
color: #00aaff;
text-decoration: none;
font-weight: bold;
padding: 10px 20px;
background: rgba(0, 170, 255, 0.2);
border-radius: 8px;
transition: all 0.3s ease;
}
.link-section a:hover {
background: rgba(0, 170, 255, 0.4);
transform: translateY(-2px);
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>🛤️ 无人机轨迹模拟测试</h1>
<p>测试无人机轨迹记录和可视化功能</p>
</div>
<div id="alertContainer"></div>
<!-- 快速启动面板 -->
<div class="control-panel">
<div class="control-group">
<h3>🚀 快速启动模拟</h3>
<div class="button-grid">
<button class="btn btn-circle" onclick="startQuickSimulation('circle')">
🔄 圆形轨迹
</button>
<button class="btn btn-line" onclick="startQuickSimulation('line')">
↔️ 直线轨迹
</button>
<button class="btn btn-random" onclick="startQuickSimulation('random')">
🎲 随机轨迹
</button>
<button class="btn btn-stop" onclick="stopSimulation()">
⏹️ 停止模拟
</button>
</div>
</div>
</div>
<!-- 高级配置面板 -->
<div class="control-panel">
<div class="control-group">
<h3>⚙️ 高级配置</h3>
<div class="input-group">
<label>轨迹类型:</label>
<select id="simulationType">
<option value="circle">圆形轨迹</option>
<option value="line">直线往返</option>
<option value="random">随机游走</option>
</select>
</div>
<div class="input-group">
<label>无人机数量:</label>
<input type="number" id="droneCount" value="2" min="1" max="5" placeholder="1-5架">
</div>
<div class="input-group">
<label>更新间隔:</label>
<input type="number" id="updateSpeed" value="3" min="1" max="10" placeholder="秒">
</div>
<div class="button-grid">
<button class="btn btn-circle" onclick="startCustomSimulation()">
🛠️ 启动自定义模拟
</button>
<button class="btn btn-clear" onclick="clearAllTrajectories()">
🗑️ 清除所有轨迹
</button>
</div>
</div>
</div>
<!-- 状态显示面板 -->
<div class="status-panel">
<h3 style="color: #00aaff; margin-bottom: 15px;">📊 模拟状态</h3>
<div class="status-item">
<span>模拟状态:</span>
<span class="status-value" id="simulationStatus">未启动</span>
</div>
<div class="status-item">
<span>轨迹类型:</span>
<span class="status-value" id="simulationType"></span>
</div>
<div class="status-item">
<span>无人机数量:</span>
<span class="status-value" id="droneCountStatus">0</span>
</div>
<div class="status-item">
<span>轨迹记录:</span>
<span class="status-value" id="trajectoryRecordingStatus">开启</span>
</div>
</div>
<!-- 无人机列表 -->
<div class="control-panel">
<div class="control-group">
<h3>🚁 模拟无人机列表</h3>
<div class="drone-list" id="droneList">
<div style="text-align: center; color: #999;">暂无模拟无人机</div>
</div>
</div>
</div>
<!-- 链接到主系统 -->
<div class="link-section">
<a href="/" target="_blank">🎯 打开主系统查看轨迹</a>
</div>
</div>
<script>
// 显示提示信息
function showAlert(message, type = 'info') {
const alertContainer = document.getElementById('alertContainer');
const alert = document.createElement('div');
alert.className = `alert ${type}`;
alert.textContent = message;
alertContainer.appendChild(alert);
alert.style.display = 'block';
setTimeout(() => {
alert.style.display = 'none';
alertContainer.removeChild(alert);
}, 5000);
}
// 快速启动模拟
async function startQuickSimulation(type) {
await startSimulation(type, 2, 3);
}
// 自定义启动模拟
async function startCustomSimulation() {
const type = document.getElementById('simulationType').value;
const droneCount = parseInt(document.getElementById('droneCount').value) || 2;
const speed = parseInt(document.getElementById('updateSpeed').value) || 3;
await startSimulation(type, droneCount, speed);
}
// 启动轨迹模拟
async function startSimulation(type, droneCount = 2, speed = 3) {
try {
showAlert(`🚀 正在启动${droneCount}架无人机的${type}轨迹模拟...`, 'info');
const response = await fetch('/api/test/start_simulation', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
type: type,
drone_count: droneCount,
speed: speed
})
});
const result = await response.json();
if (result.status === 'success') {
showAlert(`${result.message}`, 'success');
updateStatus();
} else {
showAlert(`❌ 启动模拟失败: ${result.message}`, 'error');
}
} catch (error) {
showAlert(`❌ 启动模拟失败: ${error.message}`, 'error');
}
}
// 停止轨迹模拟
async function stopSimulation() {
try {
showAlert('🛑 正在停止轨迹模拟...', 'info');
const response = await fetch('/api/test/stop_simulation', {
method: 'POST'
});
const result = await response.json();
if (result.status === 'success') {
showAlert('✅ 轨迹模拟已停止', 'success');
updateStatus();
} else {
showAlert(`❌ 停止模拟失败: ${result.message}`, 'error');
}
} catch (error) {
showAlert(`❌ 停止模拟失败: ${error.message}`, 'error');
}
}
// 清除所有轨迹
async function clearAllTrajectories() {
try {
// 这个功能需要在主页面中执行
showAlert('🗑️ 请在主系统页面中点击"清除"按钮来清除轨迹', 'info');
} catch (error) {
showAlert(`❌ 清除轨迹失败: ${error.message}`, 'error');
}
}
// 更新状态显示
async function updateStatus() {
try {
const response = await fetch('/api/test/simulation_status');
const result = await response.json();
if (result.status === 'success') {
// 更新状态显示
document.getElementById('simulationStatus').textContent =
result.simulation_active ? '运行中' : '未启动';
document.getElementById('simulationStatus').style.color =
result.simulation_active ? '#4CAF50' : '#F44336';
document.getElementById('simulationType').textContent =
result.simulation_type || '无';
document.getElementById('droneCountStatus').textContent =
result.simulated_drones.length || '0';
// 更新无人机列表
updateDroneList(result.simulated_drones);
}
} catch (error) {
console.error('获取状态失败:', error);
}
}
// 更新无人机列表
function updateDroneList(drones) {
const droneList = document.getElementById('droneList');
if (!drones || drones.length === 0) {
droneList.innerHTML = '<div style="text-align: center; color: #999;">暂无模拟无人机</div>';
return;
}
const html = drones.map((drone, index) => `
<div class="drone-item">
🚁 ${drone.name || `无人机-${index + 1}`}
<br>
<span style="color: #999;">
ID: ${drone.device_id.substring(0, 12)}...
</span>
</div>
`).join('');
droneList.innerHTML = html;
}
// 页面加载完成后的初始化
window.addEventListener('load', function () {
updateStatus();
// 定期更新状态
setInterval(updateStatus, 3000);
showAlert('🎯 轨迹模拟测试页面已加载', 'success');
});
</script>
</body>
</html>