按建议继续完成后续工作

结论:upstream rs274 side-by-side 基线已扩展到可比较的 canonical runtime edge 调用;WAIT 仍保留为 standalone harness 覆盖,完整 native 验证已通过。
This commit is contained in:
2026-06-07 22:52:35 +08:00
parent fc3dd447e9
commit 7566d733e2
4 changed files with 166 additions and 7 deletions

View File

@@ -111,9 +111,10 @@ The current fixture expectations validate standalone behavior against both the
vendored LinuxCNC source path and an upstream `rs274` side-by-side baseline for
parser/conversion, offsets, feed-control, comment/logging, numbered-parameter,
spindle-orient, file-open reset, file-finish, tool-reload, and O-word
subroutine fixtures. Fixtures that depend on standalone-only runtime adapters,
HAL/INI/tool table setup, or richer machine session state still need dedicated
native LinuxCNC baselines.
subroutine fixtures, plus the comparable canonical runtime edge calls.
Fixtures that depend on standalone-only runtime adapters, HAL/INI/tool table
setup, upstream `rs274` output gaps such as `WAIT`, or richer machine session
state still need dedicated native LinuxCNC baselines.
The kinematics probes currently cover LinuxCNC identity/trivial kinematics,
the switchable `5axiskins` XYZBCW bridge-mill model, and the TRT `xyzac`/`xyzbc`

View File

@@ -69,7 +69,9 @@ semantic rewrites:
path. The upstream `rs274` side-by-side baseline now covers simple motion,
offsets, feed-control, comment/logging, numbered-parameter, spindle-orient,
file-open reset, file-finish, tool-reload, and O-word subroutine fixtures;
adapter-heavy fixtures still need dedicated native LinuxCNC baselines.
it also covers comparable canonical runtime edge calls. Adapter-heavy
fixtures and upstream `rs274` output gaps such as `WAIT` still need dedicated
native LinuxCNC baselines.
## Current Drift Conclusion

View File

@@ -507,9 +507,12 @@ Current verified progress:
native LinuxCNC canonical output for simple motion, offsets, feed-control,
comment/logging, numbered-parameter, spindle-orient, file-finish, and
tool-reload fixtures. It now also includes file-open reset and O-word
subroutine fixture coverage, filters native output to the event classes each
standalone fixture explicitly expects, and compares the result without
introducing a project-authored CNC semantics oracle.
subroutine fixture coverage, plus comparable canonical runtime edge calls.
Native output is filtered to the event classes each standalone fixture
explicitly expects, while upstream `rs274` output gaps such as `WAIT` remain
covered by the standalone harness rather than being treated as side-by-side
evidence. The comparison does not introduce a project-authored CNC semantics
oracle.
- `tests/fixtures/gcode_errors/g1_zero_feed.ngc` and
`tests/fixtures/canon_errors/g1_zero_feed.expected` pin the negative
`G1` zero-feed case. The source basis is LinuxCNC

View File

@@ -8,6 +8,7 @@ CANON_FIXTURE_DIR="$ROOT_DIR/tests/fixtures/canon"
FIXTURES=(
minimal_linear
canon_runtime_edges
comment_logging
coordinate_offsets
cutter_comp_motion
@@ -73,6 +74,15 @@ normalize_standalone_events() {
next
}
if (line == "MIST_ON" || line == "MIST_OFF" || line == "FLOOD_ON" || line == "FLOOD_OFF" ||
line == "ENABLE_FEED_OVERRIDE" || line == "DISABLE_FEED_OVERRIDE" ||
line == "DISABLE_ADAPTIVE_FEED" || line == "ENABLE_ADAPTIVE_FEED" ||
line == "DISABLE_FEED_HOLD" || line == "ENABLE_FEED_HOLD" ||
line == "PROGRAM_STOP" || line == "PROGRAM_END") {
print line
next
}
if (line ~ /^SELECT_PLANE plane=/) {
value = line
sub(/^SELECT_PLANE plane=/, "", value)
@@ -137,6 +147,88 @@ normalize_standalone_events() {
next
}
if (line ~ /^SET_SPINDLE_SPEED /) {
split(line, fields, /[[:space:]]+/)
for (i in fields) {
split(fields[i], pair, "=")
values[pair[1]] = pair[2]
}
print "SET_SPINDLE_SPEED|" values["spindle"] "|" norm(values["speed"])
delete values
next
}
if (line ~ /^START_SPINDLE_(CLOCKWISE|COUNTERCLOCKWISE) /) {
split(line, fields, /[[:space:]]+/)
for (i in fields) {
split(fields[i], pair, "=")
values[pair[1]] = pair[2]
}
print fields[1] "|" values["spindle"]
delete values
next
}
if (line ~ /^STOP_SPINDLE_TURNING /) {
split(line, fields, /[[:space:]]+/)
for (i in fields) {
split(fields[i], pair, "=")
values[pair[1]] = pair[2]
}
print "STOP_SPINDLE_TURNING|" values["spindle"]
delete values
next
}
if (line ~ /^(ENABLE|DISABLE)_SPEED_OVERRIDE /) {
split(line, fields, /[[:space:]]+/)
for (i in fields) {
split(fields[i], pair, "=")
values[pair[1]] = pair[2]
}
print fields[1] "|" values["spindle"]
delete values
next
}
if (line ~ /^(SET|CLEAR)_(MOTION|AUX)_OUTPUT_BIT /) {
split(line, fields, /[[:space:]]+/)
for (i in fields) {
split(fields[i], pair, "=")
values[pair[1]] = pair[2]
}
print fields[1] "|" values["index"]
delete values
next
}
if (line ~ /^SET_(MOTION|AUX)_OUTPUT_VALUE /) {
split(line, fields, /[[:space:]]+/)
for (i in fields) {
split(fields[i], pair, "=")
values[pair[1]] = pair[2]
}
print fields[1] "|" values["index"] "|" norm(values["value"])
delete values
next
}
if (line ~ /^SET_SPINDLE_MODE /) {
split(line, fields, /[[:space:]]+/)
for (i in fields) {
split(fields[i], pair, "=")
values[pair[1]] = pair[2]
}
print "SET_SPINDLE_MODE|" values["spindle"] "|" norm(values["css_max"])
delete values
next
}
# Upstream rs274 does not emit saicanon WAIT for the M66 case.
if (line ~ /^WAIT /) {
next
}
if (line ~ /^SET_FEED_MODE /) {
split(line, fields, /[[:space:]]+/)
for (i in fields) {
@@ -279,6 +371,13 @@ normalize_upstream_rs274_output() {
next
}
if (line ~ /^(MIST_ON|MIST_OFF|FLOOD_ON|FLOOD_OFF|ENABLE_FEED_OVERRIDE|DISABLE_FEED_OVERRIDE|DISABLE_ADAPTIVE_FEED|ENABLE_ADAPTIVE_FEED|DISABLE_FEED_HOLD|ENABLE_FEED_HOLD|PROGRAM_STOP|PROGRAM_END)\(\)$/) {
value = line
sub(/\(\)$/, "", value)
print value
next
}
if (line ~ /^SELECT_PLANE\(CANON_PLANE_/) {
value = line
sub(/^SELECT_PLANE\(CANON_PLANE_/, "", value)
@@ -323,6 +422,60 @@ normalize_upstream_rs274_output() {
next
}
if (line ~ /^SET_SPINDLE_SPEED\(/) {
args = args_of(line)
split(args, values, ",")
print "SET_SPINDLE_SPEED|" trim(values[1]) "|" norm(values[2])
next
}
if (line ~ /^START_SPINDLE_(CLOCKWISE|COUNTERCLOCKWISE)\(/) {
op = line
sub(/\(.*/, "", op)
args = args_of(line)
print op "|" trim(args)
next
}
if (line ~ /^STOP_SPINDLE_TURNING\(/) {
args = args_of(line)
print "STOP_SPINDLE_TURNING|" trim(args)
next
}
if (line ~ /^(ENABLE|DISABLE)_SPEED_OVERRIDE\(/) {
op = line
sub(/\(.*/, "", op)
args = args_of(line)
print op "|" trim(args)
next
}
if (line ~ /^(SET|CLEAR)_(MOTION|AUX)_OUTPUT_BIT\(/) {
op = line
sub(/\(.*/, "", op)
args = args_of(line)
print op "|" trim(args)
next
}
if (line ~ /^SET_(MOTION|AUX)_OUTPUT_VALUE\(/) {
op = line
sub(/\(.*/, "", op)
args = args_of(line)
split(args, values, ",")
print op "|" trim(values[1]) "|" norm(values[2])
next
}
if (line ~ /^SET_SPINDLE_MODE\(/) {
args = args_of(line)
gsub(/[[:space:]]+/, " ", args)
split(trim(args), values, " ")
print "SET_SPINDLE_MODE|" values[1] "|" norm(values[2])
next
}
if (line ~ /^SET_FEED_MODE\(/) {
args = args_of(line)
split(args, values, ",")