Class XyzabcSolver
Support to two-way conversion between MC (machine coordinate) and NP (Normal and Point).
public class XyzabcSolver : IMachineKinematics
- Inheritance
-
XyzabcSolver
- Implements
- Inherited Members
- Extension Methods
Remarks
A shell over the native mechkinematicsxyzabc_solver_t (core.dll,
xyzabc_solver__* in Hi.Numerical.Xyzabc.NativeXyzabc): the private clone of the machine, the
rotary (cos / sin Newton) and linear solves, the teleport interpolation, the seed handling and
the travel-aware branch search all live there. The constructor creates the native solver and
runs the first Rebuild(), the finalizer releases it, and the shell keeps itself and
the source's views alive across every native call. One instance is single-threaded, as it
always was.
The source machine is named to native by the ids of its topology views: the assembly, its root anchor, the table mount and the tool mount, and the branch that carries the transformer of each axis (X Y Z A B C) — the branch the transformer object is the live view of, read through the object's own binding; a transformer not bound to a branch, nested in a stack, or whose branch is detached or now carries another object is an absent axis. The source is read only during the constructor and Rebuild(); the solves move the clone, never the source. The spindle (GetSpindleTransformer()) is cloned at 0° whatever its angle — it is set to 0° for the clone and put back — so the tilt solves, which match the tool's whole orientation, answer the same at any spindle angle.
The solver is the controller's model of the machine, and the controller knows the nominal chain only: every branch of the source marked as an error term (IsErrorTerm) is a NoTransform in the clone, whatever transformer it carries. The answers are those of the machine without its error terms. The machine itself keeps them on its runtime face while the project switch (EnableErrorTerms) is on, so a machine coordinate solved here and run on the machine leaves the error on the part; with the switch off the machine runs as the nominal chain too.
A source whose two mounts are not connected inside the machine's assembly (an empty kinematic chain — a detached branch between them) is refused by name with an InvalidOperationException; a mount outside the assembly's subtree with a KeyNotFoundException; a missing mount with the RequireEndAnchors(IXyzabcMachineTool) exception; a role branch — an axis, the spindle — marked as an error term with an ErrorTermRoleException (RequireRoleBranchesNotErrorTerm(IMachiningChain)), and so is an axis whose transformer object was put on another branch that is marked (beside a role branch still in place the exception names both, RoleBranchName; in place of a role branch that is gone it reads as a marked role branch). After such a failure every member throws InvalidOperationException restating the reason until a Rebuild() succeeds: on a mount outside the assembly or an axis branch marked as an error term a native solve would abort the process, on an empty chain it would answer on an identity chain, so the shell issues none of them.
The rotary travel of the travel-aware overloads crosses into core.dll as data, an AbcTravel (RotaryTravel(IEnumerable<INcDependency>) builds it from the stroke config).
Constructors
XyzabcSolver(IXyzabcMachineTool)
Ctor.
public XyzabcSolver(IXyzabcMachineTool srcDevice)
Parameters
srcDeviceIXyzabcMachineTooltarget device
Exceptions
- InvalidOperationException
An end anchor is missing, or the two mounts are not connected inside the machine's assembly.
- ErrorTermRoleException
A role branch of the machine is marked as an error term, or the transformer of an axis is bound to another branch that is.
- KeyNotFoundException
A mount is not inside the machine's assembly.
- OutOfMemoryException
The native solver could not be allocated.
Methods
~XyzabcSolver()
Releases the native solver.
protected ~XyzabcSolver()
IsAxisAExisted()
Whether rotary column A exists on this chain (non-null transformer bound to a branch).
public bool IsAxisAExisted()
Returns
Exceptions
- InvalidOperationException
The last rebuild was not ok.
IsAxisBExisted()
Whether rotary column B exists on this chain (non-null transformer bound to a branch).
public bool IsAxisBExisted()
Returns
Exceptions
- InvalidOperationException
The last rebuild was not ok.
IsAxisCExisted()
Whether rotary column C exists on this chain (non-null transformer bound to a branch).
public bool IsAxisCExisted()
Returns
Exceptions
- InvalidOperationException
The last rebuild was not ok.
McAbcToMat(vec3d_t)
Converts machine ABC coordinates to a tilt matrix. the tilt matrix is the transformation matrix from table to attacher.
public mat4d_t McAbcToMat(vec3d_t mcAbc_rad)
Parameters
mcAbc_radvec3d_tThe machine ABC coordinates in radians
Returns
- mat4d_t
The tilt matrix
Exceptions
- InvalidOperationException
The last rebuild was not ok.
McToMat(dvec3d_t)
Converts machine coordinates to an attacher matrix.
public mat4d_t McToMat(dvec3d_t mc)
Parameters
mcdvec3d_t
Returns
- mat4d_t
The attacher matrix
Exceptions
- InvalidOperationException
The last rebuild was not ok.
McToPn(dvec3d_t)
Machine coordinate to tool attacher Pn (Point and Normal). The Pn is from table mount to tool attacher.
public dvec3d_t McToPn(dvec3d_t mc)
Parameters
mcdvec3d_t
Returns
- dvec3d_t
tool attacher Pn (Point and Normal)
Exceptions
- InvalidOperationException
The last rebuild was not ok.
OrientationToMcAbc(mat4d_t, out vec3d_t)
Converts a tilt matrix to machine ABC coordinates.
the tilt matrix is the transformation matrix from table to attacher.
the solution only fit the orientation part of the tiltMat.
public bool OrientationToMcAbc(mat4d_t tiltMat, out vec3d_t mcAbc_rad)
Parameters
tiltMatmat4d_tThe tilt matrix to convert
mcAbc_radvec3d_tOutput parameter that will contain the machine ABC coordinates in radians
Returns
- bool
Whether the conversion was successful: the orientation the answer realises meets the target within the solver's polish tolerance (about 1e-6 rad; see SetPn(dvec3d_t, out dvec3d_t)); on false the solver state is as it was on entry. A matrix with a NaN or an infinite element is refused (false, a NaN out value).
Exceptions
- InvalidOperationException
The last rebuild was not ok.
OrientationToMcAbc(mat4d_t, AbcTravel, out vec3d_t)
OrientationToMcAbc(mat4d_t, out vec3d_t) restricted to the rotary travel
travel: a full orientation fixes the rotary positions up to axis
periodicity, so a solution outside the travel is a posture this machine cannot take — the
conversion fails (false) and leaves the solver state as it was, so that the caller can fall
back to OrientationToMcAbc(vec3d_t, AbcTravel, out vec3d_t), where the free
rotation about the tool axis opens the other branch. A null travel (or one without any
limit) is the plain overload, bit for bit. The solve runs in core.dll, which takes the
travel as data.
public bool OrientationToMcAbc(mat4d_t tiltMat, AbcTravel travel, out vec3d_t mcAbc_rad)
Parameters
tiltMatmat4d_tThe tilt matrix to convert.
travelAbcTravelThe rotary travel to respect, or null to admit everything.
mcAbc_radvec3d_tOutput machine ABC coordinates in radians.
Returns
- bool
Whether an admissible conversion was found.
Exceptions
- InvalidOperationException
The last rebuild was not ok.
OrientationToMcAbc(vec3d_t, out vec3d_t)
Converts a target tool axial direction (endpoint orientation) to machine ABC coordinates. Only the axial alignment is constrained; rotation about the tool axis is free.
Use this in place of OrientationToMcAbc(mat4d_t, out vec3d_t) when the
rotation about the tool axis is irrelevant (e.g. G53.1 rotary positioning). The
axial-only solve avoids the redundant 6-target full-matrix constraint and is more
likely to converge for tilt configurations such as G68.2 I180 J90 K0.
public bool OrientationToMcAbc(vec3d_t toolAxialNormal, out vec3d_t mcAbc_rad)
Parameters
toolAxialNormalvec3d_tTarget tool axial direction in table coordinates (the third row of the tilt matrix; e.g. AxialNormal).
mcAbc_radvec3d_tOutput machine ABC coordinates in radians.
Returns
- bool
Whether the conversion was successful: the tool axis the answer realises meets the target within the solver's polish tolerance (about 1e-6 rad; see SetPn(dvec3d_t, out dvec3d_t)); on false the solver state is as it was on entry. A normal with a NaN or an infinite component is refused (false, a NaN out value).
Exceptions
- InvalidOperationException
The last rebuild was not ok.
OrientationToMcAbc(vec3d_t, AbcTravel, out vec3d_t)
OrientationToMcAbc(vec3d_t, out vec3d_t) preferring the solution branch
inside the rotary travel travel: the axial-only problem has two branches
on a two-rotary-axis machine, and the plain overload returns the one nearest the solver's
seed; when that branch is outside the travel the other branches are searched and the
admissible one nearest the seed is returned and becomes the solver state; when none is
admissible the refused solution stands and the method still returns true, and the
stroke-limit check downstream reports it. A null travel (or one without any limit) is the
plain overload, bit for bit. The solve and the branch search run in core.dll, which takes
the travel as data.
public bool OrientationToMcAbc(vec3d_t toolAxialNormal, AbcTravel travel, out vec3d_t mcAbc_rad)
Parameters
toolAxialNormalvec3d_tTarget tool axial direction in table coordinates.
travelAbcTravelThe rotary travel to respect, or null to admit everything.
mcAbc_radvec3d_tOutput machine ABC coordinates in radians.
Returns
- bool
Whether the conversion was successful (admissible or not).
Exceptions
- InvalidOperationException
The last rebuild was not ok.
PnToMc(dvec3d_t, out dvec3d_t)
Tool attacher Pn (Point and Normal) to machine coordinate. The Pn is from table mount to tool attacher.
public bool PnToMc(dvec3d_t np, out dvec3d_t mcXyzabc_rad)
Parameters
Returns
- bool
whether conversion succeeded; a pn with a NaN or an infinite component is refused (false, a NaN out value)
Exceptions
- InvalidOperationException
The last rebuild was not ok.
Rebuild()
Rebuild the solver. It should be called after the kinematic chain of Hi.Numerical.Xyzabc.XyzabcSolver.SrcDevice is modified: the axes, the mounts and the branch ids are read again and the native clone is rebuilt from them (the solver's state restarts from the source's current steps).
public void Rebuild()
Exceptions
- InvalidOperationException
An end anchor is missing (RequireEndAnchors(IXyzabcMachineTool)), or the two mounts are not connected inside the machine's assembly (the kinematic chain between them is empty); the message names both mounts and the assembly.
- ErrorTermRoleException
A role branch of the machine — an axis, the spindle — is marked as an error term (RequireRoleBranchesNotErrorTerm(IMachiningChain)); the message names the role and the branch. Or the transformer object of an axis was put on another branch since, and that branch is marked: beside a role branch still in place the message names the role, both branches and the repair (RoleBranchName is then set); in place of a role branch that was detached or has left the assembly, the refusal is the one of a marked role branch.
- KeyNotFoundException
A mount is not inside the machine's assembly; the message names it.
- OutOfMemoryException
The native solver could not be allocated (first build only).
SetPn(dvec3d_t, out dvec3d_t)
Cutter location to machine coordinate.
On failure nothing is written back and the solver state (the
implicit seed of the next solve) is restored to what it was on
entry; the out value still reports the failed solve's parameters.
A pn with a NaN or an infinite component is no
question: native refuses it before the solve – false, a NaN
mc, the state untouched (the four
OrientationToMcAbc overloads refuse such a normal or tilt
matrix the same way). McToPn(dvec3d_t) answers such a pn for a
NaN angle on an axis the machine has.
What true promises, here and in every OrientationToMcAbc
overload (AbcSolver step 3, 2026-09-28): the rotary answer meets the
target within the polish tolerance, a first-order residual below 1e-6
(about 1e-6 rad), never the coarse Newton stage's second-order 1e-6
alone, which admitted an error of up to 1.4e-3 rad in the pole
neighbourhood. A target farther than 20° is reached through
interpolated waypoints; those are guidance, not sub-goals — each is
approached as well as it can be (an SO(3) waypoint is usually out of
reach of two rotary axes) and only the last step's verdict is the
call's.
public bool SetPn(dvec3d_t pn, out dvec3d_t mc)
Parameters
Returns
- bool
true if solved
Exceptions
- InvalidOperationException
The last rebuild was not ok.