docs: record pause wasm implementation plan

This commit is contained in:
wangdequan
2026-07-07 09:40:33 -04:00
parent 6cecd280e2
commit 83402c506e
3299 changed files with 1364681 additions and 325 deletions

View File

@@ -226,7 +226,19 @@ assert.equal(store.getState().programAxisPreviewPath.samples[0].tool.diameter, 8
assert.equal(store.getState().programAxisPreviewPath.samples[0].sourceFile, "xyzbc_switchkins_sub.ngc");
assert.equal(store.getState().programAxisPreviewPath.samples[0].statement.includes("g53 g0"), true);
store.dispatch({ type: "RUN_READY" });
store.dispatch({ type: "RUN" });
assert.equal(store.getState().machine.powerOn, false);
assert.equal(store.getState().machine.allHomed, false);
assert.equal(store.getState().machine.mode, "manual");
assert.equal(store.getState().operatorMessage, "RUN setup ready: reset ESTOP, power on, Home All, then Run");
await store.dispatch({ type: "RUN_FROM_OPERATOR" });
assert.equal(store.getState().runState, "idle");
assert.equal(store.getState().operatorMessage, "run blocked: machine must be on");
store.dispatch({ type: "TOGGLE_POWER" });
await store.dispatch({ type: "RUN_FROM_OPERATOR" });
assert.equal(store.getState().runState, "idle");
assert.equal(store.getState().operatorMessage, "run blocked: home machine first");
store.dispatch({ type: "HOME" });
await store.dispatch({ type: "RUN_FROM_OPERATOR" });
const liveRunState = store.getState();
assert.equal(liveRunState.programUiExecution.source, "programAxisPreviewPath.samples");
assert.equal(liveRunState.programUiExecution.samplePeriodMs, 50);
@@ -299,6 +311,21 @@ assert.equal(vismachState.transforms.tool.translate.z, -25);
assert.equal(vismachState.halNets.length, 9);
assert.equal(vismachState.semanticBoundary, "web_threejs_vismach_equivalent_driven_by_xyzbc_trt_hal_pins");
const pausedVismachState = buildVismachModelState({
...state,
runState: "paused",
machine: { ...state.machine, interpState: "paused", taskPaused: true },
axisPose: { x: 12.5, y: -6.25, z: 3.75, b: 35, c: -90 },
programRuntimeFeedback: {
axisPose: { x: 99, y: 88, z: 77, b: 66, c: 55 },
},
});
assert.equal(pausedVismachState.pins["table-x"], 12.5);
assert.equal(pausedVismachState.pins["saddle-y"], -6.25);
assert.equal(pausedVismachState.pins["spindle-z"], 3.75);
assert.equal(pausedVismachState.pins["tilt-b"], 35);
assert.equal(pausedVismachState.pins["rotate-c"], -90);
const stagedState = store.getState();
assert.equal(storeStage.save.profileId, "xyzbc-trt");
assert.equal(stagedState.machineFileStaging.profileId, "xyzbc-trt");
@@ -333,10 +360,26 @@ for (const action of [
const buttonStore = createSimulationStore();
buttonStore.dispatch({ type: "ESTOP" });
assert.equal(buttonStore.getState().machine.estopActive, true);
buttonStore.dispatch({ type: "TOGGLE_POWER" });
assert.equal(buttonStore.getState().machine.taskState, "off");
assert.equal(buttonStore.getState().machine.powerOn, false);
buttonStore.dispatch({ type: "TOGGLE_POWER" });
assert.equal(buttonStore.getState().machine.taskState, "off");
assert.equal(buttonStore.getState().machine.powerOn, false);
await buttonStore.dispatch({ type: "RUN_FROM_OPERATOR" });
assert.equal(buttonStore.getState().runState, "powered-off");
assert.equal(buttonStore.getState().operatorMessage, "run blocked: machine must be on");
buttonStore.dispatch({ type: "ESTOP" });
buttonStore.dispatch({ type: "RESET" });
assert.equal(buttonStore.getState().machine.taskState, "estop-reset");
await buttonStore.dispatch({ type: "RUN_FROM_OPERATOR" });
assert.equal(buttonStore.getState().runState, "idle");
assert.equal(buttonStore.getState().operatorMessage, "run blocked: machine must be on");
buttonStore.dispatch({ type: "TOGGLE_POWER" });
assert.equal(buttonStore.getState().machine.powerOn, true);
await buttonStore.dispatch({ type: "RUN_FROM_OPERATOR" });
assert.equal(buttonStore.getState().runState, "idle");
assert.equal(buttonStore.getState().operatorMessage, "run blocked: home machine first");
buttonStore.dispatch({ type: "HOME" });
assert.equal(buttonStore.getState().machine.allHomed, true);
assert.equal(buttonStore.getState().linuxCncProcessMonitor.axes.joint.x, 0);
@@ -350,12 +393,14 @@ if (buttonStore.getState().runState === "running") {
buttonStore.dispatch({ type: "PAUSE_RESUME" });
assert.equal(buttonStore.getState().runState, "paused");
assert.equal(buttonStore.getState().machine.interpState, "paused");
assert.equal(buttonStore.getState().feed.currentVelocity, 0);
buttonStore.dispatch({ type: "PAUSE_RESUME" });
assert.equal(buttonStore.getState().runState, "running");
assert.equal(buttonStore.getState().machine.interpState, "reading");
buttonStore.dispatch({ type: "PAUSE_RESUME" });
assert.equal(buttonStore.getState().runState, "paused");
assert.equal(buttonStore.getState().machine.interpState, "paused");
assert.equal(buttonStore.getState().feed.currentVelocity, 0);
const beforeStepSample = buttonStore.getState().programExecutionSampleIndex;
buttonStore.dispatch({ type: "STEP" });
assert.equal(buttonStore.getState().runState, "stepping");
@@ -367,11 +412,19 @@ if (buttonStore.getState().runState === "running") {
buttonStore.dispatch({ type: "PAUSE" });
assert.equal(buttonStore.getState().runState, "paused");
assert.equal(buttonStore.getState().machine.interpState, "paused");
assert.equal(buttonStore.getState().feed.currentVelocity, 0);
buttonStore.dispatch({ type: "RESUME" });
assert.equal(buttonStore.getState().runState, "running");
assert.equal(buttonStore.getState().machine.interpState, "reading");
}
buttonStore.dispatch({ type: "STOP" });
buttonStore.dispatch({ type: "TOGGLE_POWER" });
assert.equal(buttonStore.getState().machine.taskState, "off");
assert.equal(buttonStore.getState().machine.powerOn, false);
assert.equal(buttonStore.getState().machine.allHomed, false);
buttonStore.dispatch({ type: "TOGGLE_POWER" });
assert.equal(buttonStore.getState().machine.taskState, "off");
assert.equal(buttonStore.getState().machine.powerOn, false);
const idleInterpRunningStore = createSimulationStore({
runState: "running",
@@ -388,74 +441,147 @@ const idleInterpRunningStore = createSimulationStore({
},
});
idleInterpRunningStore.dispatch({ type: "PAUSE" });
assert.equal(idleInterpRunningStore.getState().runState, "paused");
assert.equal(idleInterpRunningStore.getState().machine.interpState, "paused");
assert.equal(idleInterpRunningStore.getState().machine.taskPaused, true);
idleInterpRunningStore.dispatch({ type: "RESUME" });
assert.equal(idleInterpRunningStore.getState().runState, "running");
assert.equal(idleInterpRunningStore.getState().machine.interpState, "reading");
buttonStore.dispatch({ type: "SET_MODE", mode: "manual" });
buttonStore.dispatch({ type: "SET_MODE", mode: "mdi" });
buttonStore.dispatch({ type: "RUN_MDI", command: "M428" });
assert.equal(buttonStore.getState().kinsType, "tcp-xyzbc");
assert.equal(buttonStore.getState().linuxCncProcessMonitor.axes.rtcpState, "on");
buttonStore.dispatch({ type: "RUN_MDI", command: "M429" });
assert.equal(buttonStore.getState().kinsType, "identity");
buttonStore.dispatch({ type: "RUN_MDI", command: "M430" });
assert.equal(buttonStore.getState().kinsType, "userk");
buttonStore.dispatch({ type: "SET_MODE", mode: "manual" });
buttonStore.dispatch({ type: "SET_ACTIVE_JOINT", joint: 4 });
const cBeforeJog = buttonStore.getState().axisPose.c;
buttonStore.dispatch({ type: "JOG", axis: "c", direction: 1, increment: 1 });
assert.equal(buttonStore.getState().axisPose.c, cBeforeJog + 1);
buttonStore.dispatch({ type: "RUN_MDI", command: "G10 L20 P0 C0", manualTouchOff: true });
assert.equal(buttonStore.getState().mdiHistory[0], "G10 L20 P0 C0");
assert.equal(buttonStore.getState().machine.mode, "manual");
assert.equal(buttonStore.getState().runState, "idle");
assert.equal(buttonStore.getState().operatorMessage, "manual touch off G10 L20 P0 C0");
buttonStore.dispatch({ type: "RUN_MDI", command: "G43", manualTouchOff: true });
assert.equal(buttonStore.getState().mdiHistory[0], "G43");
assert.equal(buttonStore.getState().machine.mode, "manual");
assert.equal(buttonStore.getState().runState, "idle");
const feedBefore = buttonStore.getState().feed.feedOverride;
buttonStore.dispatch({ type: "ADJUST_OVERRIDE", target: "feed", delta: 10 });
assert.equal(buttonStore.getState().feed.feedOverride, feedBefore + 10);
assert.equal(buttonStore.getState().linuxCncProcessMonitor.feed.feedOverridePercent, feedBefore + 10);
buttonStore.dispatch({ type: "SET_SPINDLE_DIRECTION", direction: "reverse" });
assert.equal(buttonStore.getState().spindle.direction, "reverse");
assert.equal(buttonStore.getState().linuxCncProcessMonitor.spindle.enabled, true);
assert.equal(buttonStore.getState().linuxCncProcessMonitor.spindle.halPins.on, 1);
assert.equal(buttonStore.getState().linuxCncProcessMonitor.spindle.halPins.forward, 0);
assert.equal(buttonStore.getState().linuxCncProcessMonitor.spindle.halPins.reverse, 1);
assert.equal(buttonStore.getState().linuxCncProcessMonitor.spindle.halPins.speedOut, 1600);
buttonStore.dispatch({ type: "SET_SPINDLE_DIRECTION", direction: "stop" });
assert.equal(buttonStore.getState().spindle.direction, "stop");
assert.equal(buttonStore.getState().linuxCncProcessMonitor.spindle.enabled, false);
assert.equal(buttonStore.getState().linuxCncProcessMonitor.spindle.halPins.on, 0);
assert.equal(buttonStore.getState().linuxCncProcessMonitor.spindle.halPins.forward, 0);
assert.equal(buttonStore.getState().linuxCncProcessMonitor.spindle.halPins.reverse, 0);
assert.equal(buttonStore.getState().linuxCncProcessMonitor.spindle.halPins.speedOut, 0);
buttonStore.dispatch({ type: "SET_SPINDLE_DIRECTION", direction: "forward" });
assert.equal(buttonStore.getState().spindle.direction, "forward");
assert.equal(buttonStore.getState().linuxCncProcessMonitor.spindle.enabled, true);
assert.equal(buttonStore.getState().linuxCncProcessMonitor.spindle.actualRpm, 1600);
assert.equal(buttonStore.getState().linuxCncProcessMonitor.spindle.halPins.on, 1);
assert.equal(buttonStore.getState().linuxCncProcessMonitor.spindle.halPins.forward, 1);
assert.equal(buttonStore.getState().linuxCncProcessMonitor.spindle.halPins.reverse, 0);
assert.equal(buttonStore.getState().linuxCncProcessMonitor.spindle.halPins.speedOut, 1600);
buttonStore.dispatch({ type: "TOGGLE_COOLANT", kind: "flood" });
assert.equal(buttonStore.getState().coolant.flood, true);
assert.equal(buttonStore.getState().linuxCncProcessMonitor.coolant.flood, true);
buttonStore.dispatch({ type: "SET_BLOCK_DELETE", enabled: true });
assert.equal(buttonStore.getState().gmoccapyGui.optionalBlocks, true);
buttonStore.dispatch({ type: "SET_OPTIONAL_STOP", enabled: true });
assert.equal(buttonStore.getState().gmoccapyGui.optionalStop, true);
buttonStore.dispatch({ type: "SET_IGNORE_LIMITS", enabled: true });
assert.equal(buttonStore.getState().gmoccapyGui.ignoreLimits, true);
buttonStore.dispatch({ type: "SET_VIEW", view: "x" });
assert.equal(buttonStore.getState().preview.selectedView, "x");
buttonStore.dispatch({ type: "CLEAR_PREVIEW" });
assert.equal(buttonStore.getState().preview.pathPoints, 0);
assert.equal(idleInterpRunningStore.getState().machine.interpState, "idle");
assert.equal(idleInterpRunningStore.getState().machine.taskPaused, false);
assert.equal(idleInterpRunningStore.getState().operatorMessage, "pause blocked: interpreter is not running");
idleInterpRunningStore.dispatch({ type: "PAUSE_RESUME" });
assert.equal(idleInterpRunningStore.getState().runState, "running");
assert.equal(idleInterpRunningStore.getState().machine.interpState, "idle");
assert.equal(idleInterpRunningStore.getState().operatorMessage, "pause ignored: interpreter is idle");
const staleManualRunningStore = createSimulationStore({
runState: "running",
machine: {
powerOn: true,
estopActive: false,
taskState: "on",
mode: "manual",
interpState: "reading",
interpResumeState: "reading",
taskPaused: false,
allHomed: true,
noForceHoming: false,
},
});
staleManualRunningStore.dispatch({ type: "PAUSE_RESUME" });
assert.equal(staleManualRunningStore.getState().runState, "running");
assert.equal(staleManualRunningStore.getState().machine.mode, "manual");
assert.equal(staleManualRunningStore.getState().machine.interpState, "reading");
assert.equal(staleManualRunningStore.getState().machine.taskPaused, false);
assert.equal(staleManualRunningStore.getState().operatorMessage, "pause blocked: task mode must be auto or MDI");
assert.equal(staleManualRunningStore.getState().taskHalPauseLock, null);
const lockedPauseState = staleManualRunningStore.getState();
staleManualRunningStore.dispatch({
type: "TASK_HAL_STATUS_APPLIED",
operatorMessage: "simulated stale running task/HAL status",
status: {
taskRuntimeReady: true,
taskCommandsDriveMotionRuntime: true,
task: {
state: "ON",
mode: "AUTO",
interpState: "READING",
execState: "EXEC",
taskCycle: 123,
},
motionStatus: {
cycle: 25,
motionHalSyncReady: true,
motion: {
programLine: Number(lockedPauseState.activeLine || 1) + 5,
currentVel: 12,
requestedVel: 12,
inPosition: false,
},
axis: {
x: 99,
y: 88,
z: 77,
b: 66,
c: 55,
},
},
halSnapshot: {
ready: true,
pins: {
"motion.program-line": { value: Number(lockedPauseState.activeLine || 1) + 5 },
},
},
},
});
assert.equal(staleManualRunningStore.getState().runState, "running");
assert.equal(staleManualRunningStore.getState().machine.mode, "manual");
assert.equal(staleManualRunningStore.getState().machine.interpState, "reading");
assert.equal(staleManualRunningStore.getState().taskHalPauseLock, null);
const controlStore = createSimulationStore();
controlStore.dispatch({ type: "ESTOP" });
controlStore.dispatch({ type: "RESET" });
controlStore.dispatch({ type: "TOGGLE_POWER" });
controlStore.dispatch({ type: "HOME" });
controlStore.dispatch({ type: "SET_MODE", mode: "manual" });
controlStore.dispatch({ type: "SET_MODE", mode: "mdi" });
controlStore.dispatch({ type: "RUN_MDI", command: "M428" });
assert.equal(controlStore.getState().kinsType, "tcp-xyzbc");
assert.equal(controlStore.getState().linuxCncProcessMonitor.axes.rtcpState, "on");
controlStore.dispatch({ type: "RUN_MDI", command: "M429" });
assert.equal(controlStore.getState().kinsType, "identity");
controlStore.dispatch({ type: "RUN_MDI", command: "M430" });
assert.equal(controlStore.getState().kinsType, "userk");
controlStore.dispatch({ type: "SET_MODE", mode: "manual" });
controlStore.dispatch({ type: "SET_ACTIVE_JOINT", joint: 4 });
const cBeforeJog = controlStore.getState().axisPose.c;
controlStore.dispatch({ type: "JOG", axis: "c", direction: 1, increment: 1 });
assert.equal(controlStore.getState().axisPose.c, cBeforeJog + 1);
controlStore.dispatch({ type: "RUN_MDI", command: "G10 L20 P0 C0", manualTouchOff: true });
assert.equal(controlStore.getState().mdiHistory[0], "G10 L20 P0 C0");
assert.equal(controlStore.getState().machine.mode, "manual");
assert.equal(controlStore.getState().runState, "idle");
assert.equal(controlStore.getState().operatorMessage, "manual touch off G10 L20 P0 C0");
controlStore.dispatch({ type: "RUN_MDI", command: "G43", manualTouchOff: true });
assert.equal(controlStore.getState().mdiHistory[0], "G43");
assert.equal(controlStore.getState().machine.mode, "manual");
assert.equal(controlStore.getState().runState, "idle");
const feedBefore = controlStore.getState().feed.feedOverride;
controlStore.dispatch({ type: "ADJUST_OVERRIDE", target: "feed", delta: 10 });
assert.equal(controlStore.getState().feed.feedOverride, feedBefore + 10);
assert.equal(controlStore.getState().linuxCncProcessMonitor.feed.feedOverridePercent, feedBefore + 10);
controlStore.dispatch({ type: "SET_SPINDLE_DIRECTION", direction: "reverse" });
assert.equal(controlStore.getState().spindle.direction, "reverse");
assert.equal(controlStore.getState().linuxCncProcessMonitor.spindle.enabled, true);
assert.equal(controlStore.getState().linuxCncProcessMonitor.spindle.halPins.on, 1);
assert.equal(controlStore.getState().linuxCncProcessMonitor.spindle.halPins.forward, 0);
assert.equal(controlStore.getState().linuxCncProcessMonitor.spindle.halPins.reverse, 1);
assert.equal(controlStore.getState().linuxCncProcessMonitor.spindle.halPins.speedOut, 1600);
controlStore.dispatch({ type: "SET_SPINDLE_DIRECTION", direction: "stop" });
assert.equal(controlStore.getState().spindle.direction, "stop");
assert.equal(controlStore.getState().linuxCncProcessMonitor.spindle.enabled, false);
assert.equal(controlStore.getState().linuxCncProcessMonitor.spindle.halPins.on, 0);
assert.equal(controlStore.getState().linuxCncProcessMonitor.spindle.halPins.forward, 0);
assert.equal(controlStore.getState().linuxCncProcessMonitor.spindle.halPins.reverse, 0);
assert.equal(controlStore.getState().linuxCncProcessMonitor.spindle.halPins.speedOut, 0);
controlStore.dispatch({ type: "SET_SPINDLE_DIRECTION", direction: "forward" });
assert.equal(controlStore.getState().spindle.direction, "forward");
assert.equal(controlStore.getState().linuxCncProcessMonitor.spindle.enabled, true);
assert.equal(controlStore.getState().linuxCncProcessMonitor.spindle.actualRpm, 1600);
assert.equal(controlStore.getState().linuxCncProcessMonitor.spindle.halPins.on, 1);
assert.equal(controlStore.getState().linuxCncProcessMonitor.spindle.halPins.forward, 1);
assert.equal(controlStore.getState().linuxCncProcessMonitor.spindle.halPins.reverse, 0);
assert.equal(controlStore.getState().linuxCncProcessMonitor.spindle.halPins.speedOut, 1600);
controlStore.dispatch({ type: "TOGGLE_COOLANT", kind: "flood" });
assert.equal(controlStore.getState().coolant.flood, true);
assert.equal(controlStore.getState().linuxCncProcessMonitor.coolant.flood, true);
controlStore.dispatch({ type: "SET_BLOCK_DELETE", enabled: true });
assert.equal(controlStore.getState().gmoccapyGui.optionalBlocks, true);
controlStore.dispatch({ type: "SET_OPTIONAL_STOP", enabled: true });
assert.equal(controlStore.getState().gmoccapyGui.optionalStop, true);
controlStore.dispatch({ type: "SET_IGNORE_LIMITS", enabled: true });
assert.equal(controlStore.getState().gmoccapyGui.ignoreLimits, true);
controlStore.dispatch({ type: "SET_VIEW", view: "x" });
assert.equal(controlStore.getState().preview.selectedView, "x");
controlStore.dispatch({ type: "CLEAR_PREVIEW" });
assert.equal(controlStore.getState().preview.pathPoints, 0);
const stagingPlan = await createMachineFileStagingPlan({ profile });
assert.equal(stagingPlan.summary.remapFileCount >= 3, true);