This commit is contained in:
2026-09-09 17:35:23 +08:00
parent 2a98ae7556
commit 161af68fe3
1271 changed files with 58251 additions and 98639 deletions
@@ -87,70 +87,162 @@
<article data-uid="">
<h1 id="program-zero-alignment">Program Zero Alignment</h1>
<p><strong>Program zero</strong> (<code>ProgramZeroAnchor</code>) is the point an NC program treats as <code>X0 Y0 Z0</code>. It is related to the machine's work-coordinate offset (G54/G55/...): when the machine coordinate equals the work offset, the spindle sits at program zero.</p>
<p>Setting up a simulation requires relating program zero to the work offset. <strong>Which way you align depends on the scenario.</strong></p>
<h2 id="two-alignment-directions">Two Alignment Directions</h2>
<h3 id="nc-file-scenario-planning--align-g54-to-program-zero">NC-file scenario (planning) — align G54 to program zero</h3>
<p>When you drive the simulation from an NC file for <strong>planning</strong>, you usually keep the workpiece and fixture wherever they are convenient and set the work offset to match. The G54 value may not be obtained yet, and the layout does <strong>not</strong> need to reflect the real machine.</p>
<ul>
<li>Keep the workpiece/fixture placement as-is.</li>
<li>Read the machine coordinate at program zero with <a class="xref" href="../../api/Hi.Machining.MachiningEquipmentUtils.MachiningEquipmentUtil.html#Hi_Machining_MachiningEquipmentUtils_MachiningEquipmentUtil_GetMachinePositionAtProgramZero_">GetMachinePositionAtProgramZero</a> and store it into the ISO coordinate table (<code>IsoCoordinateTable.SetCoordinateOffset(&quot;G54&quot;, ...)</code>).</li>
</ul>
<h3 id="csv--real-time--online-mc-scenario-high-fidelity--align-program-zero-to-g54">CSV / real-time / online-MC scenario (high-fidelity) — align program zero to G54</h3>
<p>When you drive the simulation from a <strong>controller CSV log</strong> (see <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_PlayCsvFile_">PlayCsvFile</a>) or a real-time / online machine coordinate feed, the data is in <strong>absolute machine coordinates</strong>. To reproduce the real cut faithfully (高還原度), the workpiece + fixture must sit at their <strong>real positions</strong> so that collisions, overcut, and engagement match reality.</p>
<pre><code class="lang-csharp">// Places workpiece + fixture so ProgramZeroAnchor coincides with the
// world position the spindle reaches when the machine coordinate equals G54.
AlignWorkpieceProgramZeroToIso(&quot;G54&quot;);
</code></pre>
<p>The same action is available in the web UI on the Controller page's ISO Coordinate Table (<code>Align P0</code> per row, with a one-shot <code>Revert Align</code>).</p>
<p><code>AlignWorkpieceProgramZeroToIso</code> mutates only <code>Fixture.GeomToTableTransformer</code>. The three buckle transformers must already be placed per the rule below.</p>
<h2 id="buckle-general-rule">Buckle General Rule</h2>
<p>The workpiece/fixture assembly is built from buckle anchors (see <a href="anchor.html">Component Assembly and Anchors</a>). A typical block-on-plate setup places them at the geometry bounding-box centers:</p>
<p>Program zero is the point an NC program treats as <code>X0 Y0 Z0</code>. The machine finds it by adding a work
offset — G54, G55 and the rest — to machine zero, so a simulation only cuts where the real machine
cuts if the program zero on the model and the work offset in the controller agree. Making them agree
is this task, and it runs in one of two directions depending on why the simulation is being built.</p>
<h2 id="which-direction-to-align">Which direction to align</h2>
<table>
<thead>
<tr>
<th>Transformer</th>
<th>Position</th>
<th>You are</th>
<th>Align</th>
<th>Because</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>Workpiece.WorkpieceGeomToFixtureBuckleTransformer</code></td>
<td>bottom center of the workpiece geom</td>
<td><strong>Planning a job</strong> from an NC file, before the part is set up on the machine</td>
<td>the <strong>work offset</strong> onto program zero</td>
<td>The workpiece and fixture can sit wherever is convenient; the offset has probably not been measured yet, and the model does not have to match a real table</td>
</tr>
<tr>
<td><code>Workpiece.WorkpieceGeomToProgramZeroTransformer</code></td>
<td>top center of the workpiece geom (or any chosen top tip)</td>
</tr>
<tr>
<td><code>Fixture.GeomToWorkpieceTransformer</code></td>
<td>top center of the fixture geom</td>
<td><strong>Reproducing a cut</strong> from a controller log, a machine-coordinate feed, or a job already running</td>
<td><strong>program zero</strong> onto the work offset</td>
<td>The recorded data is in absolute machine coordinates, so the part has to sit where it really sits, or collisions, overcut and engagement will not match what happened</td>
</tr>
</tbody>
</table>
<p><code>AlignWorkpieceProgramZeroToIso</code> then derives the final <code>Fixture.GeomToTableTransformer</code> from the live assembly topology (anchor-to-anchor vectors), so it works for any chain — it does not assume the buckles are at bounding-box centers.</p>
<h2 id="verifying-the-setup">Verifying the Setup</h2>
<p>A wrong setup (incorrect work offset or workpiece position) shows up as <strong>overcut</strong>, <strong>collision</strong>, or <strong>nocut</strong>. These are observable <strong>early</strong> — typically within the first ~100 NC lines or ~1 minute — so verify with a quick, cheap pass before a full run:</p>
<p>Both directions need the workpiece already placed on the fixture and the fixture on the table —
that is <a href="anchor.html">Anchor</a>, and it comes first.</p>
<h2 id="where-program-zero-sits-on-the-workpiece">Where program zero sits on the workpiece</h2>
<p><strong>Geom To Program Zero</strong> (<code>/general-setup?tree=equipment/workpiece/anchor/geom-to-program-zero</code>)
holds the offset from the workpiece geometry to program zero. Set it to whatever point the NC
program was written around: for most milling programs that is a corner or the centre of the stock's
top face. Nothing else on this page makes sense until that point is where the programmer put it.</p>
<h2 id="planning-write-the-offset-from-where-the-workpiece-is">Planning: write the offset from where the workpiece is</h2>
<p>The Controller branch's <strong>Work Coordinates</strong> leaf
(<code>/general-setup?tree=equipment/controller/program-data/work-coordinates</code>) holds the table the run
resolves G54 against, one row per coordinate id.</p>
<ol>
<li>Set a coarse <a class="xref" href="../../api/Hi.MachiningProcs.SessionShell.html#Hi_MachiningProcs_SessionShell_MachiningResolution_">MachiningResolution</a> ≈ <strong>1/8 of the cutter diameter</strong> for fast feedback.</li>
<li>Run and watch the <strong>opening Z plunge (下刀)</strong>. This is where overcut/collision most often appears when the work offset or workpiece Z is wrong.</li>
<li>Place the workpiece and fixture wherever the scene is convenient to work in.</li>
<li>Select the Work Coordinates leaf and find the row the program uses — <code>G54</code> for most programs.</li>
<li>Press <strong>P0</strong> in that row. It writes the machine coordinate the workpiece's program-zero anchor is
currently sitting at into the row, which is exactly the number the machine's operator would key
in after touching off. <strong>M0</strong> beside it writes machine zero instead, which is how a row is
returned to no offset at all.</li>
</ol>
<p>The leaf on a demo project, at
<code>/general-setup?tree=equipment/controller/program-data/work-coordinates</code>. The grey line above the
table names where this brand keeps the offsets — on Fanuc, its own parameter table — and the rows
below it are the coordinate ids that brand holds, with only <code>G54</code> carrying a value here. The panel
is narrow, so the row actions sit off the right edge; the same three are shown in full on the Legacy
Controller screen below.</p>
<p><img src="program-zero-alignment-img/work-coordinates.en.png" alt="The Work Coordinates leaf of the Control Tree selected on the General Setup page, its panel showing a caption reading that the offsets are stored in the Fanuc parameter table and a table of G54 through G57 rows with X, Y and Z fields, G54 holding values and the rest zero"></p>
<p><strong>P0 has something to write only once the scene is assembled.</strong> It works out where the program-zero
anchor is by walking the machine chain to it, so a project with no machine tool attached, or a
workpiece that has not been placed, gives it nothing to compute and it reports that it could not get
the machine position at program zero rather than writing a wrong number.</p>
<p>The row's values can also be typed in directly when the offset is already known from the machine.
Clicking anywhere in a row marks that coordinate on the canvas, so the offset can be seen rather
than only read.</p>
<h2 id="reproducing-a-real-cut-move-the-workpiece-onto-the-offset">Reproducing a real cut: move the workpiece onto the offset</h2>
<p>Going the other way — leaving the offset alone and moving the part to meet it — is <strong>Align P0</strong>, and
it is on the Legacy Controller screen's <strong>Coordinate Table</strong> tab (<code>/controller/coordinate-table</code>),
not on the Controller branch. It moves the workpiece and fixture together, by changing where the
fixture sits on the machine table, until program zero lands on the offset the row holds. The toast
reports the translation it assigned.</p>
<p>The tab on a demo project. Each row carries <strong>P0</strong> and <strong>M0</strong> — the same two writes the branch's
leaf offers — and <strong>ALIGN P0</strong> beside them, which is the one control that moves the part instead of
writing a number. <strong>Undo Align</strong> and <strong>Redo Align</strong> in the header step back and forth through the
alignments this screen has recorded; <strong>Show on Display</strong> turns the coordinate marker in the viewer on
and off, and the checkbox at the left of each row picks which coordinate it marks.</p>
<p><img src="program-zero-alignment-img/align-p0.en.png" alt="The Legacy Controller screen's Coordinate Table tab: an ISO Coordinate Table with Undo Align, Redo Align and Show on Display in its header, and rows G54 through G59.5 each carrying X, Y and Z fields and an Actions column with P0, M0 and ALIGN P0"></p>
<p>Align P0 needs a workpiece, a fixture and a machine tool on the project; without all three it writes
nothing and says so. Driving the screen itself — the tab strip, the alignment history and what it
does and does not survive — is <a href="../utilities/legacy-controller.html">Legacy Controller</a>.</p>
<div class="WARNING">
<h5>Warning</h5>
<p><strong>Align P0 reads a different table from the one the run uses.</strong> The offsets on the Legacy
Controller screen and the offsets on the Controller branch's Work Coordinates leaf are two
separate stores: typing a value into one does not change the other, and nothing keeps them in
step. A run resolves its work offsets through the branch's table, while Align P0 takes its target
from the legacy screen's. So before aligning, check that the row you are about to press <strong>ALIGN
P0</strong> on holds the same offset as the branch's row of the same name — otherwise the part is moved
onto a number the program will never use. A project built with both tables filled in agrees only
because it was written that way.</p>
</div>
<h2 id="checking-that-it-worked">Checking that it worked</h2>
<p>A wrong alignment — a wrong offset, or a workpiece at the wrong height — shows up as <strong>overcut</strong>,
<strong>collision</strong> or <strong>nocut</strong>, and it shows up early: usually within the first hundred or so NC lines.
Check it cheaply before committing to a full run.</p>
<ol>
<li>Set a coarse <strong>Initial Resolution</strong> on the workpiece's <strong>Mesh</strong> item — around an eighth of the
cutter diameter is enough to see gross errors, and it runs quickly. That is
<a href="workpiece.html">Workpiece</a>.</li>
<li>Run, and watch the opening Z plunge. This is where a wrong offset shows first.</li>
</ol>
<div class="TIP">
<h5>Tip</h5>
<p>If the tool plunges far deeper than the programmed depth and the holder crashes into the workpiece (a visible gouge on the rendered stock), the work offset Z is almost certainly wrong — the workpiece is modeled higher (or lower) than its real position.</p>
<p>If the tool plunges far deeper than the programmed depth and the holder gouges the stock, the work
offset's Z is almost certainly wrong — the workpiece is modelled higher or lower than it really
sits.</p>
</div>
<div class="NOTE">
<h5>Note</h5>
<p>Rare false positive: a roughing cut with a <strong>spiral entrance on tough material</strong> can legitimately exceed the modeled cutting conditions yet still be a <em>correct</em> setup. This is uncommon — in most cases early overcut/collision/nocut means the setup is wrong.</p>
</div>
<h2 id="high-fidelity-caution-work-offset-must-reflect-the-real-machine">High-Fidelity Caution: Work Offset Must Reflect the Real Machine</h2>
<p>In the CSV / online-MC scenario, the work offset (G54/G55/...) you align to must be the <strong>actual offset used on the machine</strong>, not a planned/nominal value. Operators frequently re-zero between setups (manual tool changes, re-cut stock), so a planned G54 can differ from the real one — by an amount you cannot assume in advance.</p>
<p>When driving from a controller log, <strong>derive the offset from the log's own machine coordinates</strong> rather than trusting a planned value: invariants that survive operator edits — a known cutting depth, a feature span — mapped onto the recorded machine coordinates, recover the real offset on those axes. (Positions the operator may have shifted are not recoverable this way.) A work-offset Z that is wrong places the workpiece away from its true height, so the tool over- or under-plunges; if too high, the holder crashes the stock at the opening plunge — exactly the failure the rough-resolution check above catches.</p>
<p>One false positive is worth knowing: a roughing cut with a spiral entrance into tough material can
legitimately exceed the modelled cutting conditions while the setup is perfectly correct. It is
uncommon, and early overcut, collision or nocut usually does mean the alignment is wrong.</p>
<h2 id="when-the-planned-offset-is-not-the-real-one">When the planned offset is not the real one</h2>
<p>In the reproducing direction, the offset aligned to must be <strong>the offset the machine was actually
using</strong>, not the one the job was planned with. Operators re-zero between setups — after a manual
tool change, after re-cutting stock — so a planned G54 and the real one can differ by an amount that
cannot be assumed in advance.</p>
<p>When the data comes from a controller log, derive the offset from the log's own machine coordinates
rather than trusting the plan: an invariant that survives an operator's edits — a known cutting
depth, the span of a feature — mapped onto the recorded coordinates recovers the real offset on
those axes. Axes the operator may have shifted with nothing to key on are not recoverable this way.
A wrong Z is the one that bites hardest, because it places the workpiece away from its true height
and the tool over- or under-plunges from the first block.</p>
<h2 id="a-placement-convention-that-makes-this-easier">A placement convention that makes this easier</h2>
<p>The three transforms that hold the assembly together can be put anywhere, but a block-on-plate setup
is easiest to reason about when each sits at the middle of the face it meets:</p>
<table>
<thead>
<tr>
<th>Transform</th>
<th>A good default</th>
</tr>
</thead>
<tbody>
<tr>
<td>Fixture's <strong>Geom To Workpiece</strong></td>
<td>The top centre of the fixture geometry</td>
</tr>
<tr>
<td>Workpiece's <strong>Geom To Fixture</strong></td>
<td>The bottom centre of the workpiece geometry</td>
</tr>
<tr>
<td>Workpiece's <strong>Geom To Program Zero</strong></td>
<td>The top centre of the workpiece geometry, or whichever top point the program was written around</td>
</tr>
</tbody>
</table>
<p>Align P0 does not depend on this convention — it works out the fixture's placement from the
assembly as it stands, whatever the transforms hold — but a scene built this way is far easier to
check by eye.</p>
<h2 id="see-also">See Also</h2>
<ul>
<li><a href="anchor.html">Component Assembly and Anchors</a> — buckle anchors (<code>WorkpieceBuckle</code>, <code>TableBuckle</code>, <code>SpindleBuckle</code>)</li>
<li><a href="anchor.html">Anchor</a> — placing the workpiece, fixture and tool relative to the machine, which comes before this</li>
<li><a class="xref" href="../../technique/mechanism/assembly-anchors.html">Assembly Anchors</a> — the named buckle anchors this alignment resolves against</li>
<li><a href="workpiece.html">Workpiece</a> — the branch carrying the Geom To Program Zero transform this task sets, and the Mesh resolution the check above uses</li>
<li><a href="fixture.html">Fixture</a> — the transform Align P0 rewrites when it moves the part onto an offset</li>
<li><a href="controller.html">Controller</a> — the branch whose work-offset table a run resolves against</li>
<li><a href="../utilities/legacy-controller.html">Legacy Controller</a> — the screen Align P0 lives on, and its alignment history</li>
<li><a href="../../technique/nc-dialects/index.html">NC Dialects</a> — how each brand's code names the work offset this alignment is expressed against</li>
<li><a class="xref" href="../../workflows/project-data-checklist.html">Project Data Checklist</a> — the collection step this alignment closes</li>
<li><a class="xref" href="../../workflows/basic-simulation.html">Workflow: Basic Machining Simulation</a> — driving a simulation from an NC file or a controller log</li>
<li><a class="xref" href="../../workflows/force-training.html">Workflow: Milling Force Parameter Training</a> — milling force training, which depends on a correct setup</li>
<li><a class="xref" href="../../workflows/basic-simulation.html">Workflow: Basic Machining Simulation</a> — driving simulation from NC or CSV</li>
<li><a href="index.html">Setup</a> — the rest of the pre-simulation configuration</li>
</ul>
</article>