feat: complete working8 pause semantics

This commit is contained in:
wangdequan
2026-07-07 10:27:02 -04:00
parent 83402c506e
commit 4ba45b2ec5
987 changed files with 340641 additions and 65 deletions

View File

@@ -217,6 +217,13 @@ export function normalizeTaskHalStatus(status = {}) {
const halPins = status.halSnapshot?.pins || {};
const motionProgramLine = Number(motion.programLine || 0);
const halProgramLine = Number(halPins["motion.program-line"]?.value || 0);
const motionQueueDepth = Number(
status.motionStatus?.commandQueueDepth ??
motion.commandQueueDepth ??
status.motionStatus?.queueDepth ??
motion.queueDepth ??
0,
);
const activeLine = motionProgramLine > 0
? motionProgramLine
: halProgramLine > 0
@@ -242,10 +249,17 @@ export function normalizeTaskHalStatus(status = {}) {
taskState: String(status.task?.state || "ESTOP").toLowerCase(),
taskMode: String(status.task?.mode || "MANUAL").toLowerCase(),
interpState: String(status.task?.interpState || "IDLE").toLowerCase(),
interpResumeState: String(status.task?.interpResumeState || status.task?.interpState || "IDLE").toLowerCase(),
execState: String(status.task?.execState || "DONE").toLowerCase(),
taskPaused: status.task?.taskPaused === true,
singleStepping: status.task?.singleStepping === true,
taskCycle: Number(status.task?.taskCycle ?? status.taskCycle ?? 0),
servoCycle: Number(status.motionStatus?.cycle ?? status.task?.servoCycle ?? 0),
motionQueueDepth: Number(status.motionStatus?.queueDepth ?? motion.queueDepth ?? 0),
motionQueueDepth,
motionPaused: motion.paused === true,
motionStepping: motion.stepping === true,
motionId: Number(motion.motionId || 0),
idForStep: Number(motion.idForStep || 0),
halChangedPinCount: Array.isArray(status.halSnapshot?.changedPins)
? status.halSnapshot.changedPins.length
: Number(status.halSnapshot?.changedPinCount || 0),

View File

@@ -71,6 +71,14 @@ export function createLinuxCncTaskPolicyStatus(state) {
? Boolean(machineFileStaging.selectedGcodeSourceRel)
: Boolean(machineFileStaging.selectedGcodeSourceRel || state.activeProgram);
const interpIdle = interpState === "idle";
const motionPaused = state.machine?.motionPaused === true ||
state.taskHalStatus?.ui?.motionPaused === true ||
state.taskHalStatus?.motionStatus?.motion?.paused === true;
const taskPaused = state.machine?.taskPaused === true ||
state.taskHalStatus?.ui?.taskPaused === true ||
state.taskHalStatus?.task?.taskPaused === true;
const feedbackPaused = state.programRuntimeFeedback?.paused === true;
const paused = motionPaused || taskPaused || feedbackPaused || interpState === "paused" || state.runState === "paused";
const running = taskMode === "auto" &&
(state.runState === "running" || interpState === "reading" || interpState === "waiting");
const referenceOnly = state.profile?.tcpCapable === false || state.profile?.promotionAllowed === false;
@@ -81,6 +89,10 @@ export function createLinuxCncTaskPolicyStatus(state) {
taskMode,
interpState,
runState: state.runState || "idle",
motionPaused,
taskPaused,
feedbackPaused,
paused,
allHomed,
noForceHoming,
iniLoaded,
@@ -100,7 +112,7 @@ export function createLinuxCncTaskPolicyStatus(state) {
interpIdle && iniLoaded && machineFileStaged && machineFileOpened && taskHalRuntimeReady,
canExecuteMdi: taskState === "on" && taskMode === "mdi" && (allHomed || noForceHoming),
canPause: taskState === "on" && taskMode === "auto" && (interpState === "reading" || interpState === "waiting"),
canResume: taskState === "on" && (taskMode === "auto" || taskMode === "mdi") && interpState === "paused",
canResume: taskState === "on" && (taskMode === "auto" || taskMode === "mdi") && paused,
canAbort: true,
canSpindle: taskState === "on",
canCoolant: taskState === "on",
@@ -184,7 +196,7 @@ export function gateLinuxCncTaskAction(state, action) {
if (status.taskMode !== "auto" && status.taskMode !== "mdi" && status.runState !== "paused") {
return block(status, "resume blocked: task mode must be auto or MDI");
}
if (status.interpState !== "paused") return block(status, "resume blocked: interpreter is not paused");
if (!status.paused) return block(status, "resume blocked: program is not paused");
return allow(status);
case "STOP":
case "ABORT":

View File

@@ -171,6 +171,7 @@ const initialState = {
interpState: "idle",
interpResumeState: "idle",
taskPaused: false,
motionPaused: false,
manualPanel: "manual",
allHomed: false,
noForceHoming: false,
@@ -1762,6 +1763,7 @@ export function createSimulationStore(seed = {}) {
: state.machine.interpState || "reading",
interpState: "paused",
taskPaused: true,
motionPaused: true,
};
const pauseLock = createTaskHalPauseLock(state, "task-hal-plan-pause");
setState({
@@ -1794,6 +1796,7 @@ export function createSimulationStore(seed = {}) {
: state.machine.interpState,
interpState: "paused",
taskPaused: true,
motionPaused: true,
},
runState: "paused",
taskHalPauseLock: pauseLock,
@@ -1814,7 +1817,7 @@ export function createSimulationStore(seed = {}) {
setState({ operatorMessage: "pause blocked: task mode must be auto or MDI" });
break;
}
if (state.machine?.taskPaused === true || interpState === "paused" || state.runState === "paused") {
if (state.machine?.motionPaused === true || state.machine?.taskPaused === true || interpState === "paused" || state.runState === "paused") {
dispatch({ type: "RESUME", source: "pauseresume" });
break;
}
@@ -1843,6 +1846,7 @@ export function createSimulationStore(seed = {}) {
interpState: resumeState,
interpResumeState: resumeState,
taskPaused: false,
motionPaused: false,
};
setState({
machine: resumedMachine,
@@ -1875,6 +1879,7 @@ export function createSimulationStore(seed = {}) {
interpState: resumeState,
interpResumeState: resumeState,
taskPaused: false,
motionPaused: false,
},
runState: resumeState === "reading" ? "running" : "idle",
taskHalPauseLock: null,
@@ -1910,6 +1915,7 @@ export function createSimulationStore(seed = {}) {
: state.machine.interpState || "reading",
interpState: "paused",
taskPaused: true,
motionPaused: true,
};
setState({
machine: steppedMachine,
@@ -1953,6 +1959,7 @@ export function createSimulationStore(seed = {}) {
: state.machine.interpState,
interpState: "paused",
taskPaused: true,
motionPaused: true,
},
runState: "stepping",
taskHalPauseLock: null,
@@ -3791,7 +3798,17 @@ function applyTaskHalStatusPatch(state, status, operatorMessage, {
const allHomed = Boolean(preserveMachine?.allHomed ?? state.machine.allHomed);
const activeLine = state.programStartLine + Math.max(Number(ui.activeLine || 1) - 1, 0);
const kinsType = resolveTaskHalKinsType(state, status, activeLine);
const paused = Boolean(pauseLock) || interpState === "paused" || motion.paused === true;
const motionPaused = Boolean(pauseLock) ||
ui.motionPaused === true ||
motion.paused === true ||
preserveMachine?.motionPaused === true;
const taskPaused = ui.taskPaused === true || task.taskPaused === true || preserveMachine?.taskPaused === true;
const paused = Boolean(pauseLock) || interpState === "paused" || motionPaused || taskPaused;
const interpResumeState = normalizeTaskHalInterpState(
ui.interpResumeState ||
task.interpResumeState ||
(paused ? state.machine.interpResumeState || "reading" : interpState),
);
const axisPose = pauseLock?.axisPose
? clampAxisPoseToProfile(pauseLock.axisPose, state.profile)
: paused
@@ -3917,8 +3934,9 @@ function applyTaskHalStatusPatch(state, status, operatorMessage, {
mode: taskMode,
manualPanel,
interpState,
interpResumeState: paused ? state.machine.interpResumeState || "reading" : interpState,
interpResumeState,
taskPaused: paused,
motionPaused,
allHomed,
noForceHoming: Boolean(state.machine.noForceHoming),
},
@@ -3952,7 +3970,11 @@ function shouldContinueTaskHalStatusLoop(state = {}, status = {}) {
const interpState = normalizeTaskHalInterpState(ui.interpState || task.interpState);
const taskMode = normalizeLinuxCncTaskMode(ui.taskMode || task.mode || state.machine?.mode);
const aborted = motion.aborted === true;
const paused = interpState === "paused" || motion.paused === true;
const paused = interpState === "paused" ||
ui.motionPaused === true ||
ui.taskPaused === true ||
motion.paused === true ||
task.taskPaused === true;
const openedProgramLineCount = Number(task.openedSourceLineCount || task.openedLineCount || 1);
const complete = interpState === "idle"
&& Number(task.nextProgramLine || 0) >= openedProgramLineCount;
@@ -3962,7 +3984,8 @@ function shouldContinueTaskHalStatusLoop(state = {}, status = {}) {
function isTaskHalRunPausedByOperator(state = {}) {
return state.runState === "paused"
|| state.machine?.interpState === "paused"
|| state.machine?.taskPaused === true;
|| state.machine?.taskPaused === true
|| state.machine?.motionPaused === true;
}
function programControlModeForMachine(machine = {}) {
@@ -3980,6 +4003,7 @@ function createPowerToggleMachinePatch(machine = {}, turningOn = false) {
interpState: "idle",
interpResumeState: "idle",
taskPaused: false,
motionPaused: false,
};
}
@@ -4137,7 +4161,11 @@ function createTaskHalRuntimeFeedback(state, status, axisPose, activeLine) {
const halProgramLine = Number(status?.halSnapshot?.pins?.["motion.program-line"]?.value || 0);
const motionProgramLine = Number(motion.programLine || 0);
const interpState = normalizeTaskHalInterpState(ui.interpState || status?.task?.interpState);
const paused = interpState === "paused" || motion.paused === true;
const paused = interpState === "paused" ||
ui.motionPaused === true ||
ui.taskPaused === true ||
motion.paused === true ||
status?.task?.taskPaused === true;
const currentVelocity = paused ? 0 : Number(ui.currentVelocity || 0);
const requestedVelocity = paused ? 0 : Number(motion.requestedVel || 0) * 60;
return {
@@ -4152,6 +4180,7 @@ function createTaskHalRuntimeFeedback(state, status, axisPose, activeLine) {
activeLineSource: ui.activeLineSource || (motionProgramLine > 0 ? "motion-status" : halProgramLine > 0 ? "hal-pin" : "fallback"),
activeLineHalSynced: motionProgramLine > 0 && halProgramLine > 0 && motionProgramLine === halProgramLine,
type: Number(motion.motionType || 0) === 3 ? "JOG" : "TASK_MOTION",
paused,
timeSeconds: Number(ui.taskCycle || 0) * 0.01,
axisPose,
currentVelocityMmPerMin: currentVelocity,
@@ -4546,6 +4575,7 @@ function normalizeTaskHalInterpState(value) {
const state = String(value || "").toLowerCase();
if (state === "paused") return "paused";
if (state === "reading") return "reading";
if (state === "waiting") return "waiting";
return "idle";
}
@@ -4583,6 +4613,7 @@ function normalizeMachineForLinuxCncTask(machine = {}, runState = "idle") {
interpState,
interpResumeState: machine.interpResumeState || (interpState === "paused" ? "reading" : interpState),
taskPaused: Boolean(machine.taskPaused || interpState === "paused"),
motionPaused: Boolean(machine.motionPaused || machine.taskPaused || interpState === "paused"),
powerOn: taskState === "on",
estopActive: taskState === "estop",
allHomed: Boolean(machine.allHomed),

View File

@@ -616,7 +616,9 @@ function updateToolbarButton(element, buttonId, action, title, active = false, i
function isProgramPaused(state) {
return state.runState === "paused" ||
state.machine?.interpState === "paused" ||
state.machine?.taskPaused === true;
state.machine?.taskPaused === true ||
state.machine?.motionPaused === true ||
state.programRuntimeFeedback?.paused === true;
}
function pauseResumeToolbarTitle(state) {

View File

@@ -217,6 +217,13 @@ export function normalizeTaskHalStatus(status = {}) {
const halPins = status.halSnapshot?.pins || {};
const motionProgramLine = Number(motion.programLine || 0);
const halProgramLine = Number(halPins["motion.program-line"]?.value || 0);
const motionQueueDepth = Number(
status.motionStatus?.commandQueueDepth ??
motion.commandQueueDepth ??
status.motionStatus?.queueDepth ??
motion.queueDepth ??
0,
);
const activeLine = motionProgramLine > 0
? motionProgramLine
: halProgramLine > 0
@@ -242,10 +249,17 @@ export function normalizeTaskHalStatus(status = {}) {
taskState: String(status.task?.state || "ESTOP").toLowerCase(),
taskMode: String(status.task?.mode || "MANUAL").toLowerCase(),
interpState: String(status.task?.interpState || "IDLE").toLowerCase(),
interpResumeState: String(status.task?.interpResumeState || status.task?.interpState || "IDLE").toLowerCase(),
execState: String(status.task?.execState || "DONE").toLowerCase(),
taskPaused: status.task?.taskPaused === true,
singleStepping: status.task?.singleStepping === true,
taskCycle: Number(status.task?.taskCycle ?? status.taskCycle ?? 0),
servoCycle: Number(status.motionStatus?.cycle ?? status.task?.servoCycle ?? 0),
motionQueueDepth: Number(status.motionStatus?.queueDepth ?? motion.queueDepth ?? 0),
motionQueueDepth,
motionPaused: motion.paused === true,
motionStepping: motion.stepping === true,
motionId: Number(motion.motionId || 0),
idForStep: Number(motion.idForStep || 0),
halChangedPinCount: Array.isArray(status.halSnapshot?.changedPins)
? status.halSnapshot.changedPins.length
: Number(status.halSnapshot?.changedPinCount || 0),

View File

@@ -71,6 +71,14 @@ export function createLinuxCncTaskPolicyStatus(state) {
? Boolean(machineFileStaging.selectedGcodeSourceRel)
: Boolean(machineFileStaging.selectedGcodeSourceRel || state.activeProgram);
const interpIdle = interpState === "idle";
const motionPaused = state.machine?.motionPaused === true ||
state.taskHalStatus?.ui?.motionPaused === true ||
state.taskHalStatus?.motionStatus?.motion?.paused === true;
const taskPaused = state.machine?.taskPaused === true ||
state.taskHalStatus?.ui?.taskPaused === true ||
state.taskHalStatus?.task?.taskPaused === true;
const feedbackPaused = state.programRuntimeFeedback?.paused === true;
const paused = motionPaused || taskPaused || feedbackPaused || interpState === "paused" || state.runState === "paused";
const running = taskMode === "auto" &&
(state.runState === "running" || interpState === "reading" || interpState === "waiting");
const referenceOnly = state.profile?.tcpCapable === false || state.profile?.promotionAllowed === false;
@@ -81,6 +89,10 @@ export function createLinuxCncTaskPolicyStatus(state) {
taskMode,
interpState,
runState: state.runState || "idle",
motionPaused,
taskPaused,
feedbackPaused,
paused,
allHomed,
noForceHoming,
iniLoaded,
@@ -100,7 +112,7 @@ export function createLinuxCncTaskPolicyStatus(state) {
interpIdle && iniLoaded && machineFileStaged && machineFileOpened && taskHalRuntimeReady,
canExecuteMdi: taskState === "on" && taskMode === "mdi" && (allHomed || noForceHoming),
canPause: taskState === "on" && taskMode === "auto" && (interpState === "reading" || interpState === "waiting"),
canResume: taskState === "on" && (taskMode === "auto" || taskMode === "mdi") && interpState === "paused",
canResume: taskState === "on" && (taskMode === "auto" || taskMode === "mdi") && paused,
canAbort: true,
canSpindle: taskState === "on",
canCoolant: taskState === "on",
@@ -184,7 +196,7 @@ export function gateLinuxCncTaskAction(state, action) {
if (status.taskMode !== "auto" && status.taskMode !== "mdi" && status.runState !== "paused") {
return block(status, "resume blocked: task mode must be auto or MDI");
}
if (status.interpState !== "paused") return block(status, "resume blocked: interpreter is not paused");
if (!status.paused) return block(status, "resume blocked: program is not paused");
return allow(status);
case "STOP":
case "ABORT":

View File

@@ -171,6 +171,7 @@ const initialState = {
interpState: "idle",
interpResumeState: "idle",
taskPaused: false,
motionPaused: false,
manualPanel: "manual",
allHomed: false,
noForceHoming: false,
@@ -1762,6 +1763,7 @@ export function createSimulationStore(seed = {}) {
: state.machine.interpState || "reading",
interpState: "paused",
taskPaused: true,
motionPaused: true,
};
const pauseLock = createTaskHalPauseLock(state, "task-hal-plan-pause");
setState({
@@ -1794,6 +1796,7 @@ export function createSimulationStore(seed = {}) {
: state.machine.interpState,
interpState: "paused",
taskPaused: true,
motionPaused: true,
},
runState: "paused",
taskHalPauseLock: pauseLock,
@@ -1814,7 +1817,7 @@ export function createSimulationStore(seed = {}) {
setState({ operatorMessage: "pause blocked: task mode must be auto or MDI" });
break;
}
if (state.machine?.taskPaused === true || interpState === "paused" || state.runState === "paused") {
if (state.machine?.motionPaused === true || state.machine?.taskPaused === true || interpState === "paused" || state.runState === "paused") {
dispatch({ type: "RESUME", source: "pauseresume" });
break;
}
@@ -1843,6 +1846,7 @@ export function createSimulationStore(seed = {}) {
interpState: resumeState,
interpResumeState: resumeState,
taskPaused: false,
motionPaused: false,
};
setState({
machine: resumedMachine,
@@ -1875,6 +1879,7 @@ export function createSimulationStore(seed = {}) {
interpState: resumeState,
interpResumeState: resumeState,
taskPaused: false,
motionPaused: false,
},
runState: resumeState === "reading" ? "running" : "idle",
taskHalPauseLock: null,
@@ -1910,6 +1915,7 @@ export function createSimulationStore(seed = {}) {
: state.machine.interpState || "reading",
interpState: "paused",
taskPaused: true,
motionPaused: true,
};
setState({
machine: steppedMachine,
@@ -1953,6 +1959,7 @@ export function createSimulationStore(seed = {}) {
: state.machine.interpState,
interpState: "paused",
taskPaused: true,
motionPaused: true,
},
runState: "stepping",
taskHalPauseLock: null,
@@ -3791,7 +3798,17 @@ function applyTaskHalStatusPatch(state, status, operatorMessage, {
const allHomed = Boolean(preserveMachine?.allHomed ?? state.machine.allHomed);
const activeLine = state.programStartLine + Math.max(Number(ui.activeLine || 1) - 1, 0);
const kinsType = resolveTaskHalKinsType(state, status, activeLine);
const paused = Boolean(pauseLock) || interpState === "paused" || motion.paused === true;
const motionPaused = Boolean(pauseLock) ||
ui.motionPaused === true ||
motion.paused === true ||
preserveMachine?.motionPaused === true;
const taskPaused = ui.taskPaused === true || task.taskPaused === true || preserveMachine?.taskPaused === true;
const paused = Boolean(pauseLock) || interpState === "paused" || motionPaused || taskPaused;
const interpResumeState = normalizeTaskHalInterpState(
ui.interpResumeState ||
task.interpResumeState ||
(paused ? state.machine.interpResumeState || "reading" : interpState),
);
const axisPose = pauseLock?.axisPose
? clampAxisPoseToProfile(pauseLock.axisPose, state.profile)
: paused
@@ -3917,8 +3934,9 @@ function applyTaskHalStatusPatch(state, status, operatorMessage, {
mode: taskMode,
manualPanel,
interpState,
interpResumeState: paused ? state.machine.interpResumeState || "reading" : interpState,
interpResumeState,
taskPaused: paused,
motionPaused,
allHomed,
noForceHoming: Boolean(state.machine.noForceHoming),
},
@@ -3952,7 +3970,11 @@ function shouldContinueTaskHalStatusLoop(state = {}, status = {}) {
const interpState = normalizeTaskHalInterpState(ui.interpState || task.interpState);
const taskMode = normalizeLinuxCncTaskMode(ui.taskMode || task.mode || state.machine?.mode);
const aborted = motion.aborted === true;
const paused = interpState === "paused" || motion.paused === true;
const paused = interpState === "paused" ||
ui.motionPaused === true ||
ui.taskPaused === true ||
motion.paused === true ||
task.taskPaused === true;
const openedProgramLineCount = Number(task.openedSourceLineCount || task.openedLineCount || 1);
const complete = interpState === "idle"
&& Number(task.nextProgramLine || 0) >= openedProgramLineCount;
@@ -3962,7 +3984,8 @@ function shouldContinueTaskHalStatusLoop(state = {}, status = {}) {
function isTaskHalRunPausedByOperator(state = {}) {
return state.runState === "paused"
|| state.machine?.interpState === "paused"
|| state.machine?.taskPaused === true;
|| state.machine?.taskPaused === true
|| state.machine?.motionPaused === true;
}
function programControlModeForMachine(machine = {}) {
@@ -3980,6 +4003,7 @@ function createPowerToggleMachinePatch(machine = {}, turningOn = false) {
interpState: "idle",
interpResumeState: "idle",
taskPaused: false,
motionPaused: false,
};
}
@@ -4137,7 +4161,11 @@ function createTaskHalRuntimeFeedback(state, status, axisPose, activeLine) {
const halProgramLine = Number(status?.halSnapshot?.pins?.["motion.program-line"]?.value || 0);
const motionProgramLine = Number(motion.programLine || 0);
const interpState = normalizeTaskHalInterpState(ui.interpState || status?.task?.interpState);
const paused = interpState === "paused" || motion.paused === true;
const paused = interpState === "paused" ||
ui.motionPaused === true ||
ui.taskPaused === true ||
motion.paused === true ||
status?.task?.taskPaused === true;
const currentVelocity = paused ? 0 : Number(ui.currentVelocity || 0);
const requestedVelocity = paused ? 0 : Number(motion.requestedVel || 0) * 60;
return {
@@ -4152,6 +4180,7 @@ function createTaskHalRuntimeFeedback(state, status, axisPose, activeLine) {
activeLineSource: ui.activeLineSource || (motionProgramLine > 0 ? "motion-status" : halProgramLine > 0 ? "hal-pin" : "fallback"),
activeLineHalSynced: motionProgramLine > 0 && halProgramLine > 0 && motionProgramLine === halProgramLine,
type: Number(motion.motionType || 0) === 3 ? "JOG" : "TASK_MOTION",
paused,
timeSeconds: Number(ui.taskCycle || 0) * 0.01,
axisPose,
currentVelocityMmPerMin: currentVelocity,
@@ -4546,6 +4575,7 @@ function normalizeTaskHalInterpState(value) {
const state = String(value || "").toLowerCase();
if (state === "paused") return "paused";
if (state === "reading") return "reading";
if (state === "waiting") return "waiting";
return "idle";
}
@@ -4583,6 +4613,7 @@ function normalizeMachineForLinuxCncTask(machine = {}, runState = "idle") {
interpState,
interpResumeState: machine.interpResumeState || (interpState === "paused" ? "reading" : interpState),
taskPaused: Boolean(machine.taskPaused || interpState === "paused"),
motionPaused: Boolean(machine.motionPaused || machine.taskPaused || interpState === "paused"),
powerOn: taskState === "on",
estopActive: taskState === "estop",
allHomed: Boolean(machine.allHomed),

View File

@@ -616,7 +616,9 @@ function updateToolbarButton(element, buttonId, action, title, active = false, i
function isProgramPaused(state) {
return state.runState === "paused" ||
state.machine?.interpState === "paused" ||
state.machine?.taskPaused === true;
state.machine?.taskPaused === true ||
state.machine?.motionPaused === true ||
state.programRuntimeFeedback?.paused === true;
}
function pauseResumeToolbarTitle(state) {

View File

@@ -41,6 +41,8 @@ await verifyRunFeedbackLoop({
console.log("run_feedback_status_loop_smoke=ok");
console.log("run_ready_sequence_smoke=ok");
console.log("pause_uses_motion_paused_gate=ok");
console.log("pause_freezes_task_hal_status_loop=ok");
async function verifyRunFeedbackLoop({ profileId, sourceRel, stopAction }) {
const sdk = await createLinuxCncTaskHalSdk({
@@ -125,6 +127,35 @@ async function verifyRunFeedbackLoop({ profileId, sourceRel, stopAction }) {
assert.equal(state.taskHalStatus.summary.taskRuntimeReady, true);
assert.equal(state.taskHalStatus.summary.halSyncReady, true);
const activeLineBeforePause = state.activeLine;
const motionLineBeforePause = state.taskHalStatus.motionStatus.motion.programLine;
const motionAxisBeforePause = { ...state.taskHalStatus.motionStatus.axis };
store.dispatch({ type: "PAUSE_RESUME" });
await waitForTaskHalCommand(store);
state = store.getState();
assert.equal(state.runState, "paused");
assert.equal(state.machine.motionPaused, true);
assert.equal(state.machine.taskPaused, true);
assert.equal(state.taskHalStatus.ui.motionPaused, true);
assert.equal(state.taskHalStatus.motionStatus.motion.paused, true);
assert.equal(state.programRuntimeFeedback.paused, true);
assert.equal(state.activeLine, activeLineBeforePause);
assert.equal(state.taskHalStatus.motionStatus.motion.programLine, motionLineBeforePause);
assert.deepEqual(state.taskHalStatus.motionStatus.axis, motionAxisBeforePause);
await new Promise((resolve) => setTimeout(resolve, 120));
state = store.getState();
assert.equal(state.runState, "paused");
assert.equal(state.activeLine, activeLineBeforePause);
assert.equal(state.taskHalStatus.motionStatus.motion.programLine, motionLineBeforePause);
assert.deepEqual(state.taskHalStatus.motionStatus.axis, motionAxisBeforePause);
store.dispatch({ type: "PAUSE_RESUME" });
await waitForTaskHalCommand(store);
await waitForState(store, (nextState) => nextState.machine.motionPaused === false && nextState.runState !== "paused");
state = store.getState();
assert.equal(state.machine.motionPaused, false);
assert.equal(state.taskHalStatus.motionStatus.motion.paused, false);
const cycleAfterRun = state.taskHalStatus.ui.taskCycle;
store.dispatch({ type: "STEP" });
await waitForTaskHalCommand(store);
@@ -179,15 +210,25 @@ async function verifyRunReadySequence({ profileId, sourceRel }) {
store.dispatch({ type: "RUN_READY" });
await waitForTaskHalCommand(store);
await waitForState(store, (state) => state.machine.taskState === "on" && state.machine.mode === "auto");
await waitForState(store, (state) => state.taskHalSession?.programPath?.endsWith(sourceRel.split("/").at(-1)));
let state = store.getState();
assert.equal(state.machine.powerOn, false);
assert.equal(state.machine.taskState, "estop-reset");
assert.equal(state.machine.mode, "manual");
assert.equal(state.machine.allHomed, false);
assert.equal(state.taskHalSession?.programPath?.endsWith(sourceRel.split("/").at(-1)), true);
store.dispatch({ type: "TOGGLE_POWER" });
await waitForTaskHalCommand(store);
store.dispatch({ type: "HOME" });
store.dispatch({ type: "SET_MODE", mode: "auto" });
await waitForTaskHalCommand(store);
state = store.getState();
assert.equal(state.machine.powerOn, true);
assert.equal(state.machine.taskState, "on");
assert.equal(state.machine.mode, "auto");
assert.equal(state.machine.allHomed, true);
assert.equal(state.rtcpState, "on");
assert.equal(String(state.kinsType).startsWith("tcp-"), true);
store.dispatch({ type: "RUN" });
await waitForTaskHalCommand(store);

View File

@@ -245,6 +245,7 @@ function startFrameCapture(page) {
mode: summary.mode,
interpState: summary.interpState,
taskPaused: summary.taskPaused,
motionPaused: summary.motionPaused,
activeLine: summary.activeLine,
sampleIndex: summary.programExecutionSampleIndex,
sourceFile: summary.programUiExecution?.sourceFile || null,
@@ -402,6 +403,7 @@ async function readStateSummary(page) {
interpState: state.machine?.interpState,
interpResumeState: state.machine?.interpResumeState,
taskPaused: state.machine?.taskPaused,
motionPaused: state.machine?.motionPaused,
rtcpState: state.rtcpState,
kinsType: state.kinsType,
activeLine: state.activeLine,
@@ -476,6 +478,7 @@ function summarizeForEvent(state) {
mode: state?.machine?.mode || state?.mode,
interpState: state?.machine?.interpState || state?.interpState,
taskPaused: state?.machine?.taskPaused ?? state?.taskPaused,
motionPaused: state?.machine?.motionPaused ?? state?.motionPaused,
activeLine: state?.activeLine,
sampleIndex: state?.programExecutionSampleIndex,
programExecutionSourceMode: state?.programExecutionSourceMode,

Some files were not shown because too many files have changed in this diff Show More