diff --git a/public/boardViewer.html b/public/boardViewer.html index d52071c..844d1a5 100644 --- a/public/boardViewer.html +++ b/public/boardViewer.html @@ -333,7 +333,8 @@ async function loadData() { return; } buildScene(data); - statusEl.textContent = `Run: ${data.runDir} • ${new Date().toLocaleTimeString('de-CH')}`; + const robotLabel = data.robotFile ? ` • Robot: ${data.robotFile}` : ''; + statusEl.textContent = `Run: ${data.runDir}${robotLabel} • ${new Date().toLocaleTimeString('de-CH')}`; } catch (err) { statusEl.textContent = `Fehler: ${err.message ?? err}`; } diff --git a/server/server.js b/server/server.js index 3a40535..ec797f1 100755 --- a/server/server.js +++ b/server/server.js @@ -218,6 +218,28 @@ async function findLatestCalibSession() { } } +/** + * Sucht die neueste Kalibrierungs-Session, die eine NPZ für die angegebene Kamera enthält. + * Gibt { session, npzPath } zurück oder null wenn keine gefunden. + */ +async function findLatestNpzForCamera(camId) { + try { + await fsPromises.access(calibDataDir); + const entries = await fsPromises.readdir(calibDataDir, { withFileTypes: true }); + const dirs = entries.filter(e => e.isDirectory()).map(e => e.name).sort().reverse(); + for (const dir of dirs) { + const npzPath = path.join(calibDataDir, dir, `${camId}_calibration.npz`); + try { + await fsPromises.access(npzPath); + return { session: dir, npzPath }; + } catch {} + } + return null; + } catch { + return null; + } +} + /** Liest meta.json einer Session */ async function readCalibMeta(sessionName) { try { @@ -474,7 +496,13 @@ app.post('/api/board/run', async (req, res) => { await fsPromises.mkdir(runDir, { recursive: true }); send({ type: 'log', text: `▶ Board-Run: ${ts}` }); send({ type: 'log', text: `▶ Ordner: ${runDir}` }); + + // Robot-JSON laden und Marker-Anzahl loggen + let robotData = null; + try { robotData = JSON.parse(await fsPromises.readFile(ROBOT_JSON, 'utf8')); } catch {} + const boardMarkerCount = robotData?.links?.Board?.markers?.length ?? '?'; send({ type: 'log', text: `▶ Robot-JSON: ${ROBOT_JSON}` }); + send({ type: 'log', text: `▶ Board-Marker (A0): ${boardMarkerCount} Marker aus links.Board.markers` }); send({ type: 'log', text: '' }); // 2. Kameras ermitteln @@ -482,14 +510,9 @@ app.post('/api/board/run', async (req, res) => { const camData = await new WebcamClient(WEBCAM_URL).getCameras(); const cameraIds = (camData.cameras ?? []).map(c => c.id); send({ type: 'log', text: `▶ Kameras: ${cameraIds.join(', ')}` }); - - // 3. Aktuelle Kalibrierungs-Session für NPZ-Dateien - const calibSession = await findLatestCalibSession(); - if (!calibSession) throw new Error('Keine Kalibrierungs-Session. Bitte zuerst Camera NPZ kalibrieren.'); - send({ type: 'log', text: `▶ NPZ-Session: ${calibSession}` }); send({ type: 'log', text: '' }); - // 4. Pro Kamera: Foto → Script 1 → Script 2 + // 3. Pro Kamera: Foto → Script 1 → Script 2 for (const camId of cameraIds) { send({ type: 'log', text: `─── ${camId} ${'─'.repeat(40 - camId.length)}` }); @@ -509,13 +532,14 @@ app.post('/api/board/run', async (req, res) => { await fsPromises.writeFile(imgPath, Buffer.from(await snapResp.arrayBuffer())); send({ type: 'log', text: `✅ Foto: ${camId}.jpg` }); - // NPZ prüfen - const npzPath = path.join(calibDataDir, calibSession, `${camId}_calibration.npz`); - try { await fsPromises.access(npzPath); } - catch { - send({ type: 'log', text: `⚠ Keine NPZ (${camId}_calibration.npz) – übersprungen` }); + // NPZ suchen – neueste Session, die eine NPZ für diese Kamera enthält + const npzInfo = await findLatestNpzForCamera(camId); + if (!npzInfo) { + send({ type: 'log', text: `⚠ Keine NPZ für ${camId} gefunden (in keiner Kalibrierungs-Session) – übersprungen` }); continue; } + const npzPath = npzInfo.npzPath; + send({ type: 'log', text: `▶ NPZ: data/calibration/${npzInfo.session}/${camId}_calibration.npz` }); // Script 1 – ArUco-Erkennung send({ type: 'log', text: '\n▷ 1_detect_aruco_observations' }); @@ -659,7 +683,7 @@ app.get('/api/board/latest', async (req, res) => { measuredMarkers = JSON.parse(raw); } catch {} - return res.json({ runDir: runName, robot, detections, cameraPoses, measuredMarkers }); + return res.json({ runDir: runName, robotFile: path.basename(ROBOT_JSON), robot, detections, cameraPoses, measuredMarkers }); } catch (err) { return res.status(500).json({ error: String(err) }); }