Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
55c0f80
twp: split the machine maths out of the tilted work plane remap
Sigma1912 Aug 23, 2026
eb2b66e
twp: keep the arc functions inside their domain
grandixximo Aug 24, 2026
3ddf67a
kinematics: add an optional Jacobian entry point
grandixximo Sep 3, 2026
56c1d43
trtfuncs, 5axiskins, maxkins: supply the Jacobian
grandixximo Sep 3, 2026
1e78026
corexykins, rotatekins, rosekins, matrixkins, millturn, userkins: sup…
grandixximo Sep 3, 2026
451fdd4
xyzab_tdr_kins, xyzacb_trsrn, xyzbca_trsrn: supply the Jacobian
grandixximo Sep 3, 2026
f9f5042
tripodkins, lineardeltakins, rotarydeltakins, genhexkins, pentakins: …
grandixximo Sep 3, 2026
10bda81
scarakins, scorbot-kins: supply the Jacobian
grandixximo Sep 3, 2026
c2feb43
genserkins: supply the Jacobian from its geometric one
grandixximo Sep 3, 2026
fb9020b
pumakins, three21kins: supply the Jacobian from the Denavit-Hartenber…
grandixximo Sep 21, 2026
df75875
tests: check the Jacobian of every module where it runs
grandixximo Sep 3, 2026
d48d5e8
kinematics.h: C linkage guards, and the include guard closed at the e…
grandixximo Sep 11, 2026
7e287d6
interp: G43.4 and G49 as spellings over the kinematics switch
grandixximo Sep 11, 2026
082552d
emccanon: B and C moves use the angular minimum displacement
grandixximo Sep 23, 2026
96fd7f6
Honor [AXIS_<letter>] TYPE in the interpreter and canon
grandixximo Sep 23, 2026
3ea91ab
sai: take the axes from [TRAJ] COORDINATES
grandixximo Sep 23, 2026
0d93892
tests: axis type in the interpreter and through motion
grandixximo Sep 23, 2026
433c00c
interpreter: add the tilted work plane, G68.2, G68.4 and G69
grandixximo Sep 4, 2026
4115d57
glcanon: draw the tilted work planes a program defines
grandixximo Sep 17, 2026
cfc2cc3
switchkins: separate the dispatch from rtapi_app_main()
grandixximo Aug 11, 2026
4b6eed4
switchkins: let halcompile components use the switchkins core
grandixximo Aug 11, 2026
cce6a45
switchkins: add an out-of-tree module template
grandixximo Aug 12, 2026
032ef12
kins: include switchkins.h as an exported header
grandixximo Aug 12, 2026
8d6a4e8
switchkins: install the implementation as source for out-of-tree modules
grandixximo Aug 12, 2026
e60ef3e
canon: stop printing on every kinematics switch
grandixximo Aug 24, 2026
2d45cbd
kinematics: evaluate a module outside RT by binding to its live pins
grandixximo Aug 10, 2026
cc1b818
kinematics: add the parameter block form of a module
grandixximo Sep 4, 2026
5617cfc
trtfuncs, xyzac-trt-kins, xyzbc-trt-kins, maxkins: move onto the para…
grandixximo Sep 4, 2026
cf31bd9
corexykins, rotatekins, rosekins, tripodkins, scorbot-kins, the delta…
grandixximo Sep 4, 2026
527da8a
scarakins, pumakins, three21kins: move onto the parameter block
grandixximo Sep 4, 2026
ad5279d
millturn, xyzab_tdr_kins, xyzacb_trsrn, xyzbca_trsrn: move onto the p…
grandixximo Sep 4, 2026
e1cf365
genserkins, genhexkins, pentakins: move onto the parameter block
grandixximo Sep 4, 2026
6a7e6e0
switchkinscomp: write the template on the parameter block
grandixximo Sep 4, 2026
cc7cd93
switchkins: declare the primary and the machine frame kinstype from t…
grandixximo Sep 11, 2026
697ef0a
docs: describe the parameter block form of a kinematics module
grandixximo Sep 4, 2026
38fd61d
kinematics_user: take the joints in as well as out, and bind modules …
grandixximo Sep 4, 2026
8542d01
tests: check that a module answers the same outside realtime
grandixximo Sep 4, 2026
94a4090
kinematics: take the tool offset from motion, not from a net
grandixximo Sep 4, 2026
c428abb
5axiskins, maxkins: take the tool length from motion
grandixximo Sep 14, 2026
66b8d71
5axiskins: supply the work and tool frames
grandixximo Sep 7, 2026
bd614b4
kinematics: reach the frames and the tool frame inverse from outside …
grandixximo Sep 4, 2026
200d3eb
kinematics_user: read the module's pins by name, making nothing in HAL
grandixximo Sep 14, 2026
9b368fe
kinematics: retire the KINS_NOT_SWITCHABLE macro
grandixximo Sep 11, 2026
f60bad2
kinematics.h: keep the interface, move the module side to kins_module.h
grandixximo Sep 15, 2026
5a68705
tests: put the nutating head kinematics next to the tilted work plane…
grandixximo Sep 4, 2026
48205c6
motion: add the point-to-point move, interpolated in joint space
grandixximo Sep 4, 2026
63ed4ba
interpreter: the point-to-point moves and the tool orientation codes,…
grandixximo Sep 4, 2026
7d7e79d
configs: the nutating-head sims on the native tilted work plane
grandixximo Sep 4, 2026
69d3beb
tests: give the tilted work plane a plane that tells the forms apart
grandixximo Sep 8, 2026
51b9125
docs: say where the tilted work plane conventions come from
grandixximo Sep 8, 2026
368a33c
interpreter, motion: hold the joints a point-to-point move asks for
grandixximo Sep 8, 2026
59f90b0
interpreter: seed the kinematics from the joints the machine stands in
grandixximo Sep 8, 2026
8ec7033
preview: let the canon report where the joints stand
grandixximo Sep 9, 2026
d07403e
tests: the point-to-point moves and their preview on an iterative module
grandixximo Sep 9, 2026
15d2607
genserkins: hold the inverse to a step the Jacobian is good for
grandixximo Sep 9, 2026
0ea00f4
motion: check a move against the joints the queue leaves behind
grandixximo Sep 9, 2026
358d662
interpreter: add G53.2, solve the tool orientation without moving
grandixximo Sep 17, 2026
f98003c
interpreter: keep the orientation poses inside the rotary travel
grandixximo Sep 23, 2026
a1f3752
configs: the bridgemill sim shows off the tilted work plane family
grandixximo Sep 10, 2026
8cc6376
motion, interp: a tool offset change under a tilt keeps the joints
grandixximo Sep 14, 2026
05d7060
interp: G43.5, the tool axis as a vector
grandixximo Sep 15, 2026
4ab39f5
interp: G28.5 and G30.5, the machine frame forms of G28 and G30, and …
grandixximo Sep 18, 2026
5934992
genserkins, pumakins: declare the arm kinematics the machine frame
grandixximo Sep 19, 2026
1afcd43
tests: what the limits have to mean on a kinematics that is not the i…
grandixximo Sep 19, 2026
06382dd
motion: read the [AXIS_L] box on the machine frame, whatever kinemati…
grandixximo Sep 19, 2026
4cd4a55
canon: cap every segment at what its joints can follow
grandixximo Sep 19, 2026
9c86f65
motion: cap a world jog at what its joints can follow
grandixximo Sep 19, 2026
99e4238
docs, qtvcp, hal_glib: list every code the kinematics work added
grandixximo Sep 19, 2026
0608a55
kinematics_user: a Jacobian entry at joints the caller holds
grandixximo Sep 21, 2026
7cdb591
The stack's own conversions follow [AXIS_<letter>] TYPE
grandixximo Sep 23, 2026
658faf9
Kinematics types name the axes that orient the tool
grandixximo Sep 23, 2026
d13e2a6
switchkins: a module may declare several primary types
grandixximo Sep 23, 2026
956192e
G53.2 publishes the rotaries in the order the kinematics orients with
grandixximo Sep 23, 2026
58ea0a1
twinspindlekins: a mill-turn whose two spindles are two primary types
grandixximo Sep 24, 2026
5848844
sim: twinspindle, one subroutine drilling the parts in both spindles
grandixximo Sep 24, 2026
1a264aa
genserkins: build the Jacobian from the DH frames
grandixximo Sep 26, 2026
5abdda6
tp: hold the joints when an abort stops a joint interpolated segment
grandixximo Sep 26, 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 @@ -20,6 +20,10 @@ share/menus/CNC.menu
share/desktop-directories/linuxcnc-cnc.directory
share/desktop-directories/linuxcnc-ref.directory
share/desktop-directories/linuxcnc-doc.directory
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_rot2> c#<_orient_rot1> ; one TCP turn and travel, C orients first
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
Loading