4.8 KiB
4.8 KiB
3axis Tutorial 状态机契约
本契约以 LinuxCNC axis.py、linuxcnc Python API 和 emctaskmain/taskclass 的源语义为 oracle。sim_task.v1 保持原有 schema;axis_state 是 Worker 响应中的附加 AXIS 视图。
源常量
| LinuxCNC 源常量 | 数值 | AXIS 视图 |
|---|---|---|
STATE_ESTOP |
1 | machine_state=ESTOP |
STATE_ESTOP_RESET |
2 | machine_state=ESTOP_RESET |
STATE_OFF |
3 | machine_state=OFF |
STATE_ON |
4 | machine_state=ON |
MODE_MANUAL |
1 | source_mode=MANUAL |
MODE_AUTO |
2 | source_mode=AUTO |
MODE_MDI |
3 | source_mode=MDI |
INTERP_IDLE |
1 | operation_state=IDLE |
INTERP_READING |
2 | operation_state=RUNNING |
INTERP_PAUSED |
3 | operation_state=PAUSED |
INTERP_WAITING |
4 | operation_state=RUNNING,source_interp_state=INTERP_WAITING |
八个 AXIS 核心状态
ESTOP, ESTOP_RESET, OFF, ON, HOME, IDLE, RUNNING, PAUSED
ESTOP/ESTOP_RESET/OFF/ON 是 machine/task 层;HOME 是 home command 的 transient operation;IDLE/RUNNING/PAUSED 是 interpreter/task activity 层。响应字段:
{
"axis_state": {
"state": "RUNNING",
"machine_state": "ON",
"operation_state": "RUNNING",
"source_task_state": "STATE_ON",
"source_interp_state": "INTERP_READING",
"source_mode": "AUTO"
}
}
源对齐迁移
| 当前 | 允许迁移 | 触发源行为 |
|---|---|---|
ESTOP |
ESTOP_RESET、ESTOP |
AXIS estop_clicked: command.state(STATE_ESTOP_RESET) 或保持急停 |
ESTOP_RESET |
ON、OFF、ESTOP |
AXIS onoff_clicked: STATE_ON;再次急停回 ESTOP |
OFF |
ESTOP_RESET、ESTOP、OFF |
上电必须先经过源定义的 reset 流程 |
ON |
HOME、IDLE、RUNNING、PAUSED、OFF、ESTOP |
manual_ok、home、auto/mdi、off/estop |
HOME |
ON、IDLE、ESTOP |
axis.py::go_home;本案例按 Z -> X -> Y individual home |
IDLE |
HOME、RUNNING、PAUSED、OFF、ESTOP |
manual_ok、program run/pause、power/estop |
RUNNING |
PAUSED、IDLE、ESTOP |
INTERP_READING/WAITING、pause/abort/complete/estop |
PAUSED |
RUNNING、IDLE、ESTOP |
INTERP_PAUSED、resume/abort/estop |
RUNNING -> HOME、PAUSED -> HOME、ESTOP -> HOME 等迁移必须拒绝。Home 不是普通程序运行状态,必须先满足源 manual_ok:task STATE_ON 且不在 MODE_AUTO/MDI 非 idle 执行中。
按钮门控
- 急停按钮始终可用;
ESTOP时触发 reset,其他机器状态触发 estop。 - 上电按钮只有源状态允许时可用;
ESTOP_RESET才发送STATE_ON,否则发送STATE_OFF。 - Open/Load/MDI/Jog/Home 需要
STATE_ON,且 interpreter idle 或符合 MDI queue 条件。 - Run 需要
STATE_ON + MODE_AUTO + INTERP_IDLE + task file。 - Pause 只允许
MODE_AUTO且INTERP_READING/INTERP_WAITING。 - Resume 只允许
INTERP_PAUSED。 - Step 需要 machine on 和 task file,不能在 ESTOP/OFF 执行。
- Home 需要 machine on、manual mode、interpreter idle;本案例 UI 逐轴执行。
- Tool/spindle/coolant/probe 操作必须同时受 ESTOP、fault、interlock、spindle busy 和 tool lifecycle gate 约束。
Web AXIS 操作映射
- 页面上的“取消急停”先发送
ESTOP(active=false),等待ESTOP_RESET,再发送IO_RECOVER进入ON/IDLE;急停置位始终只发送ESTOP(active=true),其错误响应仍携带完整task/motion/axis_state快照。 - “上电”使用
IO_RECOVER;“复位机床”先停止 AUTO 解释器、清除急停(如有),再执行IO_RECOVER。协议层RESET仍是生命周期复位,不能作为机床复位按钮,否则会按源协议清零序号。 - Manual 页签切换会先发
SET_MODE(MANUAL)。因此HOME、逐轴JOG_*、主轴和冷却只在STATE_ON + MODE_MANUAL + INTERP_IDLE开放;MDI/AUTO、fault、限位和急停均 fail-closed。 - Home All 遵循本案例未定义统一
HOME_SEQUENCE时的源 AXIS 行为,固定按Z -> X -> Y逐轴发送并等待每个COMMAND_RESULT。 - G-code 预览可以在加载前显示确定性解析轨迹;执行轨迹只使用 Worker authoritative planner 快照,已完成段和 active 段分层显示,DRO 从 Worker 的 motion/interpreter 快照更新。
验证
- 单元状态契约:
node web/worker/test_axis_state.mjs - 源序列:
node web/worker/test_axis3_tutorial_sequence.mjs - native recorder:
python3 scripts/run_axis3_tutorial_native_sequence.py - native/Worker sequence report:
coverage/axis3-tutorial-sequence.report.json - 现有 gate contract:
web/app/test_axis_contract.mjs、web/app/test_axis_operation_controller.mjs
禁止修改锁定 ABI、protocol、sim_task.v1 字段来承载这组视图;状态契约新增字段只能作为 additive axis_state,并必须有 hash/迁移测试。