Architecture change (2026-04-03): Mamba F722S (STM32F722) and BlackPill replaced by ESP32 BALANCE (PID loop) and ESP32 IO (motors/sensors/comms). - Update CLAUDE.md, docs, chassis BOM/ASSEMBLY, pinout, power-budget, wiring-diagram, TEAM.md, AUTONOMOUS_ARMING.md, docker-compose - Update all ROS2 package comments, config labels, launch args (stm32_port→esp32_port, /dev/stm32-bridge→/dev/esp32-bridge) - Update WebUI: stm32Mode→esp32Mode, stm32Version→esp32Version, "STM32 State/Mode" labels → "ESP32 State/Mode" (ControlMode, SettingsPanel) - Add TODO(esp32-migration) markers on stm32_protocol.py and mamba_protocol.py binary frame layouts — pending ESP32 protocol spec from max - Fix roslib CDN 1.3.0→1.4.0 in all 11 HTML panels (fixes ROS2 Humble rosbridge "Received a message without an op" incompatibility) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
139 lines
4.8 KiB
HTML
139 lines
4.8 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
|
|
<title>Saltybot — GPS Map</title>
|
|
<link rel="stylesheet" href="gps_map_panel.css">
|
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
|
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/roslib@1.4.0/build/roslib.min.js"></script>
|
|
</head>
|
|
<body>
|
|
|
|
<!-- ── Header ── -->
|
|
<div id="header">
|
|
<div class="logo">⚡ <a href="index.html">SALTYBOT</a> — GPS MAP</div>
|
|
<div id="conn-bar">
|
|
<div id="conn-dot"></div>
|
|
<input id="ws-input" type="text" value="ws://localhost:9090" placeholder="ws://robot-ip:9090" />
|
|
<button class="hdr-btn" id="btn-connect">CONNECT</button>
|
|
<span id="conn-label">Not connected</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ── Status bar ── -->
|
|
<div id="status-bar">
|
|
<span style="color:var(--text-dim);font-size:10px">ROBOT FIX</span>
|
|
<span class="sys-badge badge-stale" id="badge-fix">STALE</span>
|
|
<span style="color:var(--text-dim)">│</span>
|
|
<span style="color:var(--text-dim);font-size:10px">VELOCITY</span>
|
|
<span class="sys-badge badge-stale" id="badge-vel">STALE</span>
|
|
<span style="color:var(--text-dim)">│</span>
|
|
<span style="color:var(--text-dim);font-size:10px">PHONE</span>
|
|
<span class="sys-badge badge-stale" id="badge-phone">NO DATA</span>
|
|
<span id="last-update">Awaiting data…</span>
|
|
</div>
|
|
|
|
<!-- ── Main ── -->
|
|
<div id="main">
|
|
|
|
<!-- Map -->
|
|
<div id="map-wrap">
|
|
<div id="map"></div>
|
|
<div id="map-controls">
|
|
<button class="map-btn active" id="btn-follow">⊙ FOLLOW</button>
|
|
<button class="map-btn" id="btn-clear">✕ CLEAR</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sidebar -->
|
|
<div id="sidebar">
|
|
|
|
<!-- Speed -->
|
|
<div class="stat-section">
|
|
<div class="section-title">Speed</div>
|
|
<div class="big-stat">
|
|
<div class="big-val" id="val-speed" style="color:#f97316">—</div>
|
|
<div class="big-unit">km/h</div>
|
|
<div class="big-lbl">GROUND SPEED</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Altitude + heading -->
|
|
<div class="stat-section">
|
|
<div class="section-title">Altitude & Heading</div>
|
|
<div class="kv-grid">
|
|
<div class="kv-cell">
|
|
<div class="kv-lbl">ALT m</div>
|
|
<div class="kv-val" id="val-alt">—</div>
|
|
</div>
|
|
<div class="kv-cell">
|
|
<div class="kv-lbl">HDG °</div>
|
|
<div class="kv-val" id="val-hdg">—</div>
|
|
</div>
|
|
</div>
|
|
<div id="compass-wrap">
|
|
<canvas id="compass-canvas" width="110" height="110"></canvas>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Fix quality -->
|
|
<div class="stat-section">
|
|
<div class="section-title">Fix Quality</div>
|
|
<div class="kv-grid">
|
|
<div class="kv-cell">
|
|
<div class="kv-lbl">STATUS</div>
|
|
<div class="kv-val" id="val-stat">—</div>
|
|
</div>
|
|
<div class="kv-cell">
|
|
<div class="kv-lbl">FIXES</div>
|
|
<div class="kv-val" id="val-fixes">0</div>
|
|
</div>
|
|
</div>
|
|
<div style="margin-top:8px">
|
|
<div class="coord-row">LAT <span class="coord-val" id="val-lat">—</span></div>
|
|
<div class="coord-row">LON <span class="coord-val" id="val-lon">—</span></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Phone position -->
|
|
<div class="stat-section">
|
|
<div class="section-title" style="color:#3b82f6">📱 Phone / User</div>
|
|
<div style="margin-bottom:6px">
|
|
<div class="coord-row">LAT <span class="coord-val" id="phone-lat" style="color:#60a5fa">—</span></div>
|
|
<div class="coord-row">LON <span class="coord-val" id="phone-lon" style="color:#60a5fa">—</span></div>
|
|
</div>
|
|
<div class="kv-grid">
|
|
<div class="kv-cell">
|
|
<div class="kv-lbl">SPEED</div>
|
|
<div class="kv-val" id="phone-spd" style="color:#60a5fa">—</div>
|
|
</div>
|
|
<div class="kv-cell">
|
|
<div class="kv-lbl">ACCURACY</div>
|
|
<div class="kv-val" id="phone-acc">—</div>
|
|
</div>
|
|
</div>
|
|
<div class="coord-row" style="margin-top:6px">SRC <span id="phone-provider" style="color:#6b7280;font-family:monospace">—</span></div>
|
|
</div>
|
|
|
|
<!-- Trail log -->
|
|
<div class="section-title" style="padding:8px 12px 2px">Trail log</div>
|
|
<div id="trail-log"></div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ── Bottom bar ── -->
|
|
<div id="bottombar">
|
|
<span class="bb-lbl">FIXES</span><span id="bb-fixes">0</span>
|
|
<span class="bb-lbl">TRAIL PTS</span><span id="bb-trail">0</span>
|
|
<span class="bb-lbl">ROBOT MSGS</span><span id="bb-msgs">0</span>
|
|
<span class="bb-lbl">PHONE MSGS</span><span id="bb-phone">0</span>
|
|
<span id="last-msg">No data</span>
|
|
</div>
|
|
|
|
<script src="gps_map_panel.js"></script>
|
|
</body>
|
|
</html>
|