56 lines
3.2 KiB
JavaScript
56 lines
3.2 KiB
JavaScript
// AXIS-facing state names are a view over the native task and interpreter
|
|
// states. Keep sim_task.v1 unchanged and expose this as an additive payload.
|
|
export const AXIS_STATES = Object.freeze(["ESTOP", "ESTOP_RESET", "OFF", "ON", "HOME", "IDLE", "RUNNING", "PAUSED"]);
|
|
export const LINUXCNC_STATE_CONSTANTS = Object.freeze({
|
|
STATE_ESTOP: 1,
|
|
STATE_ESTOP_RESET: 2,
|
|
STATE_OFF: 3,
|
|
STATE_ON: 4,
|
|
MODE_MANUAL: 1,
|
|
MODE_AUTO: 2,
|
|
MODE_MDI: 3,
|
|
INTERP_IDLE: 1,
|
|
INTERP_READING: 2,
|
|
INTERP_PAUSED: 3,
|
|
INTERP_WAITING: 4,
|
|
});
|
|
export const AXIS_TRANSITIONS = Object.freeze({
|
|
ESTOP: ["ESTOP", "ESTOP_RESET"],
|
|
ESTOP_RESET: ["ESTOP", "ON", "OFF"],
|
|
OFF: ["OFF", "ESTOP", "ESTOP_RESET"],
|
|
ON: ["ON", "OFF", "ESTOP", "HOME", "IDLE", "RUNNING", "PAUSED"],
|
|
HOME: ["HOME", "ON", "IDLE", "ESTOP"],
|
|
IDLE: ["IDLE", "RUNNING", "PAUSED", "HOME", "ESTOP", "OFF"],
|
|
RUNNING: ["RUNNING", "PAUSED", "IDLE", "ESTOP"],
|
|
PAUSED: ["PAUSED", "RUNNING", "IDLE", "ESTOP"],
|
|
});
|
|
|
|
function programActivity(task, program) {
|
|
if (task?.state === "PAUSED" || program?.program_status === "paused") return "PAUSED";
|
|
if (task?.state === "RUNNING" || program?.program_status === "running") return "RUNNING";
|
|
return "IDLE";
|
|
}
|
|
|
|
export function axisState({ task = {}, program = {}, action = null, payload = {} } = {}) {
|
|
const taskState = String(task.state ?? "NEW").toUpperCase();
|
|
let machineState = ["ESTOP", "FAULT"].includes(taskState) ? "ESTOP" : ["READY", "RUNNING", "PAUSED", "STOPPED"].includes(taskState) ? "ON" : "OFF";
|
|
let operationState = programActivity(task, program);
|
|
if (action === "ESTOP" && payload.active === true) machineState = "ESTOP";
|
|
if (action === "ESTOP" && payload.active === false) machineState = "ESTOP_RESET";
|
|
if (action === "IO_RECOVER") machineState = "ON";
|
|
if (action === "HOME") operationState = "HOME";
|
|
if (action === "PROGRAM_PAUSE") operationState = "PAUSED";
|
|
if (action === "PROGRAM_RUN" || action === "PROGRAM_RESUME") operationState = "RUNNING";
|
|
if (["PROGRAM_LOAD", "PROGRAM_ABORT", "PROGRAM_RESTART", "MDI_EXECUTE"].includes(action)) operationState = "IDLE";
|
|
const state = machineState === "ESTOP" || machineState === "ESTOP_RESET" ? machineState : operationState === "HOME" ? "HOME" : operationState === "RUNNING" ? "RUNNING" : operationState === "PAUSED" ? "PAUSED" : machineState === "OFF" ? "OFF" : "IDLE";
|
|
const sourceTaskState = taskState === "ESTOP" ? "STATE_ESTOP" : machineState === "ESTOP_RESET" ? "STATE_ESTOP_RESET" : machineState === "OFF" ? "STATE_OFF" : "STATE_ON";
|
|
const sourceInterpState = operationState === "PAUSED" ? "INTERP_PAUSED" : operationState === "RUNNING" ? "INTERP_READING" : "INTERP_IDLE";
|
|
const sourceMode = String(task.mode ?? "MANUAL").toUpperCase();
|
|
return Object.freeze({ state, machine_state: machineState, operation_state: operationState, source_task_state: sourceTaskState, source_interp_state: sourceInterpState, source_mode: sourceMode, states: [...AXIS_STATES] });
|
|
}
|
|
|
|
export function validateAxisTransition(previous, next) {
|
|
if (!AXIS_STATES.includes(previous) || !AXIS_STATES.includes(next)) return { status: "blocked", code: "axis_state_unknown" };
|
|
return AXIS_TRANSITIONS[previous]?.includes(next) ? { status: "accepted", previous, next } : { status: "blocked", code: "axis_state_transition_invalid", previous, next };
|
|
}
|