Callibration Board 0

This commit is contained in:
chk
2026-06-10 13:58:21 +02:00
parent 03b7883105
commit 67257d9754
10 changed files with 4286 additions and 46 deletions

View File

@@ -253,19 +253,22 @@
<div class="sections">
<div class="section full">
<h2>Board <span class="status-badge open">offen</span></h2>
<div class="placeholder-note">
Ziel: Extrinsische Position des Marker-Boards im Kamera-Koordinatensystem bestimmen
(Rotations- und Translationsvektor via <code>solvePnP</code>).<br><br>
Geplante Aktionen: Kamerabild mit erkannten Markern anzeigen · Pose berechnen ·
Kalibrierungsdatei speichern.<br><br>
<em>Aktionen werden ergänzt sobald das Konzept feststeht.</em>
<h2>Board ArUco &amp; Kamera-Pose</h2>
<div class="info-grid" style="margin-top: 14px;">
<span class="info-label">Ablauf</span>
<span class="info-value" style="font-family: inherit; font-size: 13px; color: var(--muted);">
Foto aufnehmen → ArUco erkennen → Kamera-Pose schätzen
</span>
<span class="info-label">Schritte</span>
<span class="info-value" style="font-family: inherit; font-size: 13px; color: var(--muted);">
1_detect_aruco_observations &nbsp;&nbsp; 2_estimate_camera_from_observations
</span>
<span class="info-label">Letzter Run</span>
<span class="info-value" id="board-last-run"></span>
</div>
<div class="controls" style="margin-top: 14px;">
<button disabled>Foto aufnehmen</button>
<button disabled>Marker erkennen</button>
<button disabled>Pose berechnen</button>
<button disabled>Board-Pose speichern</button>
<div class="controls" style="margin-top: 16px;">
<button id="btn-board-run">Board erkennen</button>
<button disabled title="Folgt später">Ergebnis anzeigen</button>
</div>
</div>
@@ -543,6 +546,78 @@
btn.disabled = false;
}
});
// ── Board ──────────────────────────────────────────────────────────────────
const logBoard = document.getElementById('log-board');
function logB(msg) {
const ts = new Date().toLocaleTimeString('de-CH');
logBoard.value += `[${ts}] ${msg}\n`;
logBoard.scrollTop = logBoard.scrollHeight;
}
// SSE-Stream lesen (gleiche Logik wie compute)
async function readSseStream(response, logFn, onDone) {
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const parts = buffer.split('\n\n');
buffer = parts.pop();
for (const part of parts) {
for (const line of part.split('\n')) {
if (!line.startsWith('data: ')) continue;
try {
const evt = JSON.parse(line.slice(6));
if (evt.type === 'log') {
if (evt.text !== '') logFn(evt.text);
} else if (evt.type === 'done') {
onDone(evt);
}
} catch { /* ignore */ }
}
}
}
}
document.getElementById('btn-board-run').addEventListener('click', async () => {
logB('Board-Erkennung wird gestartet …');
const btn = document.getElementById('btn-board-run');
btn.disabled = true;
try {
const response = await fetch('/api/board/run', { method: 'POST' });
if (!response.ok) {
const raw = await response.text().catch(() => '');
let msg;
try { msg = JSON.parse(raw).error || raw; }
catch { msg = raw.slice(0, 300) || `HTTP ${response.status}`; }
logB(`❌ HTTP ${response.status}: ${msg}`);
return;
}
await readSseStream(response, logB, (evt) => {
if (evt.exitCode === 0) {
logB('✅ Board-Run abgeschlossen.');
if (evt.runDir) {
document.getElementById('board-last-run').textContent = evt.runDir;
}
} else {
logB(`❌ Beendet mit Exit-Code ${evt.exitCode}`);
}
});
} catch (err) {
logB(`❌ Fehler: ${err}`);
} finally {
btn.disabled = false;
}
});
</script>
</body>