Advance AXIS-style Three.js simulation UI
This commit is contained in:
@@ -1655,7 +1655,7 @@ const releaseArtifactMountResult = mountIniPanelShellWorkflowOverviewReleaseRead
|
||||
rowsNode: releaseArtifactRowsNode,
|
||||
});
|
||||
assert.equal(releaseArtifactRenderResult.rendered, true);
|
||||
assert.equal(releaseArtifactRenderResult.rowCount, 8);
|
||||
assert.equal(releaseArtifactRenderResult.rowCount, 9);
|
||||
assert.equal(releaseArtifactRenderResult.dataset.handoffScope, "workflow-overview-release-readiness-artifact");
|
||||
assert.equal(
|
||||
releaseArtifactRenderResult.rowIds.includes("gate-execution-manifest"),
|
||||
@@ -1669,8 +1669,12 @@ assert.equal(
|
||||
releaseArtifactRenderResult.rowIds.includes("gate-action-plan"),
|
||||
true,
|
||||
);
|
||||
assert.equal(
|
||||
releaseArtifactRenderResult.rowIds.includes("axis-screenshot-artifacts"),
|
||||
true,
|
||||
);
|
||||
assert.equal(releaseArtifactMountResult.ready, true);
|
||||
assert.equal(releaseArtifactMountResult.renderResult.rowCount, 8);
|
||||
assert.equal(releaseArtifactMountResult.renderResult.rowCount, 9);
|
||||
assert.deepEqual(
|
||||
validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson("{").missing,
|
||||
["artifact-json"],
|
||||
@@ -1711,7 +1715,7 @@ assert.equal(
|
||||
);
|
||||
assert.equal(releaseArtifactUrlWorkflow.renderState.statusLine, "Ready: No blocking reasons");
|
||||
assert.equal(releaseArtifactUrlWorkflow.mountResult.ready, true);
|
||||
assert.equal(releaseArtifactUrlWorkflow.mountResult.renderResult.rowCount, 8);
|
||||
assert.equal(releaseArtifactUrlWorkflow.mountResult.renderResult.rowCount, 9);
|
||||
const releaseArtifactUrlWorkflowSummary =
|
||||
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel(
|
||||
releaseArtifactUrlWorkflow,
|
||||
|
||||
@@ -7,12 +7,19 @@ import {
|
||||
DEFAULT_SIMULATION_PROGRAM,
|
||||
DEFAULT_SIMULATION_PROGRAM_ID,
|
||||
createPlaybackFrame,
|
||||
createDroState,
|
||||
createMachineStatusState,
|
||||
createModalState,
|
||||
createSimulationSummary,
|
||||
createToolpathPolylinePoints,
|
||||
createToolpathViewBox,
|
||||
getSimulationTestProgram,
|
||||
getSimulationTestPrograms,
|
||||
panToolpathViewBox,
|
||||
parseLinuxCncCanonicalMotion,
|
||||
runLinuxCncProgram,
|
||||
runRealBrowserSimulation,
|
||||
zoomToolpathViewBox,
|
||||
} from "../../../runtime/ui/simulation/simulation-app.js";
|
||||
import {
|
||||
SIMULATION_TEST_PROGRAMS as directoryPrograms,
|
||||
@@ -64,16 +71,59 @@ const arcCanonical = [
|
||||
"canon_event=ARC_FEED line=4 first_end=0 second_end=0 first_axis=1 second_axis=0 rotation=1 axis_end_point=0 a=0 b=0 c=0 u=0 v=0 w=0",
|
||||
].join("\n");
|
||||
const arcMotion = parseLinuxCncCanonicalMotion(arcCanonical, arcProgram.text);
|
||||
const arcModal = createModalState(arcCanonical);
|
||||
const unavailableMachineStatus = createMachineStatusState(arcCanonical);
|
||||
|
||||
assert.equal(arcMotion.length, 3);
|
||||
assert.equal(arcMotion[1].type, "ARC_FEED");
|
||||
assert.equal(arcMotion[1].statement, "G2 X1 Y1 I1 J0 F80");
|
||||
assert.deepEqual(arcMotion[1].arc.planeAxes, ["x", "y", "z"]);
|
||||
assert.equal(arcMotion[1].arc.center.x, 1);
|
||||
assert.equal(arcMotion[1].arc.center.y, 0);
|
||||
assert.equal(arcMotion[1].arc.rotation, -1);
|
||||
assert.deepEqual(
|
||||
{ x: arcMotion[1].axes.x, y: arcMotion[1].axes.y, z: arcMotion[1].axes.z },
|
||||
{ x: 1, y: 1, z: 0 },
|
||||
"arc parser should map LinuxCNC canonical arc endpoints onto active-plane axes",
|
||||
);
|
||||
assert.equal(createToolpathPolylinePoints(arcMotion), "0,0 1,-1 0,0");
|
||||
assert.equal(arcModal.apiName, "real-browser-simulation-modal-state");
|
||||
assert.equal(arcModal.source, "linuxcnc-update-tag");
|
||||
assert.ok(arcModal.raw.includes("canon_event=UPDATE_TAG line=1"));
|
||||
assert.ok(arcModal.rows.some(({ id, value, source }) => id === "plane" && value === "plane=170" && source === "linuxcnc-update-tag"));
|
||||
assert.equal(unavailableMachineStatus.spindle.state, "n/a");
|
||||
assert.equal(unavailableMachineStatus.coolant.mist, "n/a");
|
||||
|
||||
const runtimeMachineStatus = createMachineStatusState([
|
||||
"canon_event=SET_SPINDLE_SPEED spindle=0 speed=1200",
|
||||
"canon_event=START_SPINDLE_CLOCKWISE spindle=0 wait_for_at_speed=1",
|
||||
"canon_event=STOP_SPINDLE_TURNING spindle=0",
|
||||
"canon_event=MIST_ON",
|
||||
"canon_event=FLOOD_ON",
|
||||
"canon_event=MIST_OFF",
|
||||
"canon_event=FLOOD_OFF",
|
||||
"canon_event=DISABLE_FEED_OVERRIDE",
|
||||
"canon_event=ENABLE_FEED_OVERRIDE",
|
||||
"canon_event=DISABLE_SPEED_OVERRIDE spindle=0",
|
||||
"canon_event=ENABLE_SPEED_OVERRIDE spindle=0",
|
||||
].join("\n"));
|
||||
assert.equal(runtimeMachineStatus.spindle.state, "off");
|
||||
assert.equal(runtimeMachineStatus.spindle.direction, "cw");
|
||||
assert.equal(runtimeMachineStatus.spindle.speed, "1200");
|
||||
assert.equal(runtimeMachineStatus.coolant.mist, "off");
|
||||
assert.equal(runtimeMachineStatus.coolant.flood, "off");
|
||||
assert.equal(runtimeMachineStatus.overrides.feed, "enabled");
|
||||
assert.equal(runtimeMachineStatus.overrides.speed, "enabled");
|
||||
|
||||
const toolMachineStatus = createMachineStatusState([
|
||||
"canon_event=SELECT_TOOL tool=2",
|
||||
"canon_event=USE_TOOL_LENGTH_OFFSET x=0 y=0 z=1.25 a=0 b=0 c=0 u=0 v=0 w=0",
|
||||
"canon_event=CHANGE_TOOL_NUMBER pocket=2",
|
||||
].join("\n"));
|
||||
assert.equal(toolMachineStatus.tool.selected, "2");
|
||||
assert.equal(toolMachineStatus.tool.current, "2");
|
||||
assert.equal(toolMachineStatus.tool.pocket, "2");
|
||||
assert.equal(toolMachineStatus.tool.lengthOffset, "z=1.250");
|
||||
|
||||
const xzArcCanonical = [
|
||||
"canon_event=UPDATE_TAG line=1 g0=-1 motion=0 plane=180 origin=530 feed=0 speed=0 flags=1048994",
|
||||
@@ -101,12 +151,20 @@ const playbackState = {
|
||||
motion: arcMotion,
|
||||
};
|
||||
const firstFrame = createPlaybackFrame(playbackState, 0);
|
||||
const firstDro = createDroState(firstFrame);
|
||||
assert.equal(firstFrame.apiName, "real-browser-simulation-playback-frame");
|
||||
assert.equal(firstFrame.index, 0);
|
||||
assert.equal(firstFrame.step, 1);
|
||||
assert.equal(firstFrame.total, 3);
|
||||
assert.equal(firstFrame.activeLine, 1);
|
||||
assert.equal(firstFrame.visibleMotion.length, 1);
|
||||
assert.equal(firstDro.apiName, "real-browser-simulation-dro-state");
|
||||
assert.equal(firstDro.actual.x, "0.000");
|
||||
assert.equal(firstDro.distanceToGo.x, "n/a");
|
||||
assert.equal(firstDro.workOffsetG54.x, "n/a");
|
||||
assert.equal(firstDro.g92Offset.x, "n/a");
|
||||
assert.equal(firstDro.toolLengthOffset.x, "n/a");
|
||||
assert.equal(firstDro.velocity, "n/a");
|
||||
|
||||
const arcFrame = createPlaybackFrame(playbackState, 1);
|
||||
assert.equal(arcFrame.index, 1);
|
||||
@@ -120,6 +178,34 @@ const clampedFrame = createPlaybackFrame(playbackState, 99);
|
||||
assert.equal(clampedFrame.index, 2);
|
||||
assert.equal(clampedFrame.progress, 100);
|
||||
|
||||
const fitViewBox = createToolpathViewBox(arcMotion);
|
||||
const zoomedViewBox = zoomToolpathViewBox(fitViewBox, 2);
|
||||
assert.ok(zoomedViewBox.width < fitViewBox.width, "zoomed toolpath viewBox should narrow around the fit center");
|
||||
assert.ok(zoomedViewBox.height < fitViewBox.height, "zoomed toolpath viewBox should narrow around the fit center");
|
||||
const pannedViewBox = panToolpathViewBox(zoomedViewBox, { x: 0.5, y: -0.25 });
|
||||
assert.equal(pannedViewBox.minX, zoomedViewBox.minX + 0.5);
|
||||
assert.equal(pannedViewBox.minY, zoomedViewBox.minY - 0.25);
|
||||
assert.equal(pannedViewBox.width, zoomedViewBox.width);
|
||||
assert.equal(pannedViewBox.height, zoomedViewBox.height);
|
||||
|
||||
const interpCalls = [];
|
||||
const fakeInterp = {
|
||||
runProgram(programText) {
|
||||
interpCalls.push(["runProgram", programText]);
|
||||
return arcCanonical;
|
||||
},
|
||||
runProgramWithIni(programText, iniPath) {
|
||||
interpCalls.push(["runProgramWithIni", programText, iniPath]);
|
||||
return arcCanonical;
|
||||
},
|
||||
};
|
||||
assert.equal(runLinuxCncProgram(fakeInterp, arcProgram.text), arcCanonical);
|
||||
assert.equal(runLinuxCncProgram(fakeInterp, arcProgram.text, { iniPath: "/work/axis.ini" }), arcCanonical);
|
||||
assert.deepEqual(interpCalls, [
|
||||
["runProgram", arcProgram.text],
|
||||
["runProgramWithIni", arcProgram.text, "/work/axis.ini"],
|
||||
]);
|
||||
|
||||
const customRunDocument = {
|
||||
body: { dataset: {} },
|
||||
querySelector: () => null,
|
||||
@@ -133,5 +219,22 @@ assert.equal(customRun.program.id, "custom");
|
||||
assert.equal(customRun.program.source, "custom");
|
||||
assert.ok(customRun.resultText.includes("canon_event=STRAIGHT_FEED line=2 x=4.25 y=2.5"));
|
||||
assert.ok(customRun.summary.ready);
|
||||
assert.equal(customRun.modal.apiName, "real-browser-simulation-modal-state");
|
||||
|
||||
const sessionRunCalls = [];
|
||||
const sessionRun = await runRealBrowserSimulation({
|
||||
documentRef: customRunDocument,
|
||||
programText: arcProgram.text,
|
||||
interp: {
|
||||
runProgramWithIni(programText, iniPath) {
|
||||
sessionRunCalls.push([programText, iniPath]);
|
||||
return arcCanonical;
|
||||
},
|
||||
},
|
||||
iniPath: "/work/session.ini",
|
||||
});
|
||||
assert.equal(sessionRun.execution.mode, "linuxcnc-wasm-with-ini");
|
||||
assert.equal(sessionRun.execution.iniPath, "/work/session.ini");
|
||||
assert.deepEqual(sessionRunCalls, [[arcProgram.text, "/work/session.ini"]]);
|
||||
|
||||
console.log("real_simulation_programs_node_smoke=ok");
|
||||
|
||||
Reference in New Issue
Block a user