Complete XYZAC LinuxCNC WASM parity and smooth 3D preview
This commit is contained in:
@@ -9,6 +9,7 @@ export const AXIS_COMMANDS = Object.freeze({
|
||||
run: "PROGRAM_RUN", step: "PROGRAM_STEP", pause: "PROGRAM_PAUSE", resume: "PROGRAM_RESUME",
|
||||
stop: "PROGRAM_ABORT", restart: "PROGRAM_RESTART", mdi: "MDI_EXECUTE", jogStart: "JOG_START",
|
||||
jogStop: "JOG_STOP", home: "HOME", override: "SET_OVERRIDE", estop: "ESTOP", recover: "IO_RECOVER",
|
||||
power: "POWER",
|
||||
spindle: "SPINDLE_COMMAND", coolant: "COOLANT_COMMAND", toolPrepare: "TOOL_PREPARE",
|
||||
toolChange: "TOOL_CHANGE", probe: "PROBE_CONFIG",
|
||||
reset: "RESET",
|
||||
@@ -99,3 +100,27 @@ export function axisGate(action, input = {}) {
|
||||
export function axisGateMatrix(input = {}) {
|
||||
return Object.freeze(Object.fromEntries(Object.keys(AXIS_COMMANDS).map((action) => [action, axisGate(action, input)])));
|
||||
}
|
||||
|
||||
export const XYZAC_GATE_ACTIONS = Object.freeze(["switchkinsIdentity", "switchkinsXyzac", "switchkinsUserk", "vismachClear"]);
|
||||
export const XYZAC_COMMANDS = Object.freeze({ switchkinsIdentity: "KINEMATICS_SELECT", switchkinsXyzac: "KINEMATICS_SELECT", switchkinsUserk: "KINEMATICS_SELECT", vismachClear: "VISUAL_CLEAR" });
|
||||
|
||||
export function xyzacGate(action, input = {}) {
|
||||
const state = normalizeAxisState(input);
|
||||
const xyzac = input.xyzac ?? {};
|
||||
const idle = state.interpState === "IDLE" && state.taskState === "ON";
|
||||
const offsets = xyzac.finite_offsets !== false;
|
||||
const pinVars = xyzac.hal_pin_vars === true;
|
||||
const net = xyzac.switchkins_net === true;
|
||||
const coordinates = xyzac.coordinates === "XYZAC" && xyzac.joint_count === 5;
|
||||
if (action === "vismachClear") return Object.freeze({ action, enabled: true, reason: "axis_visual_only", visual_only: true, taskState: state.taskState, interpState: state.interpState });
|
||||
const common = idle && pinVars && net && offsets;
|
||||
const commonReason = state.taskState === "ESTOP" ? "xyzac_estop_active" : state.taskState !== "ON" ? "xyzac_machine_off" : !idle ? "xyzac_interp_not_idle" : !pinVars ? "xyzac_hal_pin_vars_missing" : !net ? "xyzac_switchkins_net_missing" : !offsets ? "xyzac_offsets_nonfinite" : "xyzac_switchkins_common_gate";
|
||||
if (action === "switchkinsIdentity") return Object.freeze({ action, enabled: common, reason: common ? "xyzac_m429_available" : commonReason, required_type: 0, taskState: state.taskState, interpState: state.interpState });
|
||||
if (action === "switchkinsXyzac") return Object.freeze({ action, enabled: common && coordinates, reason: !common ? commonReason : !coordinates ? "xyzac_coordinates_invalid" : "xyzac_m428_available", required_type: 1, taskState: state.taskState, interpState: state.interpState });
|
||||
if (action === "switchkinsUserk") return Object.freeze({ action, enabled: common && Boolean(xyzac.userk_capability), reason: !common ? commonReason : !xyzac.userk_capability ? "xyzac_userk_unavailable" : "xyzac_m430_available", required_type: 2, taskState: state.taskState, interpState: state.interpState });
|
||||
return Object.freeze({ action, enabled: false, reason: "xyzac_gate_unknown_action", taskState: state.taskState, interpState: state.interpState });
|
||||
}
|
||||
|
||||
export function xyzacGateMatrix(input = {}) {
|
||||
return Object.freeze(Object.fromEntries(XYZAC_GATE_ACTIONS.map((action) => [action, xyzacGate(action, input)])));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AXIS_COMMANDS, axisGate } from "./axis-contract.mjs";
|
||||
import { AXIS_COMMANDS, XYZAC_GATE_ACTIONS, axisGate, xyzacGate } from "./axis-contract.mjs";
|
||||
|
||||
export const COMMAND_ACTIONS = Object.freeze(Object.fromEntries(Object.entries(AXIS_COMMANDS).map(([action, command]) => [command, action])));
|
||||
export const COMMAND_ACTIONS = Object.freeze({ ...Object.fromEntries(Object.entries(AXIS_COMMANDS).map(([action, command]) => [command, action])), VISUAL_CLEAR: "vismachClear" });
|
||||
|
||||
export class AxisGateError extends Error {
|
||||
constructor(result) {
|
||||
@@ -26,17 +26,18 @@ export class AxisOperationController {
|
||||
|
||||
async execute(kind, payload = {}, { state = {}, action = COMMAND_ACTIONS[kind] ?? null, gate = true } = {}) {
|
||||
const operationId = this.nextOperationId(kind);
|
||||
const gateResult = action ? axisGate(action, state) : { action: null, enabled: true, reason: "axis_unrestricted_internal_command" };
|
||||
const gateResult = action ? (XYZAC_GATE_ACTIONS.includes(action) ? xyzacGate(action, state) : axisGate(action, state)) : { action: null, enabled: true, reason: "axis_unrestricted_internal_command" };
|
||||
const authoritativeGate = action && state?.gates?.[action];
|
||||
if (gate && !gateResult.enabled && !authoritativeGate) {
|
||||
this.trace.push(Object.freeze({ operation_id: operationId, kind, action, phase: "blocked", reason: gateResult.reason }));
|
||||
throw new AxisGateError(gateResult);
|
||||
const effectiveGate = authoritativeGate ?? gateResult;
|
||||
if (gate && !effectiveGate.enabled) {
|
||||
this.trace.push(Object.freeze({ operation_id: operationId, kind, action, phase: "blocked", reason: effectiveGate.reason }));
|
||||
throw new AxisGateError(effectiveGate);
|
||||
}
|
||||
this.trace.push(Object.freeze({ operation_id: operationId, kind, action, phase: "pending", reason: gateResult.reason }));
|
||||
this.trace.push(Object.freeze({ operation_id: operationId, kind, action, phase: "pending", reason: effectiveGate.reason }));
|
||||
try {
|
||||
const response = await this.client.send(kind, payload, operationId);
|
||||
this.trace.push(Object.freeze({ operation_id: operationId, kind, action, phase: "result", response_kind: response?.kind ?? null }));
|
||||
return Object.freeze({ operationId, response, gate: gateResult });
|
||||
return Object.freeze({ operationId, response, gate: effectiveGate });
|
||||
} catch (error) {
|
||||
this.trace.push(Object.freeze({ operation_id: operationId, kind, action, phase: "error", reason: error?.message ?? String(error) }));
|
||||
throw error;
|
||||
|
||||
Reference in New Issue
Block a user