Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
9857349
xyzbc-trt-kins: apply the direction sign to the offsets in the inverse
grandixximo Sep 3, 2026
a71bad1
scarakins: set the elbow flag for a negative elbow angle
grandixximo Sep 3, 2026
9675ed0
pumakins, three21kins: compare the branch flags modulo a whole turn
grandixximo Sep 3, 2026
680c882
userkins, millturn, matrixkins, xyzab_tdr_kins: set the kinematics pi…
grandixximo Sep 3, 2026
938b16d
maxkins: make the forward and the inverse describe the same machine
grandixximo Sep 15, 2026
21aef29
motion: a kinematics switch whose forward cannot solve the joints is …
grandixximo Sep 15, 2026
1383776
twp: split the machine maths out of the tilted work plane remap
Sigma1912 Aug 23, 2026
a188405
twp: keep the arc functions inside their domain
grandixximo Aug 24, 2026
9978bf0
kinematics: add an optional Jacobian entry point
grandixximo Sep 3, 2026
e8b46a3
trtfuncs, 5axiskins, maxkins: supply the Jacobian
grandixximo Sep 3, 2026
854c813
corexykins, rotatekins, rosekins, matrixkins, millturn, userkins: sup…
grandixximo Sep 3, 2026
791fdc9
xyzab_tdr_kins, xyzacb_trsrn, xyzbca_trsrn: supply the Jacobian
grandixximo Sep 3, 2026
5d454a8
tripodkins, lineardeltakins, rotarydeltakins, genhexkins, pentakins: …
grandixximo Sep 3, 2026
a052cf1
scarakins, scorbot-kins: supply the Jacobian
grandixximo Sep 3, 2026
84bc963
genserkins: supply the Jacobian from its geometric one
grandixximo Sep 3, 2026
ea2bbf5
tests: check the Jacobian of every module where it runs
grandixximo Sep 3, 2026
3544490
kinematics.h: C linkage guards, and the include guard closed at the e…
grandixximo Sep 11, 2026
a0402a8
interp: G43.4 and G49 as spellings over the kinematics switch
grandixximo Sep 11, 2026
2652267
interpreter: add the tilted work plane, G68.2, G68.4 and G69
grandixximo Sep 4, 2026
ac40f93
glcanon: draw the tilted work planes a program defines
grandixximo Sep 15, 2026
52f5546
switchkins: separate the dispatch from rtapi_app_main()
grandixximo Aug 11, 2026
2f431a4
switchkins: let halcompile components use the switchkins core
grandixximo Aug 11, 2026
6d4b7be
switchkins: add an out-of-tree module template
grandixximo Aug 12, 2026
ce628ac
kins: include switchkins.h as an exported header
grandixximo Aug 12, 2026
4300488
switchkins: install the implementation as source for out-of-tree modules
grandixximo Aug 12, 2026
a6775c9
canon: stop printing on every kinematics switch
grandixximo Aug 24, 2026
b891bb5
kinematics: evaluate a module outside RT by binding to its live pins
grandixximo Aug 10, 2026
d918af6
kinematics: add the parameter block form of a module
grandixximo Sep 4, 2026
d411926
trtfuncs, xyzac-trt-kins, xyzbc-trt-kins, maxkins: move onto the para…
grandixximo Sep 4, 2026
5a0daf7
corexykins, rotatekins, rosekins, tripodkins, scorbot-kins, the delta…
grandixximo Sep 4, 2026
7df4d68
scarakins, pumakins, three21kins: move onto the parameter block
grandixximo Sep 4, 2026
2f99d4d
millturn, xyzab_tdr_kins, xyzacb_trsrn, xyzbca_trsrn: move onto the p…
grandixximo Sep 4, 2026
0cfaea9
genserkins, genhexkins, pentakins: move onto the parameter block
grandixximo Sep 4, 2026
13bac4b
switchkinscomp: write the template on the parameter block
grandixximo Sep 4, 2026
abab22c
switchkins: declare the primary kinstype from the ops table
grandixximo Sep 11, 2026
9c672f1
docs: describe the parameter block form of a kinematics module
grandixximo Sep 4, 2026
9e4fb58
kinematics_user: take the joints in as well as out, and bind modules …
grandixximo Sep 4, 2026
de01dde
tests: check that a module answers the same outside realtime
grandixximo Sep 4, 2026
7bf7964
kinematics: take the tool offset from motion, not from a net
grandixximo Sep 4, 2026
f92dc80
5axiskins, maxkins: take the tool length from motion
grandixximo Sep 14, 2026
d992970
kinematics: reach the frames and the tool frame inverse from outside …
grandixximo Sep 4, 2026
3470709
kinematics_user: read the module's pins by name, making nothing in HAL
grandixximo Sep 14, 2026
ad8f8c8
kinematics: retire the KINS_NOT_SWITCHABLE macro
grandixximo Sep 11, 2026
7afc3d8
tests: put the nutating head kinematics next to the tilted work plane…
grandixximo Sep 4, 2026
b1313c5
motion: add the point-to-point move, interpolated in joint space
grandixximo Sep 4, 2026
d28bfa2
interpreter: the point-to-point moves and the tool orientation codes,…
grandixximo Sep 4, 2026
9d924ab
configs: the nutating-head sims on the native tilted work plane
grandixximo Sep 4, 2026
be368ab
5axiskins: supply the work and tool frames
grandixximo Sep 7, 2026
6193989
tests: give the tilted work plane a plane that tells the forms apart
grandixximo Sep 8, 2026
4a93735
docs: say where the tilted work plane conventions come from
grandixximo Sep 8, 2026
5c85e95
interpreter, motion: hold the joints a point-to-point move asks for
grandixximo Sep 8, 2026
8a89cb7
interpreter: seed the kinematics from the joints the machine stands in
grandixximo Sep 8, 2026
d2b0d79
preview: let the canon report where the joints stand
grandixximo Sep 9, 2026
6c216a9
tests: the point-to-point moves and their preview on an iterative module
grandixximo Sep 9, 2026
f741f60
genserkins: hold the inverse to a step the Jacobian is good for
grandixximo Sep 9, 2026
b194a50
motion: check a move against the joints the queue leaves behind
grandixximo Sep 9, 2026
d878037
interpreter: add G53.2, solve the tool orientation without moving
grandixximo Sep 10, 2026
320806a
configs: the bridgemill sim shows off the tilted work plane family
grandixximo Sep 10, 2026
31c3f5b
motion, interp: a tool offset change under a tilt keeps the joints
grandixximo Sep 14, 2026
55c68de
interp: G43.5, the tool axis as a vector
grandixximo Sep 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ share/desktop-directories/linuxcnc-cnc.directory
share/desktop-directories/linuxcnc-ref.directory
share/desktop-directories/linuxcnc-doc.directory
share/linuxcnc/mesa_modbus.c.tmpl
share/linuxcnc/switchkins.c
share/linuxcnc/switchkins_setup.c
share/linuxcnc/kins_util.c
share/linuxcnc/kins_single.c
src/modules.order
/configs/*/emc.nml
!/configs/common/emc.nml
Expand Down
9 changes: 7 additions & 2 deletions configs/sim/axis/vismach/5axis/bridgemill/5axis.ini
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ MACHINE = Sim-5Axis Bridge Mill (xyzbcw)
DEBUG = 0

[DISPLAY]
GEOMETRY = XYZCBW
OPEN_FILE = ./5axisgui.ngc
# GEOMETRY tells the AXIS live plot how to guess the tool position from
# the nine axis values: letters translate, ABC rotate the point. W is
# deliberately absent: the plot would add the W value as a Z offset after
# the rotations, while the kinematics spends W along the tool axis, so
# the guess never matches.
GEOMETRY = XYZCB
OPEN_FILE = ./g532-fused-orient-move.ngc
INCREMENTS = 10 mm, 1 mm, .1 mm
JOG_AXES = XYZC
DISPLAY = axis
Expand Down
1 change: 0 additions & 1 deletion configs/sim/axis/vismach/5axis/bridgemill/5axisgui.hal
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ net :gui-pivot-len <= 5axisgui.pivot_len
net :gui-pivot-len => 5axiskins.pivot-length

net :tool-len <= motion.tooloffset.z
net :tool-len => 5axiskins.tool-length
net :tool-len => 5axisgui.tool_length

net :tool-diam <= halui.tool.diameter
Expand Down
15 changes: 15 additions & 0 deletions configs/sim/axis/vismach/5axis/bridgemill/5axisgui.ngc
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
; 5axisgui.ngc - the historical demo program, unchanged.
; It drills a sphere pattern with W words. W was never a physical
; quill: no motor is connected to its joint, the kinematics folds
; the word into the XYZ slides, and the head sliding along the tool
; axis is what plunges the rigidly mounted tool. Watch the slides
; in vismach do the stroke.
;
; The quirk, then and now: the controller keeps W as a separate
; world coordinate, so the programmed XYZ point does not move and
; the preview shows nothing of the stroke; only the W DRO tracks it.
; Drilling the controller can see, check and preview is what the
; tilted work plane family is for (g532-fused-orient-move.ngc,
; g536-orient-then-move.ngc).

#<r> = 60 ; sphere radius
#<rdelta> = 5 ; safe distance
#<drilldepth> = -5
Expand All @@ -13,6 +27,7 @@
#<bdelta> = [90/#<bctmax>]

g49
g12.1 p0 ; the TCP kinematics, in case a previous run left the identity one active
t#<toolno>m6g43

g53 g0 x0y0z#<zstart>b0c0 w0
Expand Down
50 changes: 45 additions & 5 deletions configs/sim/axis/vismach/5axis/bridgemill/README
Original file line number Diff line number Diff line change
@@ -1,19 +1,59 @@
This is a simulation of an XYZBCWY 5 axis bridge mill.
This is a simulation of an XYZBCWY 5 axis bridge mill with a
tilting head (B, C) and a W axis.

Example demo:
W is not a physical axis of the machine and never was: no motor is
connected to its joint. The kinematics folds a W word into the
XYZ joints, so the head slides along the tool axis and the
rigidly mounted tool goes with it: that is the whole trick, and it
is what vismach shows. There is no quill to draw because there is
no quill.

The quirk: the controller keeps W as a separate world coordinate,
so a W word leaves the programmed XYZ point untouched and the
preview cannot show the stroke; the W DRO tracks it. It also
means the planner does not see the tool-axis motion, so for
drilling the controller can check and preview, use the tilted work
plane family.

Because the W joint is virtual, a point-to-point move on it
(g53.5/g53.7 j5=) moves no motor on a real machine while the
controller believes the world moved, the opposite of a W word.
Do not drill that way.

Demo programs:

g532-fused-orient-move.ngc -- drill a sphere pattern with tilted work
planes (g68.2), using g53.2 to solve each
orientation without moving (STAY), then
one fused g0 that turns the head and
travels to the hole at the same time
(TCP motion)
g536-orient-then-move.ngc -- the same pattern with g53.6 (Heidenhain
MOVE style): reorient about the fixed
tip, then travel in the tilted plane
5axisgui.ngc --------------- the historical demo program, unchanged:
it drills the same pattern with W words,
the slides doing the stroke while the
preview stays blind to it

The tool table provides tool 100 (length 100). Load it with
t100m6g43 so the vismach tool and the kinematics pivot length
(pivotsum: 250 + tool length) match.

Example MDI:

1) $ linuxcnc 5axis.ini
2) F1 ---------- Estop off
F2 ---------- Machine on
CTRL-HOME --- home all
F5 ---------- MDI tab
3) orient vismach gui as required
4) g0w10 ; retract w
4) g0w10 ; head slides up the tool axis, tip with it
5) g43h100 ; tool offset (100)
6) g0b45 ; tilt 45 deg wrt z
7) g0c30 ; rotate 30 deg in xy
8) g0w-10 ; simulate drill
9) g0w10 ; retract drill
8) g0w-10 ; head slides back, tip plunges 10 along the tool axis
9) g0w10 ; and back
10) etc

Note: Motion for the W coordinate is incorporated
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
; g532-fused-orient-move.ngc - drill a sphere pattern with tilted work planes:
; g68.2 tilts the plane onto each hole normal, g53.2 solves the head
; orientation without moving (STAY), and one fused g0 turns the head
; and travels to the hole at the same time (TCP motion). See README
; for the other demos.

#<r> = 60 ; sphere radius
#<rdelta> = 5 ; safe distance
#<drilldepth> = -5
#<zsafe> = 20 ; clearance above the ball for start and stop
#<bctmax> = 8
#<cctmax> = 16
#<toolno> = 100
#<frate> = 1000

#<bct> = 0
#<cct> = 0
#<cdelta> = [360/#<cctmax>]
#<bdelta> = [90/#<bctmax>]

g49
g12.1 p0 ; the TCP kinematics, in case a previous run left the identity one active
t#<toolno>m6g43

g53 g0 x0 y0 z0 b0 c0
g10 l20 p0 x0 y0 z[#<r>+#<rdelta>+#<zsafe>] b0 c0 ; ball center at program origin, we park above it
f#<frate>
o100 while [#<bct> lt #<bctmax>]
#<b> = [[#<bctmax>-1-#<bct>]*#<bdelta>] ; top ring first, the way in stays outside the ball
#<cct> = 0
o200 while [#<cct> lt #<cctmax>]
o210 if [[#<bct> mod 2] eq 0]
#<c> = [#<cct> * #<cdelta>]
o210 else
#<c> = [360 - [1+ #<cct>] * #<cdelta>]
o210 endif
g68.2 p1 j[90-#<b>] k#<c> ; plane Z is the sphere radius at b, c
g53.2 ; solve the orientation, stay put
g0 x0 y0 z[#<r>+#<rdelta>] b#<_orient_b> c#<_orient_c> ; one TCP turn and travel
g1 z[#<r>+#<drilldepth>]
g0 z[#<r>+#<rdelta>]
#<cct> = [#<cct>+1]
o200 endwhile
#<bct> = [#<bct>+1]
o100 endwhile

g69
g53 g0 z0 ; up, clear of the ball
g53 g0 x0 y0 b0 c0
m2
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
; g536-orient-then-move.ngc - same sphere as g532-fused-orient-move.ngc, but with g53.6
; (Heidenhain MOVE style): reorient about the fixed tip, a TCP move,
; then travel to the next hole in the tilted plane with a separate g0.
; g532-fused-orient-move.ngc fuses the turn and the travel into one move instead.

#<r> = 60 ; sphere radius
#<rdelta> = 5 ; safe distance
#<drilldepth> = -5
#<zsafe> = 20 ; clearance above the ball for start and stop
#<bctmax> = 8
#<cctmax> = 16
#<toolno> = 100
#<frate> = 1000

#<bct> = 0
#<cct> = 0
#<cdelta> = [360/#<cctmax>]
#<bdelta> = [90/#<bctmax>]

g49
g12.1 p0 ; the TCP kinematics, in case a previous run left the identity one active
t#<toolno>m6g43

g53 g0 x0 y0 z0 b0 c0
g10 l20 p0 x0 y0 z[#<r>+#<rdelta>+#<zsafe>] b0 c0 ; ball center at program origin, we park above it
f#<frate>
o100 while [#<bct> lt #<bctmax>]
#<b> = [[#<bctmax>-1-#<bct>]*#<bdelta>] ; top ring first, the way in stays outside the ball
#<cct> = 0
o200 while [#<cct> lt #<cctmax>]
o210 if [[#<bct> mod 2] eq 0]
#<c> = [#<cct> * #<cdelta>]
o210 else
#<c> = [360 - [1+ #<cct>] * #<cdelta>]
o210 endif
g68.2 p1 j[90-#<b>] k#<c> ; plane Z is the sphere radius at b, c
g53.6 ; reorient about the tip, a TCP move
g0 x0 y0 z[#<r>+#<rdelta>]
g1 z[#<r>+#<drilldepth>]
g0 z[#<r>+#<rdelta>]
#<cct> = [#<cct>+1]
o200 endwhile
#<bct> = [#<bct>+1]
o100 endwhile

g69
g53 g0 z0 ; up, clear of the ball
g53 g0 x0 y0 b0 c0
m2
4 changes: 1 addition & 3 deletions configs/sim/axis/vismach/5axis/max5/max5kins.hal
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ loadusr -W ./max5gui.py

# set a visible tool
setp max5gui.tool-radius 3
# the tool length is applied along the tool, not along Z, so the tip stays
# on the programmed point as B tilts
net tool-len motion.tooloffset.z max5gui.tool-length maxkins.tool-length
net tool-len motion.tooloffset.z max5gui.tool-length

# add motion controller functions to servo thread
addf motion-command-handler servo-thread
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
This is a simulation configuration for a 6 axis machine with one table rotary and two spindle rotary joints

This simulation also includes a python remap of Gcodes for tilted workplane (TWP) functionality.
Both the kinematic and the twp remap support nutation of the secondary rotary joints (ie A or B ) form 0 to 90°.
Hence this also works for the 'usual' orthogonal spindle rotary-tilt type machines by setting the nutation angle to 90°.
This simulation uses the interpreter's tilted work plane codes, documented in the G-code section of the manual:

Implemented TWP functionality:
G68.2 : defines twp using euler-angles, pitch-roll-yaw, 2-vectors, 3 points, optionally with offset in XYZ and rotation in XY
G68.3 : defines twp from current tool orientation, optionally with offset in XYZ and rotation in XY
G68.4 : same as G68.2 but as an incremental definition from an active TWP plane
G69 : cancels the current twp (resets all parameters, moves to G54 and sets Identity kinematics)
G53.1 (P) : spindle orientation without tcp, switches to G59 and activates tool kinematics
G53.3 (P XYZ) : same as G53.1 but with simultaneous move the the XYZ coords on the twp plane
G53.6 (P) : same as G53.1 but spindle orientation with tcp
G68.2 : defines the plane by three angles, three points or two vectors, with an origin in XYZ and a turn R about the plane's Z
G68.3 : defines the plane from the current tool direction, with an origin in XYZ and a turn R
G68.4 : any G68.2 form, composed onto the active plane
G69 : cancels the plane
G53.1 (P Q) : orients the tool to the plane, rotaries only, the linear joints stay where they are
G53.3 (P Q XYZ) : orients the tool and moves to XYZ in the plane, interpolated in joint space
G53.6 (P Q) : orients the tool with the tool centre point held

- Spindle is C primary, A secondary or B secondary as defined in the [TWP] section of the ini file
- All G53.x commands will respect axis limits as set in the ini file for the respective primary and secondary spindle joints.
- The P word sets the orientation strategy: 0(default)=shortest distance,
1=positive rotation only,
2=negative rotation only
(this applies to the primary rotary, the secondary moves the shortest distance)
The orientation codes need the TCP kinematics (G12.1 P1). P picks the solution, nearest to the present rotary position first. Q0 holds the table and lets the head do it, Q1 lets the table take part as well.

The kinematic supports nutation of the secondary rotary joint (A or B) from 0 to 90 degrees, so this also covers the usual orthogonal spindle rotary-tilt machines by setting the nutation angle to 90 degrees.

The python maths this configuration used to carry as a remap lives on in tests/kins-twp, where the kinematics module is checked against it.

For more:
https://forum.linuxcnc.org/show-your-stuff/49103-kinematic-model-for-a-5axis-mill-with-universal-nutating-head?start=0#271334

Full Documentation can be found at:
https://github.com/Sigma1912/LinuxCNC_Demo_Configs/tree/main/table-rotary_spindle-rotary-nutating/Documentation
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
G69
g12.1 p1 (the TCP kinematics: the plane codes need it)
g10 l2 p0 x1000 y-1000 z-1000
m6 t3 g43 h3
g68.2 q121 i25 j-10
Expand All @@ -13,5 +14,6 @@ o100 REPEAT[100]
g0 y50
o100 ENDREPEAT
g69
g13.1
M2

Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
g69
g12.1 p1 (the TCP kinematics: the plane codes need it)
g10 l2 p0 x1300 y-200 z-1400
m6 t3 g43 h3
g68.2 q121 i0 j5
Expand All @@ -20,4 +21,5 @@ o100 REPEAT[1000]

o100 ENDREPEAT
g69
g13.1
M2
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
G69
g12.1 p1 (the TCP kinematics: the plane codes need it)
g10 l2 p0 x1000 y-1000 z-1000
m6 t3 g43 h3
g68.2 q121 i25 j-10
Expand All @@ -7,7 +8,7 @@ o100 REPEAT[100]
g68.4 q131 i-35 j-35 k0
;g53.3 p0 x50y50z150
g53.6
x50y50z150
g0 x50y50z150
g0 z100
g0 x-50
g0 y-50
Expand All @@ -16,5 +17,6 @@ o100 REPEAT[100]
g0 x0y0z120
o100 ENDREPEAT
g69
g13.1
M2

Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
g69
g13.1
g12.1 p1 (the TCP kinematics: the plane codes need it)
g10 l2 p0 x1300 y-200 z-1400
m6 t3 g43 h3
g0 x0y0z100
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@ o<square>sub
g0 x50
g0 y50
g0 x0y0z120
g52 x0y0z0
o<square>endsub
Loading