Archived
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:
+144
-76
@@ -6,7 +6,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="title" content="Class PivotTransformationSyntax | HiAPI-C# 2025 ">
|
||||
|
||||
<meta name="description" content="Writes the entry into on every block, capturing the Pn→MC kinematic rigid transform for the block's endpoint rotary state. Mirrors legacy HardNcLine.GetProgramXyz's use of — without this entry, the transform chain would miss the rotary rotation on any block whose MachineCoordinate.ABC is non-zero, and McXyzSyntax (and ProgramXyzSyntax's inverse lookback) would silently drift. Scope is not limited to RTCP modal: as long as rotary axes are physically at a non-zero position (e.g. after a non-RTCP G00 B90 plus any subsequent motion), the kinematic chain still contributes a non-identity rigid transform that must appear in the endpoint chain. is orthogonal and only governs the dynamic-rotary tagging used by to pick the motion form. Chain position: must run after all Pn-frame writers (, , , , brand-specific coord offset syntaxes) so the PivotTransform entry naturally lands as the last chain element. Must run before / so they see the completed chain. Silently no-ops when is absent (3-axis configurations without rotary kinematics).">
|
||||
<meta name="description" content="ISO/Fanuc-family pivot gate: writes the entry into on blocks where the controller is interpreting commanded XYZ in a frame that needs the Pn→MC kinematic rigid transform — namely active RTCP (G43.4) or active tilted plane (G68/G68.2). On plain-mode blocks (no RTCP, no tilted plane), the controller treats commanded XYZ as machine-frame directly, so the indexed rotary angle is a positioning value only and must not fold into the linear axes; this syntax skips those blocks and leaves the chain at identity (or whatever non-kinematic offsets earlier syntaxes contributed). Brand variants with their own modal vocabulary gate the same shared engine (): Siemens TRAORI/CYCLE800 → ; Heidenhain M128/PLANE SPATIAL would follow the same pattern. Mirrors real Fanuc semantics: plain G43 offsets along the active tilted-plane normal (or machine Z when no tilt is active), and plain XYZ moves map directly to machine axis registers regardless of indexed table/head rotary position. Only G43.4 follows the live tool vector and only G68.2 redefines the work-plane orientation — both of which this guard detects via the existing chain markers. Chain position: must run after all Pn-frame writers (, , , , brand-specific coord offset syntaxes) so the guard sees the finalised mode markers and the PivotTransform entry — when emitted — naturally lands as the last chain element. Must run before / so they see the completed chain. Silently no-ops when is absent (3-axis configurations without rotary kinematics).">
|
||||
<link rel="icon" href="../img/HiAPI.favicon.ico">
|
||||
<link rel="stylesheet" href="../public/docfx.min.css">
|
||||
<link rel="stylesheet" href="../public/main.css">
|
||||
@@ -97,32 +97,38 @@ Class PivotTransformationSyntax
|
||||
<dl><dt>Assembly</dt><dd>HiMech.dll</dd></dl>
|
||||
</div>
|
||||
|
||||
<div class="markdown summary"><p>Writes the <a class="xref" href="Hi.NcParsers.Syntaxs.TransformationUtil.html#Hi_NcParsers_Syntaxs_TransformationUtil_PivotTransformSource">PivotTransformSource</a> entry
|
||||
into <a class="xref" href="Hi.NcParsers.Keywords.ITransformationDef.html#Hi_NcParsers_Keywords_ITransformationDef_ProgramToMcTransform">ProgramToMcTransform</a>
|
||||
on <b>every block</b>, capturing the Pn→MC kinematic rigid transform
|
||||
for the block's endpoint rotary state. Mirrors legacy
|
||||
<code>HardNcLine.GetProgramXyz</code>'s use of
|
||||
<a class="xref" href="Hi.Numerical.Xyzabc.IMachineKinematics.html#Hi_Numerical_Xyzabc_IMachineKinematics_McToPn_Hi_Geom_DVec3d_">McToPn(DVec3d)</a> — without this entry, the
|
||||
transform chain would miss the rotary rotation on any block whose
|
||||
<code>MachineCoordinate.ABC</code> is non-zero, and <code>McXyzSyntax</code> (and
|
||||
<code>ProgramXyzSyntax</code>'s inverse lookback) would silently drift.</p>
|
||||
<div class="markdown summary"><p>ISO/Fanuc-family pivot gate: writes the
|
||||
<a class="xref" href="Hi.NcParsers.Syntaxs.TransformationUtil.html#Hi_NcParsers_Syntaxs_TransformationUtil_PivotTransformSource">PivotTransformSource</a> entry
|
||||
into <a class="xref" href="Hi.NcParsers.Keywords.ITransformationDef.html#Hi_NcParsers_Keywords_ITransformationDef_ProgramToMcTransform">ProgramToMcTransform</a> on blocks
|
||||
where the controller is interpreting commanded XYZ in a frame that
|
||||
needs the Pn→MC kinematic rigid transform — namely active RTCP
|
||||
(G43.4) or active tilted plane (G68/G68.2). On plain-mode blocks
|
||||
(no RTCP, no tilted plane), the controller treats commanded XYZ as
|
||||
machine-frame directly, so the indexed rotary angle is a positioning
|
||||
value only and must <b>not</b> fold into the linear axes; this
|
||||
syntax skips those blocks and leaves the chain at identity (or
|
||||
whatever non-kinematic offsets earlier syntaxes contributed).
|
||||
Brand variants with their own modal vocabulary gate the same shared
|
||||
engine (<a class="xref" href="Hi.NcParsers.LogicSyntaxs.PivotTransformUtil.html">PivotTransformUtil</a>): Siemens TRAORI/CYCLE800 →
|
||||
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.Siemens.SiemensPivotTransformationSyntax.html">SiemensPivotTransformationSyntax</a>; Heidenhain
|
||||
M128/PLANE SPATIAL would follow the same pattern.</p>
|
||||
<p>
|
||||
Scope is <b>not</b> limited to RTCP modal: as long as rotary axes are
|
||||
physically at a non-zero position (e.g. after a non-RTCP <code>G00 B90</code>
|
||||
plus any subsequent motion), the kinematic chain still contributes a
|
||||
non-identity rigid transform that must appear in the endpoint chain.
|
||||
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.G43p4RtcpSyntax.html">G43p4RtcpSyntax</a> is orthogonal and only governs the
|
||||
dynamic-rotary <a class="xref" href="Hi.NcParsers.Syntaxs.TransformationUtil.html#Hi_NcParsers_Syntaxs_TransformationUtil_KindKey">KindKey</a> tagging used by
|
||||
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.LinearMotionSyntax.html">LinearMotionSyntax</a> to pick the motion form.
|
||||
Mirrors real Fanuc semantics: plain G43 offsets along the active
|
||||
tilted-plane normal (or machine Z when no tilt is active), and
|
||||
plain XYZ moves map directly to machine axis registers regardless
|
||||
of indexed table/head rotary position. Only G43.4 follows the live
|
||||
tool vector and only G68.2 redefines the work-plane orientation —
|
||||
both of which this guard detects via the existing chain markers.
|
||||
</p>
|
||||
<p>
|
||||
Chain position: must run <b>after</b> all Pn-frame writers
|
||||
(<a class="xref" href="Hi.NcParsers.LogicSyntaxs.IsoG68p2TiltSyntax.html">IsoG68p2TiltSyntax</a>, <a class="xref" href="Hi.NcParsers.LogicSyntaxs.ToolHeightOffsetSyntax.html">ToolHeightOffsetSyntax</a>,
|
||||
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.G43p4RtcpSyntax.html">G43p4RtcpSyntax</a>, <a class="xref" href="Hi.NcParsers.LogicSyntaxs.IsoCoordinateOffsetSyntax.html">IsoCoordinateOffsetSyntax</a>,
|
||||
brand-specific coord offset syntaxes) so the <code>PivotTransform</code>
|
||||
entry naturally lands as the <b>last</b> chain element. Must run
|
||||
<b>before</b> <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McXyzSyntax.html">McXyzSyntax</a> / <a class="xref" href="Hi.NcParsers.LogicSyntaxs.ProgramXyzSyntax.html">ProgramXyzSyntax</a>
|
||||
so they see the completed chain.
|
||||
brand-specific coord offset syntaxes) so the guard sees the
|
||||
finalised mode markers and the <code>PivotTransform</code> entry — when
|
||||
emitted — naturally lands as the <b>last</b> chain element. Must
|
||||
run <b>before</b> <a class="xref" href="Hi.NcParsers.LogicSyntaxs.McXyzSyntax.html">McXyzSyntax</a> /
|
||||
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.ProgramXyzSyntax.html">ProgramXyzSyntax</a> so they see the completed chain.
|
||||
</p>
|
||||
<p>
|
||||
Silently no-ops when <a class="xref" href="Hi.Numerical.Xyzabc.IMachineKinematics.html">IMachineKinematics</a> is absent
|
||||
@@ -210,62 +216,71 @@ Silently no-ops when <a class="xref" href="Hi.Numerical.Xyzabc.IMachineKinematic
|
||||
|
||||
|
||||
<h2 id="Hi_NcParsers_LogicSyntaxs_PivotTransformationSyntax_examples">Examples</h2>
|
||||
<p>Identity probe — a <code>TestDeps.Kinematics</code> stub that
|
||||
makes <code>McToPn</code> pass through XYZ and return a fixed <code>UnitZ</code>
|
||||
normal, so <a class="xref" href="Hi.NcParsers.Syntaxs.TransformationUtil.html#Hi_NcParsers_Syntaxs_TransformationUtil_MakePivotTransformMat_Hi_Numerical_Xyzabc_IMachineKinematics_Hi_Geom_Vec3d_">MakePivotTransformMat(IMachineKinematics, Vec3d)</a>'s
|
||||
four-basis probing returns identity <code>K(0)</code> and <code>K(abc)</code>,
|
||||
and the product <code>K(0) * K(abc).GetInverse()</code> collapses to
|
||||
identity. With no current or previous <code>MachineCoordinateState</code>,
|
||||
endpoint ABC defaults to <code>(0,0,0)</code>; no dynamic entries exist
|
||||
yet so the entry is tagged <a class="xref" href="Hi.NcParsers.Syntaxs.TransformationUtil.html#Hi_NcParsers_Syntaxs_TransformationUtil_KindStatic">KindStatic</a>.
|
||||
Case for the dep-guard contract only; the real kinematics paths are
|
||||
covered by the cases below.
|
||||
#BeforeBuild:</p>
|
||||
<p>Real-kinematics cases below wire <code>TestDeps.CodeKinematics</code>
|
||||
with the default chain code <code>[O][Z][A][w];[O][Y][X][B][S][t]</code>
|
||||
— a <b>table-A / head-B 5-axis</b> machine. A is on the table side
|
||||
(rotates the workpiece around -X); B is on the head side (rotates
|
||||
the spindle around +Y). Both rotary pivot axes pass through the
|
||||
origin <code>(0,0,0)</code> of the chain root frame because
|
||||
<a class="xref" href="Hi.Numerical.Xyzabc.CodeXyzabcChain.html">CodeXyzabcChain</a> uses zero-offset
|
||||
<code>Branch.Attach</code> between components — a real table-head
|
||||
machine usually has the spindle-B pivot offset from origin, but
|
||||
for the corpus the zero-offset chain keeps the matrices
|
||||
hand-verifiable. Realistic <code>MachineCoordinateState</code> carries
|
||||
A and/or B only; there is no C axis in this chain (5-axis
|
||||
machines have at most two rotary axes).</p>
|
||||
<p>
|
||||
Verification cue specific to this syntax: the zero-offset chain
|
||||
puts the machine-zero attacher at the origin, so the entry's
|
||||
translation anchor <code>T(McToPn(0).Point)</code> vanishes and the
|
||||
matrix reduces to <code>K(abc)⁻¹</code> alone. Table-A rotation moves
|
||||
the workpiece's coordinate frame around the X axis through
|
||||
origin, so the four-basis probe of
|
||||
<a class="xref" href="Hi.NcParsers.Syntaxs.TransformationUtil.html#Hi_NcParsers_Syntaxs_TransformationUtil_MakePivotTransformMat_Hi_Numerical_Xyzabc_IMachineKinematics_Hi_Geom_Vec3d_">MakePivotTransformMat(IMachineKinematics, Vec3d)</a> returns
|
||||
a pure rotation around X — case 3 below pulls out exactly Rx(45°)
|
||||
(no translation column) for table-A=45°. Head-B rotation maps
|
||||
every probe point through the same head-chain rotation, but
|
||||
because everything on the head side downstream of B is at origin
|
||||
before B applies, the rotation reduces to the identity on the
|
||||
probe set: <code>K(abc) == K(0) == I</code> and the entry collapses to
|
||||
identity. That is the symmetry the plain-mode bug fix relies on —
|
||||
head-side rotary was harmlessly writing identity matrices, while
|
||||
table-side rotary was silently rotating linear axes into MC.
|
||||
</p>
|
||||
<p>
|
||||
Plain-mode skip — kinematics dep is present but the block has no
|
||||
active tilted plane and no RTCP, so <code>ShouldFoldKinematicPivot</code>
|
||||
returns false and the syntax leaves the block untouched. This is
|
||||
the "no work to do" guard that prevents over-application of the
|
||||
kinematic transform on indexed-rotary plain XYZ moves:
|
||||
</p>
|
||||
#BeforeBuild:
|
||||
<pre><code class="lang-csharp">{}</code></pre>
|
||||
<p>#AfterBuild:</p>
|
||||
<pre><code class="lang-csharp">{
|
||||
"ProgramToMcTransform": [
|
||||
{
|
||||
"Source": "PivotTransform",
|
||||
"Kind": "Static",
|
||||
"Mat4d": [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]
|
||||
}
|
||||
]
|
||||
}</code></pre>
|
||||
<p>Real <a class="xref" href="Hi.Numerical.Xyzabc.XyzabcSolver.html">XyzabcSolver</a> (table-A / head-B 5-axis layout
|
||||
<code>[O][Z][A][w];[O][Y][X][B][S][t]</code>) with current block declaring
|
||||
<code>MachineCoordinateState.A = 45</code> — endpoint ABC =
|
||||
<code>(π/4, 0, 0)</code> radians. Table-side A rotation moves the tool
|
||||
position in the workpiece frame, so
|
||||
<code>MakePivotTransformMat</code>'s four-basis probe returns a
|
||||
non-identity rigid matrix. The exact Mat4d below was captured from
|
||||
<code>BuildAndDump</code>'s actual output (per gotcha #2: rad/deg trig
|
||||
drift, always dump first):
|
||||
#BeforeBuild:</p>
|
||||
#AfterBuild:
|
||||
<pre><code class="lang-csharp">{}</code></pre>
|
||||
Plain-mode skip with indexed rotary — same guard, but the block
|
||||
already carries a <code>MachineCoordinateState.A = 45</code> indexed
|
||||
table angle (as a prior <code>McAbcSyntax</code> would have written).
|
||||
In a real Fanuc controller, commanded XYZ on this block goes
|
||||
straight to the machine axis registers regardless of A; the
|
||||
kinematic rotation must <b>not</b> be folded into the chain.
|
||||
Real <a class="xref" href="Hi.Numerical.Xyzabc.XyzabcSolver.html">XyzabcSolver</a> dep is wired in so the guard is
|
||||
what stops the write (not the dep-guard at the top of
|
||||
<code>Build</code>):
|
||||
#BeforeBuild:
|
||||
<pre><code class="lang-csharp">{ "MachineCoordinateState": { "A": 45 } }</code></pre>
|
||||
<p>#AfterBuild:</p>
|
||||
<pre><code class="lang-csharp">{
|
||||
"MachineCoordinateState": { "A": 45 },
|
||||
"ProgramToMcTransform": [
|
||||
{
|
||||
"Source": "PivotTransform",
|
||||
"Kind": "Static",
|
||||
"Mat4d": [
|
||||
1, 0, 0, 0,
|
||||
0, 0.7071067811865475, -0.7071067811865475, 0,
|
||||
0, 0.7071067811865475, 0.7071067811865475, 0,
|
||||
0, 0, 0, 1
|
||||
]
|
||||
}
|
||||
]
|
||||
}</code></pre>
|
||||
<p>Stub <code>TestDeps.Kinematics</code> with a pre-existing Dynamic
|
||||
chain entry on the current block (as <a class="xref" href="Hi.NcParsers.LogicSyntaxs.G43p4RtcpSyntax.html">G43p4RtcpSyntax</a>
|
||||
would have written when RTCP is dynamic). <a class="xref" href="Hi.NcParsers.Syntaxs.TransformationUtil.html#Hi_NcParsers_Syntaxs_TransformationUtil_HasDynamicEntry_System_Text_Json_Nodes_JsonObject_">HasDynamicEntry(JsonObject)</a>
|
||||
returns true so the PivotTransform entry is tagged
|
||||
<a class="xref" href="Hi.NcParsers.Syntaxs.TransformationUtil.html#Hi_NcParsers_Syntaxs_TransformationUtil_KindDynamic">KindDynamic</a> even though the math
|
||||
itself collapses to identity:
|
||||
#BeforeBuild:</p>
|
||||
#AfterBuild:
|
||||
<pre><code class="lang-csharp">{ "MachineCoordinateState": { "A": 45 } }</code></pre>
|
||||
Active RTCP signalled by a pre-existing Dynamic chain entry (as
|
||||
<a class="xref" href="Hi.NcParsers.LogicSyntaxs.G43p4RtcpSyntax.html">G43p4RtcpSyntax</a> would have written when RTCP is
|
||||
active and ABC changes across the block).
|
||||
<a class="xref" href="Hi.NcParsers.Syntaxs.TransformationUtil.html#Hi_NcParsers_Syntaxs_TransformationUtil_HasDynamicEntry_System_Text_Json_Nodes_JsonObject_">HasDynamicEntry(JsonObject)</a> returns true, so
|
||||
the guard passes and the PivotTransform entry is written and
|
||||
tagged <a class="xref" href="Hi.NcParsers.Syntaxs.TransformationUtil.html#Hi_NcParsers_Syntaxs_TransformationUtil_KindDynamic">KindDynamic</a>. The
|
||||
<code>TestDeps.Kinematics</code> stub makes
|
||||
<a class="xref" href="Hi.NcParsers.Syntaxs.TransformationUtil.html#Hi_NcParsers_Syntaxs_TransformationUtil_MakePivotTransformMat_Hi_Numerical_Xyzabc_IMachineKinematics_Hi_Geom_Vec3d_">MakePivotTransformMat(IMachineKinematics, Vec3d)</a> collapse to
|
||||
identity:
|
||||
#BeforeBuild:
|
||||
<pre><code class="lang-csharp">{
|
||||
"ProgramToMcTransform": [
|
||||
{
|
||||
@@ -275,7 +290,7 @@ itself collapses to identity:
|
||||
}
|
||||
]
|
||||
}</code></pre>
|
||||
<p>#AfterBuild:</p>
|
||||
#AfterBuild:
|
||||
<pre><code class="lang-csharp">{
|
||||
"ProgramToMcTransform": [
|
||||
{
|
||||
@@ -290,6 +305,59 @@ itself collapses to identity:
|
||||
}
|
||||
]
|
||||
}</code></pre>
|
||||
Active G68.2 tilted plane — the current block carries the modal
|
||||
<a class="xref" href="Hi.NcParsers.Keywords.TiltTransform.html">TiltTransform</a> snapshot plus an existing Static
|
||||
TiltTransform chain entry (as <a class="xref" href="Hi.NcParsers.LogicSyntaxs.IsoG68p2TiltSyntax.html">IsoG68p2TiltSyntax</a>
|
||||
would have written) and <code>MachineCoordinateState.A = 45</code>. The
|
||||
guard reads <code>TiltTransform.Term = "G68.2"</code> and passes; with
|
||||
real <a class="xref" href="Hi.Numerical.Xyzabc.XyzabcSolver.html">XyzabcSolver</a> kinematics (table-A / head-B
|
||||
5-axis), <code>MakePivotTransformMat</code> at <code>abc = (π/4, 0, 0)</code>
|
||||
produces the table-A Rx(45°) rigid matrix. No Dynamic entries in
|
||||
the chain so the new entry stays Static:
|
||||
#BeforeBuild:
|
||||
<pre><code class="lang-csharp">{
|
||||
"TiltTransform": { "Term": "G68.2", "X": 0, "Y": 0, "Z": 0, "I": 0, "J": 30, "K": 0 },
|
||||
"ProgramToMcTransform": [
|
||||
{
|
||||
"Source": "TiltTransform",
|
||||
"Kind": "Static",
|
||||
"Mat4d": [
|
||||
1, 0, 0, 0,
|
||||
0, 0.8660254037844387, 0.49999999999999994, 0,
|
||||
0, -0.49999999999999994, 0.8660254037844387, 0,
|
||||
0, 0, 0, 1
|
||||
]
|
||||
}
|
||||
],
|
||||
"MachineCoordinateState": { "A": 45 }
|
||||
}</code></pre>
|
||||
#AfterBuild:
|
||||
<pre><code class="lang-csharp">{
|
||||
"TiltTransform": { "Term": "G68.2", "X": 0, "Y": 0, "Z": 0, "I": 0, "J": 30, "K": 0 },
|
||||
"ProgramToMcTransform": [
|
||||
{
|
||||
"Source": "TiltTransform",
|
||||
"Kind": "Static",
|
||||
"Mat4d": [
|
||||
1, 0, 0, 0,
|
||||
0, 0.8660254037844387, 0.49999999999999994, 0,
|
||||
0, -0.49999999999999994, 0.8660254037844387, 0,
|
||||
0, 0, 0, 1
|
||||
]
|
||||
},
|
||||
{
|
||||
"Source": "PivotTransform",
|
||||
"Kind": "Static",
|
||||
"Mat4d": [
|
||||
1, 0, 0, 0,
|
||||
0, 0.7071067811865475, -0.7071067811865475, 0,
|
||||
0, 0.7071067811865475, 0.7071067811865475, 0,
|
||||
0, 0, 0, 1
|
||||
]
|
||||
}
|
||||
],
|
||||
"MachineCoordinateState": { "A": 45 }
|
||||
}</code></pre>
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user