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/anatomy/general-setup/controller/machine/per-axis-tables.html
T
2026-09-09 17:35:23 +08:00

581 lines
34 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>Per-Axis Tables | HiAPI-C# 2025 </title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Per-Axis Tables | 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="Anatomy-ControllerAxisTables">
<h1 id="per-axis-tables">Per-Axis Tables</h1>
<p>Four leaves of the Controller branch's machine plane are one table each, keyed on the machine's
axes: <strong>Machine Limits (Stroke)</strong>, <strong>Rapid Feedrates</strong>, <strong>Home / G28 Reference</strong> and <strong>Tool-Change
Position</strong>. They live on the General Setup page at <code>/general-setup</code> under the Control-Tree ids
<code>equipment/controller/machine/limits</code>, <code>equipment/controller/machine/rapid</code>,
<code>equipment/controller/machine/home</code> and <code>equipment/controller/machine/tool-change</code>; none of them is
gated by a snapshot flag, so every brand grows all four. Two components serve them — one panel
behind the first three, discriminating on the id's last segment, and a second behind Tool-Change
Position — and the differences between those two components are what this page is mostly about.</p>
<div class="IMPORTANT">
<h5>Important</h5>
<p>Anatomy makes no claim that any id named here is stable across versions. The migration hop that
keeps an older <code>?tree=</code> value resolving is described in
<a class="xref" href="../../../platform/tree-ids-and-routes.html">Tree Ids and Routes</a>.</p>
</div>
<h2 id="where-the-rows-come-from">Where the Rows Come From</h2>
<p>Every row on all four leaves is one axis of the runner's machine-axis configuration, read as
<a class="xref" href="../../../../api/Hi.NcParsers.Dependencys.IMachineAxisConfig.html#Hi_NcParsers_Dependencys_IMachineAxisConfig_AxisNames">AxisNames</a> through the proxy-resolved dependency
list. On all five brand presets that configuration is the brand parameter table itself:
<a class="xref" href="../../../../api/Hi.NcParsers.Dependencys.ControllerParameterTableBase.html">ControllerParameterTableBase</a> declares
<a class="xref" href="../../../../api/Hi.NcParsers.Dependencys.IMachineAxisConfig.html">IMachineAxisConfig</a> alongside
<a class="xref" href="../../../../api/Hi.NcParsers.Dependencys.IStrokeLimitConfig.html">IStrokeLimitConfig</a>,
<a class="xref" href="../../../../api/Hi.NcParsers.Dependencys.IRapidFeedrateConfig.html">IRapidFeedrateConfig</a> and
<a class="xref" href="../../../../api/Hi.NcParsers.Dependencys.IHomeMcConfig.html">IHomeMcConfig</a>, so one object supplies both the row set and three of
the four value sets. Which brand carries which table is
<a class="xref" href="../brand-matrix.html">Brand Matrix</a>.</p>
<p>The table's axis set is a single parameter row: the per-axis integer bucket under the brand's
axis-type number, whose keys are the axis names and whose values are the
<a class="xref" href="../../../../api/Hi.NcParsers.Dependencys.AxisType.html">AxisType</a> — linear, rotary or spindle. Adding an axis therefore means
adding a key to that one row, and exactly one surface on this branch reaches it.</p>
<ul>
<li>Neither panel here has an add-row or delete-row control. Both render a fixed header over one
<code>&lt;tr&gt;</code> per axis and nothing else.</li>
<li>The four per-axis routes behind them write one axis' value and nothing more: the caller names an
axis, and the endpoint writes into the stroke-limit, rapid-rate, home or tool-change store under
that name. None of them touches the axis-type row, so none of them changes which rows the next
read returns.</li>
<li><a class="xref" href="native-parameters.html">Parameters (Native)</a> edits the axis-type row itself, and
is the one place on the branch that widens the axis set: its <strong>Add / Set</strong> footer takes a
free-text axis name, so the section <em>Axis (integer)</em>, the brand's axis-type number, a name and a
value of <code>0</code> linear, <code>1</code> rotary or <code>2</code> spindle adds an axis, which then appears on all four
leaves. Its grid cannot — the per-axis columns are the union of the axis names already present, so
a cell can be written only for an axis that exists — and its delete button removes a whole
parameter row, every axis cell of one number at once, rather than one axis.</li>
</ul>
<p>Axes arrive from the machining chain. Whenever the active runner suit or the chain changes, the
project service re-binds the suit and calls
<a class="xref" href="../../../../api/Hi.NcParsers.SoftNcRunner.html#Hi_NcParsers_SoftNcRunner_ConfigureByMachiningChain_">ConfigureByMachiningChain</a><small>(API)</small>, which walks the
chain's axis codes and their transformers: a rotating transformer writes the axis as rotary — and,
on a brand parameter table, writes its reference position as 0 deg and its rapid rate as 36000
deg/min — any other transformer writes the axis as linear, and every chain axis whose reference
position is still unset is seeded to 0. That is the mechanism behind the description above the
Home / G28 Reference table, <em>&quot;Axes without a value are seeded to 0 when a machine tool attaches.&quot;</em></p>
<p><strong>The stamp adds rows and never removes one.</strong> The generic axis configuration carried by the CSV and
CL runner suits is cleared before the walk; a brand parameter table is not, and keeps every axis it
already held. An axis dropped from the chain therefore keeps its rows on all four leaves, and no
surface removes it individually. The three-axis default table every brand preset seeds is why a
project with no machine tool attached still shows X, Y and Z.</p>
<p>Two <strong>values</strong> are the exception, and only on a rotary chain axis of a brand table: that branch of
the walk is unconditional, so it rewrites the axis' reference position to 0 deg and its rapid rate
to 36000 deg/min whether or not one was stored. The walk re-runs on every suit re-bind, so an edited
Home Position or Rapid Rate on a rotary axis is back at those two numbers once the chain or the
active suit changes. A linear axis' values, and every value on an axis the chain does not carry, are
left untouched.</p>
<p>The caption below the first three tables records the row half of that: <em>&quot;Axis rows follow the Machine
Tool chain; they cannot be added here.&quot;</em> Where the chain itself is edited is
<a class="xref" href="../../machine-tool.html">Machine Tool</a>.</p>
<h2 id="the-value-columns">The Value Columns</h2>
<p>Each leaf renders the axis column, its own value column or columns, and a unit column.</p>
<table>
<thead>
<tr>
<th>Leaf</th>
<th>Value columns</th>
<th>Empty cell means</th>
</tr>
</thead>
<tbody>
<tr>
<td>Machine Limits (Stroke)</td>
<td><strong>+ Limit</strong>, <strong>− Limit</strong></td>
<td>no limit set for that axis and side</td>
</tr>
<tr>
<td>Rapid Feedrates</td>
<td><strong>Rapid Rate</strong></td>
<td>never empty — see below</td>
</tr>
<tr>
<td>Home / G28 Reference</td>
<td><strong>Home Position</strong></td>
<td>no reference position stored</td>
</tr>
<tr>
<td>Tool-Change Position</td>
<td><strong>Stays put</strong>, <strong>Position</strong></td>
<td>see <a href="#stays-put-and-the-sentinel-behind-it">Stays Put</a></td>
</tr>
</tbody>
</table>
<p>The stroke-limit and home readers return an optional value and hand null straight through, so an
unset cell is blank. The rapid reader does not: it returns the stored rate, or — when the axis has
no rate of its own — the base class's fixed default, 20000 mm/min for a linear axis and 36000
deg/min for a rotary one. So a Rapid Rate cell is always a number, and a number in it is not proof
that the axis has a row.</p>
<p>A table cloned fresh from a brand's preset seed decides what the three leaves then open on, and all
four brand defaults agree in shape: a linear X, Y and Z, a reference position of 0 on each, and a
rapid rate per axis — and no stroke limit at all. Machine Limits therefore opens entirely blank on
every brand, while Rapid Feedrates and Home / G28 Reference open populated. Whether a brand switch
clones a fresh table or keeps the project's own is
<a class="xref" href="index.html">Machine and Controller Plane</a>.</p>
<h2 id="the-unit-column">The Unit Column</h2>
<p>The unit column's header is the translated label <em>Unit</em>; its cell text is not translated and does
not come from the server. Each panel computes it in the browser from the row's rotary flag, using
literal strings:</p>
<table>
<thead>
<tr>
<th>Leaf</th>
<th>Linear axis</th>
<th>Rotary axis</th>
</tr>
</thead>
<tbody>
<tr>
<td>Machine Limits (Stroke)</td>
<td><code>mm</code></td>
<td><code>deg</code></td>
</tr>
<tr>
<td>Rapid Feedrates</td>
<td><code>mm/min</code></td>
<td><code>deg/min</code></td>
</tr>
<tr>
<td>Home / G28 Reference</td>
<td><code>mm</code></td>
<td><code>deg</code></td>
</tr>
<tr>
<td>Tool-Change Position</td>
<td><code>mm</code></td>
<td><code>deg</code></td>
</tr>
</tbody>
</table>
<p>The flag itself is server-side, and it is the axis type rather than a separate setting: an axis
stored as rotary <strong>or as spindle</strong> reports rotary, so a spindle-mode axis is labelled in degrees.</p>
<p><strong>The unit is a label, not a conversion.</strong> The base class writes a linear and a rotary rapid rate
into the same per-axis cell and reads them back through the same lookup, differing only in the
default returned when the cell is absent; the stroke-limit and home accessors are equally unit-blind.
Nothing on these three leaves converts, so their numbers are the raw stored numbers, and the same
values appear in <a class="xref" href="native-parameters.html">Parameters (Native)</a> under the brand's own
parameter number:</p>
<table>
<thead>
<tr>
<th>Role</th>
<th>Fanuc, Mazak</th>
<th>Syntec</th>
<th>Siemens</th>
<th>Heidenhain</th>
</tr>
</thead>
<tbody>
<tr>
<td>Axis type — the row set</td>
<td>1006</td>
<td>1006</td>
<td>30300</td>
<td>400</td>
</tr>
<tr>
<td>Reference position (home)</td>
<td>1240</td>
<td>1240</td>
<td>34010</td>
<td>410</td>
</tr>
<tr>
<td>Positive stroke limit</td>
<td>1300</td>
<td>1300</td>
<td>36100</td>
<td>420</td>
</tr>
<tr>
<td>Negative stroke limit</td>
<td>1320</td>
<td>1320</td>
<td>36110</td>
<td>430</td>
</tr>
<tr>
<td>Rapid rate</td>
<td>1420</td>
<td>1420</td>
<td>32000</td>
<td>1010</td>
</tr>
</tbody>
</table>
<p>Mazak shares the Fanuc column because the Mazak preset carries the Fanuc parameter-table proxy;
Siemens spends its rapid-rate role on the max-axis-velocity machine datum.</p>
<p>Tool-Change Position is the exception on both counts: its values live on
<a class="xref" href="../../../../api/Hi.NcParsers.Dependencys.Generic.ToolingMcConfig.html">ToolingMcConfig</a>, a plain runner-owned dependency rather than
a parameter table, so they appear in no native form at all and a brand apply returns them to the
preset defaults — see <a class="xref" href="index.html">Machine and Controller Plane</a>.</p>
<h2 id="stays-put-and-the-sentinel-behind-it">Stays Put, and the Sentinel Behind It</h2>
<p><a class="xref" href="../../../../api/Hi.NcParsers.Dependencys.IToolingMcConfig.html">IToolingMcConfig</a> stores one number per axis, and the contract gives
one number a second meaning: <strong>NaN means the axis stays where it is</strong> during a tool change. The read
splits that back into two fields — a stored NaN becomes the <em>Stays put</em> flag with no position,
anything else becomes the position — and the panel renders the flag as a checkbox and the position
as a numeric field disabled while the box is ticked.</p>
<p>Writing goes the same way round. Ticking the box sends the stay flag and the reader writes NaN.
Unticking it sends a position, and because the panel clears its own cell when the box is ticked, the
position it sends on the way back is 0 — so unticking parks the axis at machine zero rather than
restoring what was there before.</p>
<p>A <strong>third</strong> state exists and is not the sentinel: an axis with no entry in the map at all. Its box is
unticked and its Position cell blank, because the reader reports no position and no stay. At run
time the two are indistinguishable — the tool-change motion overlays only those axes that carry a
number and are not NaN onto the current pose, and leaves every other axis alone. So the machine
stays put either way; the tick mark distinguishes only how that was recorded.</p>
<p>The overlay has a vocabulary of its own, narrower than the table. X, Y and Z always take part; every
other axis takes part only while the machine declares it rotary. A linear axis outside those three
is stored, shown and editable on this leaf, and never moved.</p>
<p>The preset default is exactly this mixture: X and Y carry the sentinel, Z carries 0, and no rotary
axis carries an entry, which is why a rotary axis usually opens unticked and blank.</p>
<p>Above the table sits <strong>Tool-change mechanism time</strong>, a single field in seconds bound to
<a class="xref" href="../../../../api/Hi.NcParsers.Dependencys.IToolingMcConfig.html#Hi_NcParsers_Dependencys_IToolingMcConfig_ToolingTime">ToolingTime</a>. It becomes the duration of the tool
change step the runner emits, and it is the changer mechanism alone — the axis travel to and from
the position is timed separately from the positions in the table. It is 0 on every brand preset, and
it is written into the runner file only when non-zero.</p>
<h2 id="one-reader-two-readings-of-its-presence-flag">One Reader, Two Readings of Its Presence Flag</h2>
<p>All four reads answer the same shape: a <code>present</code> flag plus one row per axis. <code>present</code> reports
whether the backing configuration resolved — stroke limit, rapid feedrate, home or tool change — and
it is computed <strong>independently of the rows</strong>. Each reader builds the row list from the axis set
whether or not that configuration resolved, and fills the value cells from an optional reference, so
a missing configuration yields blank limit and home cells, a 0 rapid rate, and rows all the same.</p>
<p>The two components read the answer differently, and this is the sharpest divergence between them.</p>
<ul>
<li>The <strong>axis-table panel discards <code>present</code> entirely.</strong> Its typed reader parses the flag; the panel
assigns only the rows. Its second empty layer keys on the row count instead: with no axes it shows
<em>&quot;No machine axes yet — these rows are driven by the Machine Tool chain (MechBuilder). Attach a
machine tool to edit per-axis values.&quot;</em>, and with axes it renders the table whatever the flag said.</li>
<li>The <strong>tool-change panel reads <code>present</code></strong> and, when it is false, shows <em>&quot;No tool-change config on
the active runner.&quot;</em></li>
</ul>
<p>What that costs: a runner that has axes but no stroke-limit, rapid-feedrate or home configuration
renders a full, editable table of blank or zero cells, and every commit fails with a toast naming the
missing dependency instead of the panel saying the table is absent. On the five shipped brand presets
the state cannot arise, because the one object that supplies the axis set supplies all three
configurations too. The reachable case is the mirror one, and it reaches the two panels differently:
deleting the axis-type parameter row from Parameters (Native) empties the axis set, and the three
axis-table leaves fall to the no-axes line while <strong>Tool-Change Position keeps its rows</strong>, because its
reader falls back to the tool-change configuration's own axis keys when the axis set is empty. Rows
recovered that way are reported as linear whatever they are.</p>
<p>The tool-change flag itself is never false on a shipped preset: all five carry the tool-change
configuration as a plain entry, so its empty line is reachable only on a hand-built or file-loaded
runner.</p>
<p>Above both layers sits the shared no-runner guard every leaf of the branch carries; it, and the
commit, rollback and toast rules the four leaves share with the rest of the branch, are
<a class="xref" href="../editing-contract.html">Editing Contract</a>.</p>
<h2 id="editing-a-cell">Editing a Cell</h2>
<p>Numeric cells are the shared numeric field, so a value commits on blur or on Enter and never per
keystroke — its full contract is <a class="xref" href="../../../widget/numeric-input.html">Numeric Input</a>. The <em>Stays put</em>
checkbox commits on the click. Three details govern how these four leaves commit:</p>
<ul>
<li><strong>The writes are per cell, not per row.</strong> Editing <strong>+ Limit</strong> sends that side alone, and the
endpoint leaves a side it was not sent unchanged. The branch's row-shaped editors do not agree on
this: a tool-offset or work-coordinate edit resends the whole row, while
<a class="xref" href="native-parameters.html">Parameters (Native)</a> writes one axis cell at a time as
these four do.</li>
<li><strong>Clearing a cell writes nothing.</strong> An emptied field parses to null and the handler returns before
the request, so the box is left blank on screen while the stored number stands, and the number
returns when the panel is remounted by selecting another node and coming back. There is
consequently no way to unset a stroke limit or a reference position from these panels; the only
surface that removes one is the native leaf's whole-row delete.</li>
<li><strong>No cell is bounded.</strong> None of the four tables passes a minimum or a maximum to its fields, so a
negative limit or a negative rapid rate is accepted and stored. The mechanism time is the one
bounded field on the four leaves, at zero or above.</li>
</ul>
<h2 id="what-the-values-do-when-a-program-plays">What the Values Do When a Program Plays</h2>
<p>The stroke limits are checked at each played step against the chain's current machine pose while the
session's stroke-limit check is on; a position past a configured limit is reported as a
stroke-limit validation error anchored to that step, and pauses the player when pause-on-failure is
set. The check walks a <strong>fixed axis vocabulary</strong> — X, Y and Z from the machine point, A, B and C
from its orientation — so a limit stored against any other axis name is kept and shown here but never
tested. Rapid-traverse timing has the same shape and the same six names: a G00 move is timed
axis-by-axis at each axis' rate and takes the slowest, falling back to the same 20000 mm/min and
36000 deg/min defaults when no configuration answers.</p>
<p>The reference positions reach further, but only at the start. The initializer that sets the machine
pose at the first block writes <strong>every declared axis</strong>, reading each axis' stored reference and
falling back to 0 for one that has none. The G28 reference return reads the same store through a
narrower window: X, Y and Z for its linear stage, and A, B or C for its rotary stage — and a rotary
letter only while the machine declares that axis rotary and a reference position is stored for it,
an unconfigured one being reported as a validation error instead. So an axis outside the six
canonical names still carries its stored reference into the pose at the first block, while its
stroke limit, its rapid rate and its G28 return are all inert.</p>
<h2 id="layout">Layout</h2>
<ul>
<li><strong>General Setup</strong> Control Tree — the left dock of <code>/general-setup</code>
<ul>
<li><strong>Controller</strong> Node Row
<ul>
<li><strong>Machine / Controller</strong> Group Row
<ul>
<li><strong>Machine Limits (Stroke)</strong> Node Row — <code>equipment/controller/machine/limits</code></li>
<li><strong>Rapid Feedrates</strong> Node Row — <code>equipment/controller/machine/rapid</code></li>
<li><strong>Home / G28 Reference</strong> Node Row — <code>equipment/controller/machine/home</code></li>
<li><strong>Tool-Change Position</strong> Node Row — <code>equipment/controller/machine/tool-change</code></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>Editor Row — the panel of whichever node is selected
<ul>
<li><strong>Machine Limits (Stroke)</strong> / <strong>Rapid Feedrates</strong> / <strong>Home / G28 Reference</strong> Panel — one
component, its role taken from the selected id's last segment
<ul>
<li>Description Caption — <em>&quot;Machine travel limits per axis (empty = no limit set). Motions beyond a
limit raise a stroke-limit validation error.&quot;</em>, <em>&quot;G00 rapid traverse rate per axis.&quot;</em> or
<em>&quot;G28 first reference (home) machine coordinate per axis. Axes without a value are seeded to 0
when a machine tool attaches.&quot;</em></li>
<li>Axis Table — dense, flat, bordered
<ul>
<li>Header Row — <strong>Axis</strong>, then <strong>+ Limit</strong> and <strong>− Limit</strong>, or <strong>Rapid Rate</strong>, or
<strong>Home Position</strong>, then <strong>Unit</strong></li>
<li>Axis Row, one per axis
<ul>
<li>Axis Name Label — bold, not editable</li>
<li>Value Numeric Field, one per value column</li>
<li>Unit Label — <code>mm</code> / <code>deg</code>, or <code>mm/min</code> / <code>deg/min</code> on Rapid Feedrates</li>
</ul>
</li>
</ul>
</li>
<li>Footer Caption — <em>&quot;Axis rows follow the Machine Tool chain; they cannot be added here.&quot;</em></li>
<li>No-Axes Block — replaces the description, the table and the footer caption when the axis set is
empty: a precision-manufacturing icon beside <em>&quot;No machine axes yet — these rows are driven by
the Machine Tool chain (MechBuilder). Attach a machine tool to edit per-axis values.&quot;</em></li>
</ul>
</li>
<li><strong>Tool-Change Position</strong> Panel
<ul>
<li><strong>Tool-change mechanism time</strong> Numeric Field — suffixed <code>s</code>, minimum 0</li>
<li>Axis Table — dense, flat, bordered
<ul>
<li>Header Row — <strong>Axis</strong>, <strong>Stays put</strong>, <strong>Position</strong>, <strong>Unit</strong></li>
<li>Axis Row, one per axis
<ul>
<li>Axis Name Label — bold, not editable</li>
<li><strong>Stays put</strong> CheckBox</li>
<li>Position Numeric Field — disabled while <strong>Stays put</strong> is ticked</li>
<li>Unit Label — <code>mm</code> / <code>deg</code></li>
</ul>
</li>
</ul>
</li>
<li>Footer Caption — <em>&ldquo;Stays put&rdquo; leaves the axis where it is during a tool change.</em></li>
<li>No-Config Block — replaces the field, the table and the caption:
<em>&quot;No tool-change config on the active runner.&quot;</em></li>
</ul>
</li>
<li>Shared Empty State — replaces either panel's whole body while the snapshot reports no runner:
<em>&quot;No NC runner — load a project first.&quot;</em></li>
</ul>
</li>
</ul>
<h2 id="source-code-path">Source Code Path</h2>
<p>See <a class="xref" href="../../../index.html">HiNC App Anatomy</a> for git repository links.</p>
<h3 id="web-application">Web Application</h3>
<p>HiNC-2025-webservice (Quasar CLI SPA):</p>
<ul>
<li><code>wwwroot-src/src/components/controlTree/SoftNcAxisTablePanel.vue</code> — the panel behind the first
three leaves: the role taken from the node id's last segment, the value columns and description
per role, the unit strings computed from the row's rotary flag, the row-count empty layer that
discards the read's presence flag, and the per-cell commit that returns on a cleared field.</li>
<li><code>wwwroot-src/src/components/controlTree/SoftNcToolChangePanel.vue</code> — the tool-change panel: the
mechanism-time field, the <em>Stays put</em> checkbox that clears the position and sends 0 on the way
back, the disabled position cell, and the presence-flag empty layer.</li>
<li><code>wwwroot-src/src/components/controlTree/SoftNcEmptyState.vue</code> — the shared no-runner line both
panels open with.</li>
<li><code>wwwroot-src/src/components/widgets/NumericInput.vue</code> — the numeric cell: commit on blur or Enter,
and the empty-text-to-null parse the panels reject.</li>
<li><code>wwwroot-src/src/components/controlTree/softNcItemTypes.ts</code> — the four node ids, their labels and
label keys, and the two item types that bind them to the two panels.</li>
<li><code>wwwroot-src/src/api/softNcRunner.ts</code> — the four readers and their setters: the row shapes, the
presence flag both panels receive, the per-side stroke-limit payload, and the stay-or-position
tool-change payload.</li>
<li><code>wwwroot-src/src/composables/useSoftNcRunner.ts</code> — the shared runner snapshot the first empty layer
reads.</li>
<li><code>wwwroot-src/src/i18n/en/softNc.ts</code> — the four node labels, the three descriptions, the column
headers, the two footer captions and the two empty-state lines quoted above.</li>
<li><code>wwwroot-src/src/i18n/en/common.ts</code> — the shared <strong>Axis</strong> and <strong>Unit</strong> column headers.</li>
<li><code>wwwroot-src/src/components/controlTree/SoftNcNativeParamsPanel.vue</code> — the neighbouring leaf that
edits the same parameter rows by number: the per-cell axis writes, the grid columns unioned from
the existing axis names, the delete that drops a whole row, and the <strong>Add / Set</strong> footer whose
free-text axis field is what widens the axis-type row.</li>
<li><code>Mech/SoftNcRunnerController.cs</code> — the REST surface: the chain-driven axis helper every reader
builds its rows from, the four readers with their independently computed presence flags, the four
per-axis writers that name an axis but never declare one, the native per-axis-integer route that
does, the tool-change fallback to the tool-change configuration's own axis keys, the NaN sentinel
write, and the rotary lookup the rapid write re-derives server-side.</li>
</ul>
<h3 id="hiapi-engine">HiAPI Engine</h3>
<ul>
<li><code>HiMech/NcParsers/Dependencys/ControllerParameterTableBase.cs</code> — the one object behind three of the
four leaves: the axis set as the keys of the axis-type row, the reference-position, rapid-rate and
stroke-limit accessors over the per-axis buckets, the fixed rapid defaults, and the rotary
configuration helper the chain walk calls, which writes the axis type, the reference position and
the rapid rate together with no guard on the two values.</li>
<li><code>HiMech/NcParsers/Dependencys/IMachineAxisConfig.cs</code> — the axis contract and the axis-type enum
whose rotary and spindle members both make a row rotary.</li>
<li><code>HiMech/NcParsers/Dependencys/IStrokeLimitConfig.cs</code> — the limit accessors, and the check itself
with its fixed X/Y/Z and A/B/C vocabulary and its validation report.</li>
<li><code>HiMech/NcParsers/Dependencys/IRapidFeedrateConfig.cs</code> — the linear and rotary rate accessors.</li>
<li><code>HiMech/NcParsers/Dependencys/IHomeMcConfig.cs</code> — the reference-position accessors.</li>
<li><code>HiMech/NcParsers/Dependencys/IToolingMcConfig.cs</code> — the tool-change contract: the NaN sentinel and
the mechanism time.</li>
<li><code>HiMech/NcParsers/Dependencys/Generic/ToolingMcConfig.cs</code> — the sole implementation: the per-axis
map, the preset default of X and Y staying and Z at 0, and the serialization that omits a zero
mechanism time.</li>
<li><code>HiMech/NcParsers/Dependencys/Fanuc/FanucParameterTable.cs</code>,
<code>HiMech/NcParsers/Dependencys/Syntec/SyntecParameterTable.cs</code>,
<code>HiMech/NcParsers/Dependencys/Siemens/SiemensMachineDataTable.cs</code>,
<code>HiMech/NcParsers/Dependencys/Heidenhain/HeidenhainParameterTable.cs</code> — the parameter numbers in
the table above and the three-axis default each brand opens on.</li>
<li><code>HiMech/NcParsers/Dependencys/Fanuc/FanucParameterTableProxy.cs</code>,
<code>HiMech/NcParsers/Dependencys/Syntec/SyntecParameterTableProxy.cs</code>,
<code>HiMech/NcParsers/Dependencys/Siemens/SiemensMachineDataTableProxy.cs</code>,
<code>HiMech/NcParsers/Dependencys/Heidenhain/HeidenhainParameterTableProxy.cs</code> — the placeholders the
brand presets actually carry: each clones its three-axis seed into the project's own dependency
list when that list holds none, and resolves to the project's table when it does.</li>
<li><code>HiMech/NcParsers/SoftNcRunner.cs</code> — the chain walk that stamps axis codes, hands a rotary axis to
the unconditional rotary helper on a brand table, and fills a missing reference position; and the
five brand presets that decide which parameter table and which tool-change configuration a brand
carries.</li>
<li><code>HiNc/MachiningProcs/LocalProjectService.cs</code> — where the chain walk is triggered from, why the
generic axis configuration is cleared first and a brand table is not, and the per-step stroke-limit
check that reads the limits through the proxy-resolved list.</li>
<li><code>HiMech/MachiningProcs/MachiningSession.cs</code> — the play loop that runs that check once per step and
pauses on failure.</li>
<li><code>HiMech/NcParsers/Semantics/LinearMotionUtil.cs</code> — rapid-traverse timing: per-axis rates, the
slowest axis, and the same six axis names the stroke check uses.</li>
<li><code>HiMech/NcParsers/Initializers/HomeMcInitializer.cs</code> — the reference positions written for every
declared axis at the first block.</li>
<li><code>HiMech/NcParsers/LogicSyntaxs/ReferenceReturnSyntax.cs</code> — the G28 return: the three linear names
it resolves a final position for, the three rotary letters it tests against the declared axes, and
the validation error a rotary letter the machine has not declared raises.</li>
<li><code>HiMech/NcParsers/LogicSyntaxs/ToolChangeMotionSyntax.cs</code> — the overlay: X, Y and Z plus the
declared rotary axes, of which only the ones carrying a non-NaN position move.</li>
<li><code>HiMech/NcParsers/Semantics/ToolChangeSemantic.cs</code> — the tool-change step that carries the
mechanism time as its duration.</li>
</ul>
<h2 id="see-also">See Also</h2>
<ul>
<li><a class="xref" href="index.html">Machine and Controller Plane</a> — the plane these four leaves sit on, and which half of the
project each of their values is stored in</li>
<li><a class="xref" href="../brand-matrix.html">Brand Matrix</a> — why all four are ungated, and which table each brand
resolves them through</li>
<li><a class="xref" href="../editing-contract.html">Editing Contract</a> — the fetch, commit, rollback and empty-layer rules these
panels share with the rest of the branch, and where they are recorded as departing from them</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>