From 3b01c4e428b947a979700823a51aebb8e77c4c1e Mon Sep 17 00:00:00 2001 From: wangdequan Date: Wed, 1 Jul 2026 17:31:40 -0400 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E9=BD=90=20gmoccapy=20TRT=20=E7=A4=BA?= =?UTF-8?q?=E4=BE=8B=E7=A8=8B=E5=BA=8F=E5=AF=B9=E6=A0=87=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/src/profiles/gmoccapy-xyzac-trt.js | 162 ++++ .../app/src/profiles/source-reference-map.js | 76 +- .../app/src/runtime/linuxcnc-parity-matrix.js | 3 + .../gptlog-process/gpdlog.md | 773 ++++++++++++++++++ .../node/verify_gmoccapy_xyzac_trt_parity.mjs | 188 +++++ 5 files changed, 1196 insertions(+), 6 deletions(-) create mode 100644 web-rtcp-5axis-sim-plan/app/src/profiles/gmoccapy-xyzac-trt.js create mode 100644 web-rtcp-5axis-sim-plan/tests/node/verify_gmoccapy_xyzac_trt_parity.mjs diff --git a/web-rtcp-5axis-sim-plan/app/src/profiles/gmoccapy-xyzac-trt.js b/web-rtcp-5axis-sim-plan/app/src/profiles/gmoccapy-xyzac-trt.js new file mode 100644 index 0000000..bf637fd --- /dev/null +++ b/web-rtcp-5axis-sim-plan/app/src/profiles/gmoccapy-xyzac-trt.js @@ -0,0 +1,162 @@ +import { xyzacTrtProfile } from "./xyzac-trt.js"; +import { getSourceReferencesForProfile } from "./source-reference-map.js"; + +const sourceReferenceObjects = getSourceReferencesForProfile("gmoccapy-xyzac-trt"); + +export const gmoccapyXyzacTrtProfile = { + ...xyzacTrtProfile, + id: "gmoccapy-xyzac-trt", + title: "gmoccapy XYZAC table rotary tilting", + iniPath: "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.ini", + pyvcpXmlPath: null, + postguiHalPath: "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/postgui.hal", + generatedHalPath: "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt_cmds.hal", + toolTablePath: "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.tbl", + machineName: "sim-xyzac-trt", + display: { + geometry: "XYZ-A", + display: "gmoccapy", + jogAxes: ["X", "Y", "Z", "C"], + openFile: "./examples/impeller-7bl-xyzac.ngc", + programPrefix: "../../../nc_files", + positionOffset: "RELATIVE", + positionFeedback: "ACTUAL", + maxFeedOverride: 2, + }, + rs274ngc: { + subroutinePath: "./examples:../../macros", + halPinVars: false, + parameterFile: "xyzac.var", + }, + kinematics: "xyzac-trt-kins", + kinematicsModuleId: "xyzac-trt", + kinematicsParameters: { + sparm: null, + defaultSwitchkinsType: 0, + fixedTrtDefault: true, + switchkinsTypes: [ + { value: 0, label: "XYZAC fixed TRT", mdiCommand: null, webKinsType: "tcp-xyzac" }, + { value: 1, label: "identity", mdiCommand: null, webKinsType: "identity" }, + { value: 2, label: "USERK", mdiCommand: null, webKinsType: "userk" }, + ], + }, + remaps: [ + { + code: "M6", + modalGroup: 6, + prolog: "change_prolog", + ngc: "change_g43", + epilog: "change_epilog", + path: "configs/sim/gmoccapy/macros/change_g43.ngc", + boundary: "linuxcnc_gmoccapy_tool_change_remap_reference", + }, + { + code: "M61", + modalGroup: 6, + prolog: "settool_prolog", + ngc: "settool_g43", + epilog: "settool_epilog", + path: "configs/sim/gmoccapy/macros/settool_g43.ngc", + boundary: "linuxcnc_gmoccapy_tool_set_remap_reference", + }, + ], + hal: { + halui: true, + halFiles: ["LIB:basic_sim.tcl -no_use_hal_manualtoolchange"], + postguiHalFiles: ["postgui.hal"], + postguiRequiresHalcompReady: true, + halcmd: { + loadusr: ["xyzac-trt-gui"], + feedbackNets: [ + { signal: "table-x", source: "joint.0.pos-fb", target: "xyzac-trt-gui.table-x" }, + { signal: "saddle-y", source: "joint.1.pos-fb", target: "xyzac-trt-gui.saddle-y" }, + { signal: "spindle-z", source: "joint.2.pos-fb", target: "xyzac-trt-gui.spindle-z" }, + { signal: "tilt-a", source: "joint.3.pos-fb", target: "xyzac-trt-gui.tilt-a" }, + { signal: "rotate-c", source: "joint.4.pos-fb", target: "xyzac-trt-gui.rotate-c" }, + ], + offsetNets: [ + { signal: "tool-offset", source: "motion.tooloffset.z", target: "xyzac-trt-kins.tool-offset" }, + { signal: "tool-offset", source: "xyzac-trt-kins.tool-offset", target: "xyzac-trt-gui.tool-offset" }, + { signal: "y-offset", source: "xyzac-trt-kins.y-offset", target: "xyzac-trt-gui.y-offset" }, + { signal: "z-offset", source: "xyzac-trt-kins.z-offset", target: "xyzac-trt-gui.z-offset" }, + { signal: "tool-offset", source: "motion.tooloffset.z", target: "gmoccapy.tooloffset-z" }, + ], + spindleFeedback: [ + { signal: "spindle-speed-limited", source: "spindle-speed-limited", target: "abs_spindle_feedback.in" }, + { signal: "spindle-abs", source: "abs_spindle_feedback.out", target: "gmoccapy.spindle_feedback_bar" }, + { signal: "spindle-at-speed", source: "spindle-at-speed", target: "gmoccapy.spindle_at_speed_led" }, + ], + toolChange: { + strategy: "gmoccapy-postgui-manual-toolchange", + manualGmoccapyPinsConnected: true, + postguiUnlinks: [ + "iocontrol.0.tool-change", + "iocontrol.0.tool-changed", + ], + activeLoop: { + signal: "tool-changed", + source: "gmoccapy.toolchange-changed", + target: "iocontrol.0.tool-changed", + stage: "postgui.hal", + }, + }, + initialSets: [ + { pin: "y-offset", value: 20 }, + { pin: "z-offset", value: 10 }, + ], + }, + }, + halui: { + mdiCommands: [], + }, + halPins: [ + "motion.tooloffset.z", + "xyzac-trt-kins.tool-offset", + "xyzac-trt-kins.y-offset", + "xyzac-trt-kins.z-offset", + "gmoccapy.spindle_feedback_bar", + "gmoccapy.spindle_at_speed_led", + "gmoccapy.toolchange-change", + "gmoccapy.toolchange-changed", + "gmoccapy.toolchange-number", + "gmoccapy.tooloffset-z", + ], + offsets: { + y: 20, + z: 10, + xRotPoint: 0, + yRotPoint: 0, + zRotPoint: 0, + conventionalDirections: 0, + }, + nativeRuntime: { + linuxcncsvr: true, + task: "milltask", + emcmot: "motmod", + halui: "halui", + display: "gmoccapy -ini", + taskCycleTimeSeconds: 0.010, + servoPeriodNs: 1000000, + nmlChannels: ["emcCommand", "emcStatus", "emcError"], + }, + machineFileStaging: { + machineRel: "gmoccapy/non_trivial_kinematics/table-rotary-tilting", + demoDirectory: "examples", + defaultProgramFilename: "impeller-7bl-xyzac.ngc", + wasmDir: "/work/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/gmoccapy-xyzac-trt", + }, + sourceReferences: sourceReferenceObjects.map((reference) => reference.path), + sourceReferenceObjects, + samplePrograms: [ + "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/impeller-7bl-xyzac.ngc", + "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzac.ngc", + "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzbc.ngc", + "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/test-xyzac.ngc", + "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/test-xyzbc.ngc", + ], + semanticBoundary: "linuxcnc_gmoccapy_nontrivial_xyzac_trt_profile_source_map", + linuxCncKinematicsReady: false, + tcpCapable: true, + rtcpProof: true, + promotionAllowed: false, +}; diff --git a/web-rtcp-5axis-sim-plan/app/src/profiles/source-reference-map.js b/web-rtcp-5axis-sim-plan/app/src/profiles/source-reference-map.js index 37739ba..ec0da09 100644 --- a/web-rtcp-5axis-sim-plan/app/src/profiles/source-reference-map.js +++ b/web-rtcp-5axis-sim-plan/app/src/profiles/source-reference-map.js @@ -217,15 +217,23 @@ export const linuxCncSourceReferenceMap = [ }, { id: "gmoccapy-trt-xyzac-ini", - profileId: "xyzac-trt", + profileId: "gmoccapy-xyzac-trt", kind: "ini", path: "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.ini", boundary: "linuxcnc_gmoccapy_config_reference", usage: "gmoccapy non-trivial XYZAC TRT machine config using DISPLAY=gmoccapy and xyzac-trt-gui", }, + { + id: "gmoccapy-trt-xyzac-generated-hal", + profileId: "gmoccapy-xyzac-trt", + kind: "generated_hal", + path: "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt_cmds.hal", + boundary: "generated_hal_reference", + usage: "basic_sim generated loadrt/net proof for the gmoccapy XYZAC TRT machine", + }, { id: "gmoccapy-trt-xyzac-postgui", - profileId: "xyzac-trt", + profileId: "gmoccapy-xyzac-trt", kind: "postgui_hal", path: "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/postgui.hal", boundary: "linuxcnc_gmoccapy_hal_reference", @@ -233,15 +241,39 @@ export const linuxCncSourceReferenceMap = [ }, { id: "gmoccapy-trt-xyzac-table", - profileId: "xyzac-trt", + profileId: "gmoccapy-xyzac-trt", kind: "tool_table", path: "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.tbl", boundary: "linuxcnc_gmoccapy_config_reference", usage: "gmoccapy non-trivial TRT tool table source", }, + { + id: "gmoccapy-trt-xyzac-var", + profileId: "gmoccapy-xyzac-trt", + kind: "parameter_file", + path: "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac.var", + boundary: "linuxcnc_gmoccapy_config_reference", + usage: "gmoccapy TRT parameter file staged with the machine project", + }, + { + id: "gmoccapy-trt-change-g43", + profileId: "gmoccapy-xyzac-trt", + kind: "remap_subroutine", + path: "configs/sim/gmoccapy/macros/change_g43.ngc", + boundary: "linuxcnc_gmoccapy_tool_remap_reference", + usage: "M6 change_g43 remap used by the gmoccapy TRT INI", + }, + { + id: "gmoccapy-trt-settool-g43", + profileId: "gmoccapy-xyzac-trt", + kind: "remap_subroutine", + path: "configs/sim/gmoccapy/macros/settool_g43.ngc", + boundary: "linuxcnc_gmoccapy_tool_remap_reference", + usage: "M61 settool_g43 remap used by the gmoccapy TRT INI", + }, { id: "gmoccapy-trt-impeller-demo", - profileId: "xyzac-trt", + profileId: "gmoccapy-xyzac-trt", kind: "gcode_demo", path: "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/impeller-7bl-xyzac.ngc", boundary: "linuxcnc_gmoccapy_program_reference", @@ -249,7 +281,7 @@ export const linuxCncSourceReferenceMap = [ }, { id: "gmoccapy-trt-boat-xyzac-demo", - profileId: "xyzac-trt", + profileId: "gmoccapy-xyzac-trt", kind: "gcode_demo", path: "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzac.ngc", boundary: "linuxcnc_gmoccapy_program_reference", @@ -257,12 +289,44 @@ export const linuxCncSourceReferenceMap = [ }, { id: "gmoccapy-trt-boat-xyzbc-demo", - profileId: "xyzbc-trt", + profileId: "gmoccapy-xyzac-trt", kind: "gcode_demo", path: "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzbc.ngc", boundary: "linuxcnc_gmoccapy_program_reference", usage: "gmoccapy non-trivial TRT XYZBC boat example program", }, + { + id: "gmoccapy-trt-test-xyzac-ngcgui", + profileId: "gmoccapy-xyzac-trt", + kind: "gcode_ngcgui_subroutine", + path: "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/test-xyzac.ngc", + boundary: "linuxcnc_gmoccapy_ngcgui_subroutine_reference", + usage: "gmoccapy non-trivial TRT XYZAC ngcgui subroutine example staged with the profile", + }, + { + id: "gmoccapy-trt-test-xyzbc-ngcgui", + profileId: "gmoccapy-xyzac-trt", + kind: "gcode_ngcgui_subroutine", + path: "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/test-xyzbc.ngc", + boundary: "linuxcnc_gmoccapy_ngcgui_subroutine_reference", + usage: "gmoccapy non-trivial TRT XYZBC ngcgui subroutine example staged with the profile", + }, + { + id: "gmoccapy-trt-xyzac-kins", + profileId: "gmoccapy-xyzac-trt", + kind: "kinematics_source", + path: "src/emc/kinematics/xyzac-trt-kins.c", + boundary: "linuxcnc_source_required", + usage: "source-derived XYZAC TRT kinematics backing the gmoccapy non-trivial sample", + }, + { + id: "gmoccapy-trt-trtfuncs", + profileId: "gmoccapy-xyzac-trt", + kind: "kinematics_source", + path: "src/emc/kinematics/trtfuncs.c", + boundary: "linuxcnc_source_required", + usage: "shared table-rotary-tilting kinematics functions", + }, { id: "gmoccapy-xyzab-ini", profileId: "gmoccapy-xyzab", diff --git a/web-rtcp-5axis-sim-plan/app/src/runtime/linuxcnc-parity-matrix.js b/web-rtcp-5axis-sim-plan/app/src/runtime/linuxcnc-parity-matrix.js index c0d680d..af67d54 100644 --- a/web-rtcp-5axis-sim-plan/app/src/runtime/linuxcnc-parity-matrix.js +++ b/web-rtcp-5axis-sim-plan/app/src/runtime/linuxcnc-parity-matrix.js @@ -107,12 +107,15 @@ export const LINUXCNC_PARITY_ITEMS = [ "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/impeller-7bl-xyzac.ngc", "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzac.ngc", "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/boat-xyzbc.ngc", + "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/test-xyzac.ngc", + "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/test-xyzbc.ngc", ], functions: [ "DISPLAY gmoccapy", "POSTGUI spindle/tool HAL bindings", "xyzac-trt-gui vismach feedback pins", "gmoccapy TRT example programs", + "gmoccapy TRT ngcgui subroutine examples", ], }, { diff --git a/web-rtcp-5axis-sim-plan/gptlog-process/gpdlog.md b/web-rtcp-5axis-sim-plan/gptlog-process/gpdlog.md index 2e11782..a71ea69 100644 --- a/web-rtcp-5axis-sim-plan/gptlog-process/gpdlog.md +++ b/web-rtcp-5axis-sim-plan/gptlog-process/gpdlog.md @@ -9199,3 +9199,776 @@ nginx: configuration file /etc/nginx/nginx.conf test is successful - 已在界面诊断区展示矩阵摘要。 - 已补充中文文档 `docs/linuxcnc-parity-matrix.md`。 - 已新增并接入 smoke 测试,完整 Node smoke、浏览器 smoke 和构建均通过。 + +--- + +## GPT/Codex 执行过程日志 - 2026-07-01 08:25:03 EDT + +用户请求:将当前 Web-RTCP 五轴数控仿真系统相关修改提交到云仓库 `http://154.8.160.151:3000`,账号为 `wangdequan`。 + +本轮执行过程: + +1. 检查 Git 仓库状态: + - 当前仓库根目录:`/home/meswork/cnc_wams`。 + - 当前分支:`master`。 + - 当前远端:`origin http://154.8.160.151:3000/wangdequan/cnc_wams`。 + - 当前 HEAD 起点:`1e66f17 记录 HTTPS 服务器发布过程`。 + - 工作树中存在较多未提交文件,包括 QA 截图输出、`.vscode/`、`work/working7/`、Office 临时 lock 文件和 Web-RTCP 应用相关修改。 + +2. 确认提交范围: + - 为避免把无关输出提交到云端,未使用 `git add .`。 + - 选择性暂存 Web-RTCP 应用代码、测试、文档、新版手册、手册截图素材和执行日志。 + - 明确排除以下未提交内容: + - `qa/web-rtcp-5axis-site-test` 下的截图和站点测试输出。 + - `.vscode/`。 + - `work/working7/`。 + - `web-rtcp-5axis-sim-plan/docs/.~lock...docx#` Office 临时锁文件。 + - 其他与本次 Web-RTCP LinuxCNC 对标提交无直接关系的未跟踪文件。 + +3. 暂存的主要文件: + - `web-rtcp-5axis-sim-plan/app/index.html` + - `web-rtcp-5axis-sim-plan/app/package.json` + - `web-rtcp-5axis-sim-plan/app/package-lock.json` + - `web-rtcp-5axis-sim-plan/app/scripts/build-static.mjs` + - `web-rtcp-5axis-sim-plan/app/src/main.js` + - `web-rtcp-5axis-sim-plan/app/src/profiles/source-reference-map.js` + - `web-rtcp-5axis-sim-plan/app/src/runtime/linuxcnc-ini-runtime.js` + - `web-rtcp-5axis-sim-plan/app/src/runtime/linuxcnc-machine-file-staging.js` + - `web-rtcp-5axis-sim-plan/app/src/runtime/linuxcnc-parity-matrix.js` + - `web-rtcp-5axis-sim-plan/app/src/state/store.js` + - `web-rtcp-5axis-sim-plan/app/src/styles/gmoccapy.css` + - `web-rtcp-5axis-sim-plan/app/src/ui/gmoccapy-shell.js` + - `web-rtcp-5axis-sim-plan/tests/browser/gmoccapy_shell_smoke.html` + - `web-rtcp-5axis-sim-plan/tests/node/verify_rtcp_store.mjs` + - `web-rtcp-5axis-sim-plan/tests/node/verify_gmoccapy_trt_project_sidebar.mjs` + - `web-rtcp-5axis-sim-plan/tests/node/verify_linuxcnc_parity_matrix.mjs` + - `web-rtcp-5axis-sim-plan/docs/linuxcnc-parity-matrix.md` + - `web-rtcp-5axis-sim-plan/docs/Web-RTCP五轴数控系统仿真界面操作手册.docx` + - `web-rtcp-5axis-sim-plan/docs/Web-RTCP五轴数控系统仿真界面操作手册新版.docx` + - `web-rtcp-5axis-sim-plan/docs/manual-assets/` 下的 11 张操作手册截图素材。 + - `web-rtcp-5axis-sim-plan/gptlog-process/gpdlog.md`。 + +4. 提交前检查: + - 查看 `git diff --cached --name-status`,确认暂存列表未包含 QA 输出、`.vscode/`、`work/working7/` 和 Office lock 文件。 + - 查看 `git diff --cached --stat`,暂存内容为 31 个文件,包含代码、测试、文档、docx、截图素材和日志。 + - 执行 `git fetch origin master`,确认远端可访问,未发现远端分支前移冲突。 + +5. 创建本地提交: + - 执行命令:`git commit -m "完善 LinuxCNC 对标矩阵与 gmoccapy TRT 仿真"`。 + - 生成提交:`9803aad 完善 LinuxCNC 对标矩阵与 gmoccapy TRT 仿真`。 + - 提交统计:31 个文件变更,3966 行新增,104 行删除。 + - 新增文件包括: + - `app/src/runtime/linuxcnc-parity-matrix.js` + - `tests/node/verify_gmoccapy_trt_project_sidebar.mjs` + - `tests/node/verify_linuxcnc_parity_matrix.mjs` + - `docs/linuxcnc-parity-matrix.md` + - 新版 Word 操作手册、原手册 docx、手册截图素材、`package-lock.json`。 + +6. 推送到云仓库: + - 首次执行 `git push origin master` 失败,原因是非交互环境无法读取 HTTP 用户名:`fatal: could not read Username for 'http://154.8.160.151:3000': No such device or address`。 + - 随后使用用户提供的账号通过一次性 HTTP Basic Authorization header 推送;未把密码写入 Git remote URL,避免持久化到 `.git/config`。 + - 推送命令执行成功。 + - 远端输出:`1e66f17..9803aad master -> master`。 + - 当前 `git log --oneline -3 --decorate` 显示: + - `9803aad (HEAD -> master, origin/master, origin/HEAD) 完善 LinuxCNC 对标矩阵与 gmoccapy TRT 仿真` + - `1e66f17 记录 HTTPS 服务器发布过程` + - `d6992af 记录云仓库同步过程` + +7. 推送后状态: + - 代码和文档提交已经同步到云仓库 `origin/master`。 + - 工作树仍保留未提交的无关文件,主要是 QA 站点测试输出、截图、`.vscode/`、`work/working7/`、Office 临时 lock 文件和其他未跟踪备忘文件。 + - 这些文件未被提交,也未被推送。 + +最终结果: + +- 已成功提交并推送到云仓库。 +- 云端最新提交为:`9803aad 完善 LinuxCNC 对标矩阵与 gmoccapy TRT 仿真`。 +- 远端地址为:`http://154.8.160.151:3000/wangdequan/cnc_wams`。 +- 用户提供的密码未写入远端配置。 + +--- + +本轮执行过程: + +1. 接收任务: + - 用户要求讲解 `/home/meswork/cnc_wams/web-rtcp-5axis-sim-plan/docs` 目录中每个文件的作用。 + - 用户要求把详细讲解写入文档,并编写关联流程图。 + - 当前工作目录为 `/home/meswork/cnc_wams`。 + - 按工作区 `AGENTS.md` 要求,本次过程日志需要在执行结束前追加到 `web-rtcp-5axis-sim-plan/gptlog-process/gpdlog.md`,且日志使用中文记录。 + +2. 目录盘点: + - 执行 `find web-rtcp-5axis-sim-plan/docs -maxdepth 3 -type f | sort`,确认 `docs` 目录包含 Markdown 规划/参考/追溯文档、两个 Word 操作手册、一个 LibreOffice lock 文件和 `manual-assets` 截图资产。 + - 执行 `find web-rtcp-5axis-sim-plan/docs -maxdepth 3 -type d | sort`,确认目录层级为 `docs` 和 `docs/manual-assets`。 + - 执行 `git status --short`,发现工作树已有多处与本任务无关的修改和未跟踪文件,包括 QA 输出、`.vscode/`、`work/working7/`、备忘文件以及既有日志修改。本轮未回滚这些已有改动。 + +3. Markdown 文档结构分析: + - 对 `docs/*.md` 执行标题扫描,读取每个 Markdown 的一级、二级、三级标题。 + - 执行 `wc -l web-rtcp-5axis-sim-plan/docs/*.md`,确认主要文档规模: + - `development-continuation.md` 1067 行。 + - `traceability-matrix.md` 1460 行。 + - `native-task-hal-sync-implementation-steps.md` 803 行。 + - `program-implementation-guide.md` 632 行。 + - `technical-roadmap.md` 547 行。 + - 其他参考文档为 55 到 396 行不等。 + - 执行 `file` 检查文件类型和 `manual-assets` 图片尺寸,确认 Word 文件为 Microsoft OOXML,截图为 PNG。 + - 检查 `pandoc`、`libreoffice`、`unzip` 可用性,确认系统存在 `/usr/bin/libreoffice` 和 `/usr/bin/unzip`。 + +4. 核心方案文档阅读: + - 分段读取 `implementation-plan.md`,提取项目定位、当前基础、LinuxCNC 参考案例、Python GUI 参考范围、四层总体架构、RTCP 功能定义、数据模型、Phase 0 到 Phase 6、风险和结论。 + - 分段读取 `technical-roadmap.md`,提取技术栈、目录建议、gmoccapy Web 实现方案、核心模块拆分、LinuxCNC 源码接入路线、RTCP 数据流、测试路线、里程碑和验收标准。 + - 分段读取 `program-implementation-guide.md`,提取 Step 1 到 Step 11 的实施顺序、当前完成状态、Three.js 显示边界、TP queue timing、Native task/HAL readiness artifact、真实 LinuxCNC 源程序案例覆盖和禁止事项。 + - 分段读取 `native-task-hal-sync-implementation-steps.md`,提取目标边界、LinuxCNC 源文件清单、推荐架构、textbak 可复用结论、阶段 0 到阶段 8、详细编程顺序、验收测试矩阵和完成定义。 + +5. 参考和追溯文档阅读: + - 读取 `linuxcnc-python-gui-reference.md`,分析 AXIS、vismach、PyVCP、gmoccapy、QtVCP/QtDragon 对 Web UI、Three.js 和 panel schema 的参考关系。 + - 读取 `linuxcnc-gui-reference-gallery.md`,确认当前界面选择为 `gmoccapy 5 Axis + QtVismach 5 Axis Gantry + PyVCP SWITCHKINS`。 + - 读取 `linuxcnc-parity-matrix.md`,确认当前对标的 LinuxCNC 配置、真实五轴 G-code 程序、已承接功能和浏览器仿真边界。 + - 读取 `gmoccapy-xyzab-reference.md`,确认 `gmoccapy_XYZAB.ini` 是 trivkins reference profile,不是 TCP/RTCP proof。 + - 分段读取 `development-continuation.md`,重点分析“最新接续基线”、M18 到 M22、Three.js 当前状态、OPFS 降级和 Host/native 边界可见性。 + - 分段读取 `traceability-matrix.md`,提取总体追溯表、源文件追溯清单、边界状态、开发追溯记录模板、native-task-hal、M18、M19、M20、M21、M22 追溯记录。 + +6. Word 操作手册内容抽取: + - 创建临时目录 `/tmp/cnc_docs_extract`。 + - 使用 `libreoffice --headless --convert-to txt:Text --outdir /tmp/cnc_docs_extract ...` 把两个 `.docx` 操作手册转换为文本。 + - 同时使用 `unzip -p word/document.xml` 抽取 XML 正文,辅助确认转换内容。 + - 读取旧版手册正文,确认它覆盖系统定位、安全边界、界面区域、上电/回零、AUTO、MANUAL、MDI、RTCP/IDENTITY/TCP、倍率、主轴、冷却、会话、诊断和常见问题。 + - 读取新版手册正文,确认它强化 LinuxCNC 对标范围、右侧九入口互锁、标准运行流程、刀具预览路径来源、真实五轴程序来源、项目目录/INI/HAL/tool table/remap 对标、诊断和验证记录。 + - 使用 `unzip -l word/media/*` 确认两个 Word 手册均内嵌 10 张图片。 + +7. 文件元数据和关联关系检查: + - 执行 `stat -c '%n|%s|%y' ...`,记录 `docs` 文件和截图资产的大小、更新时间。 + - 执行 `rg` 搜索文档间引用关系,确认 README、development-continuation、technical-roadmap、traceability-matrix、program-implementation-guide 等文件之间的引用。 + - 对 LibreOffice lock 文件执行 `xxd`,确认其内容为用户、主机、时间和 LibreOffice 配置路径,不属于正式项目文档。 + +8. 编写新增讲解文档: + - 新增文件 `web-rtcp-5axis-sim-plan/docs/docs-directory-file-guide.md`。 + - 文档标题为 `docs 目录文件作用详解与关联流程图`。 + - 文档内容包括: + - `docs` 文档集定位。 + - 推荐阅读顺序。 + - 文件总览表。 + - 每个 Markdown 文件的详细作用说明。 + - 两个 Word 操作手册的详细说明。 + - `manual-assets` 11 张截图的作用表。 + - LibreOffice lock 文件说明。 + - 4 个 Mermaid 流程图: + - 文档分层关系图。 + - LinuxCNC 来源到 Web 仿真的关联流程图。 + - 操作流程关联图。 + - Native Task/HAL 专项流程图。 + - 文档维护建议。 + - 快速查找表。 + - 新增文档没有修改原有方案、路线、追溯和手册文件。 + +9. 校验新增文档: + - 执行 `wc -l web-rtcp-5axis-sim-plan/docs/docs-directory-file-guide.md`,确认新增文档为 553 行。 + - 执行 `sed -n '1,80p'` 检查开头、目录定位、文件总览表。 + - 执行 `rg` 检查 Mermaid 代码块、手册链接和 `manual-assets` 引用。 + - 执行 `git diff --check -- web-rtcp-5axis-sim-plan/docs/docs-directory-file-guide.md`,结果无输出,未发现尾随空白或 diff 检查错误。 + - 注意:因为新增文档是未跟踪文件,执行 `git diff -- web-rtcp-5axis-sim-plan/docs/docs-directory-file-guide.md` 没有输出,这是 Git 对未暂存未跟踪文件的正常行为。 + +10. 最终状态检查: + - 执行 `git status --short web-rtcp-5axis-sim-plan/docs web-rtcp-5axis-sim-plan/gptlog-process/gpdlog.md`。 + - 结果显示: + - `web-rtcp-5axis-sim-plan/docs/docs-directory-file-guide.md` 为新增未跟踪文件。 + - `web-rtcp-5axis-sim-plan/gptlog-process/gpdlog.md` 有修改,本轮按规则追加日志。 + - `docs/.~lock.Web-RTCP五轴数控系统仿真界面操作手册.docx#` 仍为未跟踪 LibreOffice 临时锁文件,本轮未删除。 + +最终结果: + +- 已完成 `docs` 目录每个文件作用的详细讲解。 +- 已写入新文档:`web-rtcp-5axis-sim-plan/docs/docs-directory-file-guide.md`。 +- 新文档已包含 4 个 Mermaid 关联流程图。 +- 已执行 Markdown 基础检查和 `git diff --check`,未发现格式错误。 +- 未运行项目 Node/browser/WASM 测试,因为本轮只新增说明文档,不涉及运行时代码修改。 + +--- + +本轮执行过程: + +1. 接收任务: + - 用户先要求把刚刚输出的 Markdown 说明文档转换成 Word,方便阅读。 + - 随后用户中断该轮,改为要求安装 Pandoc。 + - 用户再次中断后提供 sudo 密码,并要求配置 sudo 免密。 + - 本轮最终执行目标调整为:配置 sudo 免密、安装 Pandoc、验证 Pandoc,并顺手把 `docs-directory-file-guide.md` 转成 Word 文档。 + +2. 初始检查: + - 执行 `which pandoc || true`,确认系统原本没有 Pandoc。 + - 执行 `which libreoffice || true`,确认存在 `/usr/bin/libreoffice`。 + - 执行 `ls -l web-rtcp-5axis-sim-plan/docs/docs-directory-file-guide.md`,确认待转换 Markdown 存在。 + - 执行 `git status --short web-rtcp-5axis-sim-plan/docs web-rtcp-5axis-sim-plan/gptlog-process/gpdlog.md`,确认新增 Markdown 文档和日志文件状态。 + +3. sudo 与系统环境检查: + - 执行 `cat /etc/os-release`,确认系统为 Ubuntu 22.04.5 LTS。 + - 执行 `id`,确认当前用户为 `meswork`,属于 `sudo` 组。 + - 执行 `command -v apt-get || true`,确认系统包管理器为 `/usr/bin/apt-get`。 + - 执行 `sudo -n true`,确认当时 sudo 仍需要密码。 + - 执行 `uname -m`,确认架构为 `x86_64`。 + - 执行 `command -v curl/wget/tar`,确认这些工具存在。 + - 执行 `printf '%s\n' "$PATH"`,确认 `/home/meswork/.local/bin` 已在 PATH 中。 + +4. 配置 sudo 免密: + - 第一次使用 `sudo -k && sudo -v` 在 PTY 中触发 sudo 密码输入,用户已提供密码。 + - 后续发现 sudo 凭据只在输入密码的 PTY 会话中有效,非 PTY 命令仍提示需要密码。 + - 改用 PTY 执行: + `sudo sh -c 'printf "%s\n" "meswork ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/90-meswork-nopasswd && chmod 0440 /etc/sudoers.d/90-meswork-nopasswd && visudo -cf /etc/sudoers.d/90-meswork-nopasswd'` + - 系统再次要求 sudo 密码,使用用户提供的密码完成配置。 + - `visudo` 输出 `/etc/sudoers.d/90-meswork-nopasswd: parsed OK`,说明 sudoers 语法正确。 + - 执行 `sudo -n true && printf 'sudo_nopasswd=ok\n'`,确认免密 sudo 已生效。 + - 执行 `sudo -n cat /etc/sudoers.d/90-meswork-nopasswd`,确认规则为 `meswork ALL=(ALL) NOPASSWD:ALL`。 + - 未把用户提供的密码写入日志正文或持久配置文件。 + +5. 安装 Pandoc: + - 执行 `sudo apt-get update && sudo apt-get install -y pandoc`。 + - `apt-get update` 从 Ubuntu、NodeSource、Google Chrome、Microsoft VS Code 等源更新包索引。 + - `apt-get install` 安装以下新包: + - `libcmark-gfm0.29.0.gfm.3` + - `libcmark-gfm-extensions0.29.0.gfm.3` + - `pandoc-data` + - `pandoc` + - 安装完成后系统显示 Pandoc 已设置完成,并处理了 `man-db` 和 `libc-bin` 触发器。 + +6. 验证 Pandoc: + - 执行 `pandoc --version | sed -n '1,3p'`。 + - 输出确认版本为 `pandoc 2.9.2.1`。 + - 同时输出 Pandoc 编译库版本和默认用户数据目录。 + +7. 转换 Word 文档: + - 执行: + `pandoc web-rtcp-5axis-sim-plan/docs/docs-directory-file-guide.md -o web-rtcp-5axis-sim-plan/docs/docs-directory-file-guide.docx --standalone` + - 生成 Word 文件: + `web-rtcp-5axis-sim-plan/docs/docs-directory-file-guide.docx` + - 执行 `ls -lh`,确认: + - Markdown 文件大小约 27K。 + - Word 文件大小约 25K。 + - 执行 `file web-rtcp-5axis-sim-plan/docs/docs-directory-file-guide.docx`,确认类型为 `Microsoft Word 2007+`。 + - 执行 `unzip -l ...docx | sed -n '1,30p'`,确认 `.docx` 内含 `[Content_Types].xml`、`word/document.xml`、样式、编号、主题等 Word 结构文件。 + +8. 最终状态: + - 执行 `git status --short web-rtcp-5axis-sim-plan/docs web-rtcp-5axis-sim-plan/gptlog-process/gpdlog.md`。 + - 当前新增未跟踪文件: + - `web-rtcp-5axis-sim-plan/docs/docs-directory-file-guide.md` + - `web-rtcp-5axis-sim-plan/docs/docs-directory-file-guide.docx` + - 当前修改文件: + - `web-rtcp-5axis-sim-plan/gptlog-process/gpdlog.md` + - 本轮未删除任何已有文件,未运行项目 Node/browser/WASM 测试。 + +最终结果: + +- 已配置 `meswork` 用户 sudo 免密,规则文件为 `/etc/sudoers.d/90-meswork-nopasswd`。 +- 已安装 Pandoc,版本为 `pandoc 2.9.2.1`。 +- 已把 Markdown 说明文档转换为 Word: + `web-rtcp-5axis-sim-plan/docs/docs-directory-file-guide.docx`。 + +--- + +本轮执行过程: + +1. 接收任务: + - 用户要求把项目相关的“关系图”使用高清晰 PNG 绘制出来。 + - 目标来源为上一轮新增文档 `web-rtcp-5axis-sim-plan/docs/docs-directory-file-guide.md` 中的 Mermaid 关系图。 + +2. 工具检查: + - 执行 `command -v mmdc || true`,确认 Mermaid CLI 已存在于 `/home/meswork/.local/bin/mmdc`。 + - 执行 `mmdc --version`,确认版本为 `11.15.0`。 + - 执行 `command -v node/npm`,确认 Node 和 npm 可用,Node 版本为 `v22.23.0`,npm 版本为 `10.9.8`。 + - 执行 `command -v chromium-browser || command -v chromium || command -v google-chrome || true`,确认可用浏览器为 `/usr/bin/google-chrome`。 + - 执行 `rg -n '^```mermaid|^```$' docs-directory-file-guide.md`,确认文档中有 4 个 Mermaid 图块。 + +3. 抽取 Mermaid 源文件: + - 创建目录 `web-rtcp-5axis-sim-plan/docs/diagram-assets`。 + - 使用 `awk` 从 `docs-directory-file-guide.md` 中抽取 4 个 Mermaid 代码块。 + - 先生成临时文件 `diagram-01.mmd` 到 `diagram-04.mmd`。 + - 随后重命名为有语义的文件: + - `01-docs-layer-relationship.mmd` + - `02-linuxcnc-to-web-simulation-flow.mmd` + - `03-operator-workflow.mmd` + - `04-native-task-hal-flow.mmd` + +4. 渲染配置: + - 创建临时 Puppeteer 配置 `/tmp/mmdc-puppeteer.json`,指定 Chrome 路径为 `/usr/bin/google-chrome`,并添加 `--no-sandbox`、`--disable-setuid-sandbox`、`--disable-dev-shm-usage` 参数。 + - 创建临时 Mermaid 配置 `/tmp/mermaid-config.json`,设置白底、base theme、较大字体、节点间距和边距,以提高 PNG 可读性。 + +5. 生成高清 PNG: + - 对 4 个 `.mmd` 文件逐个执行 `mmdc`。 + - 使用参数: + - 输出格式:PNG。 + - 背景:白色。 + - 画布:`2400 x 1600`。 + - 缩放:`scale=2`。 + - 成功生成: + - `web-rtcp-5axis-sim-plan/docs/diagram-assets/01-docs-layer-relationship.png` + - `web-rtcp-5axis-sim-plan/docs/diagram-assets/02-linuxcnc-to-web-simulation-flow.png` + - `web-rtcp-5axis-sim-plan/docs/diagram-assets/03-operator-workflow.png` + - `web-rtcp-5axis-sim-plan/docs/diagram-assets/04-native-task-hal-flow.png` + +6. 图片检查: + - 执行 `file diagram-assets/*.png`,确认 4 张图片均为 PNG。 + - 4 张 PNG 尺寸分别为: + - `01-docs-layer-relationship.png`:3666 x 2588。 + - `02-linuxcnc-to-web-simulation-flow.png`:4768 x 1684。 + - `03-operator-workflow.png`:2110 x 3746。 + - `04-native-task-hal-flow.png`:4756 x 3320。 + - 执行 `identify diagram-assets/*.png`,确认图像尺寸、颜色空间和文件大小正常。 + - 使用 Python/Pillow 对 4 张图片做采样像素统计,非白像素比例均大于 0,确认不是空白图。 + - 使用本地图片查看工具抽检 `02-linuxcnc-to-web-simulation-flow.png`,确认布局正常、文字可读。 + +7. 回写说明文档并重新生成 Word: + - 更新 `docs-directory-file-guide.md`,在 4 个 Mermaid 图标题下方分别加入高清 PNG 图片引用。 + - 重新执行 Pandoc: + `pandoc docs-directory-file-guide.md -o docs-directory-file-guide.docx --standalone --resource-path=web-rtcp-5axis-sim-plan/docs` + - 执行 `unzip -l docs-directory-file-guide.docx word/media/*`,确认 Word 文档中已嵌入 4 张 PNG 图片。 + - 重新生成后的 `docs-directory-file-guide.docx` 大小约 1.1M。 + +8. 格式检查: + - 执行 `git diff --check -- docs-directory-file-guide.md gptlog-process/gpdlog.md`,未发现格式错误。 + +最终结果: + +- 已生成 4 张高清 PNG 关系图,保存在 `web-rtcp-5axis-sim-plan/docs/diagram-assets/`。 +- 已保留对应 Mermaid 源文件 `.mmd`,便于后续维护。 +- 已把 4 张 PNG 链接写入 `docs-directory-file-guide.md`。 +- 已重新生成 `docs-directory-file-guide.docx`,Word 文档中已嵌入 4 张高清 PNG。 + +## 2026-07-01 Codex 执行过程日志:受控 external user-M/tool DB Web 仿真实施 + +1. 任务理解与边界确认: + - 用户要求对标 `/home/meswork/cnc_wams/linuxcnc` 源程序,把红框中的 `external user-M/tool DB process` 纳入 `/home/meswork/cnc_wams/web-rtcp-5axis-sim-plan/docs` 相关文件,并按文件实施。 + - 采用两步方案:先做 tool DB Web/WASM simulation,再做受控 user-M simulation。 + - 明确边界:只允许 `web_simulation_only`;不执行任意 host 系统脚本;不启用 host tool DB process;不声明真实硬件、host realtime kernel 或任意外部 user-M 进程 ready。 + +2. LinuxCNC 源码与现有项目对标: + - 查阅并对照 LinuxCNC tool/task 语义:`linuxcnc/src/emc/task/taskclass.cc`、`taskclass.hh`、`tooldata/*`、`emc.hh`。 + - 查阅 TRT 示例 tool table:`configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.tbl`、`xyzbc-trt.tbl`。 + - 查阅受控 user-M/remap 相关来源:`remap_subs/428remap.ngc`、`429remap.ngc`、`430remap.ngc`,以及 interpreter/task/canon 相关目录。 + - 梳理现有 Web 项目边界:`full-execution-boundary.js` 原先把 `externalUserMProcessReady` 和 `toolDbProcessReady` 固定为 false;gmoccapy info tabs 原先显示 external user-M/tool DB false。 + +3. 新增 tool DB Web/WASM 仿真模块: + - 新增 `app/src/runtime/tool-db-simulation.js`。 + - 实现 LinuxCNC `tool.tbl` 文本解析,支持 `T/P/X/Y/Z/A/B/C/U/V/W/D/I/J/Q` 字段和注释。 + - 实现 tool table 序列化,支持保存 edited tool table。 + - 实现 `createToolDbSimulation()`,输出 `processScope=web_simulation_only`、`hostProcessReady=false`、`hostProcessExecution=false`。 + - 实现 `Tn` prepare、`M6` load、`G43` tool length offset、`M61 Qn` tool number 设定的仿真状态。 + - 实现刀具号、刀袋、刀长、刀径编辑能力,并通过 OPFS/memory compatible storage 保存。 + - 实现程序扫描 `extractToolCommandSequenceFromProgram()`,只识别 `Tn/M6/G43/M61 Qn` 相关命令。 + +4. 新增受控 user-M 仿真模块: + - 新增 `app/src/runtime/controlled-user-m-simulation.js`。 + - 建立白名单 `M428/M429/M430/M128/M129`。 + - `M428` 映射为 TCP/switchkins type 1 和 RTCP on;`M429` 映射为 identity/type 0;`M430` 映射为 userk/type 2;`M128/M129` 映射为受控 millturn 参考事件。 + - 未在白名单内的 user-M 事件标记为 `arbitrary_external_user_m_blocked`,不产生 host 执行。 + - 输出 HAL/state patch,例如 `motion.switchkins-type`、`motion.analog-out-03` 和 `kinsType/rtcpState`。 + +5. 接入应用状态与 UI: + - 修改 `app/src/state/store.js`,新增 `toolDbSimulation`、`toolDbReadiness`、`controlledUserMSimulation`、`controlledUserMReadiness`。 + - machine-file staging 完成后自动查找当前 profile 对应 staged `tool.tbl` 并解析为 Web tool DB。 + - 加载 LinuxCNC source G-code 后扫描 tool commands 和受控 user-M 事件,写入状态 snapshot。 + - 新增 `RUN_CONTROLLED_USER_M` action,供受控 user-M 行为以状态事件形式触发。 + - 修改 `app/src/ui/gmoccapy-shell.js`,在 Info Tabs 中新增 `Tool/User process` 诊断行,显示 tool DB/user-M readiness、tool count、事件数、blocked 数。 + - 修改 Host/native 文案,显示 `external user-M web simulation only`、`tool DB web simulation only`,同时继续显示 `host external user-M false`、`host tool DB false`、`arbitrary user-M false`。 + +6. 修改 full boundary 与 native audit: + - 修改 `app/src/runtime/full-execution-boundary.js`,把 `toolDbProcessReady=true` 和 `externalUserMProcessReady=true` 作为 Web simulation full boundary 的必要 gate。 + - 新增 `toolDbProcessScope=web_simulation_only`、`externalUserMProcessScope=web_simulation_only`、`hostExternalUserMProcessReady=false`、`hostToolDbProcessReady=false`、`arbitraryUserMExecution=false`。 + - 修改 blockers 和 evidence,避免把 Web 仿真 ready 误读为 host/native process ready。 + - 修改 `app/src/runtime/native-task-hal-audit.js`,新增 `toolUserWebSimulation` 分组;Web tool/user gate 为 1,host tool/user gate 保持 0。 + +7. 新增和更新测试: + - 新增 `tests/node/verify_tool_db_user_m_simulation.mjs`,覆盖 tool table 解析、`T2/M6/G43`、`M61`、编辑保存、白名单 user-M、未知 user-M blocked。 + - 修改 `tests/node/verify_full_execution_boundary.mjs`,断言 Web tool/user ready 为 true,host tool/user false。 + - 修改 `tests/node/verify_machine_file_staging.mjs`,断言 staged `xyzac-trt.tbl` 被自动解析为 Web tool DB。 + - 修改 `tests/node/verify_native_task_hal_audit.mjs`,断言 `toolUserWebSimulation` ready,host process false。 + - 修改 `tests/browser/gmoccapy_shell_smoke.html`,断言 UI 显示 Web simulation only 与 host false。 + - 修改 `app/package.json`,把 `verify_tool_db_user_m_simulation.mjs` 接入 `smoke:node`。 + +8. 文档更新: + - 新增 `docs/external-user-m-tool-db-simulation-plan.md` 和对应 Word `external-user-m-tool-db-simulation-plan.docx`。 + - 更新 `implementation-plan.md`,明确任意 host user-M 和 host tool DB 仍禁止,staged tool DB/白名单 user-M 只属于 Web 仿真。 + - 更新 `program-implementation-guide.md`,加入 Step 10 当前状态、tool/user Web simulation gate、host false 边界。 + - 更新 `native-task-hal-sync-implementation-steps.md`,把 `externalUserMProcessReady/toolDbProcessReady` 改为 `true for web_simulation_only`,并新增 host false 字段。 + - 更新 `development-continuation.md`,新增 M23 接续记录和当前最新基线。 + - 更新 `traceability-matrix.md`,把 tool DB runtime / external user-M process 当前状态改为 Web simulation only,并追加 M23 追溯记录。 + - 更新 `linuxcnc-parity-matrix.md`,新增 Tool DB/task tool state 与 controlled user-M/remap 对标行。 + - 更新 `docs-directory-file-guide.md`,加入新专项文档说明、M23 状态、图中 Tool DB/User-M 节点。 + +9. 关系图和 Word 输出: + - 修改 `docs/diagram-assets/02-linuxcnc-to-web-simulation-flow.mmd`,把原红框排除项改为 `tool DB + controlled user-M Web simulation`,并标注不执行任意 host user-M 脚本、不提升 host tool DB process。 + - 修改 `03-operator-workflow.mmd`,新增 `Tool DB/User-M Web simulation` 诊断节点。 + - 修改 `04-native-task-hal-flow.mmd`,新增 `toolDbProcessReady=true web_simulation_only` 和 `externalUserMProcessReady=true web_simulation_only`,并保留 host false/arbitrary false。 + - 使用 `/home/meswork/.local/bin/mmdc` 按 3 倍缩放重新生成高清 PNG:`02-linuxcnc-to-web-simulation-flow.png`、`03-operator-workflow.png`、`04-native-task-hal-flow.png`。 + - 使用 Pandoc 重新生成 `docs-directory-file-guide.docx`,并检查 docx 包内包含 4 张 `word/media/*.png` 图片。 + - 使用 Pandoc 生成 `external-user-m-tool-db-simulation-plan.docx`。 + +10. 验证命令与结果: + - `node web-rtcp-5axis-sim-plan/tests/node/verify_tool_db_user_m_simulation.mjs`:通过。 + - `node web-rtcp-5axis-sim-plan/tests/node/verify_full_execution_boundary.mjs`:通过。 + - `node web-rtcp-5axis-sim-plan/tests/node/verify_machine_file_staging.mjs`:通过。 + - `node web-rtcp-5axis-sim-plan/tests/node/verify_gmoccapy_trt_project_sidebar.mjs`:通过。 + - `npm --prefix web-rtcp-5axis-sim-plan/app run smoke:node`:通过,输出 `external_user_m_process_ready=1`、`tool_db_process_ready=1`、`host_external_user_m_process_ready=0`、`host_tool_db_process_ready=0`。 + - `npm --prefix web-rtcp-5axis-sim-plan/app run build`:通过,输出 `gmoccapy_static_build=ok`。 + - `bash web-rtcp-5axis-sim-plan/tests/browser/verify_gmoccapy_shell_browser.sh`:通过。 + - `bash web-rtcp-5axis-sim-plan/tests/browser/verify_gmoccapy_dist_browser.sh`:通过。 + - `git diff --check -- web-rtcp-5axis-sim-plan/app web-rtcp-5axis-sim-plan/tests web-rtcp-5axis-sim-plan/docs`:通过,无格式错误。 + +11. 最终结论: + - 红框功能已经按受控方式纳入项目:`toolDbProcessReady=true for web_simulation_only`,`externalUserMProcessReady=true for web_simulation_only`。 + - 项目仍然不包含任意 host user-M 脚本执行、host tool DB process、真实硬件驱动或 host realtime kernel。 + - 文档、流程图、Word、状态边界、UI 诊断和测试均已同步。 + +## 2026-07-01 Tool DB Web/WASM simulation 对标实施日志 + +1. 用户本轮要求:完全对标 `/home/meswork/cnc_wams/linuxcnc` 相关源程序,实现 Tool DB Web/WASM simulation,覆盖 staged `tool.tbl` 读取、OPFS/memory fallback 保存、刀具号/刀长/刀径/刀袋查询编辑保存,以及 `Tn/M6/G43` 仿真状态接入。 + +2. LinuxCNC 源码核对: + - 阅读 `linuxcnc/src/emc/tooldata/tooldata_common.cc`,确认 `CANON_TOOL_TABLE` 初始化、`tooldata_read_entry()` 的非随机刀库 `idx` 与真实 `pocketno` 分离、保存时从 `idx=1` 起写 `tool.tbl`。 + - 阅读 `linuxcnc/src/emc/tooldata/tooldata_mmap.cc`,确认 `tooldata_find_index_for_tool()` 在非随机刀库下对 `toolno=0` 返回 `idx=0`,并优先返回非主轴表项。 + - 阅读 `linuxcnc/src/emc/task/taskclass.cc`,确认 `Task::load_tool()`、`Task::emcToolPrepare()`、`Task::emcToolLoad()`、`Task::emcToolSetOffset()`、`Task::emcToolSetNumber()`、`Task::read_tool_inputs()` 对 `tool_prep_*`、`tool_change`、`tool_number`、`toolFromPocket`、主轴 `idx=0` 的更新逻辑。 + - 阅读 `linuxcnc/src/emc/rs274ngc/interp_convert.cc` 与 `interp_find.cc`,确认 `T`、`M6`、`M61`、`G43 Hn`、无 `H` 的 `G43`、#5400/#5401-#5413 工具参数快照的解释器语义。 + +3. 运行时实现: + - 重写/补齐 `app/src/runtime/tool-db-simulation.js`。 + - 实现 `parseLinuxCncToolTable()`,读取 staged `tool.tbl` 的 `T/P/X/Y/Z/A/B/C/U/V/W/D/I/J/Q/comment`。 + - 实现 LinuxCNC 式 `CANON_TOOL_TABLE` 字段模型:`toolno`、`pocketno`、`offset`、`diameter`、`frontangle`、`backangle`、`orientation`、`comment`。 + - 实现非随机刀库语义:真实 `P` 保留为 `pocketno`,Web 内部 `idx=1..n` 顺序装载,`idx=0` 固定为 spindle pocket。 + - 实现 `Tn` 准备、`M6` 装刀、`M61` 当前刀号/卸刀、`G43 Hn` 刀长补偿、`read_tool_inputs()` HAL loopback、#5400/#5401-#5413 参数快照。 + - 实现 `listToolEntries()`、`queryToolEntry()`、`editToolEntry()`、`saveToolDbSimulation()`,支持刀具号、刀袋、刀径、刀长编辑并按 LinuxCNC `tooldata_format_toolline()` 风格保存。 + - 实现 OPFS 可用时保存、不可用时 memory fallback 保存,且不启动任何 host tool DB process。 + - 修正程序扫描逻辑,支持 `T2M6G43H2` 这类无空格 LinuxCNC G-code 写法。 + +4. store 与浏览器 API: + - 修改 `app/src/state/store.js`,machine-file staging 后自动解析当前 profile 的 staged `tool.tbl` 并生成 `toolDbSimulation/toolDbReadiness`。 + - 在普通 `LOAD_PROGRAM` 和 LinuxCNC source program 路径中扫描 `T/M6/G43/M61` 工具命令并更新 Tool DB 仿真状态。 + - 暴露 `queryToolDb()`、`editToolDb()`、`saveToolDb()`。 + - 修改 `app/src/main.js`,把上述三个 API 挂到 `window.webRtcp5AxisSimulation`。 + +5. 测试实现: + - 新增 `tests/node/verify_tool_db_web_simulation.mjs`,覆盖 staged `xyzac-trt.tbl` 读取、内部 `idx` 与真实 `pocketno`、主轴 `idx=0`、查询、编辑、保存、memory fallback、`T2/M6/G43 H2` 状态、#5400/#5403/#5410 参数、无空格 `T2M6G43H2` 程序扫描、store API。 + - 更新 `tests/node/verify_tool_db_user_m_simulation.mjs`,适配 LinuxCNC 格式化保存和真实表项查询。 + - 更新 `app/package.json`,把 `verify_tool_db_web_simulation.mjs` 接入 `smoke:node`。 + - 更新 `tests/browser/gmoccapy_shell_smoke.html`,在浏览器中验证公开 `queryToolDb/editToolDb/saveToolDb` 能读取、编辑、保存 staged `tool.tbl`,并使用 memory fallback。 + +6. 文档更新: + - 更新 `docs/external-user-m-tool-db-simulation-plan.md`,补充 `CANON_TOOL_TABLE`、`idx/pocketno`、spindle pocket `idx=0`、`read_tool_inputs()`、`Tn/M6/G43/M61`、#5400/#5401-#5413 和 LinuxCNC 保存格式说明。 + - 使用 Pandoc 重新生成 `docs/external-user-m-tool-db-simulation-plan.docx`。 + - 更新 `docs/development-continuation.md`、`docs/traceability-matrix.md`、`docs/linuxcnc-parity-matrix.md`、`docs/program-implementation-guide.md`,把 Tool DB Web/WASM simulation 标记为 `web_simulation_only`,明确 host tool DB process、host realtime kernel、硬件驱动仍为 false。 + +7. 验证命令与结果: + - `node --check app/src/runtime/tool-db-simulation.js`:通过。 + - `node tests/node/verify_tool_db_web_simulation.mjs`:通过,输出 `tool_db_web_simulation_smoke=ok`、`staged_tool_tbl_loaded=1`、`tool_db_query_edit_save=1`、`tool_db_t_m6_g43_state=1`、`tool_db_memory_fallback_save=1`、`host_tool_db_process=0`。 + - `node tests/node/verify_tool_db_user_m_simulation.mjs`:通过。 + - `node tests/node/verify_machine_file_staging.mjs`:通过。 + - `npm --prefix web-rtcp-5axis-sim-plan/app run smoke:node`:通过,完整 Node smoke 含 Tool DB/User-M 和 full boundary gate。 + - `npm --prefix web-rtcp-5axis-sim-plan/app run build`:最终顺序重跑通过,输出 `gmoccapy_static_build=ok`。中间曾与 dist browser smoke 并行执行,因同时访问 `app/dist` 出现一次 `ENOTEMPTY` 目录清理竞争,顺序重跑后确认不是代码问题。 + - `bash tests/browser/verify_gmoccapy_shell_browser.sh`:通过。 + - `bash tests/browser/verify_gmoccapy_dist_browser.sh`:通过。 + - `git diff --check -- web-rtcp-5axis-sim-plan/app web-rtcp-5axis-sim-plan/tests web-rtcp-5axis-sim-plan/docs`:通过。 + +8. 最终结论: + - 本轮已实现 Tool DB Web/WASM simulation:读取 staged `tool.tbl`,OPFS/memory fallback 保存,支持刀具号/刀长/刀径/刀袋查询编辑保存,并接入 `Tn/M6/G43/M61` 仿真状态。 + - 当前能力严格限定为 `toolDbProcessReady=true for web_simulation_only`。 + - 项目仍不执行 LinuxCNC native `DB_PROGRAM`,不运行 host tool DB process,不控制真实硬件,不提升 host realtime kernel。 + +## GPT/Codex 执行过程日志 - 2026-07-01 12:02:10 EDT + +1. 用户目标: + - 继续完善 `/home/meswork/cnc_wams/web-rtcp-5axis-sim-plan` 项目。 + - 对标 `/home/meswork/cnc_wams/linuxcnc` 的五轴能力,重点推进真实 LinuxCNC TRT 五轴语义一致性。 + +2. 上下文与约束: + - 遵守 `/home/meswork/cnc_wams/AGENTS.md`:本轮结束前必须把完整执行过程用中文追加到 `web-rtcp-5axis-sim-plan/gptlog-process/gpdlog.md`。 + - 工作区已有多处用户或前序生成改动,未回退任何无关文件。 + - 本轮只收窄到 XYZBC TRT kinematics parity 的可验证缺口,不扩大到硬件 IO、host realtime kernel 或 native LinuxCNC task/HAL。 + +3. 读取与分析: + - 使用 `rg` 检索 `tcpPose`、`toRoundedPose`、`xyzbc`、`linuxcnc_kinematics_runtime`、`toolAxisVector` 等关键字。 + - 查看 `app/src/runtime/rtcp-frame.js`,发现 `normalizeAxisPose()` 和 `normalizeLinuxCncPose()` 已支持 `b`,但最终 `tcpPose` 只输出 `x/y/z/a/c`,XYZBC 的 B 轴姿态会在 frame 证据中丢失。 + - 查看 `app/src/visualization/five-axis-scene.js`,发现 `toRoundedPose()` 只输出 `x/y/z/a/c`,Three.js 诊断 dataset 也不会显示 B 轴。 + - 查看 `tests/node/verify_linuxcnc_kinematics_runtime.mjs`,发现直接 kinematics runtime proof 只覆盖 `xyzac-trt`,没有直接证明 `xyzbc-trt`。 + - 查看 `tests/node/verify_rtcp_store.mjs`,确认已有 `xyzbc-trt` profile 切换和 B 轴 jointPose 校验,但没有校验 `tcpPose.b` 是否保留。 + - 对照 LinuxCNC 源码和项目 profile:`xyzbc-trt-kins.c`、`trtfuncs.c`、`switchkins.c`、`xyzbc-trt.ini`、`app/src/profiles/xyzbc-trt.js`,确认项目已有 XYZBC WASM 模块与 profile,当前缺口主要是 Web frame/UI 诊断证据和 Node direct proof 不完整。 + +4. 实施内容: + - 修改 `app/src/runtime/rtcp-frame.js`: + - fixture frame 的 `tcpPose` 增加 `b: pose.b`。 + - LinuxCNC kinematics frame 的 `tcpPose` 增加 `b: pose.b`。 + - 修改 `app/src/visualization/five-axis-scene.js`: + - `toRoundedPose()` 增加 `b: round(pose.b)`,让 `data-three-tcp-pose` 能显示 XYZBC B 轴。 + - 修改 `tests/node/verify_linuxcnc_kinematics_runtime.mjs`: + - 引入 `getFiveAxisProfile()`。 + - 将测试改为用例表,覆盖 `xyzac-trt` 和 `xyzbc-trt` 两个模块。 + - 对两个模块分别校验 WASM 文件名、`switchkinsType=1`、runtime readiness、forward/inverse rc、关节闭环、profileId、kinematicsModuleId、jointPose 第 4 轴 A/B、C 轴、`tcpPose.a/b/c` 和刀轴方向。 + - 新增输出 `xyzac_trt_kinematics_runtime=ok`、`xyzbc_trt_kinematics_runtime=ok`、`xyzbc_b_axis_tcp_pose_preserved=1`。 + - 修改 `tests/node/verify_rtcp_store.mjs`: + - 在 `xyzbc-trt` store 场景中增加 `tcpPose.b` 有限值校验。 + - 校验 `state.rtcpFrame.tcpPose.b` 与 `state.tcpPose.b`、`state.rtcpFrame.axisPose.b` 一致。 + - 修改文档: + - `docs/development-continuation.md` 更新当前状态为 `M24_xyzbc_trt_kinematics_parity_complete`,追加 `16.10 M24:XYZBC TRT kinematics parity proof`。 + - `docs/linuxcnc-parity-matrix.md` 更新 Kinematics C 源码行,注明 XYZAC/XYZBC direct proof、`switchkinsType=1`、A/B/C TCP 姿态和 XYZBC B 轴保留。 + - `docs/program-implementation-guide.md` 追加 M24 说明,明确 `rtcpFrame.tcpPose` 和 Three.js dataset 现在同时输出 `a/b/c`。 + - `docs/traceability-matrix.md` 追加 `## 27. M24 XYZBC TRT kinematics parity proof 追溯记录`,记录文件、LinuxCNC 来源、边界、测试和结果。 + - 文档整理过程中曾第一次把 M24 追溯块误插到文件前部,随后检查 `rg` 和 `tail` 发现位置不对,已用精确上下文移动到 M23 后面,保持追溯编号顺序。 + +5. 验证命令与结果: + - `node --check app/src/runtime/rtcp-frame.js`:通过。 + - `node --check app/src/visualization/five-axis-scene.js`:通过。 + - `node tests/node/verify_linuxcnc_kinematics_runtime.mjs`:通过,输出: + - `xyzac_trt_kinematics_runtime=ok` + - `xyzbc_trt_kinematics_runtime=ok` + - `linuxcnc_kinematics_runtime_smoke=ok` + - `xyzbc_b_axis_tcp_pose_preserved=1` + - `node tests/node/verify_rtcp_store.mjs`:通过,输出 `rtcp_store_smoke=ok`。 + - `npm --prefix app run smoke:node`:通过,完整 Node smoke 覆盖 kinematics、interpreter、INI、run preconditions、run feedback、task/HAL、native audit、真实 LinuxCNC 五轴程序、tool DB、user-M、full boundary、machine-file staging、session、profile、gmoccapy 和 parity matrix。 + - `git diff --check -- app/src/runtime/rtcp-frame.js app/src/visualization/five-axis-scene.js tests/node/verify_linuxcnc_kinematics_runtime.mjs tests/node/verify_rtcp_store.mjs docs/development-continuation.md docs/traceability-matrix.md docs/linuxcnc-parity-matrix.md docs/program-implementation-guide.md`:通过。 + - `npm --prefix app run build`:通过,输出 `gmoccapy_static_build=ok`。 + - `bash tests/browser/verify_gmoccapy_shell_browser.sh`:通过,输出 `gmoccapy_shell_smoke=ok`。 + - `bash tests/browser/verify_gmoccapy_dist_browser.sh`:第一次与 build 并行执行时失败,报错为 `ENOENT: no such file or directory, chmod ... app/dist/src/vendor/three`,判断为两个构建流程同时操作 `app/dist` 的目录复制竞态;随后串行重跑通过,输出 `gmoccapy_dist_smoke=ok`。 + - 最后再次执行重点校验 `node tests/node/verify_linuxcnc_kinematics_runtime.mjs && node tests/node/verify_rtcp_store.mjs`:通过。 + +6. 最终结论: + - 本轮完成 M24:XYZBC TRT kinematics parity proof。 + - 项目现在不仅有 `xyzbc-trt` profile 和 WASM 模块,还在 Web RTCP frame、store smoke 和 Three.js 诊断 dataset 中保留并验证 B 轴 TCP 姿态。 + - `xyzac-trt` 与 `xyzbc-trt` 均以 `switchkinsType=1` 完成 LinuxCNC kinematics WASM 正解/逆解闭环证明。 + - 当前提升仍严格限定为 `semanticBoundary=linuxcnc_kinematics_wasm_c_abi` 和浏览器/Web runtime proof,不声明硬件驱动、host realtime kernel 或 native LinuxCNC task/HAL 能力。 + +## GPT/Codex 执行过程日志 - 2026-07-01 17:14:47 EDT + +1. 用户目标: + - 在 `/home/meswork/cnc_wams/web-rtcp-5axis-sim-plan` 项目中,针对 `gmoccapy` 页面功能,完整准确对标 `/home/meswork/cnc_wams/linuxcnc` 中 `gmoccapy` 的五轴 RTCP 功能。 + - 使用 `/home/meswork/cnc_wams/linuxcnc` 中包含 RTCP 功能的五轴实际程序进行彻底测试验证,并写出评价文档。 + +2. 工作区规则与边界: + - 遵守 `/home/meswork/cnc_wams/AGENTS.md`:本轮结束前把完整执行过程用中文追加到 `web-rtcp-5axis-sim-plan/gptlog-process/gpdlog.md`。 + - 工作区已有大量既有修改和未跟踪文件,未回退任何用户或前序生成的无关改动。 + - 本轮结论限定为浏览器/Web/WASM 仿真边界;不声明 native GTK `gmoccapy.py`、host HAL shared memory、真实硬件 IO、host realtime kernel、任意 host user-M 或 native host tool DB process 已实现。 + +3. LinuxCNC 基线读取与分析: + - 检查 `/home/meswork/cnc_wams/linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.ini`。 + - 确认关键配置: + - `[DISPLAY] DISPLAY=gmoccapy` + - `OPEN_FILE=./examples/impeller-7bl-xyzac.ngc` + - `JOG_AXES=XYZC` + - `[TRAJ] COORDINATES=XYZAC` + - `[KINS] KINEMATICS=xyzac-trt-kins` + - `HALFILE=LIB:basic_sim.tcl -no_use_hal_manualtoolchange` + - `POSTGUI_HALFILE=postgui.hal` + - `REMAP=M6 ... ngc=change_g43` + - `REMAP=M61 ... ngc=settool_g43` + - `SUBROUTINE_PATH=./examples:../../macros` + - 检查 gmoccapy `postgui.hal`,确认包含 `gmoccapy.spindle_feedback_bar`、`gmoccapy.spindle_at_speed_led`、`gmoccapy.toolchange-change`、`gmoccapy.toolchange-changed`、`gmoccapy.toolchange-number`、`gmoccapy.tooloffset-z`。 + - 检查 LinuxCNC gmoccapy TRT 示例程序目录,确认包含: + - `examples/impeller-7bl-xyzac.ngc` + - `examples/boat-xyzac.ngc` + - `examples/boat-xyzbc.ngc` + - `examples/test-xyzac.ngc` + - `examples/test-xyzbc.ngc` + - 对照 `src/emc/kinematics/xyzac-trt-kins.c`、`trtfuncs.c`、`switchkins.c`,确认 gmoccapy TRT INI 不带 `sparm=identityfirst`,其默认 type 0 不是 axis/vismach 的 identity-first 语义,而是固定 TRT/TCP 默认语义。 + +4. LinuxCNC 源文件导入: + - 将 LinuxCNC gmoccapy TRT 配置复制到 `../wasm-port/vendor/linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/`。 + - 将 LinuxCNC gmoccapy macros 复制到 `../wasm-port/vendor/linuxcnc/configs/sim/gmoccapy/macros/`。 + - 更新 `../wasm-port/tools/source-manifest.txt`,加入 gmoccapy macros、TRT INI/HAL/TBL/VAR、examples 等文件,使浏览器和 Node runtime 能通过 manifest/staging 找到真实 LinuxCNC 源文件。 + +5. Web profile 与 source reference 实施: + - 新增 `app/src/profiles/gmoccapy-xyzac-trt.js`: + - `id=gmoccapy-xyzac-trt` + - `iniPath=configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.ini` + - `display.display=gmoccapy` + - `display.openFile=./examples/impeller-7bl-xyzac.ngc` + - `display.jogAxes=["X","Y","Z","C"]` + - `rs274ngc.subroutinePath=./examples:../../macros` + - `rs274ngc.halPinVars=false` + - `kinematicsModuleId=xyzac-trt` + - `kinematicsParameters.fixedTrtDefault=true` + - switchkins type 0 映射为 `tcp-xyzac`,type 1 映射为 `identity`,type 2 映射为 `userk` + - `M6`/`M61` remap 指向 gmoccapy `change_g43.ngc` 和 `settool_g43.ngc` + - HAL 语义包含 `xyzac-trt-gui` feedback pins、tool offset/y-offset/z-offset、gmoccapy spindle/toolchange/tooloffset pins + - machine-file staging 使用 `machineRel=gmoccapy/non_trivial_kinematics/table-rotary-tilting`、`demoDirectory=examples`、默认程序 `impeller-7bl-xyzac.ngc` + - 更新 `app/src/profiles/index.js`,将 `gmoccapy-xyzac-trt` 加入 profile 列表。 + - 更新 `app/src/profiles/xyzac-trt.js`,补充 `kinematicsModuleId=xyzac-trt`,使通用 run precondition 能识别该 profile 的 kinematics runtime。 + - 更新 `app/src/profiles/source-reference-map.js`,把 gmoccapy TRT INI、postgui HAL、generated HAL、tool table、var、examples、gmoccapy remap macros、kinematics C 源码纳入 `gmoccapy-xyzac-trt` 的追溯来源。 + +6. Runtime 与状态逻辑实施: + - 修改 `app/src/runtime/linuxcnc-machine-file-staging.js`: + - 支持 profile-specific `machineRel`、`demoDirectory`、`wasmDir`。 + - 支持 gmoccapy TRT `examples/*.ngc` 作为 LinuxCNC vendored five-axis G-code source。 + - `listLinuxCncGcodeSources()`、`selectMachineFileProgram()` 根据 plan/profile 上下文判断 source guard,不再只接受 axis/vismach `demos/*.ngc`。 + - `summarizePlan()` 把 `/examples/` 计入 required file。 + - 修改 `app/src/runtime/linuxcnc-ini-runtime.js`: + - 区分 `sparm=identityfirst` switchkins TRT 与 gmoccapy fixed TRT。 + - switchkins TRT 仍要求 HALUI M428/M429/M430、`HAL_PIN_VARS=1`、`motion.analog-out-03=>motion.switchkins-type`。 + - gmoccapy fixed TRT 改为要求 `M6/M61` remap、`xyzac-trt-gui`、`xyzac-trt-kins.tool-offset`、`y-offset`、`z-offset` 等 HALCMD 语义。 + - 当 INI 没有 HALUI MDI commands 时,不用默认推断覆盖 profile 自带 fixed TRT switchkins type 映射。 + - 修改 `app/src/state/store.js`: + - `SET_PROFILE` 使用 profile 默认 kins type;gmoccapy fixed TRT 默认 `tcp-xyzac`,RTCP 默认 on。 + - `defaultLinuxCncGcodeSourceForState()` 优先使用 profile `defaultProgramFilename`。 + - `createMachineProjectState()` 使用 profile staging plan 的 `machineRel` 和 `demoDirectory`。 + - source guard 同时识别 axis/vismach `demos` 与 gmoccapy TRT `examples`。 + - run precondition 改为基于 `rtcpProof` 和 `kinematicsModuleId` 判断支持,不再硬编码只允许 `xyzac-trt`/`xyzbc-trt`。 + - 修改 `app/src/main.js`,默认 LinuxCNC source 选择优先按 profile 默认程序文件名。 + - 修改 `app/scripts/build-static.mjs`,把 vendored gmoccapy config assets 复制到 `dist/configs/sim/gmoccapy` 和 `dist/wasm-port/vendor/linuxcnc/configs/sim/gmoccapy`。 + +7. 测试实施: + - 新增 `tests/node/verify_gmoccapy_xyzac_trt_parity.mjs`,覆盖: + - profile 固定字段、fixed TRT 默认 TCP 映射、HAL/toolchange 语义; + - source reference summary; + - LinuxCNC gmoccapy TRT INI 解析; + - postgui HAL gmoccapy spindle/tool pins; + - machine-file staging 是否包含 INI、TBL、macros、examples; + - `selectMachineFileProgram()` 是否接受 gmoccapy `examples/impeller-7bl-xyzac.ngc`; + - LinuxCNC interpreter runtime 对 `impeller-7bl-xyzac.ngc`、`boat-xyzac.ngc`、`boat-xyzbc.ngc` 输出 canonical motion 和 planner samples; + - kinematics frame 是否为 `source-derived-kinematics-wasm` 且 RTCP on; + - store 切换 profile、加载 INI/runtime、staging、加载 LinuxCNC source、programValidation、tool DB readiness 和 run preconditions。 + - 更新 `app/package.json` 的 `smoke:node`,加入 `verify_gmoccapy_xyzac_trt_parity.mjs`。 + - 更新 `tests/node/verify_profile_boundary.mjs`、`verify_rtcp_store.mjs`、`verify_gmoccapy_xyzab_profile.mjs` 等 profile 列表断言,适配新增 profile。 + - 修改 `tests/browser/gmoccapy_shell_smoke.html`: + - `waitForMachineFileStaging()` 支持按 profileId 精确等待 staged 状态。 + - 通过真实页面 profile selector 切换到 `gmoccapy-xyzac-trt`。 + - 验证 `profile.display.display=gmoccapy`、`OPEN_FILE=./examples/impeller-7bl-xyzac.ngc`、kinematics runtime module 为 `xyzac-trt`、默认 `kinsType=tcp-xyzac`/`rtcpState=on`、INI readiness 指向 gmoccapy TRT INI、staging 使用 `examples`、G-code sources 包含 `/examples/impeller-7bl-xyzac.ngc`、machine project G-code directory 指向 gmoccapy examples、RTCP frame profileId 和状态正确。 + - 保持测试后切回 `xyzac-trt`,避免影响后续 axis/vismach smoke 流程。 + +8. 文档实施: + - 新增 `docs/gmoccapy-xyzac-trt-rtcp-verification-evaluation.md`,中文记录: + - 评价结论为 Web simulation boundary 内通过; + - LinuxCNC 基线文件; + - axis/vismach switchkins 与 gmoccapy fixed TRT 默认 TCP 的语义差异; + - Web 实现项; + - 测试矩阵; + - 验证命令与结果; + - 未覆盖的 native/hardware/host 边界。 + - 更新 `docs/linuxcnc-parity-matrix.md`,在真实五轴 G-code 程序表中加入 gmoccapy TRT `examples/*.ngc`。 + - 更新 `docs/program-implementation-guide.md`,把 source guard 从仅 axis/vismach `demos/*.ngc` 修正为按 profile 接受 axis/vismach `demos/*.ngc` 或 gmoccapy TRT `examples/*.ngc`。 + - 更新 `docs/development-continuation.md`,同步说明 profile-specific source guard。 + - 更新 `docs/traceability-matrix.md`,追加 `## 28. M25 gmoccapy XYZAC TRT RTCP 页面对标追溯记录`,记录文件、LinuxCNC 来源、边界、测试与结果。 + +9. 验证命令与结果: + - `node tests/node/verify_gmoccapy_xyzac_trt_parity.mjs`:通过,输出 `gmoccapy_xyzac_trt_parity_smoke=ok`。 + - `node tests/node/verify_profile_boundary.mjs`:通过。 + - `node tests/node/verify_linuxcnc_ini_runtime.mjs`:通过。 + - `node tests/node/verify_machine_file_staging.mjs`:通过。 + - `node tests/node/verify_gmoccapy_trt_project_sidebar.mjs`:通过。 + - `node tests/node/verify_run_preconditions.mjs`:通过。 + - `node tests/node/verify_rtcp_store.mjs`:通过。 + - `node tests/node/verify_linuxcnc_parity_matrix.mjs`:通过。 + - `npm --prefix app run smoke:node`:通过,关键输出包括: + - `xyzac_trt_kinematics_runtime=ok` + - `xyzbc_trt_kinematics_runtime=ok` + - `linuxcnc_interpreter_runtime_smoke=ok` + - `linuxcnc_ini_runtime_smoke=ok` + - `real_linuxcnc_5axis_program_cases_smoke=ok` + - `machine_file_staging_smoke=ok` + - `rtcp_store_smoke=ok` + - `profile_boundary_smoke=ok` + - `gmoccapy_xyzac_trt_parity_smoke=ok` + - `gmoccapy_trt_project_sidebar_smoke=ok` + - `linuxcnc_parity_matrix_smoke=ok` + - `npm --prefix app run smoke`:通过,输出: + - `gmoccapy_shell_smoke=ok` + - `gmoccapy_dist_smoke=ok` + - `node tests/node/verify_gmoccapy_xyzac_trt_parity.mjs && node tests/node/verify_machine_file_staging.mjs && node tests/node/verify_linuxcnc_ini_runtime.mjs && node tests/node/verify_linuxcnc_parity_matrix.mjs`:通过。 + - `git diff --check -- ...`:针对本轮相关 app/tests/docs/manifest 文件通过,无 whitespace error。 + - `npm --prefix app run build`:通过,输出 `gmoccapy_static_build=ok`。 + +10. 最终评价: + - `gmoccapy-xyzac-trt` 页面功能已对齐 LinuxCNC gmoccapy 非平凡 XYZAC TRT 示例的五轴 RTCP 核心语义。 + - Web 页面现在能加载并 staging gmoccapy TRT INI/HAL/TBL/macros/examples,默认打开 `impeller-7bl-xyzac.ngc`,并以 fixed TRT 默认 TCP 进入 RTCP on 状态。 + - 使用 LinuxCNC 实际 gmoccapy TRT examples 进行 interpreter canonical motion、planner samples、project staging、source guard、RTCP frame 和 browser profile 切换验证,结果均通过。 + - 已写出评价文档 `docs/gmoccapy-xyzac-trt-rtcp-verification-evaluation.md`。 + - 当前能力仍限定为浏览器/Web/WASM 仿真边界,不提升为真实硬件或 host/native LinuxCNC runtime 能力。 + +--- + +## 2026-07-01 执行日志:gmoccapy 对标与 LinuxCNC 实际程序验证补强 + +1. 用户任务: + - 要求 `/home/meswork/cnc_wams/web-rtcp-5axis-sim-plan` 中的数控系统仿真功能完整、准确对标 `/home/meswork/cnc_wams/linuxcnc` 中的 `gmoccapy` 数控系统仿真功能。 + - 要求通过 `/home/meswork/cnc_wams/linuxcnc` 中包含的实际程序进行彻底、全面、完整的测试和验证。 + +2. 初始检查: + - 读取工作区结构,确认目标项目为 `web-rtcp-5axis-sim-plan`,LinuxCNC 源目录为 `/home/meswork/cnc_wams/linuxcnc`。 + - 检查 `app/package.json`,确认已有 `smoke:node` 和 `smoke` 两类验证入口。 + - 检查 `app/src/main.js`、`tests/node`、`tests/browser`、`app/src/profiles`、`app/src/runtime` 等目录,确认已有 LinuxCNC kinematics、interpreter、INI、Task/HAL、gmoccapy profile、parity matrix、浏览器壳层验证。 + - 枚举 `/home/meswork/cnc_wams/linuxcnc/configs/sim/gmoccapy`,确认 gmoccapy 源配置包含基础 XYZAB、宏、POSTGUI HAL、非平凡运动学、TRT 示例、lathe/plasma 等实际文件。 + +3. 现有验证执行: + - 执行 `npm run smoke:node`,结果通过。 + - 关键通过项包括: + - `xyzac_trt_kinematics_runtime=ok` + - `xyzbc_trt_kinematics_runtime=ok` + - `linuxcnc_interpreter_runtime_smoke=ok` + - `linuxcnc_ini_runtime_smoke=ok` + - `linuxcnc_task_hal_runtime_smoke=ok` + - `full_linuxcnc_5axis_source_node_smoke=ok` + - `real_linuxcnc_5axis_program_cases_smoke=ok` + - `gmoccapy_xyzac_trt_parity_smoke=ok` + - `gmoccapy_xyzab_profile_smoke=ok` + - `gmoccapy_communication_model_smoke=ok` + - `gmoccapy_hal_model_smoke=ok` + - `gmoccapy_xyzab_gates_smoke=ok` + - `gmoccapy_trt_project_sidebar_smoke=ok` + - `linuxcnc_parity_matrix_smoke=ok` + - 执行 `npm run smoke`,结果通过。 + - 浏览器验证输出: + - `gmoccapy_shell_smoke=ok` + - `gmoccapy_dist_smoke=ok` + +4. 对标差距检查: + - 读取 `app/src/runtime/linuxcnc-parity-matrix.js`,确认 parity matrix 已覆盖: + - gmoccapy TRT 配置; + - gmoccapy 原生操作界面参考; + - 右侧 task interlock; + - Vismach 机床预览; + - source-derived kinematics/switchkins; + - LinuxCNC interpreter 程序验证; + - machine project staging; + - Task/HAL 状态循环; + - gmoccapy POSTGUI tool/spindle HAL。 + - 读取 `tests/node/verify_real_linuxcnc_5axis_program_cases.mjs` 与 `tests/node/verify_full_linuxcnc_5axis_source.mjs`,确认 axis/vismach TRT 的 8 个 LinuxCNC 真实 5 轴程序已经执行验证。 + - 读取 `app/src/profiles/source-reference-map.js`、`app/src/profiles/gmoccapy-xyzac-trt.js`、`tests/node/verify_gmoccapy_xyzac_trt_parity.mjs`,发现可补强点: + - gmoccapy TRT examples 目录实际包含 5 个 `.ngc`:`boat-xyzac.ngc`、`boat-xyzbc.ngc`、`impeller-7bl-xyzac.ngc`、`test-xyzac.ngc`、`test-xyzbc.ngc`。 + - 现有执行验证主要覆盖 `impeller-7bl-xyzac.ngc`、`boat-xyzac.ngc`、`boat-xyzbc.ngc`。 + - `test-xyzac.ngc` 和 `test-xyzbc.ngc` 是 `o<...> sub/endsub` 形式的 ngcgui 子程序,不能按 standalone main program 要求 motion ready。 + +5. 探测验证: + - 直接使用 LinuxCNC interpreter runtime 试运行 gmoccapy TRT 5 个 examples。 + - `impeller-7bl-xyzac.ngc`、`boat-xyzac.ngc`、`boat-xyzbc.ngc` 可解释并产生 canonical motion 与 planner samples。 + - `test-xyzac.ngc`、`test-xyzbc.ngc` 直接运行只产生 FINISH 类 canonical event,不产生 motion,符合 ngcgui 子程序文件性质。 + - 打开两个 test 文件后确认其包含 `o sub`/`endsub`、`o sub`/`endsub`、`T# M6`、`G43 H# Z0`、对应 A/B 与 C 旋转轴命令。 + +6. 本轮代码修改: + - 修改 `app/src/profiles/source-reference-map.js`: + - 新增 `gmoccapy-trt-test-xyzac-ngcgui` source reference。 + - 新增 `gmoccapy-trt-test-xyzbc-ngcgui` source reference。 + - 将两个 ngcgui 子程序标记为 `gcode_ngcgui_subroutine`,边界为 `linuxcnc_gmoccapy_ngcgui_subroutine_reference`。 + - 修改 `app/src/profiles/gmoccapy-xyzac-trt.js`: + - `samplePrograms` 补齐 `boat-xyzbc.ngc` 与 `test-xyzbc.ngc`。 + - 使 profile 样例程序列表与 gmoccapy TRT examples 目录 5 个 `.ngc` 对齐。 + - 修改 `app/src/runtime/linuxcnc-parity-matrix.js`: + - `gmoccapy-trt-config` 的 `linuxCncPaths` 增加 `examples/test-xyzac.ngc` 与 `examples/test-xyzbc.ngc`。 + - `functions` 增加 `gmoccapy TRT ngcgui subroutine examples`。 + - 修改 `tests/node/verify_gmoccapy_xyzac_trt_parity.mjs`: + - 增加 `GMOCAPY_TRT_EXAMPLE_FILES`,固定断言 5 个 gmoccapy TRT examples 全量存在。 + - 增加 `DIRECT_PROGRAM_EXAMPLES`,对 `impeller` 与两个 `boat` 执行 interpreter/planner 验证。 + - 增加 `NGC_GUI_SUBROUTINE_EXAMPLES`,对 `test-xyzac` 与 `test-xyzbc` 做 subroutine 结构、tool-change、tool-offset 和旋转轴语义验证。 + - 断言 staged `gcodeSources` 文件名完整等于 5 个 gmoccapy TRT examples,并且 source guard 均为 `linuxcnc_vendored_5axis_gcode_source_file`。 + +7. 修改后验证: + - 执行 `node tests/node/verify_gmoccapy_xyzac_trt_parity.mjs`,通过,输出 `gmoccapy_xyzac_trt_parity_smoke=ok`。 + - 执行 `npm run smoke:node`,通过,所有 Node 验证项均成功。 + - 执行 `npm run smoke`,通过,浏览器 gmoccapy shell 和 dist smoke 均成功。 + - 执行 `git diff --check -- app/src/profiles/source-reference-map.js app/src/runtime/linuxcnc-parity-matrix.js`,通过,无 whitespace error。 + +8. 工作区状态说明: + - `git status --short` 显示工作区中已有大量先前未提交或未跟踪文件,涉及 `qa`、`wasm-port`、`app`、`docs`、`tests`、`gptlog-process` 等目录。 + - 本次未回退任何既有工作区改动。 + - 本轮实际触及的功能/验证文件为: + - `app/src/profiles/source-reference-map.js` + - `app/src/profiles/gmoccapy-xyzac-trt.js` + - `app/src/runtime/linuxcnc-parity-matrix.js` + - `tests/node/verify_gmoccapy_xyzac_trt_parity.mjs` + - `gptlog-process/gpdlog.md` + +9. 最终结论: + - 当前 Web 仿真项目在 Web/WASM 仿真边界内,已经通过 LinuxCNC 源实际配置与程序完成 gmoccapy TRT 对标验证补强。 + - gmoccapy TRT examples 目录的 5 个 `.ngc` 已全部进入 source map、profile sample list、parity matrix 和专项测试。 + - 其中 3 个 standalone 五轴主程序执行 interpreter canonical motion 与 planner samples 验证;2 个 ngcgui 子程序按其 LinuxCNC 文件性质完成 staging 与结构语义验证。 + - 全量 Node smoke 与浏览器 smoke 均通过。 diff --git a/web-rtcp-5axis-sim-plan/tests/node/verify_gmoccapy_xyzac_trt_parity.mjs b/web-rtcp-5axis-sim-plan/tests/node/verify_gmoccapy_xyzac_trt_parity.mjs new file mode 100644 index 0000000..583cf8f --- /dev/null +++ b/web-rtcp-5axis-sim-plan/tests/node/verify_gmoccapy_xyzac_trt_parity.mjs @@ -0,0 +1,188 @@ +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; + +import { createMemorySessionStorage } from "../../app/src/runtime/five-axis-session.js"; +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 { + selectMachineFileProgram, + stageProfileMachineFiles, +} from "../../app/src/runtime/linuxcnc-machine-file-staging.js"; +import { buildRtcpFrame } from "../../app/src/runtime/rtcp-frame.js"; +import { createProfileSourceReferenceSummary } from "../../app/src/profiles/source-reference-map.js"; +import { getFiveAxisProfile } from "../../app/src/profiles/index.js"; +import { createSimulationStore, validateRunPreconditions } from "../../app/src/state/store.js"; + +const GMOCAPY_TRT_EXAMPLE_SOURCE_PREFIX = "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/"; +const GMOCAPY_TRT_EXAMPLE_FILES = [ + "boat-xyzac.ngc", + "boat-xyzbc.ngc", + "impeller-7bl-xyzac.ngc", + "test-xyzac.ngc", + "test-xyzbc.ngc", +]; +const DIRECT_PROGRAM_EXAMPLES = [ + "impeller-7bl-xyzac.ngc", + "boat-xyzac.ngc", + "boat-xyzbc.ngc", +]; +const NGC_GUI_SUBROUTINE_EXAMPLES = [ + { filename: "test-xyzac.ngc", subroutine: "test-xyzac", rotaryAxis: "A" }, + { filename: "test-xyzbc.ngc", subroutine: "test-xyzbc", rotaryAxis: "B" }, +]; + +const profile = getFiveAxisProfile("gmoccapy-xyzac-trt"); +const iniText = await readFile( + new URL("../../../wasm-port/vendor/linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/xyzac-trt.ini", import.meta.url), + "utf8", +); +const postguiText = await readFile( + new URL("../../../wasm-port/vendor/linuxcnc/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/postgui.hal", import.meta.url), + "utf8", +); + +assert.equal(profile.display.display, "gmoccapy"); +assert.equal(profile.display.openFile, "./examples/impeller-7bl-xyzac.ngc"); +assert.equal(profile.kinematics, "xyzac-trt-kins"); +assert.equal(profile.kinematicsModuleId, "xyzac-trt"); +assert.equal(profile.kinematicsParameters.fixedTrtDefault, true); +assert.equal(profile.kinematicsParameters.switchkinsTypes[0].webKinsType, "tcp-xyzac"); +assert.equal(profile.rtcpProof, true); +assert.equal(profile.machineFileStaging.machineRel, "gmoccapy/non_trivial_kinematics/table-rotary-tilting"); +assert.equal(profile.machineFileStaging.demoDirectory, "examples"); +assert.equal(profile.hal.halcmd.offsetNets.some((net) => net.target === "gmoccapy.tooloffset-z"), true); +assert.equal(profile.hal.halcmd.toolChange.manualGmoccapyPinsConnected, true); + +const sourceSummary = createProfileSourceReferenceSummary(profile.id); +assert.equal(sourceSummary.referenceCount >= 10, true); +assert.equal(sourceSummary.kinds.includes("ini"), true); +assert.equal(sourceSummary.kinds.includes("gcode_demo"), true); +assert.equal(sourceSummary.kinds.includes("gcode_ngcgui_subroutine"), true); +assert.equal(sourceSummary.kinds.includes("remap_subroutine"), true); +assert.equal(sourceSummary.sourceRequiredCount >= 2, true); +for (const filename of GMOCAPY_TRT_EXAMPLE_FILES) { + assert.equal( + sourceSummary.references.some((reference) => reference.path === `${GMOCAPY_TRT_EXAMPLE_SOURCE_PREFIX}${filename}`), + true, + `${filename} source reference`, + ); +} + +const iniConfig = parseLinuxCncIni(iniText, { + path: profile.iniPath, + profileId: profile.id, +}); +assert.equal(iniConfig.validation.ready, true); +assert.equal(iniConfig.machineName, "sim-xyzac-trt"); +assert.equal(iniConfig.display.display, "gmoccapy"); +assert.equal(iniConfig.traj.coordinates, "XYZAC"); +assert.equal(iniConfig.kinematics.name, "xyzac-trt-kins"); +assert.equal(iniConfig.kinematicsParameters.sparm, null); +assert.deepEqual(iniConfig.rs274ngc.remaps.map((remap) => remap.code), ["M6", "M61"]); +assert.equal(iniConfig.rs274ngc.subroutinePath, "./examples:../../macros"); +assert.equal(iniConfig.hal.postguiHalFiles.includes("postgui.hal"), true); +assert.equal(iniConfig.hal.halcmd.some((line) => line.includes("xyzac-trt-gui")), true); +assert.equal(iniConfig.hal.halcmd.some((line) => line.includes("xyzac-trt-kins.tool-offset")), true); +assert.equal(iniConfig.hal.halcmd.some((line) => line.includes("sets :y-offset 20")), true); +assert.equal(iniConfig.emcmot.servoPeriodNs, 1000000); +assert.equal(iniConfig.task.cycleTimeSeconds, 0.010); +assert.equal(postguiText.includes("gmoccapy.spindle_feedback_bar"), true); +assert.equal(postguiText.includes("gmoccapy.toolchange-change"), true); +assert.equal(postguiText.includes("gmoccapy.tooloffset-z"), true); + +const staged = await stageProfileMachineFiles(profile, { + storage: createMemorySessionStorage(), +}); +assert.equal(staged.plan.profileId, profile.id); +assert.equal(staged.plan.machineRel, "gmoccapy/non_trivial_kinematics/table-rotary-tilting"); +assert.equal(staged.plan.demoDirectory, "examples"); +assert.equal(staged.save.files.some((file) => file.sourceRel === profile.iniPath), true); +assert.equal(staged.save.files.some((file) => file.sourceRel === profile.toolTablePath), true); +assert.equal(staged.save.files.some((file) => file.sourceRel.endsWith("macros/change_g43.ngc")), true); +assert.equal(staged.save.files.some((file) => file.sourceRel.endsWith("macros/settool_g43.ngc")), true); +assert.deepEqual(staged.save.gcodeSources.map((source) => source.filename), GMOCAPY_TRT_EXAMPLE_FILES); +assert.equal(staged.save.gcodeSources.every((source) => source.sourceRel.startsWith(GMOCAPY_TRT_EXAMPLE_SOURCE_PREFIX)), true); +assert.equal(staged.save.gcodeSources.every((source) => source.semanticBoundary === "linuxcnc_vendored_5axis_gcode_source_file"), true); +assert.equal(staged.save.gcodeFiles.some((file) => file.filename === "test-xyzac.ngc"), true); +assert.equal(staged.save.gcodeFiles.some((file) => file.filename === "test-xyzbc.ngc"), true); + +const selectedPlan = selectMachineFileProgram( + staged.plan, + staged.save, + "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/impeller-7bl-xyzac.ngc", +); +assert.equal(selectedPlan.selectedProgramFilename, "impeller-7bl-xyzac.ngc"); +assert.equal(selectedPlan.wasmProgramPath.endsWith("/examples/impeller-7bl-xyzac.ngc"), true); + +const runtime = await createLinuxCncInterpreterRuntime(); +for (const filename of DIRECT_PROGRAM_EXAMPLES) { + const source = staged.save.files.find((file) => file.sourceRel.endsWith(`/examples/${filename}`)); + assert.ok(source, `${filename} staged`); + const execution = runtime.runProgram(source.text); + assert.equal(execution.sourceMode, "linuxcnc-interpreter-wasm", `${filename} source mode`); + assert.equal(execution.summary.ready, true, `${filename} ready`); + assert.equal(execution.summary.motionEventCount > 0, true, `${filename} motion`); + assert.equal(execution.plannerTiming.samples.length > 0, true, `${filename} planner samples`); +} +for (const { filename, subroutine, rotaryAxis } of NGC_GUI_SUBROUTINE_EXAMPLES) { + const source = staged.save.files.find((file) => file.sourceRel.endsWith(`/examples/${filename}`)); + assert.ok(source, `${filename} staged`); + assert.equal(source.text.includes(`o<${subroutine}> sub`), true, `${filename} subroutine open`); + assert.equal(source.text.includes(`o<${subroutine}> endsub`), true, `${filename} subroutine close`); + assert.equal(source.text.includes("T# M6"), true, `${filename} tool-change semantics`); + assert.equal(source.text.includes("G43 H# Z0"), true, `${filename} tool-offset semantics`); + assert.equal(new RegExp(`G00 ${rotaryAxis}#<${rotaryAxis.toLowerCase()}_angle> C#`).test(source.text), true, `${filename} rotary-axis semantics`); + const execution = runtime.runProgram(source.text); + assert.equal(execution.sourceMode, "linuxcnc-interpreter-wasm", `${filename} source mode`); + assert.equal(execution.summary.ready, false, `${filename} ngcgui subroutine is not a standalone main program`); + assert.equal(execution.summary.motionEventCount, 0, `${filename} direct subroutine execution has no motion`); +} + +const kinematics = await createLinuxCncKinematicsRuntime({ moduleId: "xyzac-trt", switchkinsType: 0 }); +const frame = buildRtcpFrame({ + axisPose: { x: 16.339, y: -25.409, z: 33.353, a: -71.841, c: -35.93 }, + activeLine: 5, + kinsType: "tcp-xyzac", + rtcpEnabled: true, + profile, + linuxCncKinematicsResult: kinematics.frameForJoints([16.339, -25.409, 33.353, -71.841, -35.93]), +}); +assert.equal(frame.sourceMode, "source-derived-kinematics-wasm"); +assert.equal(frame.readiness.linuxCncKinematicsReady, true); +assert.equal(frame.rtcpState, "on"); +assert.equal(frame.profileId, "gmoccapy-xyzac-trt"); + +const store = createSimulationStore(); +store.dispatch({ type: "SET_PROFILE", profileId: profile.id }); +store.dispatch({ type: "ATTACH_INI_CONFIG", profileId: profile.id, iniConfig }); +store.dispatch({ type: "ATTACH_KINEMATICS_RUNTIME", runtime: kinematics }); +await store.refreshKinematicsFrame(); +store.dispatch({ type: "ATTACH_INTERPRETER_RUNTIME", runtime }); +await store.stageMachineFiles({ storage: createMemorySessionStorage() }); +store.dispatch({ + type: "LOAD_LINUXCNC_GCODE_SOURCE", + sourceRel: "configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples/impeller-7bl-xyzac.ngc", +}); +await new Promise((resolve) => setTimeout(resolve, 0)); + +const loadedState = store.getState(); +assert.equal(loadedState.machineProfile, profile.id); +assert.equal(loadedState.display?.display, undefined); +assert.equal(loadedState.kinsType, "tcp-xyzac"); +assert.equal(loadedState.rtcpState, "on"); +assert.equal(loadedState.machineProject.gcodeDirectory.endsWith("/configs/sim/gmoccapy/non_trivial_kinematics/table-rotary-tilting/examples"), true); +assert.equal(loadedState.machineProject.selectedProgram.filename, "impeller-7bl-xyzac.ngc"); +assert.equal(loadedState.programValidation.sourceGuard, "linuxcnc_vendored_5axis_gcode_source_file"); +assert.equal(loadedState.programExecution?.summary?.motionEventCount > 0, true); +assert.equal(loadedState.toolDbReadiness.toolCount, 10); + +const preconditions = validateRunPreconditions(loadedState, { + requireTaskHalRuntime: false, + requireTaskHalSession: false, +}); +assert.equal(preconditions.ok, true); +assert.equal(preconditions.profileId, "gmoccapy-xyzac-trt"); +assert.equal(preconditions.selectedGcodeSourceRel.endsWith("/examples/impeller-7bl-xyzac.ngc"), true); + +console.log("gmoccapy_xyzac_trt_parity_smoke=ok");