Native Parameters
Parameters (Native) is the machine plane's escape hatch: the brand parameter table rendered as the
flat numbered form an operator reads off the real control, with no domain vocabulary and no unit
conversion in between. It lives on the General Setup page at /general-setup under the Control-Tree
id equipment/controller/machine/native, and it is one of the two leaves the hasNativeTable
snapshot flag grows — the other, M-Code Declarations, edits a different part of the same object.
Every value the domain-grouped leaves beside it edit that is a row of the brand parameter table is
a row here; the ones stored elsewhere — the tool-change pose, the block-skip layers, the subprogram
folders and the indexing position lists among them — reach no native form at all. Several rows here
reach no domain-grouped face.
Important
Anatomy makes no claim that any id named here is stable across versions. The migration hop that
keeps an older ?tree= value resolving is described in
Tree Ids and Routes.
The leaf is pushed behind hasNativeTable, which reports whether any
ControllerParameterTableBase resolves in the runner's effective
dependency list. All five shipped presets carry one, so the flag is a gate in code and unconditional
in practice — see Brand Matrix.
How a Parameter Is Addressed
The table stores its numbers in three dictionaries, and the panel is those three dictionaries with a heading over each:
| Section heading the user reads | Backing storage | Cell |
|---|---|---|
| System parameters | SystemParams | one value per id |
| Axis parameters | AxisParams | one floating-point value per id per axis |
| Axis parameters (integer) | IntAxisParams | one integer value per id per axis |
An id is a bare number in storage. What the panel prints in front of it is the brand's prefix, and that prefix is the whole of the addressing convention:
| Brand marker | Prefix shown | Table that answers | Example row |
|---|---|---|---|
| Fanuc | # |
FanucParameterTable | #1420 rapid traverse rate |
| Mazak | # |
the Fanuc table | #1420 rapid traverse rate |
| Syntec | Pr |
SyntecParameterTable | Pr1420 rapid traverse rate |
| Siemens | MD |
SiemensMachineDataTable | MD32000 max axis velocity |
| Heidenhain | MP |
HeidenhainParameterTable | MP1010 rapid traverse rate |
Mazak borrows the Fanuc table outright. The Mazak preset carries the Fanuc parameter-table proxy
rather than one of its own, so the prefix resolves to # and every number on this leaf is a Fanuc
parameter number under a Mazak brand badge. The prefix is not taken from the brand marker string
but from the type of the parameter table that resolved, so the two cannot drift apart the way a
brand-marker label can — see Brand Matrix.
A ControllerParameterTableBase subclass outside those four resolves an empty prefix, and the ids
then render bare. No shipped preset produces that.
The prefix the panel renders comes from the leaf's own read of the parameter form. The shared runner snapshot carries a prefix field of its own, and nothing renders it.
The caption under the id
Each id cell carries the number in bold and, beneath it, a short usage caption — Rapid traverse rate (mm/min or deg/min), Axis type (0 linear / 1 rotary / 2 spindle), G54 X offset, Tool change M function code. The same text repeats as the cell's hover title.
The caption is the brand table's own description of a well-known number, produced by DescribeSystemParam(API) and its two per-axis counterparts, and it travels down the wire with the row. It is therefore engine text, not an interface string: it is written in English in the brand table and belongs to no locale bundle, so it reads the same under every language the application offers. An id the brand table does not model has no caption at all, which is how a modelled row and a free extra are told apart on screen.
Raw Values, Raw Units
The caption at the top of the panel states the rule: "Raw stored values in native units — no unit conversion is applied here. The interface-form nodes edit the same backing table."
No cell carries a unit suffix, and none can: the unit belongs to the number, not to the column. What a cell means is whatever the brand stores at that address — millimetres or degrees on a stroke limit, mm/min or deg/min on a rapid rate, rpm on a spindle limit, an enumeration ordinal on an axis type, a count on a controlled-axis parameter.
The peck clearance is the case where the two forms visibly disagree, and it ships. Canned Cycle
(Peck) always speaks millimetres; the Fanuc-family table stores millimetres at #4002, and the
Syntec table stores microns at Pr4002. A machine at a 5 mm clearance therefore reads 5 on
Interface Parameters on every brand, and reads 5 here on Fanuc
and Mazak but 5000 here on Syntec. The write endpoint converts on the way in; this leaf does not,
which is the point of it — an operator copying from a real Syntec control reads the micron form.
Two further asymmetries follow from where a value is stored rather than from its unit:
- On Siemens and Heidenhain the peck clearance has no row here at all. Those two presets supply it through a generic fallback config, a plain runner entry rather than a parameter table, so the interface leaf shows a field whose backing has no place in this form.
- On the Fanuc-family and Syntec tables the work-coordinate offsets are rows of this table. The
G54–G59 triads start at
#5221and the G54.1 P1–P48 triads at#7001, both on a stride of 20, all in the System parameters section. That mixing is why the machine plane's parameter table is stored on the project rather than on the runner — see Machine and Controller Plane. On the Fanuc-family table those two address ranges are also what an NC program's#-variable read resolves against, so those rows are live in both directions.
What Only This Leaf Reaches
Most rows have a domain-grouped twin. These do not.
The axis roster itself. Every per-axis leaf of the branch — Machine Limits (Stroke), Rapid
Feedrates, Home / G28 Reference, Tool-Change Position — lists the axes named by the axis-type row
of this table (#1006, Pr1006, MD30300, MP400), because
AxisNames is that row's key set. None of
those leaves can add an axis, rename one, remove one, or change one from linear to rotary; their
columns are handed to them. Inside the Controller branch the axis-type row is editable here and
nowhere else, through the footer with the section set to Axis (integer), the brand's axis-type
number as the id, an axis name, and a value of 0 linear, 1 rotary or 2 spindle. The one other
writer is outside the branch entirely:
ConfigureByMachiningChain(API) stamps the machining
chain's axis codes into the same row when a machine tool is attached to the project; an axis the
chain does not name stays in the row. That call does not stop at the axis-type row: a chain axis it
marks rotary also has its reference position set to 0 and its rapid rate to 36000 deg/min,
whatever those two Axis parameters rows held.
The inverse holds, with one exception. Deleting the axis-type row leaves the table with no named axes, so Machine Limits (Stroke), Rapid Feedrates and Home / G28 Reference have no rows left to draw. Tool-Change Position keeps its own: its reader falls back to the tool-change configuration's own axis keys when the axis set is empty, and every shipped preset seeds that configuration with X, Y and Z. Rows recovered that way carry no axis type and are reported linear.
The Siemens indexing machine data, all four numbers. MD30500, the per-axis assignment that
decides which axis consumes which position table, is shown on
Indexing Position Tables as display-only text and is
written here as an Axis parameters (integer) row; the REST surface carries no assignment writer
at all. The equidistant definition — the numerator MD30501 and the offset MD30503 as axis
parameters, the denominator MD30502 as an integer axis parameter — has no endpoint that reads or
writes it and no panel that offers a cell for it: it is three ordinary rows on this leaf. The engine is its reader: an axis whose MD30500 is 3 resolves its station spacing from
the trio, and Indexing Position Tables prints that axis' assignment as Equidistant
(MD30501–MD30503), naming the three numbers it offers no cell for. The two position lists
themselves are the mirror image, stored as list properties outside all three dictionaries and so
absent from this form entirely.
Numbers with no interface field. The controlled-axis count (#1020, Pr1020) is read by nothing
in the web service. The Siemens fixed-point position MD30600, the G75 target, likewise. So is the
Siemens tool-change M function MD22560, whose presence overlays a tool-change effect onto the named
code in the declaration view the parsers resolve against. M-Code Declarations renders the stored map
rather than that view, so the overlaid row is on no screen at all: the effect is honoured in every
program the machine runs, and the one number that shows anywhere is this row. The Siemens tool-change
mode MD22550 is a half case: where the row already exists, the T word performs the tool change
itself toggle on M-Code Declarations writes it, and where it does not, that toggle writes a
brand-neutral flag instead; creating the row is possible only here.
Any number the model does not name. The three writers are get-or-create, so an id outside the brand's well-known set is accepted, stored, serialized into the project file and read back. It carries no usage caption, and the engine consumes only the numbers its brand table models — a free extra is a record, not a setting.
A Fractional Number Has Three Fates
The Axis parameters (integer) section is the one place on the branch where a value can be typed, accepted by the field, and silently discarded.
The cell is the shared numeric widget, which commits on blur or Enter and carries no integer rule.
Typing 2.5 parses cleanly: the widget clears its own error state, emits 2.5 to the panel, and
rewrites its text to the parsed form. The panel's integer handler is where the value stops — it
returns without assigning and without raising anything when the number is not whole. Because the
bound value never changed, nothing pushes the stored integer back into the box. The cell goes on
reading 2.5 over a table that still holds the old integer, with no error message, no toast and no
console line. The row corrects itself only when the panel refetches: after an add, after a removal,
or on a fresh mount when the selection leaves this leaf and comes back.
The footer does not behave the same way. Add / Set with Axis (integer) selected truncates a
fractional value toward zero and writes the truncation, so the same 2.5 becomes a stored 2; and
the same button refuses a fractional Parameter id outright, with the message "Enter a
non-negative integer id and a value." That refusal belongs to the button, not to the box — the
Parameter id field is the shared numeric widget with a minimum of 0 and no integer rule, so it
accepts and keeps 2.5 the way any other cell does, and the one message answers an empty Value
(raw) as well. Three controls, one number, three outcomes.
Clearing any cell ends the same way for a different reason. An emptied field commits null, and
all three handlers return early on null, so the box is blank and the stored value is untouched.
There is no way to unset one cell of a table; the value stands until it is overwritten or its whole
row is removed. The general rule for a box that disagrees with its model is
Numeric Input; what is particular here is that the widget did nothing
wrong — the panel accepted the commit and dropped it.
Adding, Overwriting and Removing a Row
The footer is one control set for both adding and overwriting, and the button says so: Add / Set. The write is get-or-create at every level — an unknown id creates its row, an unknown axis name creates its column — so setting an existing cell and creating a new one are the same request.
- The Axis field appears only while the section is not System, is free text, and is trimmed and checked for emptiness only. It is not validated against the machine's axes: any name is accepted and becomes a new column.
- A successful add re-reads the whole form. The footer's own fields are not cleared, and Enter does not submit — see Editing Contract for how the branch's add footers differ from one another.
- The two client-side refusals are the id, which must be a non-negative whole number, and, for the two per-axis sections, a non-empty axis name. Each raises a negative toast and sends nothing.
Delete is per row, not per cell. The trailing button on a row of either per-axis table removes
the id from that dictionary entirely — every axis column of it at once, not the cell it sits beside.
A confirmation dialog comes first, titled Remove parameter and reading Remove <prefixed id> from
the <section> section?, where the section word is the storage kind — system, axis, int-axis —
rather than the heading printed above the table. The removal is not optimistic: the request is
awaited and the whole form is re-read.
A deleted well-known row can come back on its own. The brand tables' modelled accessors are
get-or-create with a default, so a read through a sibling leaf re-materializes the row it wants. The
clearest case is the maximum spindle speed: delete #3741 here, open Interface Parameters, and that
read stores the brand's default back — 60000 on Fanuc, Mazak, Siemens and Heidenhain, 24000 on
Syntec — so the row reappears at that value. The cutter-compensation type, the tool-axis direction
and the peck clearance behave the same way. A free extra id has no accessor and stays deleted.
What a Freshly Switched Brand Shows
The seed each brand's proxy clones decides what the three tables open with. All five declare a linear X, Y and Z in the axis-type row, a reference position of zero per axis and a rapid rate per axis, so on every brand the Axis parameters section opens with two rows and the Axis parameters (integer) section with one. The System section is where they part company.
| Brand | System parameters | Axis parameters | Axis parameters (integer) |
|---|---|---|---|
| Fanuc, Mazak | 166 rows — controlled axes, max spindle speed, peck retraction, cutter-comp type, and 162 seeded work-offset addresses at zero | reference position, rapid rate | axis type |
| Syntec | 166 rows — the same four under Pr numbering, the peck retraction in microns, and the same 162 offsets |
reference position, rapid rate | axis type |
| Siemens | 1 row — max spindle speed | reference position, max axis velocity | axis type |
| Heidenhain | 2 rows — max spindle speed, tool-axis direction | reference position, rapid rate | axis type |
The 162 offset rows are SeedAllDefaults(API) writing every G54–G59 and G54.1 P1–P48 triad as zero, so that a managed address always has a value the way a real control with a fresh battery reads zero rather than nothing. They dominate the System section on the three brands that carry them, and their captions — G54 X offset, G54.1P12 Z offset — are what separates them from machine configuration in the same list.
No brand seeds a stroke limit, so the positive and negative stroke-limit rows are absent from the Axis parameters section until Machine Limits (Stroke) or this leaf creates them.
The Two Empty Layers, and Which One Is Reachable
The panel opens through the branch's shared two-layer gate. The first layer is the shared "No NC runner — load a project first." from the runner snapshot; the second is "No controller parameter table on the active runner." from the leaf's own read — the same line M-Code Declarations and Interface Parameters show, and honest in all three, because every one of those reads reports presence from the same parameter-table lookup.
Neither line is normally reached by navigating, because the node itself exists only while the
snapshot reported a parameter table. The second line is also what a failed read leaves on screen: the
presence flag starts false and the failure path only raises a toast. A failed write answers inside a
success envelope — HTTP 200 carrying No ControllerParameterTableBase on the active runner — and
surfaces as one negative toast, three seconds, the panel's localized context followed by that raw
English sentence. The full rule is Editing Contract.
Layout
- General Setup Control Tree — the left dock of
/general-setup- Controller Node Row
- Machine / Controller Group Row
- Parameters (Native) Node Row —
equipment/controller/machine/native, the last leaf of the plane, after Indexing Position Tables
- Parameters (Native) Node Row —
- Machine / Controller Group Row
- Controller Node Row
- Editor Row — the panel of the selected node
- Parameters (Native) Panel — one column, gutter-spaced
- Hint Caption — "Raw stored values in native units — no unit conversion is applied here. The interface-form nodes edit the same backing table."
- System parameters Section Heading
- System Table — dense, flat, bordered
- Header Row — Id, Value, and an unlabelled action column
- Data Row — the prefixed id in bold over its usage caption (absent on a free extra), a numeric cell, and a delete button
- Axis parameters Section Heading
- Axis Table — dense, flat, bordered
- Header Row — Id, then one column per axis name, then an unlabelled action column
- Data Row — the prefixed id in bold over its usage caption, one numeric cell per axis column (blank where the row has no entry for that axis), and a delete button that removes the whole id
- Axis parameters (integer) Section Heading
- Integer Axis Table — the same shape as the Axis Table, over the integer dictionary
- Separator
- Add Row — one line, bottom-aligned
- Section Select — System / Axis (double) / Axis (integer)
- Parameter id Numeric Field — minimum 0
- Axis Text Field — present only while the section is not System
- Value (raw) Numeric Field
- Add / Set Button — primary
- No-Table Body — replaces everything above: "No controller parameter table on the active runner."
- Shared Empty State — replaces the whole body while the snapshot reports no runner: "No NC runner — load a project first."
- Remove Dialog — Remove parameter over Remove
<prefixed id>from the<section>section?, with a cancel - Toast — negative, three seconds, the panel's context followed by the server's own message
- Parameters (Native) Panel — one column, gutter-spaced
The axis columns of the two per-axis tables are computed independently of each other, and each is the union of the shared snapshot's axis names with every axis key present in that table's own rows. An axis created here therefore gets its column from the rows even before the shared snapshot is next refreshed, and an axis the snapshot knows about with no entry in a row shows an empty cell rather than being omitted.
Source Code Path
See HiNC App Anatomy for git repository links.
Web Application
HiNC-2025-webservice (Quasar CLI SPA):
wwwroot-src/src/components/controlTree/SoftNcNativeParamsPanel.vue— this panel: the three tables over the three dictionaries, the prefixed id column with its usage caption, the axis-column union, the three commit handlers with the integer test that drops a fractional value, the confirm-then-remove flow, and the add footer with its truncation and its two refusals.wwwroot-src/src/components/controlTree/softNcItemTypes.ts— the node's id, label and label key, and the snapshot flag it is pushed behind, last on the machine plane.wwwroot-src/src/api/softNcRunner.ts— the reader that parses the prefix and the three row families, the three per-cell writers and the three per-id removals, and the snapshot field carrying a prefix this panel does not use.wwwroot-src/src/composables/useSoftNcRunner.ts— the shared snapshot the first empty layer and the axis-column union read.wwwroot-src/src/components/widgets/NumericInput.vue— the cell: commit on blur or Enter, the parsed value written back into the box, and the absence of any integer rule.wwwroot-src/src/components/controlTree/SoftNcEmptyState.vue— the shared no-runner line.wwwroot-src/src/components/controlTree/SoftNcIndexingPositionsPanel.vue— the sibling that displays the MD30500 assignment this leaf writes, and points here for it.wwwroot-src/src/api/http.ts— the shared fetch helper that turns both a non-2xx status and asuccess: falsebody into one thrown error.wwwroot-src/src/i18n/en/softNc.ts— the node label, the raw-units hint, the three section headings, the three add-footer section options, the two footer refusals and the five error contexts — one read and four writes, the two per-axis savers sharing a context.wwwroot-src/src/i18n/en/common.ts— the shared Id, Value, Axis and Add / Set strings.wwwroot-src/src/i18n/en/dialog.ts— the remove dialog's title, its message, and the three storage kind words it interpolates.Mech/SoftNcRunnerController.cs— the REST surface: the read that orders each dictionary by id and attaches the brand's usage description to every row, the prefix computed from the resolved table's type, the three get-or-create writers and the three whole-row removals, the shared dependency wrapper that answers a missing table inside a success envelope, and the neighbouring readers this form's rows also feed — the three per-axis reads that take the axis-type row's key set bare, the tool-change read that falls back to its own configuration's keys when that set is empty, and the M-code read bound to the stored declaration map rather than the overlaid view.
HiAPI Engine
HiMech/NcParsers/Dependencys/ControllerParameterTableBase.cs— the three dictionaries this leaf is, the get-or-create bucket accessors, the role interfaces that let the domain-grouped leaves read the same rows, the axis-name set taken from the axis-type row, the three usage-description methods, the rotary-axis helper that writes type, reference position and rapid rate in one call, and the XML round-trip that persists every row including free extras.HiMech/NcParsers/Dependencys/Fanuc/FanucParameterTable.cs— the#vocabulary: the well-known numbers, the get-or-create defaults behind the modelled accessors, the macro-variable lookup over the work-offset address ranges, and the seed a fresh Fanuc or Mazak runner opens on.HiMech/NcParsers/Dependencys/Syntec/SyntecParameterTable.cs— thePrvocabulary, and the peck clearance stored in microns with the conversion kept in its accessor.HiMech/NcParsers/Dependencys/Siemens/SiemensMachineDataTable.cs— theMDvocabulary: the indexing assignment, the three equidistant numbers this leaf alone edits and the spacing resolution that reads them, the tool-change mode, the tool-change M function with the read-time declaration overlay that never enters the stored map, the fixed-point position, and the seed that declares one system row.HiMech/NcParsers/Dependencys/Heidenhain/HeidenhainParameterTable.cs— theMPvocabulary and its two-row seed.HiMech/NcParsers/Dependencys/IsoCoordinateAddressMap.cs— the work-offset address scheme shared by the Fanuc and Syntec tables, the per-address description that captions those rows, and the seeding of every triad to zero.HiMech/NcParsers/Dependencys/IMachineAxisConfig.cs— the axis contract, and the axis-type enumeration a cell of the integer section stores.HiMech/NcParsers/Dependencys/Generic/ToolingMcConfig.cs— the tool-change pose, stored outside the three dictionaries, whose own X / Y / Z keys are what Tool-Change Position falls back to when the axis-type row is gone.HiMech/NcParsers/SoftNcRunner.cs— the five brand presets and which parameter-table proxy each carries, the Fanuc proxy inside the Mazak preset among them, the tool-change configuration every preset seeds, and the chain configuration that is the only other writer of the axis-type row and, on a rotary chain axis, of that axis' reference position and rapid rate.
See Also
- Machine and Controller Plane — the plane this leaf sits on, and why the table it exposes is stored on the project rather than on the runner file
- Brand Matrix — the flag that grows this node, why it never reports false on a shipped preset, and why Mazak resolves the Fanuc table
- Editing Contract — the commit, rollback, confirm and toast rules this panel shares with the branch, and the add-footer details it differs on
- Interface Parameters — the same values in domain vocabulary, including the peck clearance this leaf shows in the brand's own unit
- Indexing Position Tables — the leaf that displays the MD30500 assignment and the equidistant definition that are written here