Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
e7b7cda
tests: what the limits have to mean on a kinematics that is not the i…
grandixximo Sep 19, 2026
ef8e459
motion: read the [AXIS_L] box on the machine frame, whatever kinemati…
grandixximo Sep 19, 2026
cdb4730
canon: cap every segment at what its joints can follow
grandixximo Sep 19, 2026
cc0a891
motion: cap a world jog at what its joints can follow
grandixximo Sep 19, 2026
5cfacec
docs, qtvcp, hal_glib: list every code the kinematics work added
grandixximo Sep 19, 2026
dfc7402
kinematics_user: a Jacobian entry at joints the caller holds
grandixximo Sep 21, 2026
bbf4e4a
maxkins: read the [AXIS_L] box on the carriage
grandixximo Oct 29, 2026
622b811
motion: slow a world jog to rest where a joint reaches its soft limit
grandixximo Nov 9, 2026
37a12f1
The stack's own conversions follow [AXIS_<letter>] TYPE
grandixximo Sep 23, 2026
499b114
Kinematics types name the axes that orient the tool
grandixximo Sep 23, 2026
a4fadd9
switchkins: a module may declare several primary types
grandixximo Sep 23, 2026
b846035
G53.2 publishes the rotaries in the order the kinematics orients with
grandixximo Sep 23, 2026
d7ddc04
twinspindlekins: a mill-turn whose two spindles are two primary types
grandixximo Sep 24, 2026
f0d4de6
sim: twinspindle, one subroutine drilling the parts in both spindles
grandixximo Sep 24, 2026
61e8f38
sim: twinspindle moves G53, G28 and G30 in the machine frame
grandixximo Oct 18, 2026
e1046ad
genserkins: build the Jacobian from the DH frames
grandixximo Sep 26, 2026
c992f24
tp: hold the joints when an abort stops a joint interpolated segment
grandixximo Sep 26, 2026
d8751f3
tp: cap a joint interpolated segment by the max velocity slider
grandixximo Sep 26, 2026
95fa99c
docs: the two poses differ in the first rotary from the tool
grandixximo Oct 4, 2026
7815f2d
canon: refuse a move whose joints leave their travel along it
grandixximo Oct 5, 2026
09b0143
motion: report the tool frame in the work frame in status
grandixximo Oct 10, 2026
26f9639
glcanon: point the tool marker along the tool frame the kinematics re…
grandixximo Oct 10, 2026
6dc9fdc
motion: jog X, Y and Z along the tilted work plane or the tool
grandixximo Oct 10, 2026
8368bff
halui: select the jog frame
grandixximo Oct 10, 2026
193b0fb
axis: select the jog frame from the View menu or with %
grandixximo Oct 10, 2026
9a90227
interp: cut a tilted work plane on the part under the machine frame k…
grandixximo Oct 19, 2026
bb11797
preview: draw the tool on the part under the machine frame kinematics
grandixximo Oct 26, 2026
0bd6cac
preview: read the point back from the joints at a kinematics switch
grandixximo Oct 27, 2026
b417322
kinematics: frames from the pose, for a type whose forward iterates
grandixximo Oct 28, 2026
3cb5b40
genhexkins, pentakins: state the frames from the pose
grandixximo Oct 28, 2026
c216e78
kinematics: turn the offset across the tool with the pose
grandixximo Oct 28, 2026
d9da122
motion: read the [AXIS_L] box on the platform of a parallel machine
grandixximo Oct 28, 2026
c83bd89
interp: orient the tool on a parallel machine
grandixximo Oct 28, 2026
b64d6da
kinematics: the forward and the inverse of any type, as the type in f…
grandixximo Oct 30, 2026
13b8e80
tp, motion: a joint segment that follows a line on another kinematics…
grandixximo Oct 30, 2026
5fa1e08
interp: G53.6 keeps the tool tip on the part all along under the mach…
grandixximo Oct 30, 2026
aad3b66
interp: G92, G10 L20, G43 and M6 wait for the G49 that cancels G43.4
grandixximo Nov 1, 2026
0e8326c
preview: restate G43.4 and G43.5 with the machine's offset
grandixximo Nov 9, 2026
c3a3fd7
motion_planning: the poses along a line and an arc, and how often to …
grandixximo Nov 3, 2026
d603294
preview: follow the joints along each move and warn before the run
grandixximo Nov 3, 2026
0b46627
interp: turn a coordinate system about X and Y as well as Z
grandixximo Nov 9, 2026
8c090e1
preview: restate the G52 and G92 offsets by value
grandixximo Nov 14, 2026
57d9b56
gladevcp, qtvcp: show the relative position in the tilted work plane
grandixximo Nov 14, 2026
454b261
gladevcp, qtvcp: show the relative position in the plane under G13.1
grandixximo Nov 14, 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
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ o210 else
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
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]
Expand Down
7 changes: 3 additions & 4 deletions configs/sim/axis/vismach/puma/mcodes/M128
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,11 @@ emc_init -ini $::env(INI_FILE_NAME) -quick
package require Hal
parse_ini $::env(INI_FILE_NAME)

# RESTORE INI axis limits
# RESTORE INI axis velocity and acceleration limits (the position
# limits are never changed: a box on the machine frame, the flange)
foreach l $coords {
set L [string toupper $l]
catch {hal setp ini.$l.min_limit [set ::AXIS_[set L](MIN_LIMIT)]}
catch {hal setp ini.$l.max_limit [set ::AXIS_[set L](MAX_LIMIT)]}
catch {hal setp ini.$l.min_velocity [set ::AXIS_[set L](MAX_VELOCITY)]}
catch {hal setp ini.$l.max_velocity [set ::AXIS_[set L](MAX_VELOCITY)]}
catch {hal setp ini.$l.max_acceleration [set ::AXIS_[set L](MAX_ACCELERATION)]}
}

Expand Down
9 changes: 5 additions & 4 deletions configs/sim/axis/vismach/puma/mcodes/M129
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/tclsh
# switch kinematics and change axis limits to equiv joint limits
# switch kinematics and change axis velocity limits to equiv joint limits
set kinstype 1 ;# 1: IDENTITY kins
set switchkins_pin 3 ;# agree with inifile
set max_joints 6 ;# agree with inifile
Expand All @@ -10,11 +10,12 @@ emc_init -ini $::env(INI_FILE_NAME) -quick
package require Hal
parse_ini $::env(INI_FILE_NAME)

# SET axis limits for IDENTITY kins using INI joint limits
# SET axis velocity and acceleration limits for IDENTITY kins using
# INI joint limits. The position limits stay: they are a box on the
# machine frame, the flange, which motion reads through the arm
# kinematics whatever type is in force
for {set j 0} {$j < $max_joints} {incr j} {
set l [lindex $coords $j]
catch {hal setp ini.$l.min_limit [set ::JOINT_[set j](MIN_LIMIT)]}
catch {hal setp ini.$l.max_limit [set ::JOINT_[set j](MAX_LIMIT)]}
catch {hal setp ini.$l.max_velocity [set ::JOINT_[set j](MAX_VELOCITY)]}
catch {hal setp ini.$l.max_acceleration [set ::JOINT_[set j](MAX_ACCELERATION)]}
}
Expand Down
9 changes: 5 additions & 4 deletions configs/sim/axis/vismach/puma/mcodes/M130
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/tclsh
# switch kinematics and change axis limits
# switch kinematics and change axis velocity limits
set kinstype 2 ;# 2: TYPE 2 kins
set switchkins_pin 3 ;# agree with inifile
set max_joints 6 ;# agree with inifile
Expand All @@ -10,11 +10,12 @@ emc_init -ini $::env(INI_FILE_NAME) -quick
package require Hal
parse_ini $::env(INI_FILE_NAME)

# SET axis limits for IDENTITY kins using INI joint limits
# SET axis velocity and acceleration limits for IDENTITY kins using
# INI joint limits. The position limits stay: they are a box on the
# machine frame, the flange, which motion reads through the arm
# kinematics whatever type is in force
for {set j 0} {$j < $max_joints} {incr j} {
set l [lindex $coords $j]
catch {hal setp ini.$l.min_limit [set ::JOINT_[set j](MIN_LIMIT)]}
catch {hal setp ini.$l.max_limit [set ::JOINT_[set j](MAX_LIMIT)]}
catch {hal setp ini.$l.max_velocity [set ::JOINT_[set j](MAX_VELOCITY)]}
catch {hal setp ini.$l.max_acceleration [set ::JOINT_[set j](MAX_ACCELERATION)]}
}
Expand Down
2 changes: 1 addition & 1 deletion configs/sim/axis/vismach/puma/puma.ini
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ RS274NGC_STARTUP_CODE = G21 G10L2P0 x450 y100 z-495 a-180 (debug, ini: startup o
MDI_COMMAND = M428
MDI_COMMAND = M429
MDI_COMMAND = M430
# MDI-COMMANDS 03,04,05 ALTER limits when switching
# MDI-COMMANDS 03,04,05 ALTER velocity and acceleration limits when switching
MDI_COMMAND = M128
MDI_COMMAND = M129
MDI_COMMAND = M130
Expand Down
2 changes: 1 addition & 1 deletion configs/sim/axis/vismach/puma/puma560.ini
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ PARAMETER_FILE = puma560.var
MDI_COMMAND = M428
MDI_COMMAND = M429
MDI_COMMAND = M430
# MDI-COMMANDS 03,04,05 ALTER limits when switching
# MDI-COMMANDS 03,04,05 ALTER velocity and acceleration limits when switching
MDI_COMMAND = M128
MDI_COMMAND = M129
MDI_COMMAND = M130
Expand Down
2 changes: 1 addition & 1 deletion configs/sim/axis/vismach/puma/puma560_uvw.ini
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ PARAMETER_FILE = puma560.var
MDI_COMMAND = M428
MDI_COMMAND = M429
MDI_COMMAND = M430
# MDI-COMMANDS 03,04,05 ALTER limits when switching
# MDI-COMMANDS 03,04,05 ALTER velocity and acceleration limits when switching
MDI_COMMAND = M128
MDI_COMMAND = M129
MDI_COMMAND = M130
Expand Down
2 changes: 1 addition & 1 deletion configs/sim/axis/vismach/puma/puma_cube.ini
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ POSTGUI_HALFILE = puma_postgui.hal
MDI_COMMAND = M428
MDI_COMMAND = M429
MDI_COMMAND = M430
# MDI-COMMANDS 03,04,05 ALTER limits when switching
# MDI-COMMANDS 03,04,05 ALTER velocity and acceleration limits when switching
MDI_COMMAND = M128
MDI_COMMAND = M129
MDI_COMMAND = M130
Expand Down
37 changes: 37 additions & 0 deletions configs/sim/axis/vismach/twinspindle/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
A mill-turn with a tilting head between two spindles, on twinspindlekins.

The head carries the tool on X Y Z and tilts it on B, about Y. The main
spindle turns its part on C; the sub spindle faces it along Z, 500 away,
and turns its own part on W. W is an angle, so [AXIS_W] declares it
TYPE = ANGULAR, and both spindles are WRAPPED_ROTARY. The vismach window
draws the spindle line across the screen as on a lathe: main spindle on
the left, Z to the right, X up.

Kinematics type 0 works on the part in the main spindle and orients the
tool with C and B; type 1 works on the part in the sub spindle and orients
it with W and B. Each part's frame has its Z out of its own spindle's face,
so a program reads the same on either part. Type 2 is the identity, the
machine frame, which G13.1 selects.

The INI sets MACHINE_MOVES_IN_MACHINE_FRAME, so G53, G28 and G30 move
the slides in that machine frame whichever spindle's type is in force.

Demo program:

twin-spindle-holes.ngc -- one subroutine drills a ring of six holes,
each tilted 20 degrees out from the part axis,
into the face of the part the kinematics type
in force works on; the program runs it on the
main spindle (G12.1 P0, G54) and then on the
sub spindle (G12.1 P1, G55). The subroutine
names no rotary: G53.3 turns the ones the type
orients with, and the report on the terminal
reads them by number, #<_kins_orient_1> and
#<_kins_orient_2>, 5 and 4 (C and B) on the
main spindle, 8 and 4 (W and B) on the sub
spindle, with their angles #<_orient_rot1> and
#<_orient_rot2>.

The tool table provides tool 1, length 50. The drawing hands its pivot
length and spindle distance to the kinematics (twinspindle.hal), so the
two agree.
64 changes: 64 additions & 0 deletions configs/sim/axis/vismach/twinspindle/twin-spindle-holes.ngc
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
; twin-spindle-holes.ngc - one subroutine drills the same ring of tilted
; holes into the part in the main spindle and into the part in the sub
; spindle.
;
; Kinematics type 0 works on the main spindle's part and orients the tool
; with C and B; type 1 works on the sub spindle's part and orients it with
; W and B. The subroutine names neither: G53.3 turns whatever rotaries the
; type in force orients with, and the report reads them by number,
; #<_kins_orient_1> and #<_kins_orient_2>, with their angles in the same
; order, #<_orient_rot1> and #<_orient_rot2>. Each part's frame has its Z
; out of its own spindle, so both faces are at Z60 and the offsets read
; the same.

o<ring> sub
#<n> = 6 ; holes
#<r> = 30 ; hole circle radius on the face
#<t> = 20 ; tilt of each hole out from the part axis
#<i> = 0
o101 while [#<i> lt #<n>]
#<a> = [#<i> * 360 / #<n>]
; the hole's plane: origin on the face, X along the hole circle,
; Z the hole axis
g68.2 p3 q1 x[#<r>*cos[#<a>]] y[#<r>*sin[#<a>]] z0 i[-sin[#<a>]] j[cos[#<a>]] k0
g68.2 p3 q2 i[sin[#<t>]*cos[#<a>]] j[sin[#<t>]*sin[#<a>]] k[cos[#<t>]]
g53.2 ; solve the pose, report it
(print, hole #<i>: axis #<_kins_orient_1> to #<_orient_rot1>, axis #<_kins_orient_2> to #<_orient_rot2>)
g53.3 x0 y0 z5 ; orient and go, 5 above the hole
g1 z-10
g0 z5
#<i> = [#<i> + 1]
o101 endwhile
g0 z40
g69
o<ring> endsub

; from one part to the other in the machine frame, the identity type:
; up, clear of both parts, and the head pointing down
o<park> sub
g13.1
g53 g0 x300
g53 g0 z50 b90
o<park> endsub

g21 g90 g94 g17 g40
t1 m6
g43
f300

g10 l2 p1 x0 y0 z60 c0 w0 ; G54, the main spindle's part
g10 l2 p2 x0 y0 z60 c0 w0 ; G55, the sub spindle's part

o<park> call
g12.1 p0 ; the main spindle's part
g54
o<ring> call

o<park> call
g12.1 p1 ; the sub spindle's part
g55
o<ring> call

o<park> call
g54
m2
15 changes: 15 additions & 0 deletions configs/sim/axis/vismach/twinspindle/twinspindle.hal
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
loadusr -W ./twinspindlegui.py

net :jx joint.0.pos-fb twinspindlegui.jx
net :jy joint.1.pos-fb twinspindlegui.jy
net :jz joint.2.pos-fb twinspindlegui.jz
net :jb joint.3.pos-fb twinspindlegui.jb
net :jc joint.4.pos-fb twinspindlegui.jc
net :jw joint.5.pos-fb twinspindlegui.jw

# the drawing and the kinematics share the geometry
net :pivot-len twinspindlegui.pivot_len twinspindlekins.pivot-length
net :spindle-distance twinspindlegui.spindle_distance twinspindlekins.spindle-distance

net :tool-len motion.tooloffset.z twinspindlegui.tool_length
net :tool-diam halui.tool.diameter twinspindlegui.tool_diam
166 changes: 166 additions & 0 deletions configs/sim/axis/vismach/twinspindle/twinspindle.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
[EMC]
VERSION = 1.1
MACHINE = Sim-twinspindlekins (XYZBCW mill-turn, two spindles)
DEBUG = 0

[DISPLAY]
# X Y Z are already the tip in the frame of the part the type works on, so
# the plot takes them as they are: a rotary in GEOMETRY would turn them
# again, and W, a translation there, would draw as a move along Z
GEOMETRY = XYZ
DISPLAY = axis
OPEN_FILE = ./twin-spindle-holes.ngc
INCREMENTS = 10 mm, 1 mm, .1 mm
JOG_AXES = XYZ
CYCLE_TIME = 0.100
POSITION_OFFSET = RELATIVE
POSITION_FEEDBACK = ACTUAL
MAX_FEED_OVERRIDE = 2.0
PROGRAM_PREFIX = ../../nc_files/
INTRO_GRAPHIC = linuxcnc.gif
INTRO_TIME = 2
TOOL_EDITOR = tooledit z diam

[RS274NGC]
RS274NGC_STARTUP_CODE = G17 G21 G40 G49 G54 G80 G90 G94 G97
PARAMETER_FILE = twinspindle.var
# Off the machine frame kinematics (on either spindle's type), G53, G28 and
# G30 move the slides in the machine frame, as G53.5, G28.5 and G30.5 do,
# wherever the tool and the head point, and G28.1 and G30.1 store that
# position. Unset, they move in the world of the spindle's type. See
# MACHINE_MOVES_IN_MACHINE_FRAME in the INI file documentation.
MACHINE_MOVES_IN_MACHINE_FRAME = 1

[EMCMOT]
EMCMOT = motmod
COMM_TIMEOUT = 1.0
SERVO_PERIOD = 1000000

[TASK]
TASK = milltask
CYCLE_TIME = 0.010

[HAL]
HALUI = halui
HALFILE = LIB:basic_sim.tcl
HALFILE = twinspindle.hal

[TRAJ]
COORDINATES = XYZBCW
LINEAR_UNITS = mm
ANGULAR_UNITS = degree
DEFAULT_LINEAR_VELOCITY = 50.0
MAX_LINEAR_VELOCITY = 200.0
MAX_LINEAR_ACCELERATION = 800.0
DEFAULT_LINEAR_ACCELERATION = 800.0
MAX_ANGULAR_VELOCITY = 360.0

[EMCIO]
TOOL_TABLE = twinspindle.tbl

[KINS]
# type 0: the part in the main spindle, C and B orient
# type 1: the part in the sub spindle, W and B orient
# type 2: identity, the machine frame
KINEMATICS = twinspindlekins
JOINTS = 6

[AXIS_X]
MIN_LIMIT = -400
MAX_LIMIT = 500
MAX_VELOCITY = 200
MAX_ACCELERATION = 800

[AXIS_Y]
MIN_LIMIT = -300
MAX_LIMIT = 300
MAX_VELOCITY = 200
MAX_ACCELERATION = 800

[AXIS_Z]
MIN_LIMIT = -300
MAX_LIMIT = 800
MAX_VELOCITY = 200
MAX_ACCELERATION = 800

[AXIS_B]
MIN_LIMIT = -30
MAX_LIMIT = 210
MAX_VELOCITY = 90
MAX_ACCELERATION = 400

# the main spindle
[AXIS_C]
WRAPPED_ROTARY = 1
MIN_LIMIT = -1e9
MAX_LIMIT = 1e9
MAX_VELOCITY = 180
MAX_ACCELERATION = 720

# the sub spindle: an angle, so ANGULAR, however the letter reads
[AXIS_W]
TYPE = ANGULAR
WRAPPED_ROTARY = 1
MIN_LIMIT = -1e9
MAX_LIMIT = 1e9
MAX_VELOCITY = 180
MAX_ACCELERATION = 720

# the joints home to the head over the middle, pointing down at the
# spindle line, clear of both parts
[JOINT_0]
TYPE = LINEAR
MAX_VELOCITY = 200
MAX_ACCELERATION = 800
MIN_LIMIT = -400
MAX_LIMIT = 500
HOME = 300
HOME_SEARCH_VEL = 0
HOME_SEQUENCE = 0

[JOINT_1]
TYPE = LINEAR
MAX_VELOCITY = 200
MAX_ACCELERATION = 800
MIN_LIMIT = -300
MAX_LIMIT = 300
HOME_SEARCH_VEL = 0
HOME_SEQUENCE = 0

[JOINT_2]
TYPE = LINEAR
MAX_VELOCITY = 200
MAX_ACCELERATION = 800
MIN_LIMIT = -300
MAX_LIMIT = 800
HOME = 50
HOME_SEARCH_VEL = 0
HOME_SEQUENCE = 0

[JOINT_3]
TYPE = ANGULAR
MAX_VELOCITY = 90
MAX_ACCELERATION = 400
MIN_LIMIT = -30
MAX_LIMIT = 210
HOME = 90
HOME_SEARCH_VEL = 0
HOME_SEQUENCE = 0

[JOINT_4]
TYPE = ANGULAR
MAX_VELOCITY = 180
MAX_ACCELERATION = 720
MIN_LIMIT = -1e9
MAX_LIMIT = 1e9
HOME_SEARCH_VEL = 0
HOME_SEQUENCE = 0

[JOINT_5]
TYPE = ANGULAR
MAX_VELOCITY = 180
MAX_ACCELERATION = 720
MIN_LIMIT = -1e9
MAX_LIMIT = 1e9
HOME_SEARCH_VEL = 0
HOME_SEQUENCE = 0
1 change: 1 addition & 0 deletions configs/sim/axis/vismach/twinspindle/twinspindle.tbl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
T1 P1 Z50 D10 ;drill
Loading
Loading