完善 gmoccapy XYZAB 参考功能

This commit is contained in:
2026-06-26 17:53:45 -04:00
parent 4e4f1462f5
commit a81b40447d
154 changed files with 17194 additions and 51 deletions

View File

@@ -224,6 +224,7 @@ const initialState = {
rpm: 1600,
override: 100,
enabled: true,
direction: "forward",
},
coolant: {
flood: true,
@@ -985,7 +986,7 @@ export function createSimulationStore(seed = {}) {
runState: turningOff ? "powered-off" : "idle",
feed: turningOff ? { ...state.feed, currentVelocity: 0 } : state.feed,
coolant: turningOff ? { ...state.coolant, flood: false, mist: false } : state.coolant,
spindle: turningOff ? { ...state.spindle, enabled: false } : state.spindle,
spindle: turningOff ? { ...state.spindle, enabled: false, direction: "stop" } : state.spindle,
operatorMessage: turningOff ? "task/HAL machine power off" : "task/HAL machine power on",
});
runTaskHalCommandSequence([
@@ -1006,7 +1007,7 @@ export function createSimulationStore(seed = {}) {
runState: turningOff ? "powered-off" : "idle",
feed: turningOff ? { ...state.feed, currentVelocity: 0 } : state.feed,
coolant: turningOff ? { ...state.coolant, flood: false, mist: false } : state.coolant,
spindle: turningOff ? { ...state.spindle, enabled: false } : state.spindle,
spindle: turningOff ? { ...state.spindle, enabled: false, direction: "stop" } : state.spindle,
operatorMessage: turningOff ? "machine power off" : "machine power on",
});
}
@@ -1035,6 +1036,7 @@ export function createSimulationStore(seed = {}) {
spindle: {
...state.spindle,
enabled: false,
direction: "stop",
},
operatorMessage: "emergency stop active",
});
@@ -1060,6 +1062,7 @@ export function createSimulationStore(seed = {}) {
spindle: {
...state.spindle,
enabled: false,
direction: "stop",
},
operatorMessage: "estop reset; machine off",
});
@@ -1285,6 +1288,24 @@ export function createSimulationStore(seed = {}) {
});
}
break;
case "SET_SPINDLE_DIRECTION":
{
const gate = gateLinuxCncTaskAction(state, action);
if (!gate.allowed) {
setState({ operatorMessage: gate.operatorMessage });
break;
}
const direction = normalizeSpindleDirection(action.direction);
setState({
spindle: {
...state.spindle,
enabled: direction !== "stop",
direction,
},
operatorMessage: direction === "stop" ? "spindle stopped" : `spindle ${direction}`,
});
}
break;
case "PAUSE":
{
const gate = gateLinuxCncTaskAction(state, action);
@@ -1486,9 +1507,17 @@ export function createSimulationStore(seed = {}) {
});
break;
case "SET_RTCP":
if (action.enabled && !profileSupportsTcp(state.profile)) {
setState({
kinsType: "identity",
rtcpState: "off",
operatorMessage: `RTCP blocked: ${state.profile.id} is ${state.profile.kinematics} reference only`,
});
break;
}
setState({
kinsType: action.enabled
? (state.profile.kinematicsParameters.switchkinsTypes.find((type) => type.value === 1)?.webKinsType || "tcp-xyzac")
? tcpKinsTypeForProfile(state.profile)
: "identity",
rtcpState: action.enabled ? "on" : "off",
});
@@ -1526,6 +1555,14 @@ export function createSimulationStore(seed = {}) {
});
break;
case "SET_KINS_TYPE":
if (String(action.kinsType || "").startsWith("tcp-") && !profileSupportsTcp(state.profile)) {
setState({
kinsType: "identity",
rtcpState: "off",
operatorMessage: `kinematics ${action.kinsType} blocked: ${state.profile.id} is not TCP capable`,
});
break;
}
setState({
kinsType: action.kinsType,
rtcpState: action.kinsType.startsWith("tcp-") ? "on" : "off",
@@ -1533,6 +1570,12 @@ export function createSimulationStore(seed = {}) {
});
break;
case "ADJUST_OVERRIDE":
{
const gate = gateLinuxCncTaskAction(state, action);
if (!gate.allowed) {
setState({ operatorMessage: gate.operatorMessage });
break;
}
setState({
feed: {
...state.feed,
@@ -1544,8 +1587,15 @@ export function createSimulationStore(seed = {}) {
},
operatorMessage: `${action.target} override adjusted`,
});
}
break;
case "ADJUST_SPINDLE_OVERRIDE":
{
const gate = gateLinuxCncTaskAction(state, action);
if (!gate.allowed) {
setState({ operatorMessage: gate.operatorMessage });
break;
}
setState({
spindle: {
...state.spindle,
@@ -1553,8 +1603,15 @@ export function createSimulationStore(seed = {}) {
},
operatorMessage: "spindle override adjusted",
});
}
break;
case "TOGGLE_COOLANT":
{
const gate = gateLinuxCncTaskAction(state, action);
if (!gate.allowed) {
setState({ operatorMessage: gate.operatorMessage });
break;
}
setState({
coolant: {
...state.coolant,
@@ -1562,6 +1619,7 @@ export function createSimulationStore(seed = {}) {
},
operatorMessage: `${action.kind} coolant toggled`,
});
}
break;
case "RELOAD_PROGRAM":
setState({
@@ -1875,11 +1933,13 @@ export function createSimulationStore(seed = {}) {
allHomed: true,
},
});
const tcpKinsType = state.profile.kinematicsParameters.switchkinsTypes.find((type) => type.value === 1)?.webKinsType || "tcp-xyzac";
dispatch({ type: "SET_KINS_TYPE", kinsType: tcpKinsType });
const tcpKinsType = tcpKinsTypeForProfile(state.profile);
if (tcpKinsType) {
dispatch({ type: "SET_KINS_TYPE", kinsType: tcpKinsType });
}
return state;
}
const tcpKinsType = state.profile.kinematicsParameters.switchkinsTypes.find((type) => type.value === 1)?.webKinsType || "tcp-xyzac";
const tcpKinsType = tcpKinsTypeForProfile(state.profile);
setState({
machine: {
...state.machine,
@@ -1893,9 +1953,11 @@ export function createSimulationStore(seed = {}) {
taskPaused: false,
},
runState: "idle",
kinsType: tcpKinsType,
rtcpState: "on",
operatorMessage: "RUN ready: power on, homed, auto mode",
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",
});
return state;
};
@@ -2737,7 +2799,17 @@ function createIniConfigReadiness(iniConfig) {
function normalizeKinsTypeForProfile(kinsType, profile) {
if (kinsType !== "tcp-xyzac" && kinsType !== "tcp-xyzbc") return kinsType;
return profile.kinematicsParameters.switchkinsTypes.find((type) => type.value === 1)?.webKinsType || kinsType;
return tcpKinsTypeForProfile(profile) || "identity";
}
function profileSupportsTcp(profile) {
return Boolean(profile?.tcpCapable !== false && tcpKinsTypeForProfile(profile));
}
function tcpKinsTypeForProfile(profile) {
return profile?.kinematicsParameters?.switchkinsTypes
?.find((type) => type.value === 1 && String(type.webKinsType || "").startsWith("tcp-"))
?.webKinsType || null;
}
function clampAxisPoseToProfile(axisPose, profile = defaultProfile) {
@@ -2821,6 +2893,7 @@ function executeMdiCommand(state, rawCommand) {
...state.spindle,
rpm: parsed.spindleRpm ?? state.spindle.rpm,
enabled: parsed.spindleEnabled ?? state.spindle.enabled,
direction: parsed.spindleDirection ?? state.spindle.direction,
}
: state.spindle,
coolant: parsed.coolantPatch
@@ -2850,6 +2923,7 @@ function parseMdiCommand(command) {
feedRate: null,
spindleRpm: null,
spindleEnabled: null,
spindleDirection: null,
coolantPatch: null,
distanceMode: null,
motionCode: null,
@@ -2888,8 +2962,10 @@ function parseMdiCommand(command) {
function applyMdiMCode(parsed, value) {
if (value === 3 || value === 4) {
parsed.spindleEnabled = true;
parsed.spindleDirection = value === 4 ? "reverse" : "forward";
} else if (value === 5) {
parsed.spindleEnabled = false;
parsed.spindleDirection = "stop";
} else if (value === 7) {
parsed.coolantPatch = { ...(parsed.coolantPatch || {}), mist: true };
} else if (value === 8) {
@@ -2905,9 +2981,14 @@ function applyMdiMCode(parsed, value) {
}
}
function normalizeSpindleDirection(direction) {
const value = String(direction || "stop").toLowerCase();
return value === "forward" || value === "reverse" ? value : "stop";
}
function resolveMdiKinsType(state, kinsType) {
if (kinsType !== "tcp") return kinsType;
return state.profile.kinematicsParameters.switchkinsTypes.find((type) => type.value === 1)?.webKinsType || "tcp-xyzac";
return tcpKinsTypeForProfile(state.profile);
}
function hasMdiAxisWords(parsed) {