补齐 gmoccapy TRT 示例程序对标验证

This commit is contained in:
2026-07-01 17:31:40 -04:00
parent 9803aadf0a
commit 3b01c4e428
5 changed files with 1196 additions and 6 deletions

View File

@@ -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,
};

View File

@@ -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",

View File

@@ -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",
],
},
{

View File

@@ -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 <docx> word/document.xml` 抽取 XML 正文,辅助确认转换内容。
- 读取旧版手册正文,确认它覆盖系统定位、安全边界、界面区域、上电/回零、AUTO、MANUAL、MDI、RTCP/IDENTITY/TCP、倍率、主轴、冷却、会话、诊断和常见问题。
- 读取新版手册正文,确认它强化 LinuxCNC 对标范围、右侧九入口互锁、标准运行流程、刀具预览路径来源、真实五轴程序来源、项目目录/INI/HAL/tool table/remap 对标、诊断和验证记录。
- 使用 `unzip -l <docx> 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` 固定为 falsegmoccapy 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 为 1host 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 为 truehost 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` readyhost 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 M24XYZBC 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. 最终结论:
- 本轮完成 M24XYZBC 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 typegmoccapy 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<test-xyzac> sub`/`endsub``o<test-xyzbc> sub`/`endsub``T#<tool1> M6``G43 H#<tool2> 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 均通过。

View File

@@ -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#<tool1> M6"), true, `${filename} tool-change semantics`);
assert.equal(source.text.includes("G43 H#<tool2> Z0"), true, `${filename} tool-offset semantics`);
assert.equal(new RegExp(`G00 ${rotaryAxis}#<${rotaryAxis.toLowerCase()}_angle> C#<c_angle>`).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");