# 5 轴数控系统 Web 仿真程序具体实施文档

生成时间：2026-06-20 CST

## 1. 实施目标

本文件用于指导后续正式编写 5 轴数控系统 Web 仿真程序。第一版目标是做出一个可运行、可验证、可继续扩展的浏览器前端：

- 界面风格按 `gmoccapy_5_axis.png` 实现；
- 前端使用原生 HTML/CSS + TypeScript/JavaScript ES modules；
- 3D 预览使用 Three.js；
- G-code 执行、五轴运动学、RTCP/TCP 相关计算必须来自 LinuxCNC/WASM 或 source-derived 边界；
- 不引入 React/Vue/Angular/Svelte；
- 不把 Python GUI、GTK/Glade、Tk/OpenGLTk、native HAL process 直接作为浏览器 runtime。

## 2. 第一版完成定义

第一版完成时应具备：

- 一个可启动的 Web app；
- gmoccapy 风格布局：黑底 3D 预览、大号绿色 DRO、G-code 列表、右侧模式按钮、override/spindle/coolant 区、底部运行控制；
- 至少一个 5 轴 profile：优先 `xyzac-trt`；
- 能加载 representative G-code；
- 能显示 X/Y/Z/A/B/C、joint pose、TCP pose、RTCP state、kins type；
- Three.js 视口非空，能显示机床、刀具、刀路；
- browser smoke 能截图、检查 canvas 非空、检查关键 DOM 区域存在；
- 文档明确 LinuxCNC source references 和 unsupported runtime boundary。

## 3. 推荐目录结构

后续直接在本目录中扩展：

```text
web-rtcp-5axis-sim-plan/
  app/
    index.html
    package.json
    tsconfig.json
    src/
      main.ts
      state/
        store.ts
        events.ts
      ui/
        gmoccapy-shell.ts
        gmoccapy-dro-panel.ts
        gmoccapy-gcode-panel.ts
        gmoccapy-status-sidebar.ts
        gmoccapy-override-panel.ts
        gmoccapy-spindle-coolant-panel.ts
        gmoccapy-bottom-controls.ts
        gmoccapy-info-tabs.ts
      visualization/
        five-axis-scene.ts
        machine-model.ts
        toolpath-layer.ts
        camera-controls.ts
      runtime/
        simulation-runtime.ts
        frame-builder.ts
        playback-controller.ts
        linuxcnc-adapter.ts
      profiles/
        index.ts
        xyzac-trt.ts
        xyzbc-trt.ts
      panel-schema/
        controls.ts
        pyvcp-reference.ts
      workers/
        linuxcnc-worker.ts
      styles/
        gmoccapy.css
  core/
    linuxcnc_kinematics_wasm/
  tests/
    browser/
    node/
```

## 4. 实施顺序

### Step 1：Web shell

目标：

- 创建 `app/index.html`；
- 创建 CSS layout；
- 创建 `gmoccapy-shell.ts`；
- 页面静态呈现 gmoccapy 风格区域。

必须有的 DOM 区域：

```text
data-region="titlebar"
data-region="preview"
data-region="dro"
data-region="gcode"
data-region="status-sidebar"
data-region="info-tabs"
data-region="override"
data-region="spindle-coolant"
data-region="bottom-controls"
```

验收：

- 浏览器打开页面非空；
- 页面区域与 `gmoccapy_5_axis.png` 基本一致；
- 无 React/Vue 依赖。

### Step 2：状态模型

目标：

- 实现 `GmoccapySimulationState`；
- 实现 `createStore()`、`getState()`、`subscribe()`、`dispatch()`；
- UI 面板从 state 渲染，不直接互相读写 DOM。

初始 state：

```text
machineProfile=xyzac-trt
runState=idle
rtcpState=off
kinsType=identity
axisPose={X,Y,Z,A,B,C}
jointPose=[]
tcpPose={x,y,z,toolAxisVector}
```

验收：

- Node smoke 验证 store 更新；
- DOM renderer 能响应 state 变化。

当前 M2 已实现：

```text
app/src/runtime/rtcp-frame.js
app/src/profiles/xyzac-trt.js
tests/node/verify_rtcp_store.mjs
```

状态模型已经输出：

```text
axisPose
jointPose
tcpPose
toolAxisVector
rtcpFrame
feed
spindle
coolant
preview
operatorMessage
```

当前 RTCP frame 已支持双来源：

```text
apiName=web-rtcp-5axis-motion-frame
fixture fallback:
  sourceMode=fixture-ui-only
  semanticBoundary=fixture_frame_ui_plumbing_not_linuxcnc_kinematics_proof
  linuxCncKinematicsReady=false
  promotionAllowed=false
LinuxCNC kinematics proof:
  sourceMode=source-derived-kinematics-wasm
  semanticBoundary=linuxcnc_kinematics_wasm_c_abi
  linuxCncKinematicsReady=true
  promotionAllowed=true for kinematics frame source only
```

这表示 Web 仿真已经具备 RTCP 状态链路、TCP pose 显示、刀轴向量显示和控制按钮切换；Node 和浏览器路径均已通过 `createLinuxCncKinematicsSdk({ moduleId: "xyzac-trt" })` 加载 LinuxCNC kinematics WASM 并生成 frame，浏览器默认使用 Worker 隔离 kinematics WASM 调用。fixture fallback 仍保留为 runtime load failure 的 UI 安全路径，但 smoke 不再把 fixture fallback 当作当前 proof。

当前普通 G-code 程序执行也已接入 `createLinuxCncInterpSdk()`：

```text
sourceMode=linuxcnc-interpreter-wasm
semanticBoundary=linuxcnc_interpreter_wasm_canonical_events
RUN/STEP source=LinuxCNC canonical motion events
remapRuntimeReady=false
plannerRuntimeReady=false
fullLinuxCncProgramExecutionReady=false
```

这只提升普通 G-code canonical execution source，不代表 Python remap、tool DB、external user-M process 或完整 planner 已 promoted。

### Step 3：gmoccapy UI 组件

目标：

- DRO；
- G-code panel；
- right status sidebar；
- override panel；
- spindle/coolant panel；
- bottom controls；
- info tabs。

要求：

- 按 gmoccapy 风格做大按钮、大数字、黑底预览、灰色面板；
- 所有按钮先连接仿真 action，不连接真实机床控制；
- 文本不能溢出按钮或面板。

验收：

- browser smoke 检查关键按钮、DRO、G-code rows；
- `Run/Stop/Pause/Step` 能改变仿真 state。

当前 M2 已接入的 UI action：

```text
RUN
STOP
PAUSE
STEP
SET_KINS_TYPE
SET_VIEW
RESET_VIEW
CLEAR_PREVIEW
ADJUST_OVERRIDE
ADJUST_SPINDLE_OVERRIDE
TOGGLE_COOLANT
RELOAD_PROGRAM
HOME
TOGGLE_FULLSCREEN
```

这些 action 只改变 Web 仿真状态，不连接真实机床控制。

当前 M5 已补齐 operator workflow：

```text
TOGGLE_POWER
ESTOP
RESET
SET_MODE(auto/manual/jog/mdi)
JOG
RUN_MDI
LOAD_PROGRAM
```

实现状态：

- 右侧按钮栏提供 POWER、E-STOP、RESET、AUTO、MANUAL、JOG、MDI；
- 底部控制栏提供 Open、Run/Stop/Pause/Step/Home、JOG X/Y、MDI；
- Open 使用浏览器 FileReader 读取本地 G-code 文本并进入 `LOAD_PROGRAM`；
- G-code 面板显示当前程序来源、当前执行行和高亮行；
- preview 区域显示刀具预览卡；
- RUN/STEP 仍是 fixture line playback，不是 LinuxCNC interpreter execution proof。

### Step 4：Three.js 五轴预览

目标：

- 创建基础五轴机床模型；
- 显示坐标轴、工作空间、刀具、TCP 点、刀路；
- 支持 fit/reset/clear path。

模型优先参考：

```text
qtvismach_5axis_gantry.png
lib/python/vismach.py
src/hal/user_comps/vismach/5axisgui.py
src/hal/user_comps/vismach/xyzac-trt-gui.py
src/hal/user_comps/vismach/xyzbc-trt-gui.py
```

验收：

- canvas 非空；
- tool marker 可见；
- path points 非零；
- 视口尺寸变化不破坏布局。

当前 M3 已实现：

```text
app/src/vendor/three/three.module.js
app/src/vendor/three/three.core.js
app/src/visualization/five-axis-scene.js
```

当前 Three.js 预览会渲染基础五轴工作区、工作台、刀具/TCP marker、刀轴和刀路，并消费：

```text
tcpPose
toolAxisVector
rtcpState
rtcpFrame.apiName
preview.selectedView
programExecution.motion
programExecutionTiming.samples
programRuntimeFeedback
```

browser smoke 已检查 canvas nonblank、scene objects、path points、RTCP on/off 同步和 STEP 后 TCP pose 更新。

当前 M20 已补齐真实程序显示质量 gate：

```text
program preview=LinuxCNC interpreter canonical motion
tool execution trace=LinuxCNC TP samples or task/motion/HAL feedback
rapid/feed/arc visual layers=ready
current segment highlight=ready
path fit bounds=ready
desktop/mobile canvas nonblank=ready
threejs_generated_gcode_semantics=forbidden
```

Three.js 只按 runtime 输出的 motion/timing/feedback 绘制，不解析 G-code，不生成 CNC 运动语义。

### Step 5：profile 和 panel schema

目标：

- 建立 `xyzac-trt` profile；
- 后续补 `xyzbc-trt`；
- 把 PyVCP XML 和 HAL 绑定整理成 Web panel schema。

`xyzac-trt` 必须记录：

```text
iniPath
coordinates=XYZAC
kinematics=xyzac-trt-kins
remap=M428/M429/M430
halPins=motion.switchkins-type, xyzac-trt-kins.tool-offset, y-offset, z-offset
samplePrograms
sourceReferences
```

验收：

- Node smoke 验证 profile 完整；
- UI 能显示 profile title、coordinates、kins type、source references。

当前 M4 已实现：

```text
app/src/profiles/xyzac-trt.js
app/src/profiles/source-reference-map.js
app/src/panel-schema/xyzac-trt-pyvcp.js
tests/node/verify_profile_boundary.mjs
```

`xyzac-trt` profile 现在记录：

```text
iniPath
pyvcpXmlPath
postguiHalPath
generatedHalPath
toolTablePath
coordinates=XYZAC
kinematics=xyzac-trt-kins
sparm=identityfirst
remaps=M428/M429/M430
switchkinsTypes=identity/TCP:XYZAC/USERK
halPins
offsets
samplePrograms
sourceReferences
```

`xyzac-trt-switchkins-pyvcp` panel schema 记录 SWITCHKINS multilabel、IDENTITY/TCP:XYZAC/USERK/vismach-clear buttons、HAL nets 和对应 MDI commands。

### Step 6：LinuxCNC adapter

目标：

- 第一阶段可接现有 interpreter WASM SDK；
- 若未接入完整 WASM，则先用明确标记的 fixture frame 验证 UI，不声称 CNC semantics pass；
- 所有 runtime result 必须带 `sourceMode` 字段。

允许：

```text
sourceMode=linuxcnc-wasm
sourceMode=source-derived-kinematics-wasm
sourceMode=fixture-ui-only
```

禁止：

```text
sourceMode=js-cnc-semantics
```

验收：

- UI-only fixture 不能被标记为 LinuxCNC pass；
- LinuxCNC/WASM 接入后更新 traceability。

当前 M4 已实现 adapter 接入点：

```text
app/src/runtime/linuxcnc-boundary-adapter.js
apiName=web-rtcp-5axis-linuxcnc-boundary-adapter
readinessApi=web-rtcp-5axis-linuxcnc-boundary-readiness
semanticBoundary=adapter_entrypoint_only_runtime_not_connected | linuxcnc_kinematics_wasm_runtime_connected
linuxCncKinematicsReady=false for fixture fallback, true for loaded kinematics WASM
promotionAllowed=true only for kinematics frame source proof
fullLinuxCncProgramExecutionReady=false until interpreter/remap is connected
```

store 已输出：

```text
linuxCncBoundaryAdapter
linuxCncBoundaryReadiness
```

info tabs 和 browser smoke 会检查 adapter、panel schema、source map 和 boundary readiness。Node smoke 已验证 kinematics-only runtime ready；interpreter/remap 仍显示为 missing，不得声明 full LinuxCNC program execution ready。

### Step 7：RTCP/kinematics frame

目标：

- 定义 `FiveAxisMotionFrame`；
- 将 canonical event 和 kinematics output 转成统一 frame；
- 显示 RTCP on/off、TCP pose、tool axis vector。

M2 阶段先落地 `web-rtcp-5axis-motion-frame` 的 fixture contract，M6 阶段已加入 LinuxCNC kinematics WASM frame contract：

```text
profileId
sourceMode
semanticBoundary
activeLine
kinsType
rtcpState
axisPose
jointPose
tcpPose
toolAxisVector
compensation
readiness
```

后续 LinuxCNC/source-derived kinematics WASM 接入时，必须替换 frame builder 的运动学来源，并把 `sourceMode` 从 `fixture-ui-only` 改为明确的 LinuxCNC/WASM 边界值。
当前 Node proof 已使用 `linuxCncKinematicsResult.forward.pose` 和 `linuxCncKinematicsResult.inverse.joints` 填充 `tcpPose` / `jointPose`，并输出 `kinematicsModuleId`、forward/inverse rc、flags 和 `linuxcnc_kinematics_wasm_c_abi`。

验收：

- Node smoke：frame schema；
- Browser smoke：DRO 和 Three.js 同步显示同一 frame；
- fixture fallback 必须显示 pending；Node LinuxCNC kinematics proof 必须显示 ready；interpreter/remap 未接入时仍不得显示 full program execution ready。

### Step 8：测试和验收

至少需要：

- `git diff --check`；
- Node profile/store/frame smoke；
- Browser shell smoke；
- Browser canvas nonblank smoke；
- 文档 traceability 检查。

### Step 9：LinuxCNC TP queue timing runtime

目标：

- 删除真实 G-code 路径上的
  `linuxcnc_canonical_motion_timing_estimate_not_planner_queue` 边界；
- 将 interpreter 生成的 LinuxCNC canonical motion events 输入从
  `linuxcnc/src/emc/tp` 移植构建出的 WASM runtime；
- 用 `tpCreate()`、`tpSetCycleTime()`、`tpSetVmax()`、`tpSetVlimit()`、
  `tpSetAmax()`、`tpSetTermCond()`、`tpAddLine()`、`tpRunCycle()` 和
  `tpGetPos()` 生成程序级 queue timing；
- UI 的 elapsed/remaining/current velocity 来自 TP queue runtime 输出，而不是
  JavaScript 按距离和进给率估算。

实现步骤：

1. 在 `wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_tp_wasm.c` 新增
   `lctp_run_canonical_motion_timing()` C ABI。
2. 输入只接受 interpreter runtime 已解析出的 canonical motion JSON；C 侧只做字段读取、
   TP enqueue 和 cycle loop，不解释 G-code。
3. 在 `wasm-port/runtime/sdk/src/linuxcnc-tp.js` 新增 TP SDK，负责加载
   `build/wasm/tp/linuxcnc_tp.{js,wasm}` 并调用 C ABI。
4. 在 Web interpreter runtime 中可选接入 `createLinuxCncTpSdk()`；`runProgram()` 和
   `runMachineFileProgram()` 完成 canonical motion 后立即跑 TP queue timing。
5. `programExecution.summary.plannerRuntimeReady=true` 只在 TP runtime 调用成功且
   motionCount 一致时成立；否则保留 canonical execution，但不能把 planner timing 标为 ready。
6. `web-rtcp-5axis-full-linuxcnc-execution-boundary` 可把 `plannerRuntimeReady=true` 和
   task/motion/HAL WASM cycle artifact 作为已满足项；只有 task runtime、motion runtime、
   HAL runtime、HAL sync 和 task/HAL comparison artifact 都通过时，才允许在 Web
   simulation boundary 内标记 `nativeTaskReady=true`、`nativeHalSyncReady=true` 和
   `fullLinuxCncProgramExecutionReady=true`。该提升仍不代表 hardware drive、host realtime
   kernel、external user-M process 或 tool DB process ready。

当前边界：

```text
sourceMode=linuxcnc-interpreter-wasm
timing.semanticBoundary=linuxcnc_tp_queue_runtime_timing_from_canonical_motion
plannerRuntimeReady=true
taskHal.semanticBoundary=linuxcnc_task_motion_hal_wasm_simulation_runtime
nativeTaskReady=true for Web simulation boundary
nativeHalSyncReady=true for Web simulation boundary
fullLinuxCncProgramExecutionReady=true when machine-file remap and task/HAL gates also pass
hardwareDrive=false
hostRealtimeKernel=false
externalUserMProcessReady=false
```

### Step 10：Native task/HAL readiness artifact

目标：

- 对齐 `docs/native-task-hal-sync-implementation-steps.md` 阶段 0-8 的 source/probe/runtime 证据；
- 生成机器可读 artifact，明确 Web simulation promoted 与 host realtime/hardware/native process blocked 的区别；
- 把该 gate 接入常规 Node smoke，避免文档和 runtime readiness 字段漂移。

当前实现：

```text
app/src/runtime/native-task-hal-audit.js
tests/node/verify_native_task_hal_audit.mjs
build/readiness/native-task-hal-readiness.json
```

artifact 必须包含：

```text
status=ok
taskHalWebSimulationBoundaryConsistent=true
webSimulation.promoted=true
webSimulation.nativeTaskReady=true
webSimulation.nativeHalSyncReady=true
nativeHostAndHardware.nativePromotionAllowed=false
nativeHostAndHardware.hardwareDrive=false
nativeHostAndHardware.hostRealtimeKernel=false
nativeHostAndHardware.externalUserMProcessReady=false
nativeHostAndHardware.toolDbProcessReady=false
gates.promotion_scope=web_simulation_only
```

验收：

```text
native_task_hal_source_artifact_audit=ok
task_hal_web_simulation_boundary_consistent=1
native_task_hal_host_probe_status=passed_or_ready_disabled_by_default_or_skipped_missing_host_runtime
hardware_drive=0
host_realtime_kernel=0
external_user_m_process_ready=0
tool_db_process_ready=0
promotion_scope=web_simulation_only
```

### Step 11：LinuxCNC source program case coverage

目标：

- 以 vendored LinuxCNC TRT demo `.ngc` 为案例源，不新增 Web 侧 G-code 运动语义；
- 覆盖 `boat-xyzac.ngc`、`boat-xyzbc.ngc`、`impeller-7bl-xyzac.ngc`、
  `xyzac_switchkins*.ngc`、`xyzbc_switchkins.ngc`；
- 对可直接解释的源程序，验证 interpreter canonical motion、TP queue timing samples、
  当前 G-code 行、switchkins/RTCP 状态和 Three.js 数据源；
- 对 `o<sub> call` 入口程序，验证 machine-file staging/remap run 与 source guard，
  不把 direct interpreter 无子程序上下文时的 0 motion 当成通过。

当前实现：

```text
tests/node/verify_real_linuxcnc_5axis_program_cases.mjs
tests/browser/gmoccapy_shell_smoke.html
app/src/runtime/linuxcnc-interpreter-runtime.js
wasm-port/runtime/core/linuxcnc_wrap/linuxcnc_tp_wasm.c
```

关键约束：

```text
sourceProgramBoundary=linuxcnc_vendored_5axis_gcode_source_file
toolpathPreviewBoundary=linuxcnc_interpreter_canonical_motion
toolExecutionTraceBoundary=linuxcnc_tp_samples_or_task_motion_hal_feedback
threejsGeneratedToolpathSemantics=forbidden
fixtureToolpathFallbackPromoted=false
```

验收：

```text
linuxcnc_source_program_case_count=8
all_cases_program_preview_points=ok
all_cases_executed_path_points=ok_after_run_or_step
all_cases_toolpath_preview_source=linuxcnc_interpreter_canonical_motion
all_cases_tool_execution_trace_source=linuxcnc_tp_samples_or_task_motion_hal_feedback
all_switchkins_cases_rtcp_state_changes_verified=1
all_cases_source_guard=linuxcnc_vendored_5axis_gcode_source_file
fixture_toolpath_fallback_not_promoted=1
real_linuxcnc_5axis_program_cases_smoke=ok
```

不允许：

- 用 JS 重写 lookahead、blend、exact stop、S-curve 或 G-code modal 语义；
- 把 TP queue timing 说成已经驱动硬件；
- 把 native LinuxCNC task/NML/realtime HAL 说成已经完成；
- 对没有通过 TP runtime 的 operator MDI lightweight path 标记 planner ready。

## 5. 禁止事项

- 不在 JavaScript 中实现 G-code 解释器。
- 不在 JavaScript 中实现 LinuxCNC 五轴运动学公式作为最终语义源。
- 不把 gmoccapy Python/GTK runtime 移植进浏览器。
- 不把 Python remap/tool DB/external user-M process 伪装成已支持。
- 不用 UI fixture 结果冒充 LinuxCNC runtime proof。
- 用于 5 轴 machine-file backed run 的 G-code 必须来自 LinuxCNC 源程序目录
  `configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/*.ngc`；
  用户上传或手写的 G-code 只能作为 operator file/普通 interpreter 输入，不得标记为
  `linuxcnc-vendored-5axis-gcode` 或用于 5 轴源程序边界证明。

## 6. 开工建议

当前已完成 Step 1 到 Step 9 的 Node/browser LinuxCNC kinematics proof、浏览器 Worker kinematics 隔离、浏览器 Worker interpreter canonical execution source、`xyzac-trt`/`xyzbc-trt` profile 切换、OPFS 五轴会话保存/恢复、OPFS machine-file staging、machine-file backed `fiveAxisRemap` C ABI run、程序级 `M428/M429` switchkins RTCP 自动切换、LinuxCNC TP queue timing runtime、full execution boundary audit，以及真实 LinuxCNC TRT 5 轴 `.ngc` 源程序 staging/选择/运行路径。native task/HAL 执行文档的 Phase 0-8 已建立 Web simulation boundary：source manifest、默认禁用的 native TRT probe、HAL registry/thread scheduler、minimal motion/HAL servo-cycle C ABI、`lctask_*` task shim、SDK wrapper、machine-file session、store/UI diagnostics 和 full boundary gate。`M428/M429/M430` 当前既可作为 Web runtime switchkins 事件驱动 `lckins_switch()`，也可在 staged machine-file run 中交给 vendored LinuxCNC five-axis remap C ABI 验证，还可通过 task/HAL runtime 的 MDI path 写入 `motion.switchkins-type` HAL snapshot；只有 LinuxCNC source manifest 中的 `configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/*.ngc` 可作为 `linuxcnc-vendored-5axis-gcode` 进入 UI 和 machine-file run。`web-rtcp-5axis-full-linuxcnc-execution-boundary` 可以在 kinematics/interpreter/machine-file-remap/TP/task-HAL gates 同时通过时报告 `promotionAllowed=true`，但该提升仅限 Web simulation boundary，仍必须显示 `hardwareDrive=false`、`hostRealtimeKernel=false`、`externalUserMProcessReady=false` 和 `toolDbProcessReady=false`。

OPFS session 和 machine-file staging 当前具备 capability 检测。安全上下文且 `navigator.storage.getDirectory()` 可用时使用 OPFS；公网 HTTP/IP 或浏览器禁用 OPFS 时切换到 memory fallback。memory fallback 只保证当前页面生命周期内的保存、恢复、staging 和 full boundary audit 可继续运行，不声明跨刷新持久化。UI diagnostics 必须显示 storage mode、OPFS unavailable 状态和原因，公共 HTTP smoke 必须验证无 uncaught exception，且不依赖 OPFS 的预览、DRO、G-code 加载、运行和 Three.js 显示继续通过。

gmoccapy info tabs 当前还必须显示 Host/native boundary：`hardwareDrive=false`、`hostRealtimeKernel=false`、`externalUserMProcessReady=false`、`toolDbProcessReady=false`。browser smoke 需要同时检查 DOM 和 `fullExecutionBoundary` state，避免把 Web simulation promoted 误读为 host-native 或硬件能力 ready。

注意：`wasm-port/tests/wasm/node/verify_hal_runtime.sh`、`wasm-port/tests/wasm/node/verify_motion_hal_sync.sh`、`wasm-port/tests/wasm/node/verify_task_hal_wasm.sh` 和 `wasm-port/tests/wasm/node/verify_task_hal_sdk.sh` 会写同一个 `build/wasm/task-hal/linuxcnc_task_hal.*` 输出，验证时应串行运行，避免并发构建竞争造成无效 WASM 产物。

后续如果要越过 Web simulation boundary，必须另行实现 host realtime kernel / hardware IO / external user-M / tool DB process 证明；当前完成范围仍限定为浏览器仿真。
