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

@@ -79,6 +79,9 @@ export function buildVismachModelState(state = {}) {
}
function resolveAxisPose(state) {
if (state.runState === "paused" || state.machine?.interpState === "paused" || state.machine?.taskPaused === true) {
return state.axisPose || {};
}
if (state.programRuntimeFeedback?.axisPose) return state.programRuntimeFeedback.axisPose;
if (state.taskHalStatus?.ui?.axisPose) return state.taskHalStatus.ui.axisPose;
return state.axisPose || {};

View File

@@ -99,7 +99,7 @@ export function createLinuxCncTaskPolicyStatus(state) {
canRunAutoStrict: taskState === "on" && taskMode === "auto" && (allHomed || noForceHoming) &&
interpIdle && iniLoaded && machineFileStaged && machineFileOpened && taskHalRuntimeReady,
canExecuteMdi: taskState === "on" && taskMode === "mdi" && (allHomed || noForceHoming),
canPause: taskState === "on" && (taskMode === "auto" || taskMode === "mdi"),
canPause: taskState === "on" && taskMode === "auto" && (interpState === "reading" || interpState === "waiting"),
canResume: taskState === "on" && (taskMode === "auto" || taskMode === "mdi") && interpState === "paused",
canAbort: true,
canSpindle: taskState === "on",
@@ -116,9 +116,6 @@ export function gateLinuxCncTaskAction(state, action) {
switch (type) {
case "TOGGLE_POWER":
if (status.taskState === "estop") {
return block(status, "power on blocked: reset estop first");
}
return allow(status);
case "SET_MODE":
return gateMode(status, requestedMode);
@@ -164,10 +161,7 @@ export function gateLinuxCncTaskAction(state, action) {
case "PAUSE":
if (status.taskState !== "on") return block(status, "pause blocked: machine must be on");
{
const taskIsRunning = status.runState === "running" || status.runState === "stepping";
const interpIsRunning = status.interpState === "reading" || status.interpState === "waiting";
const interpCanPauseResume = status.interpState !== "idle" || taskIsRunning;
const pauseReady = action.source === "pauseresume" ? interpCanPauseResume : (interpIsRunning || taskIsRunning);
const requiredModeMessage = action.source === "pauseresume"
? "pause blocked: task mode must be auto or MDI"
: "pause blocked: task mode must be auto";
@@ -176,18 +170,18 @@ export function gateLinuxCncTaskAction(state, action) {
: "pause blocked: interpreter is not running";
if (action.source === "pauseresume") {
if (status.taskMode !== "auto" && status.taskMode !== "mdi") {
return block(status, requiredModeMessage);
}
if (status.taskMode !== "auto" && status.taskMode !== "mdi") return block(status, requiredModeMessage);
if (status.interpState === "idle") return block(status, notRunningMessage);
} else if (status.taskMode !== "auto") {
return block(status, requiredModeMessage);
}
if (!pauseReady) return block(status, notRunningMessage);
if (action.source !== "pauseresume" && status.taskMode !== "auto") return block(status, requiredModeMessage);
if (action.source !== "pauseresume" && !interpIsRunning) return block(status, notRunningMessage);
return allow(status);
}
case "RESUME":
if (status.taskState !== "on") return block(status, "resume blocked: machine must be on");
if (status.taskMode !== "auto" && status.taskMode !== "mdi") {
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");

View File

@@ -230,6 +230,7 @@ const initialState = {
taskHalExecutionPending: false,
taskHalExecutionSequence: 0,
taskHalStatusLoop: createTaskHalStatusLoopState(),
taskHalPauseLock: null,
taskHalFallbackReason: null,
pendingJogCommand: null,
interpreterExecutionPending: false,
@@ -1147,6 +1148,7 @@ export function createSimulationStore(seed = {}) {
setState({
taskHalFallbackReason: action.error,
taskHalExecutionPending: false,
taskHalPauseLock: null,
taskHalStatusLoop: {
...state.taskHalStatusLoop,
active: false,
@@ -1269,50 +1271,34 @@ export function createSimulationStore(seed = {}) {
setState({ operatorMessage: gate.operatorMessage });
break;
}
const turningOff = state.machine.taskState === "on" || state.machine.powerOn;
const turningOn = state.machine.taskState === "estop-reset";
if (state.taskHalRuntime?.loaded) {
const nextMachine = createPowerToggleMachinePatch(state.machine, turningOn);
setState({
machine: {
...state.machine,
powerOn: !turningOff,
estopActive: false,
taskState: turningOff ? "estop-reset" : "on",
manualPanel: "manual",
interpState: "idle",
interpResumeState: "idle",
taskPaused: false,
},
runState: turningOff ? "powered-off" : "idle",
kinsType: turningOff ? "identity" : state.kinsType,
rtcpState: turningOff ? "off" : state.rtcpState,
feed: turningOff ? { ...state.feed, currentVelocity: 0 } : state.feed,
coolant: turningOff ? { ...state.coolant, flood: false, mist: false } : state.coolant,
spindle: turningOff ? stoppedSpindleState(state.spindle) : state.spindle,
operatorMessage: turningOff ? "task/HAL machine power off" : "task/HAL machine power on",
machine: nextMachine,
runState: turningOn ? "idle" : "powered-off",
kinsType: turningOn ? state.kinsType : "identity",
rtcpState: turningOn ? state.rtcpState : "off",
feed: turningOn ? state.feed : { ...state.feed, currentVelocity: 0 },
coolant: turningOn ? state.coolant : { ...state.coolant, flood: false, mist: false },
spindle: turningOn ? state.spindle : stoppedSpindleState(state.spindle),
operatorMessage: turningOn ? "task/HAL machine power on" : "task/HAL machine power off",
});
runTaskHalCommandSequence([
{ type: "EMC_TASK_SET_STATE", state: turningOff ? "ESTOP_RESET" : "ON" },
], { operatorMessage: turningOff ? "task/HAL machine power off" : "task/HAL machine power on" }).catch(() => {});
{ type: "EMC_TASK_SET_STATE", state: turningOn ? "ON" : "OFF" },
], { operatorMessage: turningOn ? "task/HAL machine power on" : "task/HAL machine power off" }).catch(() => {});
break;
}
const nextMachine = createPowerToggleMachinePatch(state.machine, turningOn);
setState({
machine: {
...state.machine,
powerOn: !turningOff,
estopActive: false,
taskState: turningOff ? "estop-reset" : "on",
manualPanel: "manual",
interpState: "idle",
interpResumeState: "idle",
taskPaused: false,
},
runState: turningOff ? "powered-off" : "idle",
kinsType: turningOff ? "identity" : state.kinsType,
rtcpState: turningOff ? "off" : state.rtcpState,
feed: turningOff ? { ...state.feed, currentVelocity: 0 } : state.feed,
coolant: turningOff ? { ...state.coolant, flood: false, mist: false } : state.coolant,
spindle: turningOff ? stoppedSpindleState(state.spindle) : state.spindle,
operatorMessage: turningOff ? "machine power off" : "machine power on",
machine: nextMachine,
runState: turningOn ? "idle" : "powered-off",
kinsType: turningOn ? state.kinsType : "identity",
rtcpState: turningOn ? state.rtcpState : "off",
feed: turningOn ? state.feed : { ...state.feed, currentVelocity: 0 },
coolant: turningOn ? state.coolant : { ...state.coolant, flood: false, mist: false },
spindle: turningOn ? state.spindle : stoppedSpindleState(state.spindle),
operatorMessage: turningOn ? "machine power on" : "machine power off",
});
}
break;
@@ -1633,6 +1619,7 @@ export function createSimulationStore(seed = {}) {
taskPaused: false,
},
runState: "running",
taskHalPauseLock: null,
operatorMessage: "task/HAL program run requested",
});
runValidatedTaskHalProgramRun().catch(() => {});
@@ -1658,6 +1645,7 @@ export function createSimulationStore(seed = {}) {
taskPaused: false,
},
runState: playback.complete ? "complete" : "running",
taskHalPauseLock: null,
...playbackPatch,
programLineExecution: createProgramLineExecutionPatch(state.programLineExecution, playback.runtimeFeedback, {
status: playback.complete ? "done" : "running",
@@ -1718,6 +1706,7 @@ export function createSimulationStore(seed = {}) {
taskPaused: false,
},
runState: "stopped",
taskHalPauseLock: null,
feed: {
...state.feed,
currentVelocity: 0,
@@ -1766,19 +1755,24 @@ export function createSimulationStore(seed = {}) {
stopTaskHalStatusLoop("paused", { operatorMessage: "task/HAL pause requested" });
const pausedMachine = {
...state.machine,
mode: programControlModeForMachine(state.machine),
manualPanel: null,
interpResumeState: state.machine.interpState === "paused"
? state.machine.interpResumeState
: state.machine.interpState || "reading",
interpState: "paused",
taskPaused: true,
};
const pauseLock = createTaskHalPauseLock(state, "task-hal-plan-pause");
setState({
machine: pausedMachine,
runState: "paused",
taskHalPauseLock: pauseLock,
feed: {
...state.feed,
currentVelocity: 0,
},
programRuntimeFeedback: zeroProgramRuntimeVelocity(state.programRuntimeFeedback),
operatorMessage: "task/HAL pause requested",
});
runTaskHalCommandSequence([
@@ -1789,9 +1783,12 @@ export function createSimulationStore(seed = {}) {
}).catch(() => {});
break;
}
const pauseLock = createTaskHalPauseLock(state, "fixture-plan-pause");
setState({
machine: {
...state.machine,
mode: programControlModeForMachine(state.machine),
manualPanel: null,
interpResumeState: state.machine.interpState === "paused"
? state.machine.interpResumeState
: state.machine.interpState,
@@ -1799,6 +1796,12 @@ export function createSimulationStore(seed = {}) {
taskPaused: true,
},
runState: "paused",
taskHalPauseLock: pauseLock,
feed: {
...state.feed,
currentVelocity: 0,
},
programRuntimeFeedback: zeroProgramRuntimeVelocity(state.programRuntimeFeedback),
operatorMessage: "program paused",
});
}
@@ -1806,17 +1809,16 @@ export function createSimulationStore(seed = {}) {
case "PAUSE_RESUME":
{
const interpState = state.machine?.interpState || state.linuxCncTaskPolicy?.interpState || "idle";
const taskMode = state.machine?.mode || state.linuxCncTaskPolicy?.taskMode || "manual";
const taskIsRunning = state.runState === "running" || state.runState === "stepping";
if (state.machine?.taskPaused === true || interpState === "paused" || state.runState === "paused") {
if (taskMode === "auto" || taskMode === "mdi") {
dispatch({ type: "RESUME" });
break;
}
setState({ operatorMessage: "resume blocked: task mode must be auto or MDI" });
const taskMode = normalizeLinuxCncTaskMode(state.machine?.mode);
if (taskMode !== "auto" && taskMode !== "mdi") {
setState({ operatorMessage: "pause blocked: task mode must be auto or MDI" });
break;
}
if ((taskMode === "auto" || taskMode === "mdi") && (interpState !== "idle" || taskIsRunning)) {
if (state.machine?.taskPaused === true || interpState === "paused" || state.runState === "paused") {
dispatch({ type: "RESUME", source: "pauseresume" });
break;
}
if (interpState !== "idle") {
dispatch({ type: "PAUSE", source: "pauseresume" });
break;
}
@@ -1836,6 +1838,8 @@ export function createSimulationStore(seed = {}) {
: state.machine.interpResumeState || "reading";
const resumedMachine = {
...state.machine,
mode: programControlModeForMachine(state.machine),
manualPanel: null,
interpState: resumeState,
interpResumeState: resumeState,
taskPaused: false,
@@ -1843,6 +1847,7 @@ export function createSimulationStore(seed = {}) {
setState({
machine: resumedMachine,
runState: resumeState === "reading" ? "running" : "idle",
taskHalPauseLock: null,
operatorMessage: "task/HAL resume requested",
});
runTaskHalCommandSequence([
@@ -1865,11 +1870,14 @@ export function createSimulationStore(seed = {}) {
setState({
machine: {
...state.machine,
mode: programControlModeForMachine(state.machine),
manualPanel: null,
interpState: resumeState,
interpResumeState: resumeState,
taskPaused: false,
},
runState: resumeState === "reading" ? "running" : "idle",
taskHalPauseLock: null,
operatorMessage: "program resumed",
});
}
@@ -1906,6 +1914,7 @@ export function createSimulationStore(seed = {}) {
setState({
machine: steppedMachine,
runState: "stepping",
taskHalPauseLock: null,
...playbackPatch,
programElapsedSeconds: playback.timing.elapsedSeconds,
programRemainingSeconds: playback.timing.remainingSeconds,
@@ -1946,6 +1955,7 @@ export function createSimulationStore(seed = {}) {
taskPaused: true,
},
runState: "stepping",
taskHalPauseLock: null,
...playbackPatch,
programElapsedSeconds: playback.timing.elapsedSeconds,
programRemainingSeconds: playback.timing.remainingSeconds,
@@ -2602,49 +2612,17 @@ export function createSimulationStore(seed = {}) {
}
if (state.taskHalRuntime?.loaded) {
await initializeTaskHalSession({ openProgram: true });
await runTaskHalCommandSequence([
{ type: "EMC_TASK_SET_STATE", state: "ON" },
{ type: "EMC_JOINT_HOME", joint: -1 },
{ type: "EMC_TASK_SET_MODE", mode: "AUTO" },
], {
taskCycles: 3,
operatorMessage: "RUN ready: power on, homed, auto mode",
allowFixtureSession: false,
preserveMachine: {
powerOn: true,
estopActive: false,
taskState: "on",
mode: "auto",
manualPanel: null,
allHomed: true,
},
setState({
operatorMessage: state.machine.powerOn && state.machine.allHomed
? "RUN ready: program opened; press Run"
: "RUN setup ready: reset ESTOP, power on, Home All, then Run",
});
const tcpKinsType = tcpKinsTypeForProfile(state.profile);
if (tcpKinsType) {
dispatch({ type: "SET_KINS_TYPE", kinsType: tcpKinsType });
}
return state;
}
const tcpKinsType = tcpKinsTypeForProfile(state.profile);
setState({
machine: {
...state.machine,
powerOn: true,
estopActive: false,
taskState: "on",
mode: "auto",
manualPanel: null,
allHomed: true,
interpState: "idle",
interpResumeState: "idle",
taskPaused: false,
},
runState: "idle",
kinsType: tcpKinsType || "identity",
rtcpState: tcpKinsType ? "on" : "off",
operatorMessage: tcpKinsType
? "RUN ready: power on, homed, auto mode"
: "RUN ready: power on, homed, auto mode; TCP unavailable for this reference profile",
operatorMessage: state.machine.powerOn && state.machine.allHomed
? "RUN ready: program opened; press Run"
: "RUN setup ready: reset ESTOP, power on, Home All, then Run",
});
return state;
};
@@ -2657,6 +2635,19 @@ export function createSimulationStore(seed = {}) {
await waitForStatePredicate((nextState) => nextState.machineFileStaging?.selectedGcodeSourceRel === sourceRel);
}
}
const runGateState = {
...state,
machine: {
...state.machine,
mode: "auto",
manualPanel: null,
},
};
const runGate = gateLinuxCncTaskAction(runGateState, { type: "RUN" });
if (!runGate.allowed) {
setState({ operatorMessage: runGate.operatorMessage });
return state;
}
const tcpKinsType = tcpKinsTypeForProfile(state.profile);
if (state.taskHalRuntime?.loaded) {
if (
@@ -2679,17 +2670,14 @@ export function createSimulationStore(seed = {}) {
setState({
machine: {
...state.machine,
powerOn: true,
estopActive: false,
taskState: "on",
mode: "auto",
manualPanel: null,
allHomed: true,
interpState: "reading",
interpResumeState: "reading",
taskPaused: false,
},
runState: "running",
taskHalPauseLock: null,
operatorMessage: "RUN ready: motion plan source ready; preparing task/HAL session",
});
const expectedProgramPath = expectedTaskHalProgramPathForState(state);
@@ -2733,7 +2721,6 @@ export function createSimulationStore(seed = {}) {
});
const status = await runTaskHalCommandSequence([
{ type: "EMC_TASK_SET_STATE", state: "ON" },
{ type: "EMC_JOINT_HOME", joint: -1 },
{ type: "EMC_TASK_SET_MODE", mode: "AUTO" },
{ type: "EMC_TASK_PLAN_RUN", line: 0 },
], {
@@ -2755,8 +2742,15 @@ export function createSimulationStore(seed = {}) {
return state;
}
const policy = createLinuxCncTaskPolicyStatus(state);
if (policy.taskMode !== "auto" || !policy.allHomed || policy.taskState !== "on") {
await runReadySequence();
if (policy.taskMode !== "auto") {
setState({
machine: {
...state.machine,
mode: "auto",
manualPanel: null,
},
operatorMessage: "mode auto",
});
}
dispatch({ type: "RUN" });
return state;
@@ -3778,27 +3772,38 @@ function applyTaskHalStatusPatch(state, status, operatorMessage, {
const ui = status?.ui || {};
const task = status?.task || {};
const motion = status?.motionStatus?.motion || {};
const pauseLock = state.taskHalPauseLock?.active === true ? state.taskHalPauseLock : null;
const rawTaskState = normalizeTaskHalTaskState(ui.taskState || task.state);
const taskState = preserveMachine?.powerOn && rawTaskState === "estop-reset"
? "on"
: rawTaskState;
const taskMode = normalizeLinuxCncTaskMode(preserveMachine?.mode || ui.taskMode || task.mode || state.machine.mode);
const taskMode = pauseLock
? programControlModeForMachine(state.machine)
: normalizeLinuxCncTaskMode(preserveMachine?.mode || ui.taskMode || task.mode || state.machine.mode);
const manualPanel = taskMode === "manual"
? (preserveMachine?.manualPanel || state.machine.manualPanel || "manual")
: null;
const interpState = Object.hasOwn(preserveMachine || {}, "interpState")
? normalizeTaskHalInterpState(preserveMachine.interpState)
: normalizeTaskHalInterpState(ui.interpState || task.interpState);
const interpState = pauseLock
? "paused"
: Object.hasOwn(preserveMachine || {}, "interpState")
? normalizeTaskHalInterpState(preserveMachine.interpState)
: normalizeTaskHalInterpState(ui.interpState || task.interpState);
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 axisPose = preserveAxisPose
? clampAxisPoseToProfile({ ...state.axisPose, ...preserveAxisPose }, state.profile)
: resolveTaskHalAxisPose(state, status);
const currentVelocity = Number.isFinite(ui.currentVelocity)
? Math.max(ui.currentVelocity, 0)
: state.feed.currentVelocity;
const paused = interpState === "paused" || motion.paused === true;
const paused = Boolean(pauseLock) || interpState === "paused" || motion.paused === true;
const axisPose = pauseLock?.axisPose
? clampAxisPoseToProfile(pauseLock.axisPose, state.profile)
: paused
? clampAxisPoseToProfile(state.axisPose, state.profile)
: preserveAxisPose
? clampAxisPoseToProfile({ ...state.axisPose, ...preserveAxisPose }, state.profile)
: resolveTaskHalAxisPose(state, status);
const currentVelocity = paused
? 0
: Number.isFinite(ui.currentVelocity)
? Math.max(ui.currentVelocity, 0)
: state.feed.currentVelocity;
const aborted = motion.aborted === true;
const openedProgramLineCount = Number(task.openedSourceLineCount || task.openedLineCount || 1);
const programComplete = interpState === "idle" && Number(task.nextProgramLine || 0) >= openedProgramLineCount;
@@ -3819,7 +3824,13 @@ function applyTaskHalStatusPatch(state, status, operatorMessage, {
const shouldTrackProgramPlayback = runState === "running"
|| runState === "mdi"
|| (runState === "complete" && (state.runState === "running" || state.runState === "mdi" || state.runState === "complete"));
const taskHalSampleIndex = shouldTrackProgramPlayback
const taskHalSampleIndex = pauseLock
? clampNumber(
pauseLock.sampleIndex,
0,
Math.max(Number(state.programAxisPreviewPath?.samples?.length || state.programAxisPreviewPath?.sampleCount || 1) - 1, 0),
)
: shouldTrackProgramPlayback
? resolveRuntimeSampleIndexForTaskHalPose(state, axisPose, activeLine, runtimeFeedback.sampleIndex)
: clampNumber(
state.programExecutionSampleIndex || 0,
@@ -3829,7 +3840,17 @@ function applyTaskHalStatusPatch(state, status, operatorMessage, {
const idleRuntimeFeedback = {
...runtimeFeedback,
sampleIndex: taskHalSampleIndex,
motionIndex: Number(state.programExecutionMotionIndex || runtimeFeedback.motionIndex || 0),
motionIndex: pauseLock
? Number(pauseLock.motionIndex || 0)
: Number(state.programExecutionMotionIndex || runtimeFeedback.motionIndex || 0),
...(paused ? {
axisPose,
tcp: {
x: Number(state.tcpPose?.x ?? axisPose.x ?? 0),
y: Number(state.tcpPose?.y ?? axisPose.y ?? 0),
z: Number(state.tcpPose?.z ?? axisPose.z ?? 0),
},
} : {}),
};
const taskHalPlaybackPatch = shouldTrackProgramPlayback
? applyProgramPlaybackUiPatch(state, {
@@ -3837,11 +3858,15 @@ function applyTaskHalStatusPatch(state, status, operatorMessage, {
axisPose,
kinsType,
rtcpState: rtcpStateFromKinsType(kinsType),
motionIndex: runtimeFeedback.motionIndex,
motionIndex: pauseLock ? Number(pauseLock.motionIndex || 0) : runtimeFeedback.motionIndex,
sampleIndex: taskHalSampleIndex,
runtimeFeedback: {
...runtimeFeedback,
sampleIndex: taskHalSampleIndex,
motionIndex: pauseLock ? Number(pauseLock.motionIndex || 0) : runtimeFeedback.motionIndex,
axisPose,
currentVelocityMmPerMin: paused ? 0 : runtimeFeedback.currentVelocityMmPerMin,
requestedVelocityMmPerMin: paused ? 0 : runtimeFeedback.requestedVelocityMmPerMin,
},
preferRuntimeAxisPose: true,
})
@@ -3879,6 +3904,7 @@ function applyTaskHalStatusPatch(state, status, operatorMessage, {
return {
taskHalStatus: status,
taskHalExecutionPending: false,
taskHalPauseLock: pauseLock ? { ...pauseLock, lastStatusAt: new Date().toISOString() } : state.taskHalPauseLock,
taskHalFallbackReason: null,
pendingJogCommand: null,
...taskHalPlaybackPatch,
@@ -3939,6 +3965,57 @@ function isTaskHalRunPausedByOperator(state = {}) {
|| state.machine?.taskPaused === true;
}
function programControlModeForMachine(machine = {}) {
return machine.mode === "mdi" ? "mdi" : "auto";
}
function createPowerToggleMachinePatch(machine = {}, turningOn = false) {
return {
...machine,
powerOn: turningOn,
estopActive: false,
taskState: turningOn ? "on" : "off",
manualPanel: "manual",
allHomed: turningOn ? Boolean(machine.allHomed) : false,
interpState: "idle",
interpResumeState: "idle",
taskPaused: false,
};
}
function createTaskHalPauseLock(state = {}, source = "pause") {
return {
apiName: "web-rtcp-5axis-task-hal-pause-lock",
active: true,
source,
createdAt: new Date().toISOString(),
runState: "paused",
interpState: "paused",
sampleIndex: Number(state.programExecutionSampleIndex || 0),
motionIndex: Number(state.programExecutionMotionIndex || 0),
activeLine: Number(state.activeLine || state.programStartLine || 1),
axisPose: clampAxisPoseToProfile(state.axisPose || initialAxisPose, state.profile),
tcpPose: {
x: Number(state.tcpPose?.x || 0),
y: Number(state.tcpPose?.y || 0),
z: Number(state.tcpPose?.z || 0),
},
semanticBoundary: "linuxcnc_axis_task_pauseresume_freezes_task_hal_status_until_resume",
};
}
function zeroProgramRuntimeVelocity(feedback) {
if (!feedback) return feedback;
return {
...feedback,
currentVelocityMmPerMin: 0,
requestedVelocityMmPerMin: 0,
distanceToGo: 0,
dtg: feedback.dtg ? { ...feedback.dtg, x: 0, y: 0, z: 0 } : feedback.dtg,
activeDepth: 0,
};
}
function createStoppedProgramStatePatch(state, {
reason = "stopped",
operatorMessage = "program stopped",
@@ -3951,6 +4028,7 @@ function createStoppedProgramStatePatch(state, {
taskPaused: false,
},
runState: reason === "aborted" ? "stopped" : reason,
taskHalPauseLock: null,
taskHalStatusLoop: {
...state.taskHalStatusLoop,
active: false,
@@ -4058,6 +4136,10 @@ function createTaskHalRuntimeFeedback(state, status, axisPose, activeLine) {
const motion = status?.motionStatus?.motion || {};
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 currentVelocity = paused ? 0 : Number(ui.currentVelocity || 0);
const requestedVelocity = paused ? 0 : Number(motion.requestedVel || 0) * 60;
return {
apiName: "web-rtcp-5axis-program-runtime-feedback",
sourceMode: "linuxcnc-task-motion-hal-wasm",
@@ -4072,8 +4154,8 @@ function createTaskHalRuntimeFeedback(state, status, axisPose, activeLine) {
type: Number(motion.motionType || 0) === 3 ? "JOG" : "TASK_MOTION",
timeSeconds: Number(ui.taskCycle || 0) * 0.01,
axisPose,
currentVelocityMmPerMin: Number(ui.currentVelocity || 0),
requestedVelocityMmPerMin: Number(motion.requestedVel || 0) * 60,
currentVelocityMmPerMin: currentVelocity,
requestedVelocityMmPerMin: requestedVelocity,
distanceToGo: motion.inPosition === true ? 0 : 1,
dtg: { x: 0, y: 0, z: 0 },
queueDepth: Number(ui.motionQueueDepth || status?.motionStatus?.commandQueueDepth || 0),

View File

@@ -10,7 +10,7 @@ export const AXIS_BUTTON_PARITY = [
{ id: "menu-estop", action: "estop", sourceSymbol: "commands.estop_clicked", sourceLines: "axis.py:2223-2229", expected: "toggle ESTOP/ESTOP_RESET" },
{ id: "menu-power", action: "power", sourceSymbol: "commands.onoff_clicked", sourceLines: "axis.py:2231-2241", expected: "toggle machine ON/OFF after estop reset" },
{ id: "menu-home-all", action: "home-all", sourceSymbol: "commands.home_all_joints", sourceLines: "axis.py:2586-2596", expected: "home all joints in manual mode" },
{ id: "menu-run-ready", action: "run-ready", sourceSymbol: "AXIS run preconditions", sourceLines: "axis.py:2308-2320", expected: "power on, home, auto mode and TCP kins ready" },
{ id: "menu-run-ready", action: "run-ready", sourceSymbol: "AXIS run preconditions", sourceLines: "axis.py:2379-2391", expected: "open/stage the selected program without substituting power, Home All, or Run" },
{ id: "menu-run", action: "run", sourceSymbol: "commands.task_run", sourceLines: "axis.py:2308-2320", expected: "AUTO_RUN from current start line" },
{ id: "menu-pause", action: "pause", sourceSymbol: "commands.task_pause", sourceLines: "axis.py:2329-2333", expected: "AUTO_PAUSE when running" },
{ id: "menu-resume", action: "resume", sourceSymbol: "commands.task_resume", sourceLines: "axis.py:2344-2351", expected: "AUTO_RESUME when paused" },