Files
argo/web/index.html
T

160 lines
11 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Sub Control</title>
<link rel="stylesheet" href="styles.css?v=20260827-model-layout-v14">
</head>
<body>
<main class="app-shell">
<!-- ── DECK (Connection, 3D Model, Battery, Deck Controls, Status) ── -->
<aside class="sidebar-deck" aria-label="Vehicle Deck and Status">
<div class="sidebar-drag-surface pywebview-drag-region" aria-hidden="true"></div>
<!-- Connection Controls -->
<div class="deck-connection">
<div class="port-row">
<select id="port" aria-label="Serial port">
<option value="demo" selected>Demo Mode (no hardware)</option>
</select>
<button id="refresh" class="icon-button" title="Refresh ports" aria-label="Refresh ports">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M20 7v5h-5M4 17v-5h5M18.5 9A7 7 0 0 0 6.8 6.8L4 10m16 4-2.8 3.2A7 7 0 0 1 5.5 15"/></svg>
</button>
<button class="icon-button" data-open="link-modal" title="Link settings" aria-label="Link settings">
<svg class="dots-icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="5" cy="12" r="1.25"/><circle cx="12" cy="12" r="1.25"/><circle cx="19" cy="12" r="1.25"/></svg>
</button>
</div>
<button id="connect" class="button connect-button" aria-label="Toggle connection">
<span class="btn-spinner" aria-hidden="true"></span>
<span class="btn-label">Connect</span>
</button>
</div>
<!-- Telemetry / Status Zone -->
<section class="telemetry-zone" aria-label="Vehicle Telemetry and Status">
<div class="deck-card model-card">
<div class="rov-stage" aria-label="Top view of three-thruster ROV">
<canvas id="model-canvas" aria-label="Interactive STL vehicle model"></canvas>
<div id="model-status" class="model-status">Initializing…</div>
<div class="model-tools">
<button id="load-model">Load STL</button>
<input id="model-input" type="file" accept=".stl,.STL" hidden>
</div>
</div>
</div>
<!-- Battery Status -->
<button class="battery-card ghost" data-open="battery-modal">
<span><small>Battery</small><strong id="battery-title">—</strong></span><i id="battery-percent">waiting</i>
<b><em id="battery-fill"></em></b>
</button>
<div class="deck-status-bar">
<ol class="activity-history" aria-label="Last three events" aria-live="polite">
<li id="activity-oldest" hidden></li>
<li id="activity-previous" hidden></li>
<li id="status-text">Not connected</li>
</ol>
<header class="activity-heading"><span>Recent activity</span><a id="logs" class="logs-link" title="Open session logs" aria-label="Open session logs">Logs</a></header>
</div>
</section>
</aside>
<!-- ── PRIMARY CONTROL ZONE ── -->
<section class="controls-workspace" aria-label="Primary Vehicle Controls">
<!-- Frameless Drag & Window Controls Header -->
<div class="workspace-topbar">
<div class="workspace-drag-area pywebview-drag-region"></div>
<div class="window-actions">
<button id="window-min" aria-label="Minimize" title="Minimize"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12h14"/></svg></button>
<button id="window-max" aria-label="Maximize" title="Maximize"><svg viewBox="0 0 24 24" aria-hidden="true"><rect x="5" y="5" width="14" height="14" rx="1.5"/></svg></button>
<button id="window-close" class="window-close" aria-label="Close" title="Close"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="m6 6 12 12M18 6 6 18"/></svg></button>
</div>
</div>
<section class="primary-control-zone" aria-label="Primary Control Zone">
<!-- Reserved Engage / Disarm row -->
<div class="engage-header-zone">
<button id="engage" class="button subtle engage-button" aria-label="Engage" aria-describedby="control-status" title="Engage (F2)">
<span class="engage-face">
<span id="engage-label" class="engage-label">engage</span>
<span class="engage-sheen-label" aria-hidden="true">engage</span>
<span class="engage-progress-label" aria-hidden="true">engage</span>
</span>
</button>
<p id="control-status" class="control-status" role="status" aria-live="polite">Connect to receive vehicle state.</p>
</div>
<!-- Main Joysticks & Thrust Control Grid -->
<div class="controls-grid">
<!-- Steering / Throttle Joystick -->
<article class="control-card steer-card">
<header>
<div><small>steer + throttle</small></div>
<span class="key-hint">w a s d</span>
</header>
<div class="joystick-pad">
<div id="joystick" class="joystick" touch-action="none">
<canvas id="joystick-canvas" aria-label="Steering and throttle joystick; W A S D keys"></canvas>
</div>
</div>
<footer>
<span class="steer-readout-left">surge <b id="surge-readout">—</b></span>
<span class="steer-readout-right"><b id="yaw-readout">—</b> turn</span>
</footer>
</article>
<!-- Vertical Thruster Slider -->
<article class="control-card vertical-card">
<header>
<div><small>vertical</small></div>
<span class="key-hint">r / f</span>
</header>
<div class="heave-pad">
<div class="vertical-control">
<span>rise</span>
<div id="heave" class="heave-track" touch-action="none">
<div class="heave-center"></div>
<div id="heave-fill" class="heave-fill"></div>
<div id="heave-knob" class="heave-knob"></div>
</div>
<span>dive</span>
</div>
</div>
<footer>
<span><b id="heave-readout">—</b> vertical</span>
</footer>
</article>
</div>
<div class="control-toolbar">
<label class="output-limit">
<span>Output limit <b id="gain-value">20%</b></span>
<div class="range-pill">
<button id="gain-down" type="button" aria-label="Decrease output limit"><svg viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="m14 6-6 6 6 6"/></svg></button>
<input id="gain" aria-label="Output limit" type="range" min="5" max="50" value="20">
<button id="gain-up" type="button" aria-label="Increase output limit"><svg viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"><path d="m10 6 6 6-6 6"/></svg></button>
</div>
</label>
<button class="button subtle config-btn" data-open="motors-modal">Motor setup</button>
</div>
</section>
</section>
</main>
<div id="toast" class="toast"></div>
<!-- Modals -->
<dialog id="link-modal" class="modal"><button class="modal-close" data-close>×</button><small>connection</small><h2>Link Settings</h2><div class="form-grid two"><label><span>Baud rate</span><select id="baud"><option>9600</option><option>19200</option><option>38400</option><option selected>57600</option><option>115200</option></select></label><label><span>Control rate</span><select id="rate"><option>10</option><option selected>20</option></select></label></div><div style="margin-top:14px;"><label style="display:flex;flex-direction:column;gap:6px;"><span style="font-size:11px;font-weight:500;color:var(--muted)">Custom Port / Endpoint</span><div style="display:flex;gap:8px;"><input id="custom-port-input" placeholder="e.g. COM3 or tcp:127.0.0.1:5760" style="flex:1;height:32px;padding:0 12px;font-size:11px;"><button type="button" id="custom-port-btn" class="button subtle" style="white-space:nowrap;">Use Port</button></div></label></div><p class="note" style="margin-top:14px;">20 Hz is recommended for smooth intermediate commands on this link.</p></dialog>
<dialog id="battery-modal" class="modal"><button class="modal-close" data-close>×</button><small>Power</small><h2>Battery Settings</h2><form id="battery-form" class="form-grid three"><label><span>Cells (S)</span><div class="number-pill"><button type="button" class="num-step down" tabindex="-1">‹</button><input name="cells" type="number" min="1" step="1"><button type="button" class="num-step up" tabindex="-1">›</button></div></label><label><span>Capacity (mAh)</span><div class="number-pill"><button type="button" class="num-step down" tabindex="-1">‹</button><input name="capacity_mah" type="number" min="1" step="50"><button type="button" class="num-step up" tabindex="-1">›</button></div></label><label><span>C rating</span><div class="number-pill"><button type="button" class="num-step down" tabindex="-1">‹</button><input name="c_rating" type="number" min="1" step=".1"><button type="button" class="num-step up" tabindex="-1">›</button></div></label><label><span>Full V / cell</span><div class="number-pill"><button type="button" class="num-step down" tabindex="-1">‹</button><input name="full_v_per_cell" type="number" step=".01"><button type="button" class="num-step up" tabindex="-1">›</button></div></label><label><span>Empty V / cell</span><div class="number-pill"><button type="button" class="num-step down" tabindex="-1">‹</button><input name="empty_v_per_cell" type="number" step=".01"><button type="button" class="num-step up" tabindex="-1">›</button></div></label><label><span>Warning %</span><div class="number-pill"><button type="button" class="num-step down" tabindex="-1">‹</button><input name="warning_percent" type="number" min="0" max="100" step="1"><button type="button" class="num-step up" tabindex="-1">›</button></div></label><div class="modal-actions wide"><button type="button" class="button subtle" data-close>Cancel</button><button class="button connect-button">Save Settings</button></div></form></dialog>
<dialog id="motors-modal" class="modal motor-modal"><button class="modal-close" data-close>×</button><small>configuration</small><h2>Motor Outputs</h2><p class="note">Function and direction are read one parameter at a time to protect the low-bandwidth link.</p><div class="motor-head"><span>Output</span><span>Function</span><span>Direction</span><span></span></div><div id="motor-list" class="motor-list"></div></dialog>
<script src="model-viewer.js?v=20260826-controls-v2"></script>
<script src="joystick-3d.js?v=20260827-keyboard-v7"></script>
<script src="control-state.js?v=20260827-state-v1"></script>
<script src="app.js?v=20260827-keyboard-v7"></script>
<script src="cursor-light.js?v=20260827-directional-v10"></script>
</body>
</html>