Add RTCP simulation QA updates

This commit is contained in:
2026-06-22 09:30:27 -04:00
parent 61e2fe8441
commit ea8e10031b
51 changed files with 10008 additions and 178 deletions

View File

@@ -84,8 +84,8 @@
}
}
if (!doc.querySelector(".machine-preview")) {
throw new Error("missing machine preview");
if (!doc.querySelector(".toolpath-preview")) {
throw new Error("missing toolpath preview");
}
let canvas = doc.querySelector("[data-five-axis-canvas]");
if (!canvas) {
@@ -95,13 +95,17 @@
canvas.dataset.threeReady !== "true" ||
canvas.dataset.threeFrameApi !== "web-rtcp-5axis-motion-frame" ||
canvas.dataset.threeSceneMode !== "program-preview-and-tool-execution" ||
canvas.dataset.threePreviewScope !== "machine-reference-and-toolpath" ||
canvas.dataset.threeMachineReferenceModel !== "webgl-five-axis-reference" ||
canvas.dataset.threeCameraControls !== "orbit-pan-zoom" ||
Number(canvas.dataset.threePathPoints ?? 0) < 64 ||
Number(canvas.dataset.threeSceneObjects ?? 0) < 5 ||
Number(canvas.dataset.threeSceneObjects ?? 0) < 12 ||
!canvas.dataset.threeToolhead ||
!canvas.dataset.threeToolAxis ||
!canvas.dataset.threeTcpPose ||
canvas.dataset.threeToolExecutionMarker !== "true"
canvas.dataset.threeToolExecutionMarker !== "true" ||
canvas.dataset.threeTcpMarker !== "sphere" ||
canvas.dataset.threeToolAxisMarker !== "line"
) {
throw new Error(`Three.js preview did not expose ready render state: ${JSON.stringify(canvas.dataset)}`);
}
@@ -428,6 +432,10 @@
}
if (
canvas.dataset.threeSceneMode !== "program-preview-and-tool-execution" ||
canvas.dataset.threePreviewScope !== "machine-reference-and-toolpath" ||
canvas.dataset.threeMachineReferenceModel !== "webgl-five-axis-reference" ||
canvas.dataset.threeTcpMarker !== "sphere" ||
canvas.dataset.threeToolAxisMarker !== "line" ||
canvas.dataset.threeToolpathPreviewSource !== "linuxcnc_interpreter_canonical_motion" ||
canvas.dataset.threeToolExecutionTraceSource !== "linuxcnc_tp_samples_or_task_motion_hal_feedback" ||
canvas.dataset.threePathFitBounds !== "ok" ||
@@ -813,23 +821,38 @@
});
function assertCanvasNonblank(canvas, context) {
const stats = canvasPixelStats(canvas, context);
if (stats.nonBlackRatio <= 0.02) {
throw new Error(`${context}: non-black pixel ratio too low ${JSON.stringify(stats)}`);
}
if (stats.averageLuminance <= 5) {
throw new Error(`${context}: average luminance too low ${JSON.stringify(stats)}`);
}
}
function canvasPixelStats(canvas, context) {
const gl = canvas.getContext("webgl2") || canvas.getContext("webgl");
if (!gl) {
throw new Error(`${context}: missing WebGL context`);
}
const pixel = new Uint8Array(4);
gl.readPixels(
Math.floor(canvas.width / 2),
Math.floor(canvas.height / 2),
1,
1,
gl.RGBA,
gl.UNSIGNED_BYTE,
pixel,
);
if (pixel[0] === 0 && pixel[1] === 0 && pixel[2] === 0 && pixel[3] === 0) {
throw new Error(`${context}: center pixel was blank`);
const width = Math.max(canvas.width || 0, 1);
const height = Math.max(canvas.height || 0, 1);
const pixels = new Uint8Array(width * height * 4);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
let nonBlack = 0;
let luminance = 0;
for (let index = 0; index < pixels.length; index += 4) {
const luma = pixels[index] * 0.2126 + pixels[index + 1] * 0.7152 + pixels[index + 2] * 0.0722;
luminance += luma;
if (luma > 8) nonBlack += 1;
}
const total = width * height;
return {
width,
height,
nonBlackRatio: nonBlack / total,
averageLuminance: luminance / total,
};
}
</script>
</body>