提交当前项目改动

This commit is contained in:
mes123456
2026-07-02 08:01:34 -04:00
parent 83075c4b96
commit c4a721f6cf
274 changed files with 157294 additions and 1394 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

View File

@@ -0,0 +1,66 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="900" viewBox="0 0 1600 900">
<defs>
<style>
text { font-family: "Noto Sans CJK SC", "Microsoft YaHei", Arial, sans-serif; fill: #172033; }
.title { font-size: 40px; font-weight: 700; }
.sub { font-size: 23px; fill: #475569; }
.head { font-size: 27px; font-weight: 700; }
.body { font-size: 21px; }
.small { font-size: 18px; fill: #475569; }
.box { fill: #f8fafc; stroke: #64748b; stroke-width: 2.5; rx: 14; }
.native { fill: #eef6ff; stroke: #2563eb; stroke-width: 3; rx: 16; }
.web { fill: #f4fbf7; stroke: #16a34a; stroke-width: 3; rx: 16; }
.json { fill: #fff7ed; stroke: #f97316; stroke-width: 3; rx: 16; }
.ok { fill: #f0fdf4; stroke: #22c55e; stroke-width: 3; rx: 16; }
.line { stroke: #334155; stroke-width: 3; fill: none; marker-end: url(#arrow); }
</style>
<marker id="arrow" markerWidth="14" markerHeight="14" refX="12" refY="7" orient="auto" markerUnits="strokeWidth">
<path d="M 0 0 L 14 7 L 0 14 z" fill="#334155"/>
</marker>
</defs>
<rect width="1600" height="900" fill="#ffffff"/>
<text x="60" y="70" class="title">刀具预览路径与执行路径 JSON 比对流程</text>
<text x="60" y="110" class="sub">真实 LinuxCNC 与 Web 仿真统一采用 20 ms 采样周期,便于曲线、姿态和 switchkins 状态逐点对齐。</text>
<rect x="75" y="170" width="440" height="225" class="native"/>
<text x="110" y="220" class="head">LinuxCNC 真实系统</text>
<text x="110" y="270" class="body">1. 加载 xyzbc-trt.ini</text>
<text x="110" y="310" class="body">2. 预览 xyzbc_switchkins.ngc</text>
<text x="110" y="350" class="body">3. 采集 status / HAL / path</text>
<rect x="75" y="505" width="440" height="225" class="web"/>
<text x="110" y="555" class="head">Web 仿真系统</text>
<text x="110" y="605" class="body">1. 解析同一组配置和程序</text>
<text x="110" y="645" class="body">2. 生成等价预览和执行轨迹</text>
<text x="110" y="685" class="body">3. 输出同字段 evidence JSON</text>
<rect x="620" y="210" width="360" height="145" class="json"/>
<text x="660" y="260" class="head">native-evidence.json</text>
<text x="660" y="305" class="small">previewPath / executionPath / halPins</text>
<rect x="620" y="545" width="360" height="145" class="json"/>
<text x="678" y="595" class="head">web-evidence.json</text>
<text x="660" y="640" class="small">同 sampleIndex / timeMs / 坐标系</text>
<rect x="1080" y="360" width="410" height="185" class="box"/>
<text x="1125" y="410" class="head">逐点对齐和误差计算</text>
<text x="1125" y="458" class="body">位置误差X/Y/Z/B/C</text>
<text x="1125" y="498" class="body">TCP 误差toolTip 与 toolAxis</text>
<text x="1125" y="538" class="body">状态误差kinsType / G-code / HAL</text>
<rect x="1080" y="645" width="410" height="115" class="ok"/>
<text x="1135" y="695" class="head">compare-report.json</text>
<text x="1135" y="735" class="small">max / rms / firstMismatch / screenshots</text>
<path d="M515 282 L620 282" class="line"/>
<path d="M515 617 L620 617" class="line"/>
<path d="M980 282 C1050 282 1050 405 1080 405" class="line"/>
<path d="M980 617 C1050 617 1050 500 1080 500" class="line"/>
<path d="M1285 545 L1285 645" class="line"/>
<rect x="610" y="750" width="385" height="65" class="json"/>
<text x="642" y="790" class="head">samplePeriodMs = 20</text>
<path d="M805 545 L805 355" class="line"/>
<text x="645" y="845" class="small">所有曲线采样周期固定一致,禁止真实系统与 Web 系统使用不同周期。</text>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View File

@@ -0,0 +1,97 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1800" height="1100" viewBox="0 0 1800 1100">
<defs>
<style>
text { font-family: "Noto Sans CJK SC", "Microsoft YaHei", Arial, sans-serif; fill: #172033; }
.title { font-size: 42px; font-weight: 700; }
.sub { font-size: 24px; fill: #475569; }
.box { stroke-width: 3; rx: 18; }
.file { fill: #eef6ff; stroke: #2563eb; }
.core { fill: #f4fbf7; stroke: #16a34a; }
.ui { fill: #fff7ed; stroke: #f97316; }
.data { fill: #f8fafc; stroke: #64748b; }
.warn { fill: #fef2f2; stroke: #ef4444; }
.head { font-size: 28px; font-weight: 700; }
.body { font-size: 20px; }
.small { font-size: 18px; fill: #475569; }
.line { stroke: #334155; stroke-width: 3; fill: none; marker-end: url(#arrow); }
.dash { stroke-dasharray: 8 7; }
</style>
<marker id="arrow" markerWidth="14" markerHeight="14" refX="12" refY="7" orient="auto" markerUnits="strokeWidth">
<path d="M 0 0 L 14 7 L 0 14 z" fill="#334155"/>
</marker>
</defs>
<rect width="1800" height="1100" fill="#ffffff"/>
<text x="60" y="70" class="title">xyzbc-trt 程序逻辑总图</text>
<text x="60" y="112" class="sub">从文件装载、运动学、HAL、界面、执行到证据采样的完整逻辑链路。</text>
<rect x="60" y="170" width="330" height="170" class="box file"/>
<text x="95" y="218" class="head">配置与程序文件</text>
<text x="95" y="262" class="body">xyzbc-trt.ini</text>
<text x="95" y="298" class="body">xyzbc-trt.xml</text>
<text x="95" y="334" class="body">switchkins_postgui.hal</text>
<rect x="60" y="380" width="330" height="210" class="box file"/>
<text x="95" y="428" class="head">演示与参数文件</text>
<text x="95" y="472" class="body">xyzbc_switchkins.ngc</text>
<text x="95" y="508" class="body">428/429/430 remap</text>
<text x="95" y="544" class="body">xyzbc-trt.tbl / xyzbc.var</text>
<text x="95" y="580" class="body">remap_subs/*.ngc</text>
<rect x="470" y="155" width="410" height="230" class="box core"/>
<text x="510" y="205" class="head">启动与装载</text>
<text x="510" y="250" class="body">rip-environment 设置 RIP 环境</text>
<text x="510" y="286" class="body">linuxcnc 读取 xyzbc-trt.ini</text>
<text x="510" y="322" class="body">HALFILE / POSTGUI_HALFILE 装配</text>
<text x="510" y="358" class="body">open_file = ./demos/xyzbc_switchkins.ngc</text>
<rect x="470" y="430" width="410" height="240" class="box core"/>
<text x="510" y="480" class="head">运动学与 HAL</text>
<text x="510" y="524" class="body">xyzbc-trt-kins.c</text>
<text x="510" y="560" class="body">switchkins.c / kinstype.is.N</text>
<text x="510" y="596" class="body">trtfuncs.c / xyzbc forward-inverse</text>
<text x="510" y="632" class="body">motion.switchkins-type &lt;= motion.analog-out-03</text>
<text x="510" y="668" class="body">tool-offset / x-offset / z-offset / conventional-directions</text>
<rect x="965" y="155" width="370" height="230" class="box ui"/>
<text x="1000" y="205" class="head">界面与交互</text>
<text x="1000" y="249" class="body">AXIS 主界面</text>
<text x="1000" y="285" class="body">PyVCP SWITCHKINS 面板</text>
<text x="1000" y="321" class="body">MDI / 点动 / DRO / 程序</text>
<text x="1000" y="357" class="body">vismach-clear / 相机视图</text>
<rect x="965" y="430" width="370" height="240" class="box ui"/>
<text x="1000" y="480" class="head">三维机床模型</text>
<text x="1000" y="524" class="body">xyzbc-trt-gui.py</text>
<text x="1000" y="560" class="body">table-x / saddle-y / spindle-z</text>
<text x="1000" y="596" class="body">tilt-b / rotate-c / tool-offset</text>
<text x="1000" y="632" class="body">Three.js 等价模型</text>
<text x="1000" y="668" class="body">显示路径、刀具、工件、姿态</text>
<rect x="1405" y="205" width="330" height="205" class="box data"/>
<text x="1440" y="255" class="head">运行状态</text>
<text x="1440" y="299" class="body">task_state / interp_state</text>
<text x="1440" y="335" class="body">joint.*.pos-fb / DRO</text>
<text x="1440" y="371" class="body">kinstype.is-0/1/2</text>
<rect x="1405" y="470" width="330" height="205" class="box data"/>
<text x="1440" y="520" class="head">路径证据 JSON</text>
<text x="1440" y="564" class="body">previewPath / executionPath</text>
<text x="1440" y="600" class="body">samplePeriodMs = 20</text>
<text x="1440" y="636" class="body">screenshots / compare-report</text>
<rect x="470" y="760" width="1265" height="220" class="box warn"/>
<text x="510" y="812" class="head">关键约束</text>
<text x="510" y="856" class="body">1. switchkins 切换前必须同步解释器和 motion程序中用 M428/M429/M430 或等价 HAL/MDI 触发。</text>
<text x="510" y="892" class="body">2. 真实系统与 Web 系统的路径采样周期必须一致,当前统一为 20 ms禁止一端快一端慢。</text>
<text x="510" y="928" class="body">3. UI 只反映 HAL 和状态机,不直接篡改机床内部状态;所有操作必须回到 HAL/任务/运动学层。</text>
<text x="510" y="964" class="body">4. 五轴姿态、tooloffset、x/z offset、conventional-directions 与原型系统一致后,才能进入对比验收。</text>
<path d="M390 255 L470 255" class="line"/>
<path d="M390 490 L470 490" class="line"/>
<path d="M880 265 L965 265" class="line"/>
<path d="M880 545 L965 545" class="line"/>
<path d="M1335 255 L1405 255" class="line"/>
<path d="M1335 545 L1405 545" class="line"/>
<path d="M1130 395 L1130 430" class="line dash"/>
<path d="M1550 410 L1550 470" class="line"/>
</svg>

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

View File

@@ -0,0 +1,72 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="900" viewBox="0 0 1600 900">
<defs>
<style>
text { font-family: "Noto Sans CJK SC", "Microsoft YaHei", Arial, sans-serif; fill: #1f2937; }
.title { font-size: 40px; font-weight: 700; }
.sub { font-size: 24px; fill: #475569; }
.box-title { font-size: 28px; font-weight: 700; }
.body { font-size: 22px; }
.small { font-size: 18px; fill: #475569; }
.linux { fill: #eef6ff; stroke: #2563eb; stroke-width: 3; }
.web { fill: #f4fbf7; stroke: #16a34a; stroke-width: 3; }
.evidence { fill: #fff7ed; stroke: #f97316; stroke-width: 3; }
.neutral { fill: #f8fafc; stroke: #64748b; stroke-width: 2; }
.line { stroke: #334155; stroke-width: 3; fill: none; marker-end: url(#arrow); }
.dash { stroke-dasharray: 8 7; }
</style>
<marker id="arrow" markerWidth="14" markerHeight="14" refX="12" refY="7" orient="auto" markerUnits="strokeWidth">
<path d="M 0 0 L 14 7 L 0 14 z" fill="#334155"/>
</marker>
</defs>
<rect width="1600" height="900" fill="#ffffff"/>
<text x="60" y="70" class="title">xyzbc-trt 完全对标的 Web 数控仿真架构</text>
<text x="60" y="110" class="sub">以 LinuxCNC 真实运行链路为基线Web 端逐项复刻界面、运动学、HAL 语义和路径证据。</text>
<rect x="60" y="165" width="520" height="560" rx="16" class="linux"/>
<text x="95" y="215" class="box-title">LinuxCNC 原型系统</text>
<text x="95" y="265" class="body">rip-environment + linuxcnc</text>
<text x="95" y="310" class="body">xyzbc-trt.ini</text>
<text x="95" y="355" class="body">AXIS 主界面 + PyVCP 面板</text>
<text x="95" y="400" class="body">Vismach 机床模型 xyzbc-trt-gui</text>
<text x="95" y="445" class="body">HAL: basic_sim.tcl / postgui HAL</text>
<text x="95" y="490" class="body">KINS: xyzbc-trt-kins switchkins</text>
<text x="95" y="535" class="body">TASK / motion / tool table / var</text>
<text x="95" y="580" class="body">演示程序 xyzbc_switchkins.ngc</text>
<text x="95" y="645" class="small">运行路径:/home/mes123456/cnc_wams/linuxcnc</text>
<rect x="1020" y="165" width="520" height="560" rx="16" class="web"/>
<text x="1055" y="215" class="box-title">Web 数控仿真系统</text>
<text x="1055" y="265" class="body">浏览器首屏 CNC 工作台</text>
<text x="1055" y="310" class="body">INI/XML/HAL/NGC/TBL/VAR 解析器</text>
<text x="1055" y="355" class="body">AXIS 等价 UI 与 PyVCP 等价控件</text>
<text x="1055" y="400" class="body">Three.js 五轴机床与刀具路径</text>
<text x="1055" y="445" class="body">HAL 信号总线与 switchkins 状态机</text>
<text x="1055" y="490" class="body">XYZBC 正逆运动学与 TCP 模式</text>
<text x="1055" y="535" class="body">预览、执行、MDI、复位、清轨迹</text>
<text x="1055" y="580" class="body">证据 JSON 导出和对比报告</text>
<text x="1055" y="645" class="small">目标:功能、状态、路径、误差可量化对标</text>
<rect x="660" y="230" width="280" height="115" rx="12" class="evidence"/>
<text x="698" y="278" class="box-title">采集基线 JSON</text>
<text x="698" y="316" class="small">状态、引脚、路径、截图</text>
<rect x="660" y="415" width="280" height="115" rx="12" class="evidence"/>
<text x="702" y="463" class="box-title">Web 输出 JSON</text>
<text x="704" y="501" class="small">同周期、同字段、同坐标系</text>
<rect x="660" y="600" width="280" height="115" rx="12" class="neutral"/>
<text x="704" y="648" class="box-title">对标验收报告</text>
<text x="704" y="686" class="small">误差、缺口、截图、结论</text>
<path d="M580 290 L660 290" class="line"/>
<path d="M940 290 L1020 290" class="line"/>
<path d="M1020 475 L940 475" class="line dash"/>
<path d="M660 475 L580 475" class="line dash"/>
<path d="M800 345 L800 415" class="line"/>
<path d="M800 530 L800 600" class="line"/>
<text x="621" y="205" class="small">真实系统采样</text>
<text x="996" y="205" class="small">Web 复刻与回放</text>
<text x="1005" y="535" class="small">差异闭环</text>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -0,0 +1,726 @@
# xyzbc-trt 当前运行配置文件说明
本文档记录当前运行的 LinuxCNC RTCP/TCP 五轴示例:
`configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini`
它是一个 `XYZBC` table rotary/tilting 五轴仿真配置,使用 AXIS 主界面、PyVCP 面板、Vismach 三维机床模型,以及 `switchkins` 方式在不同运动学模式之间切换。
当前对标的 run-in-place 根目录:
```text
/home/mes123456/cnc_wams/linuxcnc
```
当前启动命令:
```bash
/home/mes123456/cnc_wams/linuxcnc/scripts/rip-environment linuxcnc \
/home/mes123456/cnc_wams/linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini
```
## 当前进程
当前目标配置运行时的关键进程如下:
```text
/bin/bash /home/mes123456/cnc_wams/linuxcnc/scripts/linuxcnc /home/mes123456/cnc_wams/linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini
linuxcncsvr -ini /home/mes123456/cnc_wams/linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini
/home/mes123456/cnc_wams/linuxcnc/bin/rtapi_app load tpmod
milltask -ini /home/mes123456/cnc_wams/linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini
halui -ini /home/mes123456/cnc_wams/linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini
/usr/bin/python3.13 /home/mes123456/cnc_wams/linuxcnc/bin/hal_manualtoolchange
/usr/bin/python3.13 /home/mes123456/cnc_wams/linuxcnc/bin/xyzbc-trt-gui
/usr/bin/python3.13 /home/mes123456/cnc_wams/linuxcnc/bin/axis -ini /home/mes123456/cnc_wams/linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini
```
当前目标配置的进程均来自 `/home/mes123456/cnc_wams/linuxcnc`,并使用 `configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini`
当前 LinuxCNC Python API 状态检查:
```text
file = ./demos/xyzbc_switchkins.ngc
axis_mask = 55
position = [0.0, 0.0, 0.0, 0.0, 0.0]
task_state = 1
interp_state = 1
```
## 启动入口
快捷方式:
```text
/home/mes123456/cnc_wams/linuxcnc/linuxcnc-rtcp-5axis-shortcuts/table-rotary-tilting/xyzbc-trt.desktop
```
快捷方式执行命令:
```bash
/home/mes123456/cnc_wams/linuxcnc/scripts/rip-environment linuxcnc \
/home/mes123456/cnc_wams/linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini
```
`rip-environment` 负责设置 run-in-place 环境,包括 `PATH``LD_LIBRARY_PATH``PYTHONPATH``TCLLIBPATH` 等,使本地编译出来的 LinuxCNC 程序、库、Python 模块可被找到。
## 文件关系总览
主配置文件:
```text
configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini
```
它引用或触发以下文件:
```text
[DISPLAY] DISPLAY = axis
-> bin/axis
-> src/emc/usr_intf/axis/scripts/axis.py
[DISPLAY] PYVCP = ./xyzbc-trt.xml
-> configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.xml
[DISPLAY] OPEN_FILE = ./demos/xyzbc_switchkins.ngc
-> configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc
[HAL] HALFILE = LIB:basic_sim.tcl
-> lib/hallib/basic_sim.tcl
-> 运行后生成 configs/.../xyzbc-trt_cmds.hal
[HAL] POSTGUI_HALFILE = switchkins_postgui.hal
-> configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins_postgui.hal
[HAL] HALCMD = loadusr -W xyzbc-trt-gui
-> bin/xyzbc-trt-gui
-> src/hal/user_comps/vismach/xyzbc-trt-gui.py
[RS274NGC] SUBROUTINE_PATH = ./remap_subs
-> remap_subs/428remap.ngc
-> remap_subs/429remap.ngc
-> remap_subs/430remap.ngc
-> remap_subs/xyzbc_switchkins_sub.ngc
-> remap_subs/centering.ngc
-> remap_subs/helix_bc.ngc
[EMCIO] TOOL_TABLE = xyzbc-trt.tbl
-> configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.tbl
[RS274NGC] PARAMETER_FILE = xyzbc.var
-> configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc.var
```
## 主 INI 文件
路径:
```text
configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini
```
关键内容:
```ini
[EMC]
VERSION = 1.1
MACHINE = sim-xyzbc-trt-kins (switchkins)
[DISPLAY]
GEOMETRY = XYZB
OPEN_FILE = ./demos/xyzbc_switchkins.ngc
PYVCP = ./xyzbc-trt.xml
JOG_AXES = XYZC
DISPLAY = axis
MAX_ANGULAR_VELOCITY = 360
MAX_LINEAR_VELOCITY = 1000
POSITION_OFFSET = RELATIVE
POSITION_FEEDBACK = ACTUAL
MAX_FEED_OVERRIDE = 2
PROGRAM_PREFIX = ../../nc_files
INTRO_GRAPHIC = emc2.gif
INTRO_TIME = 1
TOOL_EDITOR = tooledit z diam
TKPKG = Ngcgui 1.0
NGCGUI_FONT = Helvetica -12 normal
NGCGUI_SUBFILE = xyzbc_switchkins_sub.ngc
NGCGUI_SUBFILE = centering.ngc
[RS274NGC]
SUBROUTINE_PATH = ./remap_subs
HAL_PIN_VARS = 1
REMAP = M428 modalgroup=10 ngc=428remap
REMAP = M429 modalgroup=10 ngc=429remap
REMAP = M430 modalgroup=10 ngc=430remap
PARAMETER_FILE = xyzbc.var
[KINS]
# default switchkins-type == 0 is xyzbc-trt-kins
# here switchkins-type == 0 is identity kins
KINEMATICS = xyzbc-trt-kins sparm=identityfirst
JOINTS = 5
[HAL]
HALUI = halui
HALFILE = LIB:basic_sim.tcl
POSTGUI_HALFILE = switchkins_postgui.hal
# net for control of motion.switchkins-type
HALCMD = net :kinstype-select <= motion.analog-out-03 => motion.switchkins-type
# vismach xyzbc-trt-gui items
HALCMD = loadusr -W xyzbc-trt-gui
HALCMD = net :table-x joint.0.pos-fb xyzbc-trt-gui.table-x
HALCMD = net :saddle-y joint.1.pos-fb xyzbc-trt-gui.saddle-y
HALCMD = net :spindle-z joint.2.pos-fb xyzbc-trt-gui.spindle-z
HALCMD = net :tilt-b joint.3.pos-fb xyzbc-trt-gui.tilt-b
HALCMD = net :rotate-c joint.4.pos-fb xyzbc-trt-gui.rotate-c
HALCMD = net :tool-offset motion.tooloffset.z
HALCMD = net :tool-offset xyzbc-trt-kins.tool-offset xyzbc-trt-gui.tool-offset
HALCMD = net :x-offset xyzbc-trt-kins.x-offset xyzbc-trt-gui.x-offset
HALCMD = net :z-offset xyzbc-trt-kins.z-offset xyzbc-trt-gui.z-offset
HALCMD = sets :x-offset -20
HALCMD = sets :z-offset -15
HALCMD = setp xyzbc-trt-kins.x-rot-point 0
HALCMD = setp xyzbc-trt-kins.y-rot-point 0
HALCMD = setp xyzbc-trt-kins.z-rot-point 0
HALCMD = setp xyzbc-trt-kins.conventional-directions 0
[HALUI]
# kinstype==0 is identity kins because sparm=identityfirst
# M429: identity kins
# M428: xyzbc kins / TCP mode
# M430: userk kins
MDI_COMMAND = M429
MDI_COMMAND = M428
MDI_COMMAND = M430
[TRAJ]
COORDINATES = XYZBC
LINEAR_UNITS = mm
ANGULAR_UNITS = deg
DEFAULT_LINEAR_VELOCITY = 20
MAX_LINEAR_VELOCITY = 35
MAX_LINEAR_ACCELERATION = 400
DEFAULT_LINEAR_ACCELERATION = 300
[EMCMOT]
EMCMOT = motmod
SERVO_PERIOD = 1000000
COMM_TIMEOUT = 1
[TASK]
TASK = milltask
CYCLE_TIME = 0.010
[EMCIO]
TOOL_TABLE = xyzbc-trt.tbl
```
轴和关节部分定义 `XYZBC` 五轴:
```ini
[AXIS_X] [AXIS_Y] [AXIS_Z]
LINEAR axes, limits in mm.
[AXIS_B] [AXIS_C]
ANGULAR axes, limits in degrees.
[JOINT_0] X linear
[JOINT_1] Y linear
[JOINT_2] Z linear
[JOINT_3] B angular, MIN_LIMIT=-100, MAX_LIMIT=50
[JOINT_4] C angular, MIN_LIMIT=-36000, MAX_LIMIT=36000
```
## PyVCP 界面文件
路径:
```text
configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.xml
```
这个 XML 文件由 AXIS 读取 `[DISPLAY]PYVCP` 后加载,显示在 AXIS 窗口右侧。它提供:
- 当前运动学模式显示:`0:IDENTITY``1: XYZBC``2: USERK`
- 三个按钮:`IDENTITY``TCP:XYZBC``userk`
- 一个 `vismach-clear` 按钮,用于清除 Vismach 轨迹显示
完整内容:
```xml
<?xml version='1.0' encoding='UTF-8'?>
<pyvcp>
<vbox>
<relief>"ridge"</relief>
<bd>5</bd>
<label>
<text>"SWITCHKINS"</text>
<relief>RIDGE</relief>
<bd>3</bd>
</label>
<multilabel>
<legends>["0:IDENTITY", "1: XYZBC ", "2: USERK "]</legends>
<font>("Helvetica",16)</font>
<bg>"black"</bg>
<fg>"yellow"</fg>
</multilabel>
<button>
<halpin>"type0-button"</halpin>
<text>"IDENTITY"</text>
<bd>3</bd>
</button>
<button>
<halpin>"type1-button"</halpin>
<text>"TCP:XYZBC"</text>
<bd>3</bd>
</button>
<button>
<halpin>"type2-button"</halpin>
<text>"userk"</text>
<bd>3</bd>
</button>
</vbox>
<vbox>
<relief>"ridge"</relief>
<bd>5</bd>
<button>
<halpin>"vismach-clear"</halpin>
<text>"vismach-clear"</text>
<bd>3</bd>
</button>
</vbox>
</pyvcp>
```
## POSTGUI HAL 文件
路径:
```text
configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins_postgui.hal
```
这个文件在 AXIS/PyVCP 界面创建完成后加载,所以它可以连接 `pyvcp.*` 引脚。
完整内容:
```hal
# switchkins pyvcp connections for:
# xyzac-trt-kins.ini,xyzbc-trt-kins.ini
net :kinstype.is-0 <= kinstype.is-0 => pyvcp.multilabel.0.legend0
net :kinstype.is-1 <= kinstype.is-1 => pyvcp.multilabel.0.legend1
net :kinstype.is-2 <= kinstype.is-2 => pyvcp.multilabel.0.legend2
net :vismach-clear <= pyvcp.vismach-clear => vismach.plotclear
net :type0-button <= pyvcp.type0-button => halui.mdi-command-00
net :type1-button <= pyvcp.type1-button => halui.mdi-command-01
net :type2-button <= pyvcp.type2-button => halui.mdi-command-02
```
作用:
- `kinstype.is-*` 驱动 PyVCP 的 `multilabel`,显示当前 kinematics 类型。
- PyVCP 三个按钮连接到 `halui.mdi-command-00/01/02`
- `[HALUI] MDI_COMMAND` 定义这三个命令分别执行 `M429``M428``M430`
- `vismach-clear` 连接到 `vismach.plotclear`,清除 Vismach 显示轨迹。
## Vismach Python 界面文件
运行入口:
```text
/home/mes123456/cnc_wams/linuxcnc/bin/xyzbc-trt-gui
```
源码路径:
```text
src/hal/user_comps/vismach/xyzbc-trt-gui.py
```
该 Python 文件创建名为 `xyzbc-trt-gui` 的 HAL 用户组件,并建立 Vismach 三维机床模型。INI 中的以下 HALCMD 启动并连接它:
```hal
HALCMD = loadusr -W xyzbc-trt-gui
HALCMD = net :table-x joint.0.pos-fb xyzbc-trt-gui.table-x
HALCMD = net :saddle-y joint.1.pos-fb xyzbc-trt-gui.saddle-y
HALCMD = net :spindle-z joint.2.pos-fb xyzbc-trt-gui.spindle-z
HALCMD = net :tilt-b joint.3.pos-fb xyzbc-trt-gui.tilt-b
HALCMD = net :rotate-c joint.4.pos-fb xyzbc-trt-gui.rotate-c
HALCMD = net :tool-offset xyzbc-trt-kins.tool-offset xyzbc-trt-gui.tool-offset
HALCMD = net :x-offset xyzbc-trt-kins.x-offset xyzbc-trt-gui.x-offset
HALCMD = net :z-offset xyzbc-trt-kins.z-offset xyzbc-trt-gui.z-offset
```
### HAL 引脚
`xyzbc-trt-gui.py` 创建这些输入引脚:
```python
c = hal.component("xyzbc-trt-gui")
c.newpin("table-x", hal.HAL_FLOAT, hal.HAL_IN)
c.newpin("saddle-y", hal.HAL_FLOAT, hal.HAL_IN)
c.newpin("spindle-z", hal.HAL_FLOAT, hal.HAL_IN)
c.newpin("tilt-b", hal.HAL_FLOAT, hal.HAL_IN)
c.newpin("rotate-c", hal.HAL_FLOAT, hal.HAL_IN)
c.newpin("z-offset", hal.HAL_FLOAT, hal.HAL_IN)
c.newpin("x-offset", hal.HAL_FLOAT, hal.HAL_IN)
c.newpin("tool-offset", hal.HAL_FLOAT, hal.HAL_IN)
c.ready()
```
### 模型结构
该脚本使用 `vismach``Collection``Box``CylinderZ``HalTranslate``HalRotate` 等构造机床模型:
- `tool`: 刀具和刀尖捕获点,受 `tool-offset` 影响。
- `spindle`: 主轴和刀柄。
- `head`: 主轴头,受 `spindle-z` 影响。
- `ctable`: C 轴旋转台,受 `rotate-c` 影响。
- `arotary`: B 轴倾斜组件,受 `tilt-b` 影响。
- `table`: X 方向工作台,受 `table-x` 影响。
- `saddle`: Y 方向滑鞍,受 `saddle-y` 影响。
- `base`: 机床底座和立柱。
最终调用:
```python
model = Collection([yslide, base])
myhud = Hud()
myhud.show("XYZBC")
main(model, tooltip, work, size=500, hud=myhud, lat=-60, lon=25)
```
这会打开 Vismach 窗口,显示 `XYZBC` 五轴仿真模型。
## AXIS 主界面 Python 文件
运行入口:
```text
/home/mes123456/cnc_wams/linuxcnc/bin/axis
```
对应源码:
```text
src/emc/usr_intf/axis/scripts/axis.py
```
`bin/axis` 是构建后的可执行 Python 脚本,当前进程为:
```text
/usr/bin/python3.13 /home/mes123456/cnc_wams/linuxcnc/bin/axis -ini /home/mes123456/cnc_wams/linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini
```
这个文件很大,当前源码约 `4308` 行。与本配置直接相关的加载点如下。
读取 INI
```python
if sys.argv[1] != "-ini":
raise SystemExit("-ini must be first argument")
inifile = linuxcnc.ini(sys.argv[2])
```
读取 POSTGUI HAL、几何、坐标等配置
```python
vars.emcini.set(sys.argv[2])
jointcount = inifile.getint("KINS", "JOINTS", fallback=0)
open_directory = inifile.getstring("DISPLAY", "PROGRAM_PREFIX", fallback=open_directory)
vars.machine.set(inifile.getstring("EMC", "MACHINE", fallback="<unknown>"))
postgui_halfile = inifile.findall("HAL", "POSTGUI_HALFILE") or None
postgui_halcmds = inifile.findall("HAL", "POSTGUI_HALCMD") or None
geometry = inifile.getstring("DISPLAY", "GEOMETRY", fallback="XYZABCUVW")
```
读取 PyVCP
```python
vcp = inifile.find("DISPLAY", "PYVCP")
```
创建 PyVCP 面板:
```python
if vcp:
import vcpparse
f = Tkinter.Frame(root_window)
if inifile.find("DISPLAY", "PYVCP_POSITION") == "BOTTOM":
f.grid(row=4, column=0, columnspan=6, sticky="nw", padx=4, pady=4)
else:
f.grid(row=0, column=4, rowspan=6, sticky="nw", padx=4, pady=4)
vcpparse.filename = vcp
vcpcomp = hal.component("pyvcp")
vcpparse.create_vcp(f, vcpcomp)
vcpcomp.ready()
vcp_frame = f
```
这些代码解释了为什么 `[DISPLAY]PYVCP = ./xyzbc-trt.xml` 会在 AXIS 中生成右侧的 `SWITCHKINS` 面板。
## 基础仿真 HAL/Tcl 文件
路径:
```text
lib/hallib/basic_sim.tcl
```
INI 中:
```ini
[HAL]
HALFILE = LIB:basic_sim.tcl
```
作用:
- 加载通用仿真组件。
- 根据 `[TRAJ]COORDINATES``[KINS]JOINTS` 创建基础运动仿真。
- 创建 `ddt`、模拟回零、手动换刀和模拟主轴。
- 运行后生成等效 HAL 文件:
```text
configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt_cmds.hal
```
关键逻辑:
```tcl
source [file join $::env(HALLIB_DIR) sim_lib.tcl]
set axes [get_traj_coordinates]
set number_of_joints $::KINS(JOINTS)
core_sim $axes \
$number_of_joints \
$::EMCMOT(SERVO_PERIOD) \
$base_period \
$::EMCMOT(EMCMOT)
make_ddts $number_of_joints
simulated_home $number_of_joints
use_hal_manualtoolchange
sim_spindle
save_hal_cmds $savefilename $save_options
```
## switchkins / RTCP 切换逻辑
本配置使用 `motion.switchkins-type` 选择不同运动学模式。
关键 HAL 连接:
```hal
net :kinstype-select <= motion.analog-out-03 => motion.switchkins-type
```
关键 MDI 命令:
```ini
[HALUI]
MDI_COMMAND = M429
MDI_COMMAND = M428
MDI_COMMAND = M430
```
三个 remap 子程序:
```text
remap_subs/429remap.ngc -> kinstype = 0 -> IDENTITY
remap_subs/428remap.ngc -> kinstype = 1 -> XYZBC / TCP
remap_subs/430remap.ngc -> kinstype = 2 -> USERK
```
`M428` 的核心逻辑:
```ngc
;M428 by remap: kinstype==1 (xyzac,xyzbc)
o<428remap>sub
#<kinstype> = 1
#<SWITCHKINS_PIN> = 3
M68 E#<SWITCHKINS_PIN> Q#<kinstype>
M66 E0 L0
o2 if [[#<_task> EQ 1] AND [#<_hal[motion.switchkins-type]> NE #<kinstype>]]
(debug,M428: Wrong motion.switchkins-type)
(debug,or missing hal net to analog-out-0x)
(debug,STOP)
M2
o2 else
o2 endif
o<428remap>endsub
```
`M429` 类似,但设置 `kinstype = 0``M430` 设置 `kinstype = 2`
## 演示 G-code
启动时自动打开:
```text
configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc
```
内容:
```ngc
; zmax zmin r frate n a b c dist
o<xyzbc_switchkins_sub> call [10] [5] [10][1000][3][0][20][45][20]
m2
```
它调用:
```text
remap_subs/xyzbc_switchkins_sub.ngc
```
该子程序会在四个象限中:
- 先用 `M429` 切到 Identity kinematics。
- 设置机器坐标和 G54。
- 调用 `helix_bc`,用 B/C 角度演示 TCP/五轴联动轨迹。
- 最后回到 Identity kinematics。
## 工具表
路径:
```text
configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.tbl
```
内容:
```text
T1 P1 D1
T2 P2 Z10 D8
```
工具表会影响 `motion.tooloffset.z`,并通过 HAL 连接到:
```hal
xyzbc-trt-kins.tool-offset
xyzbc-trt-gui.tool-offset
```
所以工具长度会同时影响运动学计算和 Vismach 显示。
## 运动学组件
运行时加载:
```text
rtlib/xyzbc-trt-kins.so
```
源码:
```text
src/emc/kinematics/xyzbc-trt-kins.c
```
相关说明文件:
```text
configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.txt
```
说明文件中的核心语义:
```text
M429: Identity Kinematics
M428: XYZBC (TCP)
M430: userk Kinematics
net :kinstype-select <= motion.analog-out-03
net :kinstype-select => motion.switchkins-type
```
`xyzbc-trt-kins` 提供这些和配置相关的 HAL 输入:
```text
xyzbc-trt-kins.x-offset
xyzbc-trt-kins.z-offset
xyzbc-trt-kins.x-rot-point
xyzbc-trt-kins.y-rot-point
xyzbc-trt-kins.z-rot-point
xyzbc-trt-kins.conventional-directions
xyzbc-trt-kins.tool-offset
```
## 加载顺序
简化后的启动流程:
1. `.desktop` 执行 `rip-environment linuxcnc xyzbc-trt.ini`
2. `scripts/linuxcnc` 读取 INI启动 `linuxcncsvr``rtapi_app``milltask``halui`
3. `[HAL] HALFILE = LIB:basic_sim.tcl` 加载基础仿真 HAL。
4. `[KINS] KINEMATICS = xyzbc-trt-kins sparm=identityfirst` 加载运动学组件。
5. `[HAL] HALCMD = loadusr -W xyzbc-trt-gui` 启动 Vismach Python 模型。
6. `[DISPLAY] DISPLAY = axis` 启动 AXIS。
7. AXIS 读取 `[DISPLAY] PYVCP = ./xyzbc-trt.xml`,创建 PyVCP 面板。
8. AXIS 界面创建后加载 `POSTGUI_HALFILE = switchkins_postgui.hal`,连接 PyVCP 引脚和 HALUI MDI 命令。
9. `[DISPLAY] OPEN_FILE = ./demos/xyzbc_switchkins.ngc` 自动载入演示 G-code。
## 重要文件清单
```text
主配置:
configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini
AXIS 主界面:
bin/axis
src/emc/usr_intf/axis/scripts/axis.py
PyVCP 面板:
configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.xml
POSTGUI HAL:
configs/sim/axis/vismach/5axis/table-rotary-tilting/switchkins_postgui.hal
Vismach Python 机床模型:
bin/xyzbc-trt-gui
src/hal/user_comps/vismach/xyzbc-trt-gui.py
基础仿真 HAL/Tcl:
lib/hallib/basic_sim.tcl
运行后生成的等效 HAL:
configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt_cmds.hal
运动学组件:
rtlib/xyzbc-trt-kins.so
src/emc/kinematics/xyzbc-trt-kins.c
remap 子程序:
configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/428remap.ngc
configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/429remap.ngc
configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/430remap.ngc
configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/xyzbc_switchkins_sub.ngc
configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/centering.ngc
configs/sim/axis/vismach/5axis/table-rotary-tilting/remap_subs/helix_bc.ngc
演示程序:
configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/xyzbc_switchkins.ngc
configs/sim/axis/vismach/5axis/table-rotary-tilting/demos/boat-xyzbc.ngc
工具表和参数:
configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.tbl
configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc.var
```

View File

@@ -0,0 +1,381 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>xyzbc-trt Web 数控仿真系统设计任务书和技术方案</title>
<style>
@page { size: A4; margin: 18mm 16mm; }
body {
font-family: "Noto Sans CJK SC", "Microsoft YaHei", Arial, sans-serif;
color: #172033;
line-height: 1.55;
font-size: 10.8pt;
}
h1 { font-size: 24pt; margin: 0 0 10pt; color: #0f172a; }
h2 { font-size: 17pt; margin: 22pt 0 8pt; border-bottom: 1.2pt solid #94a3b8; padding-bottom: 4pt; color: #0f172a; }
h3 { font-size: 13pt; margin: 16pt 0 6pt; color: #1e293b; }
p { margin: 5pt 0; }
.cover {
min-height: 215mm;
display: block;
padding-top: 45mm;
}
.cover .subtitle { font-size: 15pt; color: #334155; margin-top: 10pt; }
.meta { margin-top: 35pt; border-collapse: collapse; width: 100%; }
.meta td { border: 1pt solid #cbd5e1; padding: 8pt; font-size: 11pt; }
.page-break { page-break-before: always; }
.note {
border-left: 4pt solid #2563eb;
background: #eff6ff;
padding: 8pt 10pt;
margin: 8pt 0 10pt;
}
.warn {
border-left: 4pt solid #f97316;
background: #fff7ed;
padding: 8pt 10pt;
margin: 8pt 0 10pt;
}
table { border-collapse: collapse; width: 100%; margin: 8pt 0 12pt; }
th, td { border: 1pt solid #cbd5e1; padding: 6pt 7pt; vertical-align: top; }
th { background: #e2e8f0; font-weight: 700; }
code, pre {
font-family: "DejaVu Sans Mono", Consolas, monospace;
font-size: 9.2pt;
}
pre {
background: #0f172a;
color: #e5e7eb;
padding: 9pt;
white-space: pre-wrap;
border-radius: 4pt;
margin: 8pt 0 12pt;
}
.figure { margin: 12pt 0 16pt; text-align: center; page-break-inside: avoid; }
.figure img { max-width: 100%; height: auto; border: 1pt solid #cbd5e1; }
.caption { color: #475569; font-size: 9.5pt; margin-top: 5pt; text-align: center; }
ul { margin-top: 4pt; }
li { margin: 3pt 0; }
</style>
</head>
<body>
<section class="cover">
<h1>xyzbc-trt Web 数控仿真系统<br>设计任务书和技术方案</h1>
<p class="subtitle">完全对标 LinuxCNC <code>xyzbc-trt</code> 五轴 table rotary/tilting 仿真配置</p>
<table class="meta">
<tr><td>原型系统</td><td><code>/home/mes123456/cnc_wams/linuxcnc</code></td></tr>
<tr><td>启动命令</td><td><code>/home/mes123456/cnc_wams/linuxcnc/scripts/rip-environment linuxcnc /home/mes123456/cnc_wams/linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini</code></td></tr>
<tr><td>目标产物</td><td>浏览器端 Web 数控仿真界面、五轴机床模型、switchkins 逻辑、路径预览与执行对比 JSON</td></tr>
<tr><td>文档位置</td><td><code>/home/mes123456/cnc_wams/web-rtcp-5axis-xyzbc-trt-sim-plan/doc</code></td></tr>
<tr><td>编制日期</td><td>2026-07-02</td></tr>
</table>
</section>
<section class="page-break">
<h2>1. 项目目标</h2>
<p>本项目建设一个 Web 数控仿真系统,功能和行为完全对标 LinuxCNC 真实运行配置 <code>xyzbc-trt.ini</code>。Web 系统不是展示页而是首屏即进入数控仿真工作台提供程序加载、预览、DRO、MDI、PyVCP 等价控件、五轴机床运动显示、switchkins 模式切换、刀具路径采样、执行过程记录和误差对比。</p>
<p>对标基线以已编译成功并能运行的 <code>/home/mes123456/cnc_wams/linuxcnc</code> 为准,历史旧 LinuxCNC 目录不再作为本方案的运行基线。</p>
<div class="note">
<p>核心验收原则:同一份配置、同一份 G-code、同一运动学模式、同一采样周期、同一 JSON 字段,分别采集 LinuxCNC 真实系统和 Web 仿真系统的预览路径与执行路径,逐点比对位置、姿态、运动学模式和 HAL 状态。</p>
</div>
<h2>2. 原型系统运行证据</h2>
<h3>2.1 当前启动命令</h3>
<pre>/home/mes123456/cnc_wams/linuxcnc/scripts/rip-environment linuxcnc \
/home/mes123456/cnc_wams/linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini</pre>
<h3>2.2 当前关键进程</h3>
<table>
<tr><th>进程</th><th>对标含义</th></tr>
<tr><td><code>scripts/linuxcnc xyzbc-trt.ini</code></td><td>LinuxCNC 主启动入口Web 端需实现等价启动会话和配置装载流程。</td></tr>
<tr><td><code>linuxcncsvr</code></td><td>NML/状态服务Web 端需提供统一运行状态中心。</td></tr>
<tr><td><code>rtapi_app load tpmod</code></td><td>运动规划模块Web 端需实现轨迹规划与采样接口。</td></tr>
<tr><td><code>milltask</code></td><td>任务解释和程序执行Web 端需实现程序状态机、运行、暂停、复位、MDI。</td></tr>
<tr><td><code>halui</code></td><td>HAL UI 指令通道Web 端需复刻 PyVCP 按钮到 MDI 命令的连接。</td></tr>
<tr><td><code>hal_manualtoolchange</code></td><td>手动换刀流程Web 端需提供换刀提示和工具状态。</td></tr>
<tr><td><code>xyzbc-trt-gui</code></td><td>Vismach 五轴机床模型Web 端需使用 Three.js 对标机床结构和运动。</td></tr>
<tr><td><code>axis -ini xyzbc-trt.ini</code></td><td>AXIS 主界面Web 端需对标界面信息架构和操作入口。</td></tr>
</table>
<h3>2.3 当前界面截图</h3>
<div class="figure">
<img src="assets/xyzbc-trt-axis-window.png" alt="xyzbc-trt AXIS window">
<div class="caption">图 1通过真实 LinuxCNC 会话抓取的 AXIS 主界面包含预览、DRO、PyVCP SWITCHKINS 面板、程序区和状态栏。</div>
</div>
<div class="figure">
<img src="assets/xyzbc-trt-desktop.png" alt="xyzbc-trt desktop screenshot">
<div class="caption">图 2桌面级运行截图用于保留真实执行环境和窗口布局证据。</div>
</div>
<h3>2.4 HAL 状态基线</h3>
<table>
<tr><th>HAL 项</th><th>当前值或连接</th><th>Web 对标要求</th></tr>
<tr><td><code>motion.switchkins-type</code></td><td><code>0</code>,由 <code>:kinstype-select</code> 驱动</td><td>实现 <code>0:IDENTITY</code><code>1:XYZBC</code><code>2:USERK</code> 三态切换。</td></tr>
<tr><td><code>kinstype.is-0/1/2</code></td><td><code>TRUE/FALSE/FALSE</code></td><td>驱动 Web PyVCP multilabel 的当前模式显示。</td></tr>
<tr><td><code>joint.0..4.pos-fb</code></td><td>X/Y/Z/B/C 五轴反馈均为 <code>0</code></td><td>映射到 Web DRO、机床模型关节和路径采样。</td></tr>
<tr><td><code>motion.tooloffset.z</code></td><td>连接 <code>:tool-offset</code></td><td>影响 TCP 刀尖位置和机床模型刀具长度。</td></tr>
<tr><td><code>xyzbc-trt-kins.x-offset</code></td><td><code>-20</code></td><td>Web 运动学参数必须使用同值。</td></tr>
<tr><td><code>xyzbc-trt-kins.z-offset</code></td><td><code>-15</code></td><td>Web 运动学参数必须使用同值。</td></tr>
<tr><td><code>xyzbc-trt-kins.conventional-directions</code></td><td><code>FALSE</code></td><td>Web 端旋转方向和矩阵约定必须一致。</td></tr>
</table>
</section>
<section class="page-break">
<h2>3. 完全对标范围</h2>
<table>
<tr><th>LinuxCNC 文件或模块</th><th>真实功能</th><th>Web 对标实现</th></tr>
<tr><td><code>xyzbc-trt.ini</code></td><td>定义 AXIS、PyVCP、KINS、HAL、TRAJ、TASK、EMCIO、轴和关节参数。</td><td>实现 INI 解析器,生成 Web 会话配置、轴参数、速度限制、文件引用和 UI 初始状态。</td></tr>
<tr><td><code>xyzbc-trt.xml</code></td><td>定义 SWITCHKINS multilabel、IDENTITY、TCP:XYZBC、userk、vismach-clear 按钮。</td><td>实现 PyVCP 等价面板,按钮通过 Web HAL 总线触发 MDI 命令或清除轨迹。</td></tr>
<tr><td><code>switchkins_postgui.hal</code></td><td>把 PyVCP 控件接到 <code>halui.mdi-command-00/01/02</code><code>vismach.plotclear</code></td><td>实现 postgui HAL 装配层,保证 UI 控件不直接改状态,而是经 HAL 语义连接。</td></tr>
<tr><td><code>LIB:basic_sim.tcl</code></td><td>生成仿真 HAL 基础链路。</td><td>在 Web 中建立基础 HAL 信号、仿真 joint、motion、halui、pyvcp、vismach 命名空间。</td></tr>
<tr><td><code>xyzbc-trt-kins.so</code></td><td>XYZBC table rotary/tilting 运动学和 switchkins。</td><td>实现或移植为 WASM/TypeScript 运动学模块,支持 identity、XYZBC TCP、userk。</td></tr>
<tr><td><code>xyzbc-trt-gui</code></td><td>Vismach 三维机床模型,随 HAL 引脚运动。</td><td>使用 Three.js 建立桌台、转台、倾斜轴、主轴、刀具、工件和路径轨迹。</td></tr>
<tr><td><code>xyzbc_switchkins.ngc</code></td><td>默认打开的演示程序,调用 <code>xyzbc_switchkins_sub</code></td><td>Web 端默认加载同一程序,预览曲线和执行曲线可导出 JSON。</td></tr>
<tr><td><code>remap_subs/*.ngc</code></td><td>M428/M429/M430 以及演示子程序。</td><td>支持 remap 调用或预编译宏展开,保证模式切换轨迹一致。</td></tr>
<tr><td><code>xyzbc-trt.tbl</code></td><td>刀具表。</td><td>Web 端提供刀具表加载、显示、选择、tooloffset 影响。</td></tr>
<tr><td><code>xyzbc.var</code></td><td>RS274 参数文件。</td><td>Web 端持久化参数,支持会话恢复和对标导出。</td></tr>
</table>
<h2>4. Web 界面设计任务书</h2>
<h3>4.1 首屏布局</h3>
<p>Web 应用启动后直接进入数控仿真界面,不设置营销式首页。首屏按 AXIS 的工作流组织:</p>
<ul>
<li>顶部:文件、机器、视图、帮助菜单,以及急停、上电、打开文件、运行、暂停、单步、停止、视图方向、清扫轨迹等图标按钮。</li>
<li>左侧Manual Control 与 MDI 标签页,包含 Joint 0 到 4 选择、连续/增量点动、Home、Touch Off、Tool Touch Off、主轴控制和倍率滑块。</li>
<li>中间Preview/DRO/程序标签页,预览页显示 Three.js 五轴机床、工件、刀具、坐标轴、尺寸标注和刀具路径。</li>
<li>右侧SWITCHKINS 面板,显示 <code>0:IDENTITY</code><code>1:XYZBC</code><code>2:USERK</code>,并提供 <code>IDENTITY</code><code>TCP:XYZBC</code><code>userk</code><code>vismach-clear</code> 按钮。</li>
<li>底部G-code 程序区、Active G-Codes、状态栏、错误和日志输出。</li>
</ul>
<h3>4.2 视觉和交互要求</h3>
<table>
<tr><th>界面区域</th><th>对标要求</th><th>验收证据</th></tr>
<tr><td>AXIS 工具栏</td><td>保留关键数控操作入口,按钮使用明确图标和 tooltip。</td><td>截图比对,操作事件 JSON。</td></tr>
<tr><td>DRO</td><td>显示 X/Y/Z/B/C、joint 或 world 坐标、实际/命令位置。</td><td><code>uiState.dro</code> 与 LinuxCNC status 对比。</td></tr>
<tr><td>PyVCP</td><td>按钮和 multilabel 文案、状态、HAL 连线语义一致。</td><td><code>halPins.kinstype</code><code>uiState.pyvcp</code></td></tr>
<tr><td>Preview</td><td>显示默认程序的圆形/螺旋路径、刀尖、刀轴、XYZBC 坐标。</td><td><code>previewPath.samples</code> 和截图。</td></tr>
<tr><td>Vismach 等价模型</td><td>五轴结构、B/C 旋转、X/Y/Z 平移、tooloffset、x/z offset 生效。</td><td>模型姿态 JSON 和截图。</td></tr>
</table>
<div class="figure">
<img src="assets/xyzbc-trt-web-architecture.png" alt="web architecture">
<div class="caption">图 3LinuxCNC 原型系统与 Web 仿真系统的模块级对标关系。</div>
</div>
</section>
<section class="page-break">
<h2>5. 技术方案</h2>
<h3>5.1 总体架构</h3>
<table>
<tr><th>层级</th><th>模块</th><th>职责</th></tr>
<tr><td>文件层</td><td>OPFS/IndexedDB 工作区</td><td>保存 <code>ini/xml/hal/ngc/tbl/var/json</code>,支持导入 LinuxCNC 原始目录。</td></tr>
<tr><td>解析层</td><td>INI/XML/HAL/NGC/TBL/VAR parser</td><td>结构化解析配置、控件、信号、程序和参数,禁止手工硬编码配置结果。</td></tr>
<tr><td>运行层</td><td>Task/Interp/Motion/HAL runtime</td><td>复刻 LinuxCNC 任务状态机、G-code 解释、运动规划、HAL pin/net。</td></tr>
<tr><td>运动学层</td><td>xyzbc-trt-kins</td><td>实现 identity、XYZBC TCP、userk输出关节、世界坐标、刀尖和刀轴。</td></tr>
<tr><td>界面层</td><td>React/Vue/Svelte 或原生组件</td><td>对标 AXIS、PyVCP、DRO、MDI、程序窗口、状态栏。</td></tr>
<tr><td>三维层</td><td>Three.js</td><td>五轴机床、工件、刀具、路径、坐标系、清轨迹和相机视图。</td></tr>
<tr><td>证据层</td><td>Evidence JSON + Compare report</td><td>采集真实系统和 Web 系统,按同周期逐点比对。</td></tr>
</table>
<h3>5.2 switchkins 逻辑</h3>
<p>Web 端必须复刻原型中的 switchkins 控制链路PyVCP 按钮触发 <code>halui.mdi-command-00/01/02</code>MDI 执行 <code>M429/M428/M430</code>remap 子程序改变 <code>motion.analog-out-03</code>,再驱动 <code>motion.switchkins-type</code>。UI 当前模式由 <code>kinstype.is-0/1/2</code> 反向驱动,而不是由按钮直接写 UI 标签。</p>
<table>
<tr><th>按钮</th><th>HAL 目标</th><th>MDI 命令</th><th>目标模式</th></tr>
<tr><td><code>IDENTITY</code></td><td><code>halui.mdi-command-00</code></td><td><code>M429</code></td><td><code>0:IDENTITY</code></td></tr>
<tr><td><code>TCP:XYZBC</code></td><td><code>halui.mdi-command-01</code></td><td><code>M428</code></td><td><code>1:XYZBC</code></td></tr>
<tr><td><code>userk</code></td><td><code>halui.mdi-command-02</code></td><td><code>M430</code></td><td><code>2:USERK</code></td></tr>
<tr><td><code>vismach-clear</code></td><td><code>vismach.plotclear</code></td><td></td><td>清除三维路径显示。</td></tr>
</table>
<h3>5.3 五轴运动学和模型</h3>
<p>Web 端机床模型采用 XYZBC table rotary/tilting 结构。X 对应 table-xY 对应 saddle-yZ 对应 spindle-zB 对应 tilt-bC 对应 rotate-c。运动学参数使用原型系统当前 HAL 值:<code>x-offset=-20</code><code>z-offset=-15</code>、旋转点均为 <code>0</code><code>conventional-directions=false</code>。刀具长度来自 <code>motion.tooloffset.z</code></p>
<p>三维模型不只显示程序预览曲线,还必须在执行时按采样点刷新桌台、转台、主轴和刀具姿态。执行暂停、复位、清轨迹、模式切换后,模型状态和 JSON 状态必须同步。</p>
<h3>5.4 路径采样和 JSON 比对</h3>
<div class="warn">
<p>曲线采样周期固定为 <code>samplePeriodMs = 20</code>,即 50 Hz。LinuxCNC 真实系统和 Web 仿真系统必须使用相同采样周期、相同 sampleIndex、相同时间基准和相同坐标字段禁止一端 10 ms、另一端 20 ms 或使用不同插补点。</p>
</div>
<div class="figure">
<img src="assets/xyzbc-trt-json-compare-flow.png" alt="json compare flow">
<div class="caption">图 4刀具预览路径和执行路径 JSON 的同周期采样与逐点比对流程。</div>
</div>
<h3>5.5 Evidence JSON 字段规范</h3>
<pre>{
"schema": "xyzbc-trt-evidence/v1",
"source": "linuxcnc-native | web-sim",
"samplePeriodMs": 20,
"linuxcncRoot": "/home/mes123456/cnc_wams/linuxcnc",
"ini": "configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini",
"program": "./demos/xyzbc_switchkins.ngc",
"runtime": {
"taskState": 1,
"interpState": 1,
"axisMask": 55,
"kinstype": 0
},
"halPins": {
"motion.switchkins-type": 0,
"xyzbc-trt-kins.x-offset": -20,
"xyzbc-trt-kins.z-offset": -15,
"xyzbc-trt-kins.conventional-directions": false
},
"previewPath": {
"coordinateSystem": "XYZBC",
"samples": [
{
"sampleIndex": 0,
"timeMs": 0,
"line": 1,
"joint": {"x": 0, "y": 0, "z": 0, "b": 0, "c": 0},
"world": {"x": 0, "y": 0, "z": 0, "b": 0, "c": 0},
"toolTip": {"x": 0, "y": 0, "z": 0},
"toolAxis": {"i": 0, "j": 0, "k": 1},
"kinstype": 0
}
]
},
"executionPath": {
"samples": []
},
"screenshots": []
}</pre>
<h3>5.6 对比报告字段</h3>
<table>
<tr><th>字段</th><th>说明</th></tr>
<tr><td><code>sampleCount.native/web</code></td><td>真实系统和 Web 系统采样点数量。</td></tr>
<tr><td><code>maxPositionError</code></td><td>X/Y/Z/B/C 最大逐点误差。</td></tr>
<tr><td><code>rmsPositionError</code></td><td>路径整体均方根误差。</td></tr>
<tr><td><code>maxToolTipError</code></td><td>TCP 刀尖位置最大误差。</td></tr>
<tr><td><code>maxToolAxisErrorDeg</code></td><td>刀轴方向最大角度误差。</td></tr>
<tr><td><code>firstMismatch</code></td><td>首个超差点的 sampleIndex、line、timeMs、native/web 值。</td></tr>
<tr><td><code>uiEquivalence</code></td><td>AXIS/PyVCP/DRO/状态栏截图和 DOM 状态对比。</td></tr>
<tr><td><code>pass</code></td><td>是否通过设定阈值。</td></tr>
</table>
</section>
<section class="page-break">
<h2>6. 开发任务分解</h2>
<table>
<tr><th>阶段</th><th>任务</th><th>交付物</th><th>验收方式</th></tr>
<tr><td>阶段 1</td><td>导入并解析 <code>xyzbc-trt.ini</code>、XML、HAL、TBL、VAR、NGC 文件。</td><td>结构化配置 JSON、文件依赖图。</td><td><code>xyzbc-trt-runtime-files.md</code> 逐项核对。</td></tr>
<tr><td>阶段 2</td><td>搭建 AXIS 等价 Web UI 和 PyVCP 面板。</td><td>首屏数控工作台。</td><td>与真实 AXIS 截图逐区比对。</td></tr>
<tr><td>阶段 3</td><td>实现 HAL 总线、halui、switchkins 状态机和 remap 命令链路。</td><td>HAL 状态面板、MDI 命令记录。</td><td>按钮触发 M429/M428/M430 后状态一致。</td></tr>
<tr><td>阶段 4</td><td>实现 XYZBC 运动学和 Three.js Vismach 等价模型。</td><td>五轴机床模型、刀具和工件。</td><td>X/Y/Z/B/C 点动与 HAL pin 一致。</td></tr>
<tr><td>阶段 5</td><td>实现 G-code 预览路径、执行路径、暂停/复位/单步。</td><td>预览轨迹、执行轨迹、状态机。</td><td>默认程序 <code>xyzbc_switchkins.ngc</code> 可回放。</td></tr>
<tr><td>阶段 6</td><td>实现 native 和 web evidence JSON固定 20 ms 采样周期。</td><td><code>native-evidence.json</code><code>web-evidence.json</code></td><td>字段、单位、sampleIndex 对齐。</td></tr>
<tr><td>阶段 7</td><td>实现 compare-report 自动生成。</td><td><code>compare-report.json</code>、HTML 报告。</td><td>误差统计和首个差异点可追溯。</td></tr>
</table>
<h2>7. 验收标准</h2>
<table>
<tr><th>类别</th><th>必须通过的标准</th></tr>
<tr><td>路径标准</td><td>所有文档、配置和运行基线均指向 <code>/home/mes123456/cnc_wams/linuxcnc</code></td></tr>
<tr><td>界面标准</td><td>Web 首屏包含 AXIS 主要工作区、PyVCP SWITCHKINS 面板、预览区、DRO、程序区和状态栏。</td></tr>
<tr><td>功能标准</td><td>默认加载 <code>xyzbc_switchkins.ngc</code>,支持 MDI、模式切换、清轨迹、点动、倍率、刀具和参数。</td></tr>
<tr><td>运动学标准</td><td>identity、XYZBC TCP、userk 模式状态和轨迹计算与真实系统一致。</td></tr>
<tr><td>JSON 标准</td><td>预览路径和执行路径同时导出,采样周期统一为 20 ms字段一致。</td></tr>
<tr><td>比对标准</td><td>能输出最大误差、RMS 误差、首个差异点、截图和通过/失败结论。</td></tr>
<tr><td>证据标准</td><td>每次验收保存 LinuxCNC 原始截图、Web 截图、native JSON、web JSON、compare report。</td></tr>
</table>
<h2>8. 风险和控制措施</h2>
<table>
<tr><th>风险</th><th>影响</th><th>控制措施</th></tr>
<tr><td>LinuxCNC 内部解释器和 Web 解释器细节不一致</td><td>路径点或模式切换时序不同。</td><td>优先移植或复用 LinuxCNC 解析/运动学逻辑,保留 native evidence 作为回归基准。</td></tr>
<tr><td>采样周期不一致</td><td>曲线无法逐点比较。</td><td>强制配置 <code>samplePeriodMs=20</code>JSON schema 校验不允许缺省。</td></tr>
<tr><td>Three.js 模型和 Vismach 结构偏差</td><td>视觉对标通过但运动不一致。</td><td>每个关节都绑定 HAL pin模型矩阵由运动学输出驱动。</td></tr>
<tr><td>UI 直接改状态绕过 HAL</td><td>无法对标真实控制链路。</td><td>PyVCP 控件只发 HAL/MDI 事件,状态由 HAL pin 回读。</td></tr>
<tr><td>路径或旧目录混入</td><td>证据不可复现。</td><td>文档和脚本统一扫描旧路径,禁止使用历史旧 LinuxCNC 目录。</td></tr>
</table>
<h2>9. 附录:对标文件清单</h2>
<table>
<tr><th>文件</th><th>用途</th></tr>
<tr><td><code>/home/mes123456/cnc_wams/web-rtcp-5axis-xyzbc-trt-sim-plan/doc/xyzbc-trt-runtime-files.md</code></td><td>当前运行配置文件说明和路径基线。</td></tr>
<tr><td><code>/home/mes123456/cnc_wams/linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzbc-trt.ini</code></td><td>主 INI 配置。</td></tr>
<tr><td><code>xyzbc-trt.xml</code></td><td>PyVCP SWITCHKINS 面板。</td></tr>
<tr><td><code>switchkins_postgui.hal</code></td><td>PyVCP 与 HALUI、Vismach 清轨迹连接。</td></tr>
<tr><td><code>demos/xyzbc_switchkins.ngc</code></td><td>默认加载的演示程序。</td></tr>
<tr><td><code>remap_subs/428remap.ngc</code><code>429remap.ngc</code><code>430remap.ngc</code></td><td>switchkins 模式切换 remap。</td></tr>
<tr><td><code>xyzbc-trt.tbl</code></td><td>刀具表。</td></tr>
<tr><td><code>xyzbc.var</code></td><td>参数文件。</td></tr>
<tr><td><code>bin/xyzbc-trt-gui</code></td><td>Vismach 原型模型入口。</td></tr>
<tr><td><code>rtlib/xyzbc-trt-kins.so</code></td><td>真实五轴运动学模块。</td></tr>
</table>
</section>
<section class="page-break">
<h2>10. xyzbc-trt 程序逻辑全量分析</h2>
<p>下面按“文件装载 - 运动学 - HAL - 界面 - 执行 - 证据”的顺序,把 <code>xyzbc-trt</code> 的实际逻辑拆开说明。这里不是抽象架构而是与当前源码、HAL pin 和界面行为一一对应的执行逻辑。</p>
<h3>10.1 启动入口逻辑</h3>
<table>
<tr><th>步骤</th><th>逻辑</th><th>结果</th></tr>
<tr><td>1</td><td><code>rip-environment</code> 先建立 run-in-place 环境,确保本地 <code>bin/</code><code>lib/</code><code>rtlib/</code><code>bin/python</code> 可被当前会话找到。</td><td>执行路径完全指向 <code>/home/mes123456/cnc_wams/linuxcnc</code></td></tr>
<tr><td>2</td><td><code>linuxcnc xyzbc-trt.ini</code> 读取主 INI按段装载 DISPLAY、RS274NGC、KINS、HAL、TRAJ、TASK、EMCIO。</td><td>界面、运动学和程序执行进入同一会话。</td></tr>
<tr><td>3</td><td>AXIS、PyVCP、Vismach、halui、milltask、linuxcncsvr、rtapi_app 同时被拉起。</td><td>形成“界面 + 任务 + 运动 + 证据”闭环。</td></tr>
</table>
<p>这个启动链路的关键点是:界面不是单独运行的,而是被 INI 文件和 HAL 图驱动。Web 端要完全对标就不能把预览、模式切换、DRO、刀具、执行按钮做成彼此割裂的前端组件而要让它们共享同一个运行态和信号总线。</p>
<h3>10.2 配置装载逻辑</h3>
<table>
<tr><th>文件</th><th>逻辑作用</th><th>Web 对标要点</th></tr>
<tr><td><code>xyzbc-trt.ini</code></td><td>定义机器类型、显示方式、五轴坐标、最大速度、轴/关节限制、默认程序、运动学模块和 HAL 连线。</td><td>必须解析成结构化会话配置,不能只读出少量文本字段。</td></tr>
<tr><td><code>xyzbc-trt.xml</code></td><td>定义 SWITCHKINS 面板和按钮文案。</td><td>按钮状态要由 HAL 输出决定multilabel 要能随 kinstype 更新。</td></tr>
<tr><td><code>switchkins_postgui.hal</code></td><td>把按钮接到 MDI 命令,把清轨迹接到 <code>vismach.plotclear</code></td><td>Web 端的按钮必须走同样的“事件 - HAL - MDI - 状态”链路。</td></tr>
<tr><td><code>xyzbc_switchkins.ngc</code></td><td>默认加载的程序是演示切换程序,既包含路径,也包含模式切换场景。</td><td>Web 必须默认回放同一程序并记录同一套证据字段。</td></tr>
</table>
<h3>10.3 switchkins 运动学逻辑</h3>
<p><code>xyzbc-trt-kins</code> 通过 <code>switchkinsSetup()</code> 绑定三个运动学分支:</p>
<ul>
<li><code>type0</code>:在当前配置里被重定义为 <code>identity</code>,用于启动后的关节直接操控。</li>
<li><code>type1</code><code>xyzbc-trt-kins</code> 本体,执行 XYZBC table rotary/tilting 的 TCP 运动学。</li>
<li><code>type2</code>:用户自定义运动学 <code>userk</code></li>
</ul>
<p>源码里明确设置了 <code>kinsname = "xyzbc-trt-kins"</code><code>halprefix = "xyzbc-trt-kins"</code><code>required_coordinates = "xyzbc"</code><code>allow_duplicates = 1</code>,这意味着它既是一个五轴模块,也是一个允许坐标字母重复映射的 switchkins 模块。<code>identityfirst</code> 参数把启动默认值切换成 identity而不是让机床类型本体成为 type0这正是 sim 配置的关键差异。</p>
<div class="figure">
<img src="assets/xyzbc-trt-logic-map.png" alt="xyzbc-trt logic map">
<div class="caption">图 5`xyzbc-trt` 程序逻辑总图,展示从文件装载到证据采样的完整执行链。</div>
</div>
<p>switchkins 内部的逻辑顺序很重要:先由 <code>rtapi_app_main()</code> 创建 HAL 组件和输出 pin再调用 <code>kinematicsSwitch(0)</code> 设定初始模式,然后把三个 setup 函数分别执行一遍,最后 <code>hal_ready()</code>。这意味着 Web 端在启动时也必须先完成状态总线和模式初始化,再挂载界面和三维模型,不能反过来。</p>
<h3>10.4 正逆运动学逻辑</h3>
<table>
<tr><th>函数</th><th>逻辑</th><th>对标意义</th></tr>
<tr><td><code>xyzbcKinematicsForward()</code></td><td>根据 X/Y/Z/B/C 和 offset、tooloffset、旋转点、方向约定计算 TCP 世界坐标与姿态。</td><td>Web 端预览路径和三维模型必须采用同一套正解公式。</td></tr>
<tr><td><code>xyzbcKinematicsInverse()</code></td><td>根据目标 TCP 位姿反推关节角和关节位移,再写回 mapped joints。</td><td>MDI、点动、程序执行时的运动控制必须能从目标位姿反推关节。</td></tr>
<tr><td><code>conventional-directions</code></td><td>默认关闭时,旋转轴方向与 conventional 约定相反。</td><td>Web 模型如果方向画反,视觉上会“像”,但运动学会错,必须严格对齐。</td></tr>
</table>
<p>在当前配置里B/C 轴是主运动学轴A/U/V/W 只是可选字母。前向解使用主关节 <code>JX/JY/JZ/JB/JC</code> 计算 TCP 位姿;逆解再根据目标位姿回算这些主关节。这个路径对 Web 端非常关键,因为预览路径不能只画“刀尖折线”,还要把每个采样点对应的关节姿态也算出来,否则无法和真实系统逐点比对。</p>
<h3>10.5 HAL 和状态逻辑</h3>
<table>
<tr><th>HAL 语义</th><th>逻辑</th><th>Web 对标实现</th></tr>
<tr><td><code>motion.switchkins-type</code></td><td>当前运动学类型输入,浮点值被截断为整数 0/1/2。</td><td>前端 switchkins 状态必须是整数型并保持和任务状态一致。</td></tr>
<tr><td><code>kinstype.is-0/1/2</code></td><td>当前模式输出,供 GUI、指示灯、程序逻辑读取。</td><td>Web 端要提供同样的可读状态给 PyVCP 等价面板和检测逻辑。</td></tr>
<tr><td><code>motion.analog-out-03</code></td><td>通过 M68/MDI 等方式写入,间接控制 kinstype。</td><td>Web 端模式切换必须保留“间接驱动”语义,不可直接写最终状态。</td></tr>
<tr><td><code>halui.mdi-command-00/01/02</code></td><td>PyVCP 按钮发出的 MDI 入口。</td><td>按钮点击后必须先变成命令,再进入状态机。</td></tr>
</table>
<p><code>switchkins.c</code> 的实现说明了一个很重要的行为:模式切换后先清除 <code>use_lastpose</code>,再根据当前模式把对应的 <code>kinstype.is.N</code> 置位。也就是说Web 仿真不能把“当前模式”当作普通表单状态,它必须是一次完整状态机切换,切换后还要在 UI 上立即反映。</p>
<h3>10.6 UI 与三维模型逻辑</h3>
<p><code>axis.py</code> 的行为说明 AXIS 窗口里存在“轴模式”和“关节模式”的切换;当配置处于非 trivkins 或特殊 kinstype 时,按钮和焦点会根据当前运动模式自动切换到关节/轴对应控件。Web 端要对标的不只是布局,还有这个控件激活规则。</p>
<p><code>xyzbc-trt-gui.py</code> 则把 Vismach 模型拆成可响应的 HAL 变换链:<code>tool-offset</code> 作用于刀具,<code>spindle-z</code> 作用于主轴头,<code>tilt-b</code> 作用于倾斜轴,<code>rotate-c</code> 作用于回转台,<code>table-x</code><code>saddle-y</code> 则驱动横向与纵向运动。这个顺序决定了几何层级关系,所以 Web 端模型必须按同样层级搭建,而不是把每个零件独立摆放。</p>
<h3>10.7 程序执行与同步逻辑</h3>
<table>
<tr><th>阶段</th><th>逻辑</th><th>结果</th></tr>
<tr><td>预览</td><td>读取 <code>xyzbc_switchkins.ngc</code>,在预览区生成 G-code 轨迹和位置采样。</td><td>得到 previewPath JSON。</td></tr>
<tr><td>切换</td><td>通过 M428/M429/M430 或等价按钮改变 switchkins 模式,并执行同步命令。</td><td>运动学和解释器状态对齐。</td></tr>
<tr><td>执行</td><td>根据当前模式执行程序,同时刷新关节反馈和 TCP 位姿。</td><td>得到 executionPath JSON。</td></tr>
<tr><td>比对</td><td>用固定 20 ms 采样周期对比预览和执行曲线。</td><td>输出 compare-report.json。</td></tr>
</table>
<p>同步逻辑是这个程序最容易被误解的地方:切换模式不是单独改一个 pin 就结束了,必须让解释器和 motion 同步,否则 G-code 看到的坐标语义和 motion 看到的坐标语义会不同。这个要求在文档中已经被固化为“预览路径和执行路径统一采样周期,并在切换时强制同步”。</p>
<h3>10.8 异常和约束逻辑</h3>
<ul>
<li>如果 <code>motion.switchkins-type</code> 没有连接,只有 type0 默认运动学可用,这属于兼容旧配置的行为。</li>
<li>如果切换到身份不匹配的运动学类型,程序逻辑必须在 G-code 中先检查 <code>kinstype.is.N</code> 或等价输入,再决定是否继续。</li>
<li>如果当前系统的坐标偏置、刀补、外部偏置在切换后不一致,必须先清理或重置偏置,再切换模式。</li>
<li>如果 Web 端和 LinuxCNC 真实系统的采样周期不一致,则即使图形看起来接近,也不能通过对标验收。</li>
</ul>
<p>总的来说,<code>xyzbc-trt</code> 的逻辑不是“一个五轴模型 + 一个预览窗口”,而是“配置驱动的状态机 + 可切换运动学 + HAL 事件 + 三维可视化 + 路径证据”的组合。Web 端要做到完全对标,必须把这五件事统一成一条链。</p>
</section>
</body>
</html>