518 lines
22 KiB
JavaScript
518 lines
22 KiB
JavaScript
import assert from "node:assert/strict";
|
|
|
|
import { createLinuxCncInterpreterRuntime } from "../../app/src/runtime/linuxcnc-interpreter-runtime.js";
|
|
import { createLinuxCncKinematicsRuntime } from "../../app/src/runtime/linuxcnc-kinematics-runtime.js";
|
|
import { parseLinuxCncIni } from "../../app/src/runtime/linuxcnc-ini-runtime.js";
|
|
import { buildRtcpFrame } from "../../app/src/runtime/rtcp-frame.js";
|
|
import { createSimulationStore } from "../../app/src/state/store.js";
|
|
import { readFile } from "node:fs/promises";
|
|
|
|
async function waitForInterpreterExecution(store) {
|
|
for (let attempt = 0; attempt < 20; attempt += 1) {
|
|
const state = store.getState();
|
|
if (!state.interpreterExecutionPending && state.programExecutionSourceMode === "linuxcnc-interpreter-wasm") {
|
|
return state;
|
|
}
|
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
}
|
|
return store.getState();
|
|
}
|
|
|
|
const identityFrame = buildRtcpFrame({
|
|
axisPose: { x: 43, y: -32.15, z: -11.306, a: 0, b: 0, c: 0 },
|
|
activeLine: 501,
|
|
kinsType: "identity",
|
|
rtcpEnabled: false,
|
|
});
|
|
|
|
assert.equal(identityFrame.apiName, "web-rtcp-5axis-motion-frame");
|
|
assert.equal(identityFrame.rtcpState, "off");
|
|
assert.equal(identityFrame.readiness.frameReady, true);
|
|
assert.equal(identityFrame.readiness.linuxCncKinematicsReady, false);
|
|
assert.equal(identityFrame.readiness.promotionAllowed, false);
|
|
assert.equal(identityFrame.semanticBoundary, "fixture_frame_ui_plumbing_not_linuxcnc_kinematics_proof");
|
|
assert.deepEqual(identityFrame.compensation, { x: 0, y: 0, z: 0 });
|
|
|
|
const tcpFrame = buildRtcpFrame({
|
|
axisPose: { x: 43, y: -32.15, z: -11.306, a: 15, b: 0, c: 30 },
|
|
activeLine: 502,
|
|
kinsType: "tcp-xyzac",
|
|
rtcpEnabled: true,
|
|
});
|
|
|
|
assert.equal(tcpFrame.rtcpState, "on");
|
|
assert.equal(tcpFrame.kinsType, "tcp-xyzac");
|
|
assert.notEqual(tcpFrame.compensation.z, 0);
|
|
assert.ok(Number.isFinite(tcpFrame.tcpPose.x));
|
|
assert.ok(Number.isFinite(tcpFrame.toolAxisVector.z));
|
|
assert.equal(tcpFrame.jointPose.length, 5);
|
|
|
|
const runtime = await createLinuxCncKinematicsRuntime({ moduleId: "xyzac-trt" });
|
|
const interpreterRuntime = await createLinuxCncInterpreterRuntime();
|
|
const linuxCncKinematicsResult = runtime.frameForJoints([10, 20, 30, 25, 40]);
|
|
const linuxCncFrame = buildRtcpFrame({
|
|
axisPose: { x: 10, y: 20, z: 30, a: 25, b: 0, c: 40 },
|
|
activeLine: 503,
|
|
kinsType: "tcp-xyzac",
|
|
rtcpEnabled: true,
|
|
linuxCncKinematicsResult,
|
|
});
|
|
assert.equal(linuxCncFrame.sourceMode, "source-derived-kinematics-wasm");
|
|
assert.equal(linuxCncFrame.semanticBoundary, "linuxcnc_kinematics_wasm_c_abi");
|
|
assert.equal(linuxCncFrame.readiness.linuxCncKinematicsReady, true);
|
|
assert.equal(linuxCncFrame.readiness.promotionAllowed, true);
|
|
assert.equal(linuxCncFrame.readiness.fullLinuxCncProgramExecutionReady, false);
|
|
assert.equal(linuxCncFrame.kinematicsModuleId, "xyzac-trt");
|
|
assert.equal(linuxCncFrame.jointPose[3].value, 25);
|
|
assert.equal(linuxCncFrame.jointPose[4].value, 40);
|
|
|
|
const fixtureInitialStore = createSimulationStore();
|
|
assert.equal(fixtureInitialStore.getState().rtcpState, "off");
|
|
assert.equal(fixtureInitialStore.getState().machine.powerOn, false);
|
|
assert.equal(fixtureInitialStore.getState().machine.mode, "manual");
|
|
assert.equal(
|
|
fixtureInitialStore.getState().linuxCncBoundaryAdapter.apiName,
|
|
"web-rtcp-5axis-linuxcnc-boundary-adapter",
|
|
);
|
|
assert.equal(fixtureInitialStore.getState().linuxCncBoundaryAdapter.panelSummary.schemaId, "xyzac-trt-switchkins-pyvcp");
|
|
assert.equal(fixtureInitialStore.getState().linuxCncBoundaryAdapter.sourceSummary.referenceCount >= 8, true);
|
|
assert.equal(fixtureInitialStore.getState().linuxCncBoundaryAdapter.profileSummary.toolCount, 10);
|
|
assert.equal(fixtureInitialStore.getState().linuxCncBoundaryAdapter.profileSummary.coordinates, "XYZAC");
|
|
assert.equal(fixtureInitialStore.getState().linuxCncBoundaryReadiness.ready, false);
|
|
assert.equal(fixtureInitialStore.getState().linuxCncBoundaryReadiness.promotionAllowed, false);
|
|
assert.equal(fixtureInitialStore.getState().fullExecutionBoundary.fullLinuxCncProgramExecutionReady, false);
|
|
assert.equal(fixtureInitialStore.getState().fullExecutionBoundary.promotionAllowed, false);
|
|
assert.equal(fixtureInitialStore.getState().fullExecutionBoundary.phase, "blocked");
|
|
assert.equal(fixtureInitialStore.getState().linuxCncTaskPolicy.semanticBoundary, "linuxcnc_task_state_mode_command_gate");
|
|
assert.equal(
|
|
fixtureInitialStore.getState().linuxCncTaskPolicy.sourceReferences.some((reference) => reference.path === "linuxcnc/src/emc/task/emctaskmain.cc"),
|
|
true,
|
|
);
|
|
assert.equal(fixtureInitialStore.getState().linuxCncTaskPolicy.canRunAuto, false);
|
|
|
|
const xyzacIniText = await readFile(
|
|
new URL("../../../wasm-port/vendor/linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.ini", import.meta.url),
|
|
"utf8",
|
|
);
|
|
const xyzacIniConfig = parseLinuxCncIni(xyzacIniText, {
|
|
path: fixtureInitialStore.getState().profile.iniPath,
|
|
profileId: fixtureInitialStore.getState().machineProfile,
|
|
});
|
|
fixtureInitialStore.dispatch({ type: "ATTACH_INI_CONFIG", iniConfig: xyzacIniConfig });
|
|
assert.equal(fixtureInitialStore.getState().iniConfigReadiness.loaded, true);
|
|
assert.equal(fixtureInitialStore.getState().iniConfigReadiness.ready, true);
|
|
assert.equal(fixtureInitialStore.getState().profile.axisLimits.X.max, 200);
|
|
fixtureInitialStore.dispatch({ type: "TOGGLE_POWER" });
|
|
fixtureInitialStore.dispatch({ type: "HOME" });
|
|
fixtureInitialStore.dispatch({ type: "SET_MODE", mode: "mdi" });
|
|
fixtureInitialStore.dispatch({ type: "RUN_MDI", command: "G90 X999 Y-999 Z999 A999 C99999" });
|
|
assert.equal(fixtureInitialStore.getState().axisPose.x, 200);
|
|
assert.equal(fixtureInitialStore.getState().axisPose.y, -100);
|
|
assert.equal(fixtureInitialStore.getState().axisPose.z, 120);
|
|
assert.equal(fixtureInitialStore.getState().axisPose.a, 50);
|
|
assert.equal(fixtureInitialStore.getState().axisPose.c, 36000);
|
|
|
|
const kinematicsStore = createSimulationStore();
|
|
kinematicsStore.dispatch({ type: "ATTACH_KINEMATICS_RUNTIME", runtime });
|
|
let kinematicsState = kinematicsStore.getState();
|
|
assert.equal(kinematicsState.linuxCncBoundaryAdapter.linuxCncKinematicsReady, true);
|
|
assert.equal(kinematicsState.linuxCncBoundaryAdapter.interpreterRuntimeReady, false);
|
|
assert.equal(kinematicsState.linuxCncBoundaryReadiness.ready, true);
|
|
assert.equal(kinematicsState.linuxCncBoundaryReadiness.fullLinuxCncProgramExecutionReady, false);
|
|
assert.equal(kinematicsState.linuxCncBoundaryReadiness.missing.includes("interpreter/remap runtime"), true);
|
|
assert.equal(kinematicsState.fullExecutionBoundary.satisfied.includes("linuxcnc-kinematics-wasm"), true);
|
|
assert.equal(kinematicsState.fullExecutionBoundary.missing.includes("linuxcnc interpreter WASM runtime"), true);
|
|
assert.equal(kinematicsState.kinematicsExecutionContext, "direct");
|
|
assert.equal(kinematicsState.rtcpFrame.sourceMode, "source-derived-kinematics-wasm");
|
|
assert.equal(kinematicsState.rtcpFrame.semanticBoundary, "linuxcnc_kinematics_wasm_c_abi");
|
|
assert.equal(kinematicsState.rtcpFrame.readiness.linuxCncKinematicsReady, true);
|
|
|
|
kinematicsStore.dispatch({ type: "SET_RTCP", enabled: true });
|
|
kinematicsState = kinematicsStore.getState();
|
|
assert.equal(kinematicsState.rtcpState, "on");
|
|
assert.equal(kinematicsState.rtcpFrame.sourceMode, "source-derived-kinematics-wasm");
|
|
assert.equal(kinematicsState.lastKinematicsResult.moduleId, "xyzac-trt");
|
|
assert.equal(kinematicsState.dro.tcpX, kinematicsState.rtcpFrame.tcpPose.x);
|
|
|
|
kinematicsStore.dispatch({ type: "TOGGLE_POWER" });
|
|
kinematicsStore.dispatch({ type: "HOME" });
|
|
kinematicsStore.dispatch({ type: "SET_MODE", mode: "auto" });
|
|
kinematicsStore.dispatch({ type: "STEP" });
|
|
kinematicsState = kinematicsStore.getState();
|
|
assert.equal(kinematicsState.runState, "stepping");
|
|
assert.equal(kinematicsState.rtcpFrame.sourceMode, "source-derived-kinematics-wasm");
|
|
assert.equal(kinematicsState.rtcpFrame.readiness.fullLinuxCncProgramExecutionReady, false);
|
|
|
|
kinematicsStore.dispatch({ type: "ATTACH_INTERPRETER_RUNTIME", runtime: interpreterRuntime });
|
|
kinematicsStore.dispatch({
|
|
type: "LOAD_PROGRAM",
|
|
filename: "linuxcnc-canonical-demo.ngc",
|
|
content: [
|
|
"G90 G17",
|
|
"G0 X0 Y0 Z0",
|
|
"G1 X10 Y2 F100",
|
|
"G1 X12 Y4 A5 C7",
|
|
"M2",
|
|
].join("\n"),
|
|
});
|
|
kinematicsState = await waitForInterpreterExecution(kinematicsStore);
|
|
assert.equal(kinematicsState.linuxCncBoundaryAdapter.linuxCncInterpreterReady, true);
|
|
assert.equal(kinematicsState.linuxCncBoundaryReadiness.linuxCncInterpreterReady, true);
|
|
assert.equal(kinematicsState.programExecutionSourceMode, "linuxcnc-interpreter-wasm");
|
|
assert.equal(kinematicsState.programExecution.summary.motionEventCount >= 3, true);
|
|
assert.equal(kinematicsState.programExecutionTiming.motionCount >= 3, true);
|
|
assert.equal(kinematicsState.programExecutionTiming.sampleCount >= 3, true);
|
|
assert.equal(kinematicsState.programExecutionTiming.totalSeconds > 0, true);
|
|
assert.equal(kinematicsState.programExecutionTiming.semanticBoundary, "linuxcnc_tp_queue_runtime_timing_from_canonical_motion");
|
|
assert.equal(kinematicsState.programExecution.summary.plannerRuntimeReady, true);
|
|
assert.equal(kinematicsState.fullExecutionBoundary.plannerRuntimeReady, true);
|
|
assert.equal(kinematicsState.programExecution.summary.fullLinuxCncProgramExecutionReady, false);
|
|
assert.equal(kinematicsState.fullExecutionBoundary.readyForUiSimulation, true);
|
|
assert.equal(kinematicsState.fullExecutionBoundary.machineFileBackedRemapReady, false);
|
|
assert.equal(kinematicsState.fullExecutionBoundary.fullLinuxCncProgramExecutionReady, false);
|
|
assert.equal(
|
|
kinematicsState.fullExecutionBoundary.semanticBoundary,
|
|
"linuxcnc_interpreter_canonical_ready_planner_task_hal_blocked",
|
|
);
|
|
|
|
kinematicsStore.dispatch({ type: "STEP" });
|
|
kinematicsState = kinematicsStore.getState();
|
|
assert.equal(kinematicsState.programExecutionMotionIndex, 1);
|
|
assert.equal(kinematicsState.activeLine, kinematicsState.programExecution.motion[1].line);
|
|
assert.equal(kinematicsState.programRuntimeFeedback.sourceMode, "linuxcnc-tp-runtime-sample");
|
|
assert.equal(kinematicsState.programRuntimeFeedback.semanticBoundary, "linuxcnc_tp_run_cycle_feedback_without_hardware");
|
|
assert.equal(kinematicsState.axisPose.x, kinematicsState.programRuntimeFeedback.axisPose.x);
|
|
assert.notEqual(kinematicsState.axisPose.x, kinematicsState.programExecution.motion[1].axes.x);
|
|
assert.equal(kinematicsState.programRuntimeFeedback.queueDepth >= 0, true);
|
|
assert.equal(kinematicsState.programElapsedSeconds > 0, true);
|
|
assert.equal(kinematicsState.programRemainingSeconds >= 0, true);
|
|
assert.equal(kinematicsState.feed.currentVelocity > 0, true);
|
|
|
|
kinematicsStore.dispatch({
|
|
type: "LOAD_PROGRAM",
|
|
filename: "linuxcnc-switchkins-rtcp-demo.ngc",
|
|
content: [
|
|
"G90 G17",
|
|
"M428",
|
|
"G0 X0 Y0 Z0 A0 C0",
|
|
"G1 X10 Y2 Z-1 A15 C30 F120",
|
|
"M429",
|
|
"G1 X0 Y0 Z0 A0 C0 F120",
|
|
"M2",
|
|
].join("\n"),
|
|
});
|
|
kinematicsState = await waitForInterpreterExecution(kinematicsStore);
|
|
assert.equal(kinematicsState.programExecutionSourceMode, "linuxcnc-interpreter-wasm");
|
|
assert.equal(kinematicsState.programExecution.summary.switchkinsEventCount, 2);
|
|
assert.equal(kinematicsState.programExecution.motion[0].switchkinsType, 1);
|
|
assert.equal(kinematicsState.kinsType, "tcp-xyzac");
|
|
assert.equal(kinematicsState.rtcpState, "on");
|
|
assert.equal(kinematicsState.rtcpFrame.kinematicsSwitchkinsType, 1);
|
|
|
|
kinematicsStore.dispatch({ type: "STEP" });
|
|
kinematicsState = kinematicsStore.getState();
|
|
assert.equal(kinematicsState.programExecutionMotionIndex, 1);
|
|
assert.equal(kinematicsState.programRuntimeFeedback.semanticBoundary, "linuxcnc_tp_run_cycle_feedback_without_hardware");
|
|
assert.equal(kinematicsState.axisPose.a > 0 && kinematicsState.axisPose.a < 15, true);
|
|
assert.equal(kinematicsState.axisPose.c > 0 && kinematicsState.axisPose.c < 30, true);
|
|
assert.equal(kinematicsState.programRuntimeFeedback.distanceToGo > 0, true);
|
|
assert.equal(kinematicsState.kinsType, "tcp-xyzac");
|
|
assert.equal(kinematicsState.rtcpState, "on");
|
|
assert.equal(kinematicsState.rtcpFrame.kinematicsSwitchkinsType, 1);
|
|
const switchkinsStepSampleIndex = kinematicsState.programExecutionSampleIndex;
|
|
|
|
kinematicsStore.dispatch({ type: "RESUME" });
|
|
kinematicsStore.dispatch({ type: "RUN" });
|
|
kinematicsState = kinematicsStore.getState();
|
|
assert.equal(kinematicsState.programExecutionSampleIndex > switchkinsStepSampleIndex, true);
|
|
assert.equal(kinematicsState.programExecutionMotionIndex, 1);
|
|
assert.equal(kinematicsState.programRuntimeFeedback.semanticBoundary, "linuxcnc_tp_run_cycle_feedback_without_hardware");
|
|
assert.equal(kinematicsState.programRuntimeFeedback.distanceToGo > 0, true);
|
|
assert.equal(kinematicsState.kinsType, "tcp-xyzac");
|
|
assert.equal(kinematicsState.rtcpState, "on");
|
|
assert.equal(kinematicsState.rtcpFrame.kinematicsSwitchkinsType, 1);
|
|
|
|
kinematicsStore.dispatch({ type: "PAUSE" });
|
|
kinematicsState = kinematicsStore.getState();
|
|
assert.equal(kinematicsState.runState, "paused");
|
|
assert.equal(kinematicsState.machine.interpState, "paused");
|
|
assert.equal(kinematicsState.machine.taskPaused, true);
|
|
|
|
kinematicsStore.dispatch({ type: "RUN" });
|
|
kinematicsState = kinematicsStore.getState();
|
|
assert.equal(kinematicsState.operatorMessage, "run blocked: resume paused program first");
|
|
assert.equal(kinematicsState.runState, "paused");
|
|
|
|
kinematicsStore.dispatch({ type: "RESUME" });
|
|
kinematicsState = kinematicsStore.getState();
|
|
assert.equal(kinematicsState.runState, "running");
|
|
assert.equal(kinematicsState.machine.interpState, "reading");
|
|
assert.equal(kinematicsState.machine.taskPaused, false);
|
|
|
|
kinematicsStore.dispatch({ type: "STOP" });
|
|
kinematicsState = kinematicsStore.getState();
|
|
assert.equal(kinematicsState.runState, "stopped");
|
|
assert.equal(kinematicsState.machine.interpState, "idle");
|
|
|
|
kinematicsStore.dispatch({ type: "SET_FRAME_SOURCE", sourceMode: "fixture-ui-only" });
|
|
kinematicsState = kinematicsStore.getState();
|
|
assert.equal(kinematicsState.rtcpFrame.sourceMode, "fixture-ui-only");
|
|
assert.equal(kinematicsState.rtcpFrame.readiness.linuxCncKinematicsReady, false);
|
|
|
|
const store = createSimulationStore();
|
|
let state;
|
|
assert.equal(store.getState().availableProfiles.length, 2);
|
|
store.dispatch({ type: "SET_PROFILE", profileId: "xyzbc-trt" });
|
|
assert.equal(store.getState().machineProfile, "xyzbc-trt");
|
|
assert.equal(store.getState().profile.traj.coordinates, "XYZBC");
|
|
const xyzbcRuntime = await createLinuxCncKinematicsRuntime({ moduleId: "xyzbc-trt" });
|
|
store.dispatch({ type: "ATTACH_KINEMATICS_RUNTIME", runtime: xyzbcRuntime });
|
|
store.dispatch({ type: "SET_RTCP", enabled: true });
|
|
state = store.getState();
|
|
assert.equal(state.kinsType, "tcp-xyzbc");
|
|
assert.equal(state.rtcpFrame.kinematicsModuleId, "xyzbc-trt");
|
|
assert.equal(state.rtcpFrame.jointPose[3].axis, "B");
|
|
|
|
store.dispatch({ type: "SET_PROFILE", profileId: "xyzac-trt" });
|
|
store.dispatch({ type: "RUN" });
|
|
assert.equal(store.getState().activeLine, 501);
|
|
assert.equal(store.getState().operatorMessage, "run blocked: machine must be on");
|
|
|
|
store.dispatch({ type: "TOGGLE_POWER" });
|
|
assert.equal(store.getState().machine.powerOn, true);
|
|
store.dispatch({ type: "HOME" });
|
|
assert.equal(store.getState().machine.allHomed, true);
|
|
store.dispatch({ type: "SET_MODE", mode: "auto" });
|
|
assert.equal(store.getState().linuxCncTaskPolicy.canRunAuto, true);
|
|
assert.equal(store.getState().linuxCncTaskPolicy.canExecuteMdi, false);
|
|
|
|
store.dispatch({ type: "SET_RTCP", enabled: true });
|
|
state = store.getState();
|
|
assert.equal(state.rtcpState, "on");
|
|
assert.equal(state.kinsType, "tcp-xyzac");
|
|
assert.equal(state.rtcpFrame.readiness.linuxCncKinematicsReady, false);
|
|
assert.notEqual(state.dro.tcpZ, state.dro.z);
|
|
|
|
const previousLine = state.activeLine;
|
|
const previousTcpX = state.tcpPose.x;
|
|
store.dispatch({ type: "STEP" });
|
|
state = store.getState();
|
|
assert.equal(state.activeLine, previousLine + 1);
|
|
assert.equal(state.runState, "stepping");
|
|
assert.notEqual(state.tcpPose.x, previousTcpX);
|
|
|
|
store.dispatch({ type: "STOP" });
|
|
store.dispatch({ type: "SET_MODE", mode: "manual" });
|
|
store.dispatch({ type: "JOG", axis: "x", direction: 1, increment: 2 });
|
|
state = store.getState();
|
|
assert.equal(state.machine.mode, "manual");
|
|
assert.equal(state.runState, "jogging");
|
|
assert.equal(Math.round(state.axisPose.x), Math.round(state.rtcpFrame.axisPose.x));
|
|
|
|
store.dispatch({ type: "SET_MODE", mode: "mdi" });
|
|
store.dispatch({ type: "RUN_MDI", command: "G0 X1" });
|
|
state = store.getState();
|
|
assert.equal(state.machine.mode, "mdi");
|
|
assert.equal(state.machine.mdiCommand, "G0 X1");
|
|
assert.equal(state.runState, "mdi");
|
|
assert.equal(state.axisPose.x, 1);
|
|
assert.equal(state.programSource, "operator-mdi");
|
|
assert.equal(state.programLines[0], "G0 X1");
|
|
assert.equal(state.mdiHistory[0], "G0 X1");
|
|
|
|
const mdiRelativeBase = store.getState().axisPose;
|
|
store.dispatch({ type: "RUN_MDI", command: "G91 X2 Y-3 F1200 M3 S2400 M8" });
|
|
state = store.getState();
|
|
assert.equal(state.machine.mdiDistanceMode, "relative");
|
|
assert.equal(state.axisPose.x, mdiRelativeBase.x + 2);
|
|
assert.equal(state.axisPose.y, mdiRelativeBase.y - 3);
|
|
assert.equal(state.feed.feedRate, 1200);
|
|
assert.equal(state.spindle.enabled, true);
|
|
assert.equal(state.spindle.rpm, 2400);
|
|
assert.equal(state.coolant.flood, true);
|
|
|
|
store.dispatch({ type: "RUN_MDI", command: "M428" });
|
|
state = store.getState();
|
|
assert.equal(state.kinsType, "tcp-xyzac");
|
|
assert.equal(state.rtcpState, "on");
|
|
|
|
store.dispatch({ type: "RUN_MDI", command: "M429 M9 M5" });
|
|
state = store.getState();
|
|
assert.equal(state.kinsType, "identity");
|
|
assert.equal(state.rtcpState, "off");
|
|
assert.equal(state.coolant.flood, false);
|
|
assert.equal(state.coolant.mist, false);
|
|
assert.equal(state.spindle.enabled, false);
|
|
|
|
store.dispatch({
|
|
type: "LOAD_PROGRAM",
|
|
filename: "operator-demo.ngc",
|
|
content: "G0 X0 Y0\nG1 X10 F100\nM30\n",
|
|
});
|
|
state = await waitForInterpreterExecution(store);
|
|
assert.equal(state.activeProgram, "operator-demo.ngc");
|
|
assert.equal(state.programSource, "operator-file");
|
|
assert.equal(state.programStartLine, 1);
|
|
assert.equal(state.activeLine, 1);
|
|
assert.equal(state.programLines.length, 3);
|
|
assert.equal(state.machine.mode, "auto");
|
|
|
|
store.dispatch({ type: "RUN" });
|
|
state = store.getState();
|
|
assert.equal(state.activeLine, 3);
|
|
assert.equal(state.runState, "complete");
|
|
|
|
store.dispatch({ type: "SET_RTCP", enabled: false });
|
|
state = store.getState();
|
|
assert.equal(state.rtcpState, "off");
|
|
assert.equal(state.kinsType, "identity");
|
|
assert.equal(state.dro.tcpX, state.dro.x);
|
|
|
|
store.dispatch({ type: "ADJUST_OVERRIDE", target: "feed", delta: -10 });
|
|
state = store.getState();
|
|
assert.equal(state.feed.feedOverride, 90);
|
|
assert.equal(state.operatorMessage, "feed override adjusted");
|
|
|
|
store.dispatch({ type: "ADJUST_OVERRIDE", target: "rapid", delta: 20 });
|
|
state = store.getState();
|
|
assert.equal(state.feed.rapidOverride, 120);
|
|
|
|
store.dispatch({ type: "ADJUST_SPINDLE_OVERRIDE", delta: 10 });
|
|
state = store.getState();
|
|
assert.equal(state.spindle.override, 110);
|
|
|
|
const floodBeforeToggle = store.getState().coolant.flood;
|
|
store.dispatch({ type: "TOGGLE_COOLANT", kind: "flood" });
|
|
state = store.getState();
|
|
assert.equal(state.coolant.flood, !floodBeforeToggle);
|
|
|
|
const mistBeforeToggle = store.getState().coolant.mist;
|
|
store.dispatch({ type: "TOGGLE_COOLANT", kind: "mist" });
|
|
state = store.getState();
|
|
assert.equal(state.coolant.mist, !mistBeforeToggle);
|
|
|
|
store.dispatch({ type: "SET_VIEW", view: "x" });
|
|
state = store.getState();
|
|
assert.equal(state.preview.selectedView, "x");
|
|
|
|
store.dispatch({ type: "CLEAR_PREVIEW" });
|
|
state = store.getState();
|
|
assert.equal(state.preview.pathPoints, 0);
|
|
|
|
store.dispatch({ type: "RELOAD_PROGRAM" });
|
|
state = store.getState();
|
|
assert.equal(state.preview.pathPoints, 3);
|
|
assert.equal(state.activeLine, 1);
|
|
assert.equal(state.runState, "idle");
|
|
|
|
store.dispatch({ type: "TOGGLE_FULLSCREEN" });
|
|
state = store.getState();
|
|
assert.equal(state.preview.fullscreen, true);
|
|
|
|
store.dispatch({ type: "SET_MODE", mode: "manual" });
|
|
store.dispatch({ type: "HOME" });
|
|
state = store.getState();
|
|
assert.equal(state.axisPose.x, 43);
|
|
assert.equal(state.operatorMessage, "machine homed to fixture origin");
|
|
|
|
store.dispatch({ type: "ESTOP" });
|
|
state = store.getState();
|
|
assert.equal(state.machine.powerOn, false);
|
|
assert.equal(state.machine.estopActive, true);
|
|
assert.equal(state.runState, "estopped");
|
|
|
|
store.dispatch({ type: "RESET" });
|
|
state = store.getState();
|
|
assert.equal(state.machine.estopActive, false);
|
|
assert.equal(state.machine.powerOn, false);
|
|
assert.equal(state.machine.taskState, "estop-reset");
|
|
assert.equal(state.operatorMessage, "estop reset; machine off");
|
|
|
|
const taskHalSwitchkinsStore = createSimulationStore({
|
|
programStartLine: 1,
|
|
activeLine: 5,
|
|
kinsType: "tcp-xyzac",
|
|
rtcpState: "on",
|
|
programExecutionSourceMode: "linuxcnc-interpreter-wasm",
|
|
programExecution: {
|
|
sourceMode: "linuxcnc-interpreter-wasm",
|
|
motion: [
|
|
{
|
|
type: "STRAIGHT_TRAVERSE",
|
|
line: 5,
|
|
axes: { x: 1, y: 2, z: 3, a: 10, c: 20 },
|
|
switchkinsType: 1,
|
|
kinsType: "tcp",
|
|
},
|
|
{
|
|
type: "STRAIGHT_FEED",
|
|
line: 20,
|
|
axes: { x: 2, y: 3, z: 4, a: 0, c: 0 },
|
|
switchkinsType: 0,
|
|
kinsType: "identity",
|
|
},
|
|
],
|
|
summary: {
|
|
motionEventCount: 2,
|
|
switchkinsEventCount: 2,
|
|
switchkinsCodes: ["M428", "M429"],
|
|
},
|
|
},
|
|
});
|
|
taskHalSwitchkinsStore.dispatch({
|
|
type: "TASK_HAL_STATUS_APPLIED",
|
|
status: taskHalStatusForSwitchkinsLine({ activeLine: 5, switchkinsType: 0 }),
|
|
operatorMessage: "task/HAL status retained program TCP switchkins",
|
|
});
|
|
state = taskHalSwitchkinsStore.getState();
|
|
assert.equal(state.activeLine, 5);
|
|
assert.equal(state.kinsType, "tcp-xyzac");
|
|
assert.equal(state.rtcpState, "on");
|
|
|
|
taskHalSwitchkinsStore.dispatch({
|
|
type: "TASK_HAL_STATUS_APPLIED",
|
|
status: taskHalStatusForSwitchkinsLine({ activeLine: 20, switchkinsType: 0 }),
|
|
operatorMessage: "task/HAL status applied program identity switchkins",
|
|
});
|
|
state = taskHalSwitchkinsStore.getState();
|
|
assert.equal(state.activeLine, 20);
|
|
assert.equal(state.kinsType, "identity");
|
|
assert.equal(state.rtcpState, "off");
|
|
|
|
console.log("rtcp_store_smoke=ok");
|
|
|
|
function taskHalStatusForSwitchkinsLine({ activeLine, switchkinsType }) {
|
|
return {
|
|
semanticBoundary: "linuxcnc_task_motion_hal_wasm_simulation_runtime",
|
|
task: {
|
|
state: "ON",
|
|
mode: "AUTO",
|
|
interpState: "READING",
|
|
execState: "WAITING_FOR_MOTION",
|
|
},
|
|
motionStatus: {
|
|
motion: {
|
|
programLine: activeLine,
|
|
motionType: 1,
|
|
switchkinsType,
|
|
currentVel: 1,
|
|
requestedVel: 1,
|
|
inPosition: false,
|
|
},
|
|
},
|
|
ui: {
|
|
taskState: "on",
|
|
taskMode: "auto",
|
|
interpState: "reading",
|
|
activeLine,
|
|
switchkinsType,
|
|
axisPoseFrame: "work",
|
|
axisPose: { x: 1, y: 2, z: 3, a: 10, b: 0, c: 20 },
|
|
currentVelocity: 60,
|
|
servoCycle: 1,
|
|
taskCycle: 1,
|
|
motionQueueDepth: 1,
|
|
},
|
|
};
|
|
}
|