Files
cnc_wams/web-rtcp-5axis-sim-plan/working1/02-repair-plan.md

6.6 KiB
Raw Blame History

02 修复总体方案

生成时间2026-06-22

1. 修复原则

  1. 不用 JavaScript 重写 LinuxCNC 运动学语义。
  2. RTCP/TCP frame 必须优先来自 LinuxCNC source-derived kinematics WASM。
  3. 视觉层只能消费 runtime frame、canonical motion、task/HAL feedback不生成 G-code/CNC 语义。
  4. JOG/HOME/DRO 必须明确坐标系,不允许 task-local 坐标无标记覆盖 UI work pose。
  5. 每项修复必须新增或更新测试,先复现问题,再验证修复。

2. 修复优先级

优先级 问题 原因
P0 D1 RTCP/运动学边界自动挂接 影响语义边界可信度,且修复面较集中
P0 D2 3D 预览可见性 影响产品第一视觉和核心仿真价值
P1 D3 HOME/JOG 坐标连续性 影响手动操作正确性,需谨慎处理坐标系

3. D1 修复方案

目标状态

页面稳定加载后无需手动调用,自动达到:

state.sourceMode=source-derived-kinematics-wasm
state.frameSourceMode=source-derived-kinematics-wasm
state.rtcpFrame.semanticBoundary=linuxcnc_kinematics_wasm_c_abi
data-rtcp-diagnostic="kinematics-ready" -> ready
data-rtcp-diagnostic="boundary" -> linuxcnc_kinematics_wasm_c_abi

推荐设计

把“期望使用的 frame source”和“当前已经解析出的 frame source”分开

desiredFrameSourceMode: source-derived-kinematics-wasm | fixture-ui-only
frameSourceMode: 当前 rtcpFrame.sourceMode

或者在不新增字段的情况下,至少保证 setState() 不用异步 runtime 的临时 fixture frame 覆盖 kinematics 请求状态。

推荐更清晰的做法:

  1. 新增 desiredFrameSourceMode
  2. ATTACH_KINEMATICS_RUNTIME 成功后设置:
desiredFrameSourceMode: "source-derived-kinematics-wasm"
  1. buildFrameForState() 对 async worker 不直接降级修改 desired state只生成临时 fixture frame并标记
asyncFrameRefreshPending=true
  1. scheduleAsyncKinematicsRefresh() 判断:
state.kinematicsRuntime?.loaded &&
state.desiredFrameSourceMode === "source-derived-kinematics-wasm"

而不是依赖已经被 fixture 覆盖的 frameSourceMode

  1. refreshAsyncKinematicsFrame() 成功后写入:
sourceMode: "source-derived-kinematics-wasm"
frameSourceMode: "source-derived-kinematics-wasm"
desiredFrameSourceMode: "source-derived-kinematics-wasm"

防回退要求

任何以下动作后都不能把 frame 永久退回 fixture

ATTACH_INI_CONFIG
SET_PROFILE
MACHINE_FILE_STAGING_COMPLETE
TASK_HAL_STATUS_APPLIED
LOAD_PROGRAM
LOAD_LINUXCNC_GCODE_SOURCE
HOME/JOG/RUN/STEP

如果某次 frame 刷新失败,应显示错误并保留 retry 能力,不能静默永久降级。

4. D2 修复方案

目标状态

首屏不加载任何用户程序时也必须可见:

机床基准/工作台
XYZ 坐标轴
旋转轴标识
刀具/TCP marker
预览路径或占位路径

WebGL 不可用时2D fallback 也必须绘制清晰的轴线、路径和 TCP 点。

推荐设计

  1. 修复 updateToolpathPreview() 中未定义变量风险:
const toolPosition = executionToolPosition(state, previewPoints);
const fitPoints = collectFitPoints(previewPoints, executedPoints, currentSegmentPoints, toolPosition);
const fitKey = buildFitKey(...);
  1. createScene() 中加入常驻机床模型:
machineRoot
tableGroup
rotaryA/rotaryB/rotaryC visual rings
toolHolder
axisHelper
grid/reference plane
  1. 增加单独函数:
createMachineReferenceModel()
updateMachineReferenceModel(preview, state)
  1. renderFallbackPreview() 中绘制:
灰色工作台矩形
绿色/红色/蓝色 XYZ 轴
青色 TCP 点
亮色刀路 polyline
明显的 fallback 标签和点数
  1. exposePreviewDataset() 必须稳定输出:
data-three-ready=true
data-three-renderer=webgl | 2d-fallback
data-three-scene-objects > 0
data-three-path-points > 0 或 data-three-tool-execution-marker=true

可见性门槛

自动化测试应检查 canvas 像素,不只检查 DOM

nonBlackRatio > 0.02
averageLuminance > 5

5. D3 修复方案

目标状态

HOME 后执行 JOG

after HOME: X=43, Y=-32.15, Z=-11.306
after JOG X+: X=44, Y=-32.15, Z=-11.306
after JOG Y-: X=44, Y=-33.15, Z=-11.306

实际增量以 state.machine.jogIncrement 为准。

推荐设计

必须明确 task/HAL status 中 ui.axisPose 的坐标系。

推荐新增字段:

ui.axisPoseFrame = "work" | "machine" | "task-local" | "joint-local"
ui.axisPoseDelta = { x, y, z, a, b, c } // JOG 增量可选

处理规则:

  1. 如果 axisPoseFrame === "work",可直接覆盖 UI work pose。
  2. 如果 axisPoseFrame === "task-local" 且本次 motion type 是 JOG优先使用 axisPoseDelta 加到当前 state.axisPose。
  3. 如果没有 frame 标记,不允许直接覆盖非零 UI pose必须保守保留旧 pose 或走 fallback 增量。
  4. HOME 命令要把 task/HAL runtime 的参考 pose 与 UI HOME pose 同步,或者返回 axisPoseFrame="work"

短期修复方案

如果 task/HAL runtime 暂时不能增加 frame 元数据,可在 store 层先做保护:

当 status motion type 为 JOG 且 ui.axisPose 接近局部原点时,
不要整体覆盖 state.axisPose
改用本次 JOG action 的 axis/direction/increment 计算 UI pose。

为了实现这点store 需要在发送 task/HAL JOG 命令时记录 pending jog context

pendingJogCommand: { axis, direction, increment, basePose }

收到 TASK_HAL_STATUS_APPLIED 后:

axisPose = {
  ...pendingJogCommand.basePose,
  [axis]: pendingJogCommand.basePose[axis] + direction * increment
}

这是短期 UI 连续性修复;长期仍应让 runtime 明确坐标系。

6. 风险控制

风险 控制方式
D1 修复导致 fixture fallback 不可用 保留 fallback但作为显式错误/降级状态,不覆盖 desired frame source
D2 加机床模型影响性能 常驻模型低面数,路径点仍受 MAX_TOOLPATH_POINTS 限制
D3 坐标修复与真实 task/HAL 状态冲突 axisPoseFrame 标记,避免无标记状态直接覆盖
测试只在 headless 下通过 同时跑本地浏览器截图和 headless pixel 检查

7. 建议提交拆分

  1. fix: keep desired LinuxCNC kinematics frame source across async refresh
  2. fix: render visible five-axis preview model and fallback scene
  3. fix: preserve work-pose continuity for task-hal jog feedback
  4. test: add browser regression for kinematics auto-refresh preview and jog continuity