This commit is contained in:
chk
2026-06-10 14:41:55 +02:00
parent 86bee8810b
commit 1032c53630
4 changed files with 432 additions and 1 deletions

View File

@@ -572,6 +572,73 @@ app.post('/api/board/run', async (req, res) => {
}
});
/** Neuestes Board-Run-Verzeichnis (Timestamp-Name) oder null */
async function findLatestBoardRun() {
try {
await fsPromises.access(boardDataDir);
const entries = await fsPromises.readdir(boardDataDir, { withFileTypes: true });
const dirs = entries.filter(e => e.isDirectory()).map(e => e.name).sort().reverse();
return dirs[0] ?? null;
} catch {
return null;
}
}
/**
* GET /api/board/latest
* Gibt Daten des letzten Board-Runs zurück: robot.json + Detection-Ergebnisse + Kamera-Posen.
* Wird vom Board-Viewer (boardViewer.html) abgefragt.
*/
app.get('/api/board/latest', async (req, res) => {
try {
const runName = await findLatestBoardRun();
if (!runName) return res.json({ runDir: null, robot: null, detections: [], cameraPoses: [] });
const runDir = path.join(boardDataDir, runName);
let robot = null;
try { robot = JSON.parse(await fsPromises.readFile(ROBOT_JSON, 'utf8')); } catch {}
let files = [];
try { files = await fsPromises.readdir(runDir); } catch {}
const detections = [];
const cameraPoses = [];
for (const f of files.sort()) {
if (f.endsWith('_aruco_detection.json')) {
try {
const data = JSON.parse(await fsPromises.readFile(path.join(runDir, f), 'utf8'));
detections.push({
file: f,
cameraId: data.camera?.camera_id ?? f.replace('_aruco_detection.json', ''),
detectedMarkerIds: (data.detections ?? []).map(d => d.marker_id),
numDetected: data.aruco?.num_detected_markers ?? 0,
numRejected: data.aruco?.num_rejected_candidates ?? 0,
});
} catch {}
} else if (f.endsWith('_camera_pose.json')) {
try {
const data = JSON.parse(await fsPromises.readFile(path.join(runDir, f), 'utf8'));
const cp = data.camera_pose;
cameraPoses.push({
file: f,
cameraId: data.camera?.camera_id ?? f.replace('_camera_pose.json', ''),
position_mm: cp?.camera_in_world?.position_mm ?? null,
rotation_matrix: cp?.world_to_camera?.rotation_matrix ?? null,
usedMarkerIds: data.estimation?.used_marker_ids ?? [],
rms_px: data.estimation?.residual_rms_px ?? null,
});
} catch {}
}
}
return res.json({ runDir: runName, robot, detections, cameraPoses });
} catch (err) {
return res.status(500).json({ error: String(err) });
}
});
/**
* POST /api/calibration/upload-npz
* Liest {camera}_calibration.npz aus der aktuellen Session und