完善 gmoccapy XYZAB 参考功能
This commit is contained in:
@@ -56,24 +56,55 @@ export function createLinuxCncTaskPolicyStatus(state) {
|
||||
const interpState = normalizeLinuxCncInterpState(state.machine, state.runState);
|
||||
const allHomed = Boolean(state.machine.allHomed);
|
||||
const noForceHoming = Boolean(state.machine.noForceHoming);
|
||||
const machineFileStaging = state.machineFileStaging || {};
|
||||
const profileId = state.profile?.id || state.machineProfile || null;
|
||||
const taskHalReadiness = state.taskHalRuntimeReadiness || {};
|
||||
const taskHalRuntimeReady = Boolean(
|
||||
state.taskHalRuntime?.loaded &&
|
||||
taskHalReadiness.taskRuntimeReady === true &&
|
||||
taskHalReadiness.motionRuntimeReady === true &&
|
||||
taskHalReadiness.halRuntimeReady === true,
|
||||
);
|
||||
const iniLoaded = state.iniConfigReadiness?.loaded === true && state.iniConfigReadiness?.ready === true;
|
||||
const machineFileStaged = machineFileStaging.status === "staged" && Boolean(machineFileStaging.save?.files?.length);
|
||||
const machineFileOpened = profileId === "gmoccapy-xyzab"
|
||||
? Boolean(machineFileStaging.selectedGcodeSourceRel)
|
||||
: Boolean(machineFileStaging.selectedGcodeSourceRel || state.activeProgram);
|
||||
const interpIdle = interpState === "idle";
|
||||
const running = taskMode === "auto" &&
|
||||
(state.runState === "running" || interpState === "reading" || interpState === "waiting");
|
||||
const referenceOnly = state.profile?.tcpCapable === false || state.profile?.promotionAllowed === false;
|
||||
|
||||
return {
|
||||
...LINUXCNC_TASK_POLICY,
|
||||
taskState,
|
||||
taskMode,
|
||||
interpState,
|
||||
runState: state.runState || "idle",
|
||||
allHomed,
|
||||
noForceHoming,
|
||||
iniLoaded,
|
||||
machineFileStaged,
|
||||
machineFileOpened,
|
||||
taskHalRuntimeReady,
|
||||
interpIdle,
|
||||
referenceOnly,
|
||||
profileId,
|
||||
powerOn: taskState === "on",
|
||||
estopActive: taskState === "estop",
|
||||
canMove: taskState === "on",
|
||||
canJog: taskState === "on" && taskMode === "manual",
|
||||
canHome: taskState === "on" && taskMode === "manual",
|
||||
canJog: taskState === "on" && taskMode === "manual" && !running,
|
||||
canHome: taskState === "on" && taskMode === "manual" && !running,
|
||||
canRunAuto: taskState === "on" && taskMode === "auto" && (allHomed || noForceHoming),
|
||||
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"),
|
||||
canResume: taskState === "on" && (taskMode === "auto" || taskMode === "mdi") && interpState === "paused",
|
||||
canAbort: true,
|
||||
canSpindle: taskState === "on",
|
||||
canCoolant: taskState === "on",
|
||||
canOverride: taskState === "on",
|
||||
canLeaveAuto: taskMode !== "auto" || interpState === "idle",
|
||||
};
|
||||
}
|
||||
@@ -94,15 +125,26 @@ export function gateLinuxCncTaskAction(state, action) {
|
||||
case "JOG":
|
||||
if (status.taskState !== "on") return block(status, "jog blocked: machine must be on");
|
||||
if (status.taskMode !== "manual") return block(status, "jog blocked: switch to manual mode first");
|
||||
if (status.taskMode === "auto" &&
|
||||
(status.runState === "running" || status.interpState === "reading" || status.interpState === "waiting")) {
|
||||
return block(status, "jog blocked: interpreter must be idle");
|
||||
}
|
||||
return allow(status);
|
||||
case "HOME":
|
||||
if (status.taskState !== "on") return block(status, "home blocked: machine must be on");
|
||||
if (status.taskMode !== "manual") return block(status, "home blocked: switch to manual mode first");
|
||||
if (status.taskMode === "auto" &&
|
||||
(status.runState === "running" || status.interpState === "reading" || status.interpState === "waiting")) {
|
||||
return block(status, "home blocked: interpreter must be idle");
|
||||
}
|
||||
return allow(status);
|
||||
case "RUN_MDI":
|
||||
if (status.taskState !== "on") return block(status, "MDI blocked: machine must be on");
|
||||
if (status.taskMode !== "mdi") return block(status, "MDI blocked: switch to MDI mode first");
|
||||
if (!status.allHomed && !status.noForceHoming) return block(status, "MDI blocked: home machine first");
|
||||
if (status.interpState === "reading" || status.interpState === "waiting") {
|
||||
return block(status, "MDI blocked: interpreter must be idle");
|
||||
}
|
||||
return allow(status);
|
||||
case "RUN":
|
||||
case "STEP":
|
||||
@@ -111,6 +153,10 @@ export function gateLinuxCncTaskAction(state, action) {
|
||||
if (status.taskMode !== "auto") return block(status, `${type.toLowerCase()} blocked: switch to auto mode first`);
|
||||
if (!status.allHomed && !status.noForceHoming) return block(status, `${type.toLowerCase()} blocked: home machine first`);
|
||||
if (type === "RUN" && status.interpState === "paused") return block(status, "run blocked: resume paused program first");
|
||||
if (type === "RUN" && status.profileId === "gmoccapy-xyzab") {
|
||||
const strictGate = gateGmoccapyXyzabRun(status);
|
||||
if (!strictGate.allowed) return strictGate;
|
||||
}
|
||||
return allow(status);
|
||||
case "PAUSE":
|
||||
if (status.taskState !== "on") return block(status, "pause blocked: machine must be on");
|
||||
@@ -128,11 +174,42 @@ export function gateLinuxCncTaskAction(state, action) {
|
||||
case "STOP":
|
||||
case "ABORT":
|
||||
return allow(status);
|
||||
case "SET_SPINDLE_DIRECTION":
|
||||
case "SPINDLE":
|
||||
return gateSpindle(status, typeof action === "object" ? action.direction : undefined);
|
||||
case "TOGGLE_COOLANT":
|
||||
case "COOLANT":
|
||||
if (status.taskState !== "on") return block(status, "coolant blocked: machine must be on");
|
||||
return allow(status);
|
||||
case "ADJUST_OVERRIDE":
|
||||
case "ADJUST_SPINDLE_OVERRIDE":
|
||||
case "OVERRIDE":
|
||||
if (status.taskState !== "on") return block(status, "override blocked: machine must be on");
|
||||
return allow(status);
|
||||
default:
|
||||
return allow(status);
|
||||
}
|
||||
}
|
||||
|
||||
function gateGmoccapyXyzabRun(status) {
|
||||
if (!status.iniLoaded) return block(status, "run blocked: LinuxCNC INI not loaded");
|
||||
if (!status.machineFileStaged) return block(status, "run blocked: LinuxCNC machine files not staged");
|
||||
if (!status.machineFileOpened) return block(status, "run blocked: no machine-file G-code opened for task/HAL session");
|
||||
if (!status.interpIdle) return block(status, "run blocked: interpreter must be idle");
|
||||
if (!status.taskHalRuntimeReady) return block(status, "run blocked: task/HAL runtime not ready");
|
||||
return allow(status);
|
||||
}
|
||||
|
||||
function gateSpindle(status, direction = "stop") {
|
||||
if (status.taskState !== "on") return block(status, "spindle blocked: machine must be on");
|
||||
const requested = String(direction || "stop").toLowerCase();
|
||||
if ((requested === "forward" || requested === "reverse") &&
|
||||
(status.interpState === "reading" || status.interpState === "waiting")) {
|
||||
return block(status, "spindle blocked: interpreter is running");
|
||||
}
|
||||
return allow(status);
|
||||
}
|
||||
|
||||
function gateMode(status, requestedMode) {
|
||||
const targetMode = normalizeLinuxCncTaskMode(requestedMode);
|
||||
if (!LINUXCNC_TASK_MODES.has(targetMode)) {
|
||||
|
||||
Reference in New Issue
Block a user