This repository has been archived on 2026-10-11. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
HiNC-2025-win-desktop-Deploy/App/wwwroot/HiAPI-docsite/release-note/upgrading-to-3.2/results-that-change-on-upgrade.html
T
2026-09-16 00:00:49 +08:00

307 lines
23 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Results that change on upgrade | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Results that change on upgrade | HiAPI-C# 2025 ">
<link rel="icon" href="../../img/HiAPI.favicon.ico">
<link rel="stylesheet" href="../../public/docfx.min.css">
<link rel="stylesheet" href="../../public/main.css">
<meta name="docfx:navrel" content="../../toc.html">
<meta name="docfx:tocrel" content="toc.html">
<meta name="docfx:rel" content="../../">
<meta name="loc:inThisArticle" content="In this article">
<meta name="loc:searchResultsCount" content="{count} results for &quot;{query}&quot;">
<meta name="loc:searchNoResults" content="No results for &quot;{query}&quot;">
<meta name="loc:tocFilter" content="Filter by title">
<meta name="loc:nextArticle" content="Next">
<meta name="loc:prevArticle" content="Previous">
<meta name="loc:themeLight" content="Light">
<meta name="loc:themeDark" content="Dark">
<meta name="loc:themeAuto" content="Auto">
<meta name="loc:changeTheme" content="Change theme">
<meta name="loc:copy" content="Copy">
<meta name="loc:downloadPdf" content="Download PDF">
<script type="module" src="./../../public/docfx.min.js"></script>
<script>
const theme = localStorage.getItem('theme') || 'auto'
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
</script>
</head>
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="">
<header class="bg-body border-bottom">
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
<div class="container-xxl flex-nowrap">
<a class="navbar-brand" href="../../index.html">
<img id="logo" class="svg" src="../../img/HiAPI.logo.png" alt="">
</a>
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
<i class="bi bi-three-dots"></i>
</button>
<div class="collapse navbar-collapse" id="navpanel">
<div id="navbar">
<form class="search" role="search" id="search">
<i class="bi bi-search"></i>
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
</form>
</div>
</div>
</div>
</nav>
</header>
<main class="container-xxl">
<div class="toc-offcanvas">
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<nav class="toc" id="toc"></nav>
</div>
</div>
</div>
<div class="content">
<div class="actionbar">
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
<i class="bi bi-list"></i>
</button>
<nav id="breadcrumb"></nav>
</div>
<article data-uid="Release-Upgrading-ResultsThatChange">
<h1 id="results-that-change-on-upgrade">Results that change on upgrade</h1>
<p>None of the following breaks a build. All of them change what a simulation produces, so a
byte-for-byte comparison against 3.1.175 output will differ — usually because 3.1.175 was wrong.</p>
<p><strong>Silent wrong geometry, now fixed.</strong> Each of these produced a plausible-looking simulation of the
wrong thing.</p>
<ul>
<li><strong>The kinematic pivot anchor.</strong> The pivot-transform chain entry was built as <code>K(0)·K(abc)⁻¹</code>,
folding the whole machine-zero forward kinematic — its linear part included — into the pre-pivot
anchor. That linear part encodes each axis' motion sense and tool/workpiece-side ownership, so it
mirrored the program components of every workpiece-side linear axis before the IK ran. On a
table-side chain whose machine-zero linear part is <code>diag(1,1,-1)</code>, every program Z was mirrored and
a near-180° swing amplified it into metres of machine-Z error, floating the toolpath above the
workpiece. The anchor is now the translation alone, matching what HardNc has always kept. Machines
whose linear axes all ride the tool side are unaffected.</li>
<li><strong>G68 2D coordinate rotation was a silent no-op.</strong> <a class="xref" href="../../api/Hi.NcParsers.LogicSyntaxs.TiltTransformUtil.html">TiltTransformUtil</a>
judged the active mode from the current block but always took the matrix from the previous one, so
every G68 activation past the first block had its freshly authored rotation overwritten with an
identity that then propagated. G68 rotation did nothing at all while the block's term still read
<code>G68</code>, and the simulation machined the unrotated pattern. Re-running an existing G68 program now
gives different — correct — geometry.</li>
<li><strong>A blank line reset G90/G91.</strong> A piece with no parsing section — a blank line, a comment-only line,
<code>%</code>, an O-number — left the next block's single-step lookback empty, and it fell back to the G90
default. A program that was incremental throughout silently flipped to absolute mid-file. Such
pieces now carry the positioning section forward like every other modal syntax.</li>
<li><strong>A Siemens D offset with no <code>$TC_DP</code> row resolved to zero length, in silence.</strong> A whole TRAORI
program machined one tool length low. The read point now falls back to the generic tool-number-keyed
height and emits <code>SiemensToolOffset--TcdpRowMissing</code>.</li>
<li><strong>G43.4 with an unresolvable H word activated RTCP with a zero-length tool.</strong> It now reports
<code>Comp-ToolHeight--001</code> as a warning and keeps processing the block. An omitted H is no longer a
silent zero: it takes the equipped tool's own offset row first (HardNc parity), then a non-zero
modal id, and only then warns <code>Comp-ToolHeight--NoToolForOmittedH</code> (plain G43) or
<code>Comp-ToolHeight--NoToolForOmittedHRtcp</code> (G43.4). A vacant table row warns
<code>Comp-ToolHeight--RowMissing</code> instead of compensating a zero length.</li>
<li><strong><code>G43.4</code> survived <code>M02</code> / <code>M30</code> and a rotary-only <code>G53</code> still coupled through RTCP.</strong> A sequence
that ended one program with <code>M02</code> and started the next with a rotary rapid — without a <code>G49</code> —
kept tool-centre-point control on, pinned the tip, and dragged machine XYZ through the stock. On
SoftNc the program-end block is a <strong>reset edge</strong>: tool-length compensation (G43 / G44 / G43.4,
Siemens <code>TRAORI</code>, Heidenhain <code>M128</code>), tilt (G68 / G68.2 / CYCLE800 / <code>PLANE</code> / TRANS), G41/G42 and
G81–G89 cancel on the <em>next</em> block, written as explicit cancel sections so modal carry cannot copy
the previous state. The <code>M02</code> block itself still runs under the modal state it executed with, so a
retract on the same line as <code>M30</code> still carries tool length. A rotary-only <code>G53</code> under active
RTCP now holds the linear axes at the previous machine position and stays McLinear, which is what
G53 does on a control (no compensation). <strong>HardNc still carries G43.4 across <code>M02</code></strong> — the two
engines are deliberately divergent on that edge; 3.2's default is SoftNc. A tool change that
leaves <code>G43.4 Hm</code> alive for a different tool warns
<code>Comp-ToolHeight--RtcpOutlivesToolChange</code> on the change block.</li>
<li><strong>Fanuc <code>G54.1 Pn</code> (also written <code>G54 Pn</code>) was not resolved.</strong> Additional work coordinate systems
now resolve against the extended table; a selected row nobody has entered reports
<code>Coord-WorkOffset--AdditionalZero</code> and runs on the machine origin. <code>G59.1</code>–<code>G59.9</code> have a
provider on the ISO presets. See
<a href="../../anatomy/general-setup/controller/program-data/work-coordinates.html">Work Coordinates</a>.</li>
<li><strong>Heidenhain DIN/ISO arc centres.</strong> <code>I</code> / <code>J</code> / <code>K</code> are <strong>absolute</strong> circle centres on Heidenhain —
the ISO face of the klartext <code>CC</code> pole — not start-to-centre offsets. Reading them incrementally
turned arcs into near-full phantom circles. Fixed in all three engines: the HardNc reader
(<a class="xref" href="../../api/Hi.Numerical.NcArgs.ArcNcArg.html#Hi_Numerical_NcArgs_ArcNcArg_IsIjkAbsolute">IsIjkAbsolute</a>), the SoftNc reader
(<a class="xref" href="../../api/Hi.NcParsers.LogicSyntaxs.CircularMotionSyntax.html#Hi_NcParsers_LogicSyntaxs_CircularMotionSyntax_IsIjkAbsolute">IsIjkAbsolute</a>) and the optimizer's write-back.
<code>G91</code> is the exception: an incremental block switches the words back to start-to-centre offsets, so
an arc programmed under <code>G91</code> is unaffected by this change. Also delivered on the 3.1.175.x service
line.</li>
<li><strong>Feed per tooth, MRR and cutting forces follow the equipped tool's tip, not the controller's F
word.</strong> The physics used to read the commanded CL feedrate. It now reads the step's real tip
feedrate (<a class="xref" href="../../api/Hi.MachiningSteps.MachineMotionStep.html#Hi_MachiningSteps_MachineMotionStep_ActualTipFeedrate_mmds">ActualTipFeedrate_mmds</a>, client key
<a class="xref" href="../../api/Hi.MachiningSteps.MachiningStep.html#Hi_MachiningSteps_MachiningStep_ActualTipFeedrate_mmdmin">ActualTipFeedrate_mmdmin</a>): the tip's displacement relative
to the workpiece over the step duration. On XYZ moves, CL files and RTCP with the equipped tool's own
offset the two agree (the recomputation moves forces by at most about 1e-4 relative, from the
<code>TimeSpan</code>-quantised step duration); they part under RTCP with a tool-length offset that does not
describe the equipped tool, on rotary-axis-limited simultaneous five-axis blocks (the tip is slower
than F, up to a few percent), and wherever the commanded value was stale.</li>
<li><strong>A feed block that does not move lost its F word.</strong> A block that repeats the current position
(<code>X.. Y.. Z.. F1600.</code> right after the same point at <code>F800.</code>, a common CAM habit) returned on
zero distance before emitting anything, so every following block showed and cut at the old
feed. Its <code>ActFeedrate</code> now lands on a zero-length linear, arc or polar block alike. The same
stale commanded value is one of the cases the tip-feedrate split above parts on.</li>
<li><strong>A rotary-bearing act mixed tip travel with the commanded CL feed resolution.</strong> On a pure RTCP
rapid swing the CL point stands still, the commanded feed is ~0, and dividing the equipped tool's
tip sweep by that resolution saturated the step count (the play appeared to hang on one line). A
rotary-bearing act now splits by posture change (each rotary-axis delta over the rotary
resolution) and by spindle cycles when the spindle turns — never by tip travel over the CL-feed
resolution. Step counts of existing five-axis projects therefore shift on non-RTCP rotary
blocks; XYZ-only programs are unaffected.</li>
<li><strong>A <code>K0</code> word on a HardNc G02/G03 saturated the turn count.</strong> Under the default G17 plane a
written-but-zero plane-normal word divided the axial travel by zero, the additional-turn count
saturated to <code>int.MaxValue</code>, and one arc block became a spiral act of roughly 302 simulated years —
the play appeared to hang on a single NC line. The reading now falls back to the closed-circle rule
for a zero pace, matching the guard the SoftNc side already had.</li>
<li><strong>Indexed-rotary programs folded the pivot into plain moves.</strong> A block with no active G68.2 or
G43.4 no longer folds the kinematic pivot transform into a plain XYZ move, which is what a real
controller does with a table-side rotary program.</li>
<li><strong>The radius-compensation arc transient cache landed on the wrong block.</strong> Any non-motion line
between the corner and the arc orphaned the cache, so the arc lost its leading linear bridge and
began at the corner intersection instead of on the offset arc.</li>
<li><strong>Cutter radius compensation on G18 / G19 ran out of the plane.</strong> Both engines built the
perpendicular as <code>Z × axis</code> whatever plane was selected, so under G18 or G19 the whole offset went
one radius along the plane normal (a <code>G41</code> region in the ZX plane was displaced in Y), every arc of
the region reported <code>Arc-EndpointOffRadius</code>, and the <code>RadiusComp--Interference</code> gate could not fire
there. Both engines now take the perpendicular, the in-plane test for blocks without movement and
the interference gate from the selected plane: the offset lies in the plane, left/right is judged
looking down the plane's positive normal (the same convention that orients G02/G03), and the
diagnostics behave as on G17. G17 programs are unaffected.</li>
<li><strong>The G68.2 tool-axis IK fallback probed the mirrored tool axis.</strong> Both normal-only fallbacks in
<a class="xref" href="../../api/Hi.NcParsers.LogicSyntaxs.IsoG68p2TiltSyntax.html">IsoG68p2TiltSyntax</a> read the transposed third column instead of the
third row. On the no-hint path this only skewed a warning gate, but the explicit A/B/C path seeds
its hint blend from that solve, so a machine with fewer than three rotary axes composed a mirrored
tilted plane.</li>
<li><strong>A Fanuc <code>WHILE</code> forward jump bound to the wrong <code>END</code>.</strong> Sequential loops idiomatically reuse
<code>DO 1</code>, so a second <code>WHILE</code>'s falsy-condition exit bound to the <em>first</em> loop's <code>END 1</code> and
redirected execution to a point before the second <code>WHILE</code> — an unbounded loop the iteration
watchdog cannot see, because it only ticks on <code>END</code> reverse jumps. The jump now uses the anchored
label scan the Siemens loop family already used.</li>
<li><strong>Heidenhain G28 is MIRROR IMAGE, not a reference-point return.</strong> On the Heidenhain preset the
shared pipeline had been reading it as the Fanuc reference return, so a <code>G28 X</code> block minted a
phantom rapid to home while the mirror silently vanished. It is now simulated as a program-to-MC
transform, <code>ReferenceReturnSyntax</code> leaves the Heidenhain logic list, and klartext <code>CYCL DEF 8</code>
records the same mirror statement so one program mirrors identically in either dialect. <strong>HardNc
keeps the Fanuc reading</strong>, so the two engines are deliberately divergent on Heidenhain G28 files and
any parity comparison must account for it.</li>
<li><strong><code>MathUtil.Convert_inchdmin_To_mmds</code> returned mm/min, not mm/s.</strong> The body multiplied by 25.4 and
never divided by 60, so a caller trusting the name got a 60× feedrate; the sibling
<code>Convert_mmdmin_To_mmds</code> divides as its name demands. No shipped path called it — the CL/APT
feedrate route converts inches-per-minute to mm/min itself — so this changes nothing inside the
product, but a caller who had compensated for the old behaviour must remove that compensation.</li>
<li><strong><code>GetRByZ(List&lt;PairZr&gt;)</code> never interpolated.</strong> The list overload looked up its ceiling node with
the floor lookup, so floor equalled ceiling and the method degenerated into a step function. For a
sharp cone whose inner-beam Z–R list has no node between apex and rim, that pinned the inner radius
to 0 across the whole cone face and produced NaN flute vertices — the root cause of the transparent
cone-tip flute that 3.1.180 addressed at the display layer. It affects every consumer of
radius-by-Z interpolation, force geometry included.</li>
</ul>
<p><strong>Numerical results move even where nothing was renamed.</strong></p>
<ul>
<li>Five-axis IK is roughly <strong>1000× tighter</strong>. The rotary solver behind
<a class="xref" href="../../api/Hi.Numerical.Xyzabc.XyzabcSolver.html">XyzabcSolver</a> now runs coarse→polish: the coarse stage keeps the
original dot residual so solve success and failure
semantics are unchanged, then a <code>[dot, cross, rr-per-axis]</code> system polishes. The dot criterion is
quadratically blind to angle error — an envelope of about 1.4e-3 rad, and the resulting tip error is
that envelope times the tool length — so adding the cross term restores quadratic convergence and
drops the envelope to about 1e-6 rad. Failed solves no longer pollute the implicit seed, and the
measure-zero perfect-saddle case is escaped by a deterministic retry offset instead of by leftover
seed pollution.</li>
<li><a class="xref" href="../../api/Hi.Numerical.Acts.ActMcXyzLinearContour.html">ActMcXyzLinearContour</a> steps by <strong>euclidean</strong> tip travel instead of the
largest per-axis component, so <code>LinearResolution_mm</code> now caps actual tool-tip travel per step and a
diagonal move produces up to √3× more steps at the same setting.</li>
<li><strong>Cutter–workpiece engagement no longer depends on how the contact surface was tiled.</strong> The scan
that turns a step's contact contours into the engaged angle ranges of
<a class="xref" href="../../api/Hi.Milling.Engagements.LayerMillingEngagement.html">LayerMillingEngagement</a> switched to a bounding-box approximation on
dense steps, could pull a merged range back when a shorter slice nested inside it, started bottom
rings the floor never reached, and read the winding of each triangle — so the same cut produced a
different engagement, and therefore different cutting forces and temperatures, depending on how
many polygons the geometry kernel happened to cut the contact surface into. Every triangle is now
scanned exactly and orientation-free; a cylinder wall and a flat floor sector with known engagement
arcs reproduce them to 1e-9 rad at four tessellations, and the managed and native paths stay
bit-identical. Re-running an existing program moves the forces on most engaged steps (58–95% of
them on the bench fixtures); the largest moves are floors that used to register as empty — the
whole bottom disc dropped out — and side ranges that were fragmented into pieces separated by
phantom 1° gaps. Coefficient sets trained before this change embed the old engagement of their
training program; retrain on a replay if that fit matters.</li>
<li><strong>SoftNc canned cycles index a rotary axis.</strong> A G81–G89 repeat block carrying an A / B / C word
used to skip the hole (rotary-only repeat), drill it at the previous angle (mixed block) or let it
follow the table under <code>G68.2</code>. It now indexes the table and drills again, pre-positioning XYZ and
the table in one move, and under <code>G68.2</code> without RTCP the feature frame stays pinned in machine
space. Under <code>G91</code> only the words the block itself spoke are increments — an X-pitch repeat used
to add the previous cycle's Y a second time and drill upward. A bolt-circle program that ran
short of holes, or drilled them in the wrong place, now matches the HardNc replay.</li>
<li><strong>A rotary word under modal <code>G91</code> is an increment.</strong> <code>G91 … C20.</code> then <code>C20.</code> left the table at
20; it is 40 now. A spoken <code>G91 B270.</code> stays a +270° traverse instead of folding to −90°, and a
<code>G91 G28</code> rotary intermediate anchors on the previous modal angle instead of on zero (<code>G91 G28 C0</code> from C90 now holds the table and returns home instead of swinging to 0 first). Per-word
directives (<code>C=AC(90)</code>, <code>ACP</code> / <code>ACN</code>, <code>IC()</code>) are unchanged. HardNc keeps its absolute reading
and warns.</li>
<li><strong>Rotary IK from a pole seed.</strong> Every solve attempt now runs coarse then polish, so a small tilt
with a large azimuth that ran out of iterations a few milliradians short — and was refused by
<code>G53.1</code>, leaving the table at A = C = 0 with the tilt active and the path rotated off the part —
now solves to 1e-8 rad. On a Fanuc IJK grid from the pole seed 54 / 69 failures per A/C chain
become 0; a CL program goes from 44 dropped endpoints of 536 to 0.</li>
<li><strong>The rotary branch inside the travel wins.</strong> When the nearest IK solution lies outside an axis'
configured travel, <code>G53.1</code>, <code>G68.2</code>, <code>CYCLE800</code>, <code>PLANE SPATIAL</code> and <code>LN</code> now take the admissible
branch nearest the entry (sign, half-turn and supplement combinations are searched); a posture
the cradle cannot take is no longer commanded silently. This needs the travel to be known, and
it now is on every project: stroke limits declared only in the legacy machine-limits boxes are
copied into the controller parameter table on load for the axes carrying no end there, where they
used to be checked against nothing on SoftNc. An axis parked exactly on its limit is no longer
reported (<a class="xref" href="../../api/Hi.NcParsers.Dependencys.StrokeLimitUtil.html#Hi_NcParsers_Dependencys_StrokeLimitUtil_Tolerance">Tolerance</a>).</li>
<li>The SoftNc pipeline is the default engine.</li>
<li>Executed <code>SyntaxPiece</code>s freeze to UTF-8 (below), so their <code>JsonObject</code> is a fresh read-only snapshot
per call rather than a retained live graph.</li>
<li><code>SyntaxPiece.SentenceIndex</code> becomes a session-global execution-order counter and is no longer
contiguous per file.</li>
<li>Repeated NC diagnostics fold into per-run summaries at the run boundaries.</li>
<li><strong>HardNc tool changes</strong> fire on M06 / Heidenhain <code>TOOL CALL</code> rather than on a changed <code>T</code> word — a
bare <code>T</code> is magazine pre-selection, and a same-tool M06 still runs the changer cycle — and unset
<code>HardNcEnv</code> tooling defaults become the three-axis shape (XYZ = NaN, NaN, 0; ABC all NaN). The old
defaults swung all three rotary axes home on every M06, which no post expects.</li>
</ul>
</article>
<div class="contribution d-print-none">
</div>
<div class="next-article d-print-none border-top" id="nextArticle"></div>
</div>
<div class="affix">
<nav id="affix"></nav>
</div>
</main>
<div class="container-xxl search-results" id="search-results"></div>
<footer class="border-top text-secondary">
<div class="container-xxl">
<div class="flex-fill">
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
</div>
</div>
</footer>
</body>
</html>