deploy webservice static-file routing for docsite folder URLs, per-instance step-cache db, and constant-height panel title bars.

This commit is contained in:
2026-08-27 14:51:37 +08:00
parent 1fc510af5e
commit 2a98ae7556
1468 changed files with 182837 additions and 18888 deletions
@@ -94,6 +94,48 @@
<h3 id="classes">
Classes
</h3>
<dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensCircularMotionSyntax.html">SiemensCircularMotionSyntax</a></dt>
<dd><p>Siemens variant of <a class="xref" href="Hi.NcParsers.LogicSyntaxs.CircularMotionSyntax.html">CircularMotionSyntax</a> (replaces it in
the Siemens preset — do not run both): writes
<a class="xref" href="Hi.NcParsers.Keywords.Generic.MotionForm.html#Hi_NcParsers_Keywords_Generic_MotionForm_McArc">McArc</a> motion for G02/G03 blocks from
I/J/K center offsets or the Siemens signed radius <code>CR=</code>
(captured as <code>Parsing.CR</code> by an equals-form
<a class="xref" href="Hi.NcParsers.ParsingSyntaxs.FloatTagValueSyntax.html">FloatTagValueSyntax</a>), with the helix
turn count from <code>TURN=</code> (<code>Parsing.TURN</code>).</p>
<p>
Differences from the Fanuc/ISO parent, per the corpus-driven plan:
<ul><li><code>CR</code> replaces <code>R</code> — same math
(<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.int32">ResolveCenterFromSignedRadius(Vec3d, Vec3d, int, bool, double)</a>;
negative CR selects the &gt;180° arc), but a CR full circle
(start ≈ end on the plane) is invalid on Sinumerik and the chord
collapse would produce a NaN center — rejected with
<code>Arc-CR--ClosedChord</code>, params left visible.</li><li><code>TURN=N</code> means N <b>additional</b> full circles:
<code>AdditionalCircleNum = TURN + (closed ? 1 : 0)</code> — <b>no −1</b>
(the legacy HardNc path treated TURN like Fanuc L and silently
undercounted Siemens helices by one turn; deliberately not ported).
The closed-loop +1 stacks on the same closure heuristic used when
TURN is absent, because the downstream angle wrap yields 0 rad for
closed arcs and the whole loop count must come from
<code>AdditionalCircleNum</code>.</li><li>No <code>L</code> and no K-as-pitch reading — Siemens <code>L{n}</code> is a
subprogram call and helix travel is endpoint + TURN driven.</li><li>Per-word absolute center: an <code>I=AC(...)</code> /
<code>J=AC(...)</code> / <code>K=AC(...)</code> wrapper (unwrapped by
<a class="xref" href="Hi.NcParsers.EvaluationSyntaxs.Siemens.SiemensAcIcSyntax.html">SiemensAcIcSyntax</a> into a
numeric <code>Parsing</code> value plus a <code>PositioningOverride</code>
entry) switches that one component from the default incremental
offset-from-start to an absolute center coordinate
(<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.int32">ResolveCenterFromMixedIjk(Vec3d, int, double, double, double, bool, bool, bool)</a>);
components without an entry — and <code>IC()</code>-wrapped ones —
keep the incremental reading. Blocks without the section take the
legacy <a class="xref" href="https://learn.microsoft.com/dotnet/api/system.int32">ResolveCenterFromIjk(Vec3d, int, double, double, double)</a>
path byte-for-byte.</li></ul>
<p>
Must be placed before <a class="xref" href="Hi.NcParsers.LogicSyntaxs.LinearMotionSyntax.html">LinearMotionSyntax</a> (shared
Group 01 motion slot).
</p>
</dd>
</dl>
<dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensCoordinateOffsetSyntax.html">SiemensCoordinateOffsetSyntax</a></dt>
<dd><p>Siemens Sinumerik: resolves work coordinate offset from G54–G57 (ISO-compatible),
@@ -101,6 +143,399 @@ G505–G599 (extended Siemens), and G500 (cancel — machine coordinate mode).
Reads from <a class="xref" href="Hi.NcParsers.Keywords.IFlagsDef.html#Hi_NcParsers_Keywords_IFlagsDef_Flags">Flags</a>,
looks up <a class="xref" href="Hi.NcParsers.Dependencys.Generic.IsoCoordinateTable.html">IsoCoordinateTable</a> dependency,
composes into <a class="xref" href="Hi.NcParsers.Keywords.ITransformationDef.html#Hi_NcParsers_Keywords_ITransformationDef_ProgramToMcTransform">ProgramToMcTransform</a>.</p>
</dd>
</dl>
<dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensCutCompModeSyntax.html">SiemensCutCompModeSyntax</a></dt>
<dd><p>Consumes the Siemens <code>CUT3DC</code> flag (3D circumferential cutter
compensation mode, used with <code>TRAORI</code>) from
<a class="xref" href="Hi.NcParsers.Keywords.IFlagsDef.html#Hi_NcParsers_Keywords_IFlagsDef_Flags">Flags</a> and records a non-modal block-root
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensCutCompModeSyntax.html#Hi_NcParsers_LogicSyntaxs_Siemens_SiemensCutCompModeSyntax_CutCompMode">CutCompMode</a> section. The offline
<a class="xref" href="Hi.NcParsers.PostLogicSyntaxs.RadiusCompensationSyntax.html">RadiusCompensationSyntax</a> only models
the 2D plane modes, so a <code>SiemensCutComp&ndash;Unsupported</code> warning
is emitted: a later <code>G41</code>/<code>G42</code> in this program simulates
as plane compensation, not as the control's 3D surface-normal
offset — recognized, visibly not simulated, never a half-guess.</p>
<p>
Capture side: <code>CUT3DC</code> is a bare word collected by the Siemens
preset's <a class="xref" href="Hi.NcParsers.ParsingSyntaxs.FlagSyntax.html">FlagSyntax</a> word list.
</p>
</dd>
</dl>
<dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensCycle800TiltSyntax.html">SiemensCycle800TiltSyntax</a></dt>
<dd><p>Siemens CYCLE800 (swivel cycle): resolves the tilted work plane from
the positional arguments captured by
<a class="xref" href="Hi.NcParsers.ParsingSyntaxs.Siemens.SiemensCycleCallSyntax.html">SiemensCycleCallSyntax</a> and composes it into
<a class="xref" href="Hi.NcParsers.Keywords.ITransformationDef.html#Hi_NcParsers_Keywords_ITransformationDef_ProgramToMcTransform">ProgramToMcTransform</a> as the shared
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.TiltTransformUtil.html#Hi_NcParsers_LogicSyntaxs_TiltTransformUtil_TransformSource">TransformSource</a> entry — the Siemens
sibling of <a class="xref" href="Hi.NcParsers.LogicSyntaxs.IsoG68p2TiltSyntax.html">IsoG68p2TiltSyntax</a> its XmlDoc promises.
Unlike Fanuc G68.2 (plane only), CYCLE800 also positions the rotary
axes implicitly (the G53.1 half): with
<a class="xref" href="Hi.Numerical.Xyzabc.IMachineKinematics.html">IMachineKinematics</a> wired, the tilt normal is solved to
machine ABC and written into
<a class="xref" href="Hi.NcParsers.Keywords.IMachineCoordinateStateDef.html#Hi_NcParsers_Keywords_IMachineCoordinateStateDef_MachineCoordinateState">MachineCoordinateState</a>, and
the block gets a non-modal rapid <a class="xref" href="Hi.NcParsers.Keywords.MotionEvent.html">MotionEvent</a> with
<code>Term = &ldquo;CYCLE800&rdquo;</code> (mirroring
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.G53p1RotaryPositionSyntax.html">G53p1RotaryPositionSyntax</a>).</p>
<p>
Argument layout (HardNc reference <code>NcArgCycle800</code>):
<code>CYCLE800(FR, TC, ST, MODE, X0, Y0, Z0, A, B, C, X1, Y1, Z1, DIR
[, FR_I, DMODE])</code> — 15- and 16-arg post variants both occur in
the corpus. <code>MODE</code> is bit-coded: bits 7-6 select the swivel
mode (00 axis-by-axis, 01 solid angle, 10 projection angle,
11 direct rotary), bit pairs 1-0/3-2/5-4 select each angle's axis
(01=X, 10=Y, 11=Z). The motion-convention matrix is
<code>T(X1,Y1,Z1) · R · T(X0,Y0,Z0)</code> (row-vector; the post-rotation
zero offset applies innermost). <code>ST</code> units digit 1 composes
additively onto the current programmable frame; <code>FR</code>/<code>FR_I</code>
retraction and <code>DIR</code> solution preference are recorded in the
section but not simulated (<code>DIR = 0</code> suppresses the rotary
positioning, per the control's frame-only variant).
</p>
<p>
Cancel forms — bare <code>CYCLE800</code>, empty parentheses, the
single-argument <code>CYCLE800(0)</code>, or swivel-data-record name
<code>TC = "0"</code> — reset the tilt to the shared inactive sentinel
(<code>Term = "G69"</code> + identity entry, HardNc's convention). An
in-between argument count (1–9 with a live TC) is treated as a
truncated/unmodeled capture, not a cancel — warning + visible
residue, so a mis-parsed call can never silently drop an active
swivel. The rotary axes are <b>not</b> re-positioned on cancel: the
retract/re-orient behavior depends on the machine's swivel data
record, which does not exist offline; corpus programs follow the
cancel with explicit <code>G0 A.. C..</code> moves anyway.
</p>
<p>
Fail-soft: a non-numeric argument (machine-runtime variable) leaves
the <code>Parsing.CYCLE800</code> residue visible and applies no transform
(<code>Coord-Tilt--003</code>); an IK failure keeps the euler tilt and
skips positioning (<code>Coord-Tilt--004</code>); a rotating CYCLE800 on a
machine without kinematics/rotary axes keeps the tilt and warns
(<code>Coord-Tilt--005</code>).
</p>
<p>
Must run <b>before</b> <a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensProgrammableFrameSyntax.html">SiemensProgrammableFrameSyntax</a>
(which owns the once-per-block <a class="xref" href="Hi.NcParsers.Keywords.TiltTransform.html">TiltTransform</a> modal
carry and composes additive AROT/ATRANS onto this cycle's fresh
matrix) and before the coordinate-offset syntaxes (chain order:
frame entry ahead of <code>CoordinateOffset</code>).
</p>
</dd>
</dl>
<dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensFixedPointReturnSyntax.html">SiemensFixedPointReturnSyntax</a></dt>
<dd><p>Consumes the Siemens <code>G74</code> (reference-point approach) /
<code>G75</code> (fixed-point approach) statement captured into
<code>Parsing.G74</code> / <code>Parsing.G75</code> by the Siemens preset's
dedicated <a class="xref" href="Hi.NcParsers.ParsingSyntaxs.ParameterizedFlagSyntax.html">ParameterizedFlagSyntax</a>
instance, and emits a one-shot machine-coordinate move for the
participating axes.</p>
<p>
Siemens semantics honored here: non-modal; only the axes written in
the block participate; the numeric axis value is a dummy
(conventionally 0) and is discarded; the motion happens in MACHINE
coordinates ignoring every active frame; the F word in the block does
not change the modal feed (the machine travels at its own rapid).
The frame bypass reuses the <a class="xref" href="Hi.NcParsers.LogicSyntaxs.MachineCoordSelectSyntax.html">MachineCoordSelectSyntax</a>
mechanism — write <a class="xref" href="Hi.NcParsers.Keywords.IMachineCoordinateStateDef.html#Hi_NcParsers_Keywords_IMachineCoordinateStateDef_MachineCoordinateState">MachineCoordinateState</a>
directly and back-derive <a class="xref" href="Hi.NcParsers.Keywords.IProgramXyzDef.html#Hi_NcParsers_Keywords_IProgramXyzDef_ProgramXyz">ProgramXyz</a>
through the inverse of the composed
<a class="xref" href="Hi.NcParsers.Keywords.ITransformationDef.html#Hi_NcParsers_Keywords_ITransformationDef_ProgramToMcTransform">ProgramToMcTransform</a> — so a G54/G505
offset or programmable frame shifts the recovered program coordinate,
never the machine target.
</p>
<p>
Target position: G74 (reference-point approach) reads the per-axis
machine reference from <a class="xref" href="Hi.NcParsers.Dependencys.IHomeMcConfig.html#Hi_NcParsers_Dependencys_IHomeMcConfig_GetHomePosition_System_String_">GetHomePosition(string)</a>
(MD34010 on a Siemens table; 0 when the axis has no configured home).
G75 (fixed-point approach) reads the fixed-point table MD30600
<code>$MA_FIX_POINT_POS</code> via
<a class="xref" href="Hi.NcParsers.Dependencys.Siemens.SiemensMachineDataTable.html#Hi_NcParsers_Dependencys_Siemens_SiemensMachineDataTable_GetFixPointPosition_System_String_">GetFixPointPosition(string)</a>,
falling back per axis to the same reference position when no fixed
point is configured — so machines whose fixed point differs from the
reference retract to the right place. Only fixed point 1 is modeled;
a <code>FP=</code> word in the block emits <code>Coord-FixPoint--003</code> and
uses fixed point 1. Non-participating linear axes keep the previous
machine position; rotary axes participate only when written and
configured rotary (their target lands in the shared MC section,
wrapped shortest-path later by <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McAbcCyclicPathSyntax.html">McAbcCyclicPathSyntax</a>).
</p>
<p>
Placement: after <a class="xref" href="Hi.NcParsers.LogicSyntaxs.ReferenceReturnSyntax.html">ReferenceReturnSyntax</a> (the G28 slot) —
behind every coordinate-offset / frame syntax so the composed
transform is complete for the ProgramXyz back-derivation, and before
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.McXyzSyntax.html">McXyzSyntax</a> / <a class="xref" href="Hi.NcParsers.LogicSyntaxs.LinearMotionSyntax.html">LinearMotionSyntax</a> (the
stamped <a class="xref" href="Hi.NcParsers.Keywords.MotionEvent.html">MotionEvent</a> makes the motion syntaxes skip the
block; a G0/G1 word on the block is claimed into the modal
<a class="xref" href="Hi.NcParsers.Keywords.MotionState.html">MotionState</a> exactly like
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.MachineCoordSelectSyntax.html">MachineCoordSelectSyntax</a> does). Without an
<a class="xref" href="Hi.NcParsers.Dependencys.IHomeMcConfig.html">IHomeMcConfig</a> dependency the statement stays in
<code>Parsing</code> and surfaces as unconsumed residue.
</p>
</dd>
</dl>
<dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensModalCycleSyntax.html">SiemensModalCycleSyntax</a></dt>
<dd><p>Maps Siemens <code>MCALL CYCLE8x(…)</code> modal drilling calls onto the
shared canned-cycle machinery — the &ldquo;setup half&rdquo; of the Fanuc
G66-style modal pattern; the &ldquo;expansion half&rdquo; needs no new code
because <a class="xref" href="Hi.NcParsers.LogicSyntaxs.CannedCycleResolveSyntax.html">CannedCycleResolveSyntax</a>'s previous-block modal
lookback already re-triggers the armed cycle at every subsequent
block carrying X/Y words, exactly Sinumerik's MCALL semantic.</p>
<ul><li><code>MCALL CYCLE81/82(RTP,RFP,SDIS,DP,DPR[,DTB])</code> → an armed
<code>CannedCycle</code> section (<code>Term</code> G81/G82) with
<code>Params.R = RFP + |SDIS|</code>, <code>Params.Z = DP</code> (or
<code>RFP − DPR</code>), dwell <code>P = DTB</code> for G82.</li><li><code>MCALL CYCLE83(…,FDEP,FDPR,DAM,DTB,DTS,FRF,VARI,…)</code> →
G83 (VARI≠0, full retract) or G73 (VARI=0, chip-break) with
<code>Q = |RFP − FDEP|</code> or <code>|FDPR|</code>. The FDEP/DAM decreasing
peck chain is approximated by that constant first-peck depth.</li><li><code>MCALL CYCLE85(…,DTB,FFR,RFF)</code> → G89 (DTB&gt;0, dwell) or
G85, feed-in <code>F = FFR</code>; the separate retract feed RFF has no
slot in the shared expansion (retract reuses F).</li><li>bare <code>MCALL</code> → the G80 cancel sentinel
(<a class="xref" href="https://learn.microsoft.com/dotnet/api/system.text.json.nodes.jsonobject">WriteCannedCycleCancel(JsonObject, string)</a>).</li></ul>
<p>
The MCALL block itself must NOT execute the cycle (Sinumerik arms
only), so no <code>Parsing.G8x</code> section is written here — the armed
section rides the <a class="xref" href="Hi.NcParsers.PostLogicSyntaxs.ModalCarrySyntax.html">ModalCarrySyntax</a>
<code>CannedCycle</code> tracked key to the following motion blocks.
Return plane: <code>ReturnMode = G98</code> (previous-block Z); RTP has no
slot in the shared expansion — programs that park at RTP before the
first trigger get exactly RTP back, the corpus shape.
Fail-soft paths (consume + structured warning + no arm): non-literal
arguments (R-parameter args — cycle args bypass the P2 evaluator),
missing RFP / depth / peck values, and any callee outside the CYCLE8x
map (<code>MCALL L123</code> modal subprogram calls are not simulated).
Pipeline placement: before <a class="xref" href="Hi.NcParsers.LogicSyntaxs.CannedCycleResolveSyntax.html">CannedCycleResolveSyntax</a> in
the Siemens Logic bundle.
</p>
</dd>
</dl>
<dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensPathSmoothingSyntax.html">SiemensPathSmoothingSyntax</a></dt>
<dd><p>Records the Siemens path-control / smoothing modal registers into the
brand-invariant <code>PathSmoothing</code> section (fields per
<a class="xref" href="Hi.NcParsers.Keywords.Siemens.ISiemensPathSmoothingDef.html">ISiemensPathSmoothingDef</a>): the G-code groups
G60/G64/G641/G642 (path control) and G601/G602 (exact-stop criterion)
from <a class="xref" href="Hi.NcParsers.Keywords.IFlagsDef.html#Hi_NcParsers_Keywords_IFlagsDef_Flags">Flags</a>, the bare modal words
FNORM / SOFT / BRISK / FFWON / FFWOF / COMPCAD / COMPON / COMPOF /
UPATH / SPATH (captured by the preset's
<a class="xref" href="Hi.NcParsers.ParsingSyntaxs.FlagSyntax.html">FlagSyntax</a> word list), and the
<code>Parsing.CYCLE832</code> call sub-object (captured by
<a class="xref" href="Hi.NcParsers.ParsingSyntaxs.Siemens.SiemensCycleCallSyntax.html">SiemensCycleCallSyntax</a>) whose first argument arms the
high-speed tolerance (0 / empty parentheses cancel it).</p>
<p>
Record-only — simulation does not alter the tool path (same contract
as the Fanuc G05.1 sibling <a class="xref" href="Hi.NcParsers.LogicSyntaxs.FanucPathSmoothingSyntax.html">FanucPathSmoothingSyntax</a>,
which this class replaces in the Siemens preset: that one reads only
the <code>Parsing["G05.1"]</code> sub-object no Siemens capture produces).
<a class="xref" href="Hi.NcParsers.Keywords.IPathSmoothingDef.html#Hi_NcParsers_Keywords_IPathSmoothingDef_IsEnabled">IsEnabled</a> is derived — true while a
CYCLE832 tolerance is armed or the path-control group sits on a
continuous-path mode (G64/G641/G642).
</p>
<p>
Modal behavior: a block touching any group starts from a clone of the
previous block's section, applies the touched groups and rewrites the
section; untouched blocks write nothing and
<a class="xref" href="Hi.NcParsers.PostLogicSyntaxs.ModalCarrySyntax.html">ModalCarrySyntax</a> (whose
<code>TrackedKeys</code> already contain <code>PathSmoothing</code>) carries the
previous section forward. The stream's first block stamps a
conservative <code>{ IsEnabled: false }</code> default — the actual
delivered state of a real control is machine-data dependent, so no
term is invented for it.
</p>
</dd>
</dl>
<dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensPivotTransformationSyntax.html">SiemensPivotTransformationSyntax</a></dt>
<dd><p>Siemens pivot gate over the shared engine
(<a class="xref" href="Hi.NcParsers.LogicSyntaxs.PivotTransformUtil.html">PivotTransformUtil</a>): writes the
<a class="xref" href="Hi.NcParsers.Syntaxs.TransformationUtil.html#Hi_NcParsers_Syntaxs_TransformationUtil_PivotTransformSource">PivotTransformSource</a> entry on blocks
where commanded XYZ needs the Pn→MC kinematic rigid transform —
active TRAORI RTCP (<a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensTraoriSyntax.html">SiemensTraoriSyntax</a>'s
<code>ToolHeightCompensation.Term</code>), an active swivel/tilt
(CYCLE800, or a mixed-dialect G68/G68.2 term), or a Dynamic chain
entry. The Siemens-specific exclusion: a plain geometric frame
(TRANS/ATRANS/ROT/AROT,
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.TiltTransformUtil.html#Hi_NcParsers_LogicSyntaxs_TiltTransformUtil_IsPlainGeometryFrame_System_String_">IsPlainGeometryFrame(string)</a>) transforms
coordinates only and implies no physically positioned rotaries, so
it must <b>not</b> open the gate — a corpus <code>TRANS X0 Y0 Z0</code>
reset would otherwise leave the modal term folding the pivot on
every later plain-mode block.</p>
<p>
The ISO/Fanuc sibling gate is
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.PivotTransformationSyntax.html">PivotTransformationSyntax</a>; both write the identical
JSON vocabulary through the shared engine, and only one of them is
registered per brand pipeline. Same chain-position contract: after
all Pn-frame writers, so the <code>PivotTransform</code> entry lands last.
</p>
</dd>
</dl>
<dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensProgrammableFrameSyntax.html">SiemensProgrammableFrameSyntax</a></dt>
<dd><p>Siemens programmable frame (<code>TRANS/ATRANS/ROT/AROT</code> incl.
<code>RPL=</code>, plus the solid-angle forms <code>ROTS/AROTS</code>): consumes
the structured
<code>Parsing.&lt;keyword&gt;</code> sub-objects captured by
<a class="xref" href="Hi.NcParsers.ParsingSyntaxs.Siemens.SiemensFrameStatementSyntax.html">SiemensFrameStatementSyntax</a>, accumulates the
programmable-frame matrix across blocks, and composes it into
<a class="xref" href="Hi.NcParsers.Keywords.ITransformationDef.html#Hi_NcParsers_Keywords_ITransformationDef_ProgramToMcTransform">ProgramToMcTransform</a> as the shared
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.TiltTransformUtil.html#Hi_NcParsers_LogicSyntaxs_TiltTransformUtil_TransformSource">TransformSource</a> entry — the same
Source CYCLE800 writes, so the two stay mutually exclusive via
<code>AddOrReplaceTransform</code>'s in-place replacement (on a real
Sinumerik, CYCLE800 itself writes the programmable frame chain, so
single ownership mirrors the control).</p>
<p>
Semantics follow the Sinumerik programmable-frame rules (HardNc
reference: <code>HardNcLine.ParseSiemensFrameTransform</code> +
<code>NcArgSiemensFrame</code>): the absolute forms <code>TRANS</code>/<code>ROT</code>
reset the <b>whole</b> programmable frame and set only their own
component; the additive forms <code>ATRANS</code>/<code>AROT</code> compose onto
the current frame with the new operation applied first
(<code>M = M_op · M_prev</code>, row-vector convention — an <code>AROT</code>
after a <code>TRANS</code> rotates inside the translated frame). A bare
keyword (any of the four) resets the programmable frame entirely —
written as the shared inactive sentinel <code>Term = "G69"</code> plus an
identity chain entry (the same convention HardNc's CYCLE800 reset
uses). Multi-axis rotation in one statement applies the Sinumerik
RPY order (intrinsic Z → Y′ → X″, i.e. row-vector
<code>Rx·Ry·Rz</code>); <code>RPL</code> rotates about the active G17/G18/G19
plane normal and composes after the axis angles.
</p>
<p>
The solid-angle forms <code>ROTS</code>/<code>AROTS</code> follow the Sinumerik
rules (Programming Manual Fundamentals 03/2010 §12.5, "ROTS and
AROTS behave in the same way as ROT and AROT"): at most two solid
angles orient a plane, composed first-named axis first with the
second rotation about the <b>original</b> (extrinsic) axis — the
pair X,Y keeps the new X axis in the old Z/X plane (row-vector
<code>Rx·Ry</code>), Y,Z keeps the new Y axis in the old X/Y plane
(<code>Ry·Rz</code>), Z,X keeps the new Z axis in the old Y/Z plane
(<code>Rz·Rx</code>). A single angle is identical to <code>ROT</code>/<code>AROT</code>;
<code>RPL=</code> alone rotates in the active plane. Three angles, or
<code>RPL</code> mixed with axis angles, fall outside the documented
grammar: the statement is left unapplied with a
<code>SiemensFrame--SolidAngleInvalid</code> warning plus the visible
<code>Parsing--Unconsumed</code> residue — never a guessed frame.
</p>
<p>
<code>CROTS/SCALE/ASCALE/MIRROR/AMIRROR</code> (zero corpus occurrences;
CROTS references the control's frame database which has no offline
counterpart, SCALE/MIRROR would inject non-rigid matrices whose
remaining breakages are the radius-compensation magnitude, the
program-space path length feeding durations, and the writeback Euler
decomposition) are consumed recognized-but-not-simulated with a
<code>SiemensFrame--Unsupported</code> warning and zero transform effect.
A structured keyword whose capture fell back to the verbatim
<code>Statement</code> shape, or whose value is an unevaluated variable
expression, is left in <code>Parsing</code> — the
<code>VariableExpression--Unevaluated</code> diagnostic plus the visible
<code>Parsing--Unconsumed</code> residue is the correct fail-soft (P2
acceptance doctrine); the frame is not partially applied.
</p>
<p>
Must run <b>after</b> <a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensCycle800TiltSyntax.html">SiemensCycle800TiltSyntax</a> (this
syntax owns the once-per-block <a class="xref" href="Hi.NcParsers.Keywords.TiltTransform.html">TiltTransform</a> modal
carry: it carries only when no earlier syntax authored the section
on this block) and <b>before</b> the coordinate-offset syntaxes, so
the frame entry lands ahead of
<code>CoordinateOffset</code> in the chain
(<code>McXyz = ProgramXyz · M_frame · M_offset · …</code> — the
programmable frame applies to program coordinates first, then the
settable G54 frame, matching the Sinumerik frame chain).
</p>
</dd>
</dl>
<dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensStopreSyntax.html">SiemensStopreSyntax</a></dt>
<dd><p>Consumes the Siemens <code>STOPRE</code> flag (stop preprocessing — the
control's look-ahead buffer sync) from <a class="xref" href="Hi.NcParsers.Keywords.IFlagsDef.html#Hi_NcParsers_Keywords_IFlagsDef_Flags">Flags</a>
and records a non-modal block-root <a class="xref" href="Hi.NcParsers.Keywords.Siemens.Stopre.html">Stopre</a> section.
STOPRE has no effect in offline simulation (there is no preprocessing
buffer to flush), so an <code>Stopre&ndash;NoOp</code> Unsupported Message is
emitted: recognized, intentionally not simulated, safe offline.</p>
<p>
Capture side: <code>STOPRE</code> is a bare word collected by the Siemens
preset's <a class="xref" href="Hi.NcParsers.ParsingSyntaxs.FlagSyntax.html">FlagSyntax</a> word list.
</p>
</dd>
</dl>
<dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensToolOffsetSyntax.html">SiemensToolOffsetSyntax</a></dt>
<dd><p>Siemens cutting-edge tool offset activation: consumes a standalone
<code>D</code> word (<code>D1</code> activates edge 1 of the active tool,
<code>D0</code> cancels compensation), resolves the effective length via
<a class="xref" href="Hi.NcParsers.Dependencys.Siemens.ISiemensToolOffsetConfig.html#Hi_NcParsers_Dependencys_Siemens_ISiemensToolOffsetConfig_TryGetToolHeightOffset_mm_System_Int32_System_Int32_System_Double__">TryGetToolHeightOffset_mm(int, int, out double)</a>
($TC_DP3, geometry + additive wear) for the (active tool, D) pair —
a pair without a $TC_DP row falls back to the generic
<a class="xref" href="Hi.NcParsers.Dependencys.IToolOffsetConfig.html">IToolOffsetConfig</a> height for the tool number (with a
<code>SiemensToolOffset&ndash;TcdpRowMissing</code> configuration warning), so
an unfilled per-case table follows the ToolHouse-fed source instead
of silently machining with offset 0 — and writes
the same downstream state as the ISO sibling
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.ToolHeightOffsetSyntax.html">ToolHeightOffsetSyntax</a>: the
<a class="xref" href="Hi.NcParsers.Keywords.IToolHeightCompensationDef.html">IToolHeightCompensationDef</a> section (with
<code>Term = &ldquo;D&rdquo;</code>) plus the <code>ToolHeightCompensation</code> entry in the
<a class="xref" href="Hi.NcParsers.Keywords.ITransformationDef.html#Hi_NcParsers_Keywords_ITransformationDef_ProgramToMcTransform">ProgramToMcTransform</a> chain — sharing
the transform Source keeps the two brands' compensation mutually
exclusive via <code>AddOrReplaceTransform</code>'s in-place replacement.</p>
<p>
The active tool number comes from the block's (or previous block's)
<code>ToolChange</code> section; a string tool name resolves through
<a class="xref" href="Hi.NcParsers.Dependencys.Siemens.SiemensToolOffsetTable.html#Hi_NcParsers_Dependencys_Siemens_SiemensToolOffsetTable_FindToolNumberByName_System_String_">FindToolNumberByName(string)</a>. Modal
ownership follows the same yield protocol as the ISO sibling: blocks
without a D word re-resolve only when the previous section's
<code>Term</code> is ours (<code>"D"</code>); an ISO term (G43/G44/G49) leaves the
section to <a class="xref" href="Hi.NcParsers.LogicSyntaxs.ToolHeightOffsetSyntax.html">ToolHeightOffsetSyntax</a> — real Siemens files
mix both dialects (<code>G43H1</code> headers next to <code>D1</code> blocks).
Must therefore be placed <b>after</b> <a class="xref" href="Hi.NcParsers.LogicSyntaxs.ToolHeightOffsetSyntax.html">ToolHeightOffsetSyntax</a>
(and after <a class="xref" href="Hi.NcParsers.LogicSyntaxs.ToolChangeSyntax.html">ToolChangeSyntax</a>) in the Logic bundle, and
before the brand pivot gate (<a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensPivotTransformationSyntax.html">SiemensPivotTransformationSyntax</a>
in the Siemens list) so the pivot entry
stays at the chain tail.
</p>
<p>
Consuming <code>Parsing.D</code> here (Logic) intentionally precedes
<a class="xref" href="Hi.NcParsers.PostLogicSyntaxs.RadiusCompensationSyntax.html">RadiusCompensationSyntax</a> (PostLogic):
on Siemens, D selects the cutting edge — it is not the Fanuc
<code>G41 D5</code> radius argument, and radius state derives from the same
(T, D) edge ($TC_DP6; wiring the radius value is a follow-up).
</p>
</dd>
</dl>
<dl class="jumplist">
<dt><a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensTraoriSyntax.html">SiemensTraoriSyntax</a></dt>
<dd><p>Siemens TRAORI/TRAFOOF (orientation transformation = RTCP): the
Siemens sibling of <a class="xref" href="Hi.NcParsers.LogicSyntaxs.G43p4RtcpSyntax.html">G43p4RtcpSyntax</a>. While TRAORI is
active, the <a class="xref" href="Hi.NcParsers.Keywords.IToolHeightCompensationDef.html">IToolHeightCompensationDef</a> section carries
<code>Term = &ldquo;TRAORI&rdquo;</code> and the <code>ToolHeightCompensation</code> chain
entry becomes a tool-normal · offset translation at the block
endpoint ABC (<a class="xref" href="Hi.NcParsers.Syntaxs.TransformationUtil.html#Hi_NcParsers_Syntaxs_TransformationUtil_MakeToolHeightMat_Hi_Numerical_Xyzabc_IMachineKinematics_Hi_Geom_Vec3d_System_Double_">MakeToolHeightMat(IMachineKinematics, Vec3d, double)</a>),
tagged <a class="xref" href="Hi.NcParsers.Syntaxs.TransformationUtil.html#Hi_NcParsers_Syntaxs_TransformationUtil_KindDynamic">KindDynamic</a> when the rotary
state changes across the block — the single signal that routes the
block to <a class="xref" href="Hi.NcParsers.Keywords.Generic.MotionForm.html#Hi_NcParsers_Keywords_Generic_MotionForm_ClLinear">ClLinear</a> per-step IK.</p>
<p>
Tool length ownership stays with the (T,D) machinery: on real
Sinumerik, TRAORI uses the active D edge's length. Activation adopts
the compensation the D edge (or a mixed-dialect ISO G43) has already
resolved — <a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensToolOffsetSyntax.html">SiemensToolOffsetSyntax</a> runs earlier in the
bundle, so an explicit <code>D1</code> on any TRAORI-modal block first
resolves <code>Term = "D"</code> and this syntax re-takes the section with
the fresh <code>Offset_mm</code>. The adopted owner is recorded in
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensTraoriSyntax.html#Hi_NcParsers_LogicSyntaxs_Siemens_SiemensTraoriSyntax_PriorTermKey">PriorTermKey</a>; TRAFOOF hands the section back to it
(default <code>"D"</code>), because plain length compensation survives
TRAORI deactivation on the control — TRAFOOF only ends the
orientation-following. A TRAFOOF with no active TRAORI (the corpus'
ubiquitous defensive preamble) is consumed silently.
</p>
<p>
Must run <b>after</b> <a class="xref" href="Hi.NcParsers.LogicSyntaxs.ToolHeightOffsetSyntax.html">ToolHeightOffsetSyntax</a> /
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensToolOffsetSyntax.html">SiemensToolOffsetSyntax</a> / the coordinate-offset
syntaxes (mirroring <a class="xref" href="Hi.NcParsers.LogicSyntaxs.G43p4RtcpSyntax.html">G43p4RtcpSyntax</a>'s Fanuc slot) and
<b>before</b> <a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensPivotTransformationSyntax.html">SiemensPivotTransformationSyntax</a>, whose gate
recognizes the <code>TRAORI</code> term and folds the kinematic pivot.
Silently degrades to a plain <code>UnitZ · offset</code> translation when
<a class="xref" href="Hi.Numerical.Xyzabc.IMachineKinematics.html">IMachineKinematics</a> is absent.
</p>
</dd>
</dl>