This commit is contained in:
2026-09-15 01:12:50 +08:00
parent 2db889ad89
commit 1a75503105
99 changed files with 4168 additions and 726 deletions
@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Class McAbcCyclicPathSyntax | HiAPI-C# 2025 ">
<meta name="description" content="Resolve modular rotary axes to the shortest cyclic path relative to the previous node. Uses to determine which axes within need cyclic resolution. Falls back to hardcoded A/B/C if no is available. Must be placed after in . Two stages, mirroring : Root MachineCoordinateState — anchored at the previous block&#39;s modal rotary state..[*] — sequential walk through items, anchoring item 0 at the previous block&#39;s modal state and item i &amp;gt; 0 at item i-1&#39;s post-cycle value (per-axis chain). Items without a rotary MachineCoordinateState are skipped. The items pass enables rotary motion (e.g. G28 ABC intermediate / home stages) to surface as motion segments rather than a single root-MC stamp. Per-word directional override: a block-root entry (stamped by ) valued (Siemens ACP()) or (ACN()) swaps that axis&#39;s window for this block only: [anchor, anchor+360&#176;) / (anchor-360&#176;, anchor] instead of the default &#177;180&#176; — the approach direction is forced even when it is the longer way around. A target congruent with the anchor (within an ULP-scale epsilon) keeps the anchor value verbatim — no move, never a spurious full turn, and no deg→rad→deg drift. (DC()) is the default window and needs no special path here. The override is read from the current block only (it is one-shot, never carried — deliberately unlike the modal RotaryWrap gate&#39;s one-step previous fallback) and applies to the root MC stage, not to items in general (G28/G74/G75 expansions capture their words in sub-objects the stamping syntax never sees, so an override can only ever describe a root word) — with one exception: an item whose value for an axis equals the root&#39;s pre-pass value verbatim carries that same root word (the canned-cycle pre-positioning item that stamps from the root MC) and inherits the root&#39;s directive for that axis, so the default window cannot fold the forced swing the root resolved into the short way. Directional/shortest entries keyed by an axis outside the modular set are reported as Coord-McAbc--003 — the promise cannot be honored there and silence would mis-read the program&#39;s intent; an entry with no anchor to resolve against (first rotary value in the stream) is reported as Coord-McAbc--004 and adopted unwrapped, matching the default path. Per-word incremental override: an entry (Siemens IC(), klartext IC+270) is a signed traverse by definition — already wrote anchor + delta — so this pass keeps that value verbatim for the axis instead of folding it into the &#177;180&#176; window (a +270&#176; chain dimension must not become a -90&#176; swing). Incremental entries on non-modular axes need no warning: the literal value is what the axis would do anyway.">
<meta name="description" content="Resolve modular rotary axes to the shortest cyclic path relative to the previous node. Uses to determine which axes within need cyclic resolution. Falls back to hardcoded A/B/C if no is available. Must be placed after in . Two stages, mirroring : Root MachineCoordinateState — anchored at the previous block&#39;s modal rotary state..[*] — sequential walk through items, anchoring item 0 at the previous block&#39;s modal state and item i &amp;gt; 0 at item i-1&#39;s post-cycle value (per-axis chain). Items without a rotary MachineCoordinateState are skipped. The items pass enables rotary motion (e.g. G28 ABC intermediate / home stages) to surface as motion segments rather than a single root-MC stamp. Per-word directional override: a block-root entry (stamped by ) valued (Siemens ACP()) or (ACN()) swaps that axis&#39;s window for this block only: [anchor, anchor+360&#176;) / (anchor-360&#176;, anchor] instead of the default &#177;180&#176; — the approach direction is forced even when it is the longer way around. A target congruent with the anchor (within an ULP-scale epsilon) keeps the anchor value verbatim — no move, never a spurious full turn, and no deg→rad→deg drift. (DC()) is the default window and needs no special path here. The override is read from the current block only (it is one-shot, never carried — deliberately unlike the modal RotaryWrap gate&#39;s one-step previous fallback) and applies to the root MC stage, not to items in general (G28/G74/G75 expansions capture their words in sub-objects the stamping syntax never sees, so an override can only ever describe a root word) — with one exception: an item whose value for an axis equals the root&#39;s pre-pass value verbatim carries that same root word (the canned-cycle pre-positioning item that stamps from the root MC) and inherits the root&#39;s directive for that axis, so the default window cannot fold the forced swing the root resolved into the short way. Directional/shortest entries keyed by an axis outside the modular set are reported as Coord-McAbc--003 — the promise cannot be honored there and silence would mis-read the program&#39;s intent; an entry with no anchor to resolve against (first rotary value in the stream) is reported as Coord-McAbc--004 and adopted unwrapped, matching the default path. Incremental words: a rotary word programmed as an increment — per-word (Siemens IC(), klartext IC+270) or a bare word under modal G91 — is a signed traverse by definition. already wrote anchor + delta into the MC and listed the axis in the one-shot record; this pass reads that record — and only that record — and keeps the listed axes verbatim instead of folding them into the &#177;180&#176; window (a +270&#176; chain dimension must not become a -90&#176; swing). A listed non-modular axis needs nothing: the literal value is what the axis would do anyway. A rotary value the block carries without a word (lookback fill, or an absolute target another writer put there — G53.1, the Heidenhain PLANE syntax) is not listed and keeps the default window even under G91.">
<link rel="icon" href="../img/HiAPI.favicon.ico">
<link rel="stylesheet" href="../public/docfx.min.css">
<link rel="stylesheet" href="../public/main.css">
@@ -148,14 +148,19 @@ to resolve against (first rotary value in the stream) is reported as
path.
</p>
<p>
Per-word incremental override: an <a class="xref" href="Hi.NcParsers.Keywords.Positioning.html#Hi_NcParsers_Keywords_Positioning_Incremental">Incremental</a>
entry (Siemens <code>IC()</code>, klartext <code>IC+270</code>) is a signed
traverse by definition — <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a> already wrote
anchor + delta — so this pass keeps that value verbatim for the
axis instead of folding it into the ±180° window (a +270° chain
dimension must not become a -90° swing). Incremental entries on
non-modular axes need no warning: the literal value is what the
axis would do anyway.
Incremental words: a rotary word programmed as an increment —
per-word (Siemens <code>IC()</code>, klartext <code>IC+270</code>) or a bare
word under modal <code>G91</code> — is a signed traverse by definition.
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcSyntax.html">McAbcSyntax</a> already wrote anchor + delta into the MC
and listed the axis in the one-shot <a class="xref" href="Hi.NcParsers.Keywords.IncrementalWords.html">IncrementalWords</a>
record; this pass reads that record — and only that record — and
keeps the listed axes verbatim instead of folding them into the ±180°
window (a +270° chain dimension must not become a -90° swing). A
listed non-modular axis needs nothing: the literal value is what the
axis would do anyway. A rotary value the block carries without a
word (lookback fill, or an absolute target another writer put there
— <code>G53.1</code>, the Heidenhain <code>PLANE</code> syntax) is not listed
and keeps the default window even under G91.
</p>
</div>
<div class="markdown conceptual"></div>
@@ -354,20 +359,24 @@ would decide between "no move" and a spurious full -360° turn):
"PositioningOverride": { "B": "NegativeOnly" }
}</code></pre>
Incremental word (<code>B=IC(270)</code> / klartext <code>L IB+270</code>): the
rotary writer accumulated anchor 0° + 270° = 270°, and the pass keeps
the traverse literal — the same 270° that the default window above
rewrote to -90° stays +270°:
rotary writer accumulated anchor 0° + 270° = 270° and listed B in
<code>IncrementalWords</code>, and the pass keeps the traverse literal —
the same 270° that the default window above rewrote to -90° stays
+270°. The per-word entry is still on the block (nothing consumes
it) but is not what this pass reads:
#Previous:
<pre><code class="lang-csharp">{ "MachineCoordinateState": { "B": 0 } }</code></pre>
#BeforeBuild:
<pre><code class="lang-csharp">{
"MachineCoordinateState": { "B": 270 },
"PositioningOverride": { "B": "Incremental" }
"PositioningOverride": { "B": "Incremental" },
"IncrementalWords": { "B": 270 }
}</code></pre>
#AfterBuild:
<pre><code class="lang-csharp">{
"MachineCoordinateState": { "B": 270 },
"PositioningOverride": { "B": "Incremental" }
"PositioningOverride": { "B": "Incremental" },
"IncrementalWords": { "B": 270 }
}</code></pre>
A <code>CompoundMotion</code> item carrying the root word verbatim — the
canned-cycle pre-positioning item that
@@ -402,6 +411,26 @@ and resolves under the default window against the chained anchor
]
}
}</code></pre>
A bare rotary word under modal G91 (Fanuc <code>G91 … B270.</code>) has no
per-word entry at all — the rotary writer accumulated 0° + 270° and
listed B in <code>IncrementalWords</code>, and that listing alone keeps the
+270° traverse literal. C is on the block without a word (the value
an absolute writer such as <code>G53.1</code> would leave), so it is not
listed and still resolves under the default window: 270° from anchor
0° folds to −90°. Neither <code>Positioning</code> nor <code>RotaryWords</code>
is consulted, so the case carries neither:
#Previous:
<pre><code class="lang-csharp">{ "MachineCoordinateState": { "B": 0, "C": 0 } }</code></pre>
#BeforeBuild:
<pre><code class="lang-csharp">{
"IncrementalWords": { "B": 270 },
"MachineCoordinateState": { "B": 270, "C": 270 }
}</code></pre>
#AfterBuild:
<pre><code class="lang-csharp">{
"IncrementalWords": { "B": 270 },
"MachineCoordinateState": { "B": 270, "C": -90 }
}</code></pre>