This chapter belongs to the multi-channel extension of linuxcncMulti. It
documents what the trajectory planner of this fork offers beyond LinuxCNC
2.9, how to measure its behaviour on CAM-style programs, and the simulated
5-axis gantry used for that. The development concept (German) is
docs/multichannel/bahnplaner.md.
Planner features present in this fork
-
Jerk-limited S-curve profiles.
[TRAJ]PLANNER_TYPE = 1selects the S-curve planner; it needs[TRAJ]MAX_LINEAR_JERK(machine units/s^3, at least 1.0). Every segment is planned with a jerk-limited velocity profile along the path, and the radius of blend arcs is limited so that the lateral jerk stays within the limit. Programs select the smooth planner withG64 R>0;[TRAJ]SMOOTH_PLANNERnames the implementation. -
Look-ahead bounds of the S-curve planner. The look-ahead limits each segment’s end velocity by what the following segment can brake away and by what the segment itself can reach from its start velocity. Earlier versions clamped both bounds to the peak of a rest-to-rest move over the segment, which held short CAM segments (0.2 to 2 mm) at a fraction of the programmed feed; the bounds are now the exact jerk-limited values.
-
Acceleration step at blend arcs.
[TRAJ]MAX_ACCEL_OVL_FACTOR(0 to 1, default 1.0, HAL pinini.traj_max_accel_ovl_factor) is the counterpart of Siemens MD32310: with the S-curve planner, the normal acceleration may jump at the ends of a blend arc up to this factor of the acceleration limit, so blend arcs are run atv = sqrt(f * a_n * R)like with the trapezoidal planner, while the motion along the arc stays jerk-limited. With 0 the planner keeps the strict model that limits every blend arc by the lateral jerk of its entry; on a 1 ms servo thread that holds blend arcs between 25 and 60 mm/s whatever the radius, andG64 Pbecomes slower than exact stop. -
Per-axis jerk limits
[AXIS_x]MAX_JERKand[JOINT_n]MAX_JERKare read and exported as HAL pins (ini.x.max_jerk,ini.N.max_jerk). Like velocity and acceleration, the jerk limit of every linear move is derived from the limits of the axes that move (the axis with the longest characteristic time sets the move’s jerk), so a move along the slowest axis never exceeds that axis' jerk;[TRAJ]MAX_LINEAR_JERKis the upper bound for the path. Blend arcs use the path limit. Under non-identity kinematics the joint limits are applied separately, see below. -
Look-ahead. Each channel has a queue of 2000 segments. When a segment is queued, the planner walks back over
[TRAJ]ARC_BLEND_OPTIMIZATION_DEPTHsegments (default 50) and raises the end velocities of the queued segments as far as the following segments allow. -
Blending. Tangent segments are joined directly, other transitions get a blend arc within the
G64 Ptolerance. Line-line transitions with rotary (ABC) or UVW motion are blended as well: the blend carries the rotary motion between its end points on a quintic Hermite curve that takes over the rate of each line at its end and has zero acceleration there, so the orientation rate and acceleration stay continuous, and the neighbouring lines are trimmed in all coordinates. The blend is limited by the rotary axes' velocity, acceleration and jerk limits and by the joint limits of the kinematics. Pure rotary segments and arcs with rotary motion still blend parabolically. -
Curvature-continuous blends.
[TRAJ]BLEND_TYPE = POLY(defaultARC, HAL pinini.traj_blend_type, 0 = ARC, 1 = POLY) replaces the blend arc between two lines by a polynomial of degree 7 whose tangent, curvature and change of curvature match the lines at both ends (G3), the counterpart of Siemens G642 with SOFT. The normal acceleration then ramps up and down inside the blend instead of jumping at the ends of an arc, the lateral jerk starts from zero at the junctions, so the joint jerk at corners stays within the limits andMAX_ACCEL_OVL_FACTORhas no effect on these transitions. The blend uses the wholeG64 Ptolerance; its speed is limited by the peak curvature (normal acceleration) and by the peak change of curvature (lateral jerkv^3 dk/ds), which makes a corner slower than the arc with its allowed acceleration step: the price of a jerk-limited corner. The jerk budget of the blend is split between the velocity profile (tangential, 0.5) and the curvature change (lateral, 0.866) so that their sum stays within the limit. Rotary and UVW motion is carried as with the arc. Transitions that involve a programmed arc, and corners sharper than 160 degrees, keep the blend arc. The simconfigs/sim/multichannel/portal_bcruns withPOLY. -
Merging micro-segments with rotary motion. The naive CAM detector (
G64 Q, the tolerance defaults toP) merges consecutive lines that stay within the tolerance of one straight line. In standard LinuxCNC any ABC or UVW motion ends the chain, so 5-axis CAM programs, which change the orientation in every block, were never merged.[RS274NGC]G64_DEFAULT_ORITOLERANCE(degrees, default 0 = standard behaviour) also chains such lines when the orientation of every merged point stays within that angle of the merged line’s linear orientation interpolation; UVW motion is held to the length tolerance. Merged lines give the blends room and halve the number of transitions. -
Spline compressor.
[RS274NGC]COMPRESSOR = OFF|LINE|SPLINE(defaultLINE, the naive CAM detector;OFFmerges nothing). WithSPLINE, the counterpart of Siemens COMPCAD with ORISON, the feed blocks of aG64program are collected in groups of up to 256 and fitted with a cubic B-spline in all nine coordinates: every programmed point stays within theG64 Qtolerance (defaultP) of the curve, the orientation withinG64_DEFAULT_ORITOLERANCE, and the curve stays within the tolerance of the polyline between the points plus the polyline’s own faceting there (the chord error of the CAM program). The planner gets the spline as cubic Bezier pieces (segment type TC_BEZIER) that are curvature-continuous across all junctions, also from group to group. A group ends at a corner (deflection above 15 degrees), at a block without XYZ motion, when the buffer is full, and at everything that interrupts the path (feed change,G61,G0, M-codes); where the path goes on smoothly the next group continues the spline, a corner leaves the ends free and the planner takes the kink. A group the fit cannot hold within the tolerances is sent as lines. Pieces with rotary motion need an orientation tolerance; a program whose orientation has kinks (rate limited by the CAM) forces the fit to nearly every point there.
Joint limits under a non-identity kinematics
The planner plans in world coordinates. With a swivel head (5axiskins)
or a kinematic transformation (TRAORI) the joints move differently from
the tool centre point: a change of the head orientation swings the pivot
and adds to the linear joints. Before the fix the benchmark gantry ran its
X joint at twice its acceleration limit and five times its jerk limit on a
5-axis surface program.
Every linear and circular segment is now sampled with the inverse
kinematics when it is queued (motion.kins-limit-samples, s32 in, default
12 samples, at most 16; 0 switches the check off). From the joint displacement per unit
of path and its first, second and third change, the segment’s velocity,
acceleration and jerk limits are reduced so that every joint of the
channel stays within its [JOINT_n] limits: the joint acceleration
q'' v^2 + q' a and the joint jerk q''' v^3 + 3 q'' v a + q' j are
evaluated at every sample with the segment’s limits. Blends are sampled
too and the line before a blend keeps to the blend’s acceleration limit.
This is the Siemens behaviour of limiting the path feed from the
machine-axis limits under TRAORI. Identity kinematics are not sampled.
HAL pins for planner diagnostics
motion.tp-queue-depth(s32, out)-
Number of segments in channel 0’s planner queue.
motion.N.tp-queue-depthgives the same for channel N. A depth that keeps dropping to 0..2 while the program runs means the interpreter does not deliver segments as fast as the machine consumes them (short segments, slow task cycle); the planner then has to stop at the end of every segment.
Simulated 5-axis gantry with BC head
configs/sim/multichannel/portal_bc/portal_bc.ini is a gantry router with
a BC swivel head on the 5axiskins kinematics (pivot length 250 mm, tool
length from the tool table via G43). X runs at 60 m/min on a rack, Y at
50 m/min, Z at 25 m/min, 3 m/s^2 and 60 m/s^3; B tilts +/-120 degrees, C is
continuous. The S-curve planner with arc blending and a look-ahead depth of
100 is enabled. portal_bc.ini starts AXIS with the vismach model,
portal_bc_bench.ini is the headless variant for the benchmark.
Simulated 5-axis machining centre DMU 60
configs/sim/multichannel/dmu60/dmu60.ini is a vertical machining centre
in the DMU 60 eVo layout: X/Y/Z in the column and head (600/500/500 mm,
50 m/min, 6 m/s^2, jerk 100 m/s^3), a swivel rotary table with B (-5 to
+110 degrees about Y) and C (endless) in the bed, spindle 18000 rpm. The
kinematics is xyzbc-trt-kins (table rotary tilting): the program is
written in the workpiece frame and the controller turns it with the
table (TCP; the tool length of G43 goes into the kinematics so that the
table turns about the tool tip). Every path optimisation is enabled:
PLANNER_TYPE = 1 with MAX_LINEAR_JERK, BLEND_TYPE = POLY, look-ahead
100, COMPRESSOR = SPLINE with G64_DEFAULT_ORITOLERANCE = 0.5 and
motion.kins-limit-samples = 16 for the joint check of B and C at the
tilted table. The window is mchmi with the 3D column (vismach model
dmu60_model.py, the blank on the table with material removal in the
workpiece frame, [WORKPIECE_0]FRAME = TCP); dmu60_bench.ini is the
headless variant for the benchmark.
A second channel (WECHSLER, axes A and W on joints 5 and 6) is the
automatic tool changer with a 30-place disc magazine and a double
gripper: nc_files/wechsler.ngc is the channel’s event program (power-on,
reset), which retracts from an interrupted change and then serves the
prepare / change requests of iocontrol.0 (through HAL, dmu60.hal)
in an endless loop (see the ASUP section of the configuration chapter
and the tool management chapter), so T.. M6 in the machining channel
waits for the magazine disc and the gripper.
The tool management (WZ-Liste, mctooldb) belongs to the machining
channel alone, with the magazine and the gripper places of
[TOOLMAG_0] / [TOOLBUFFER_0]. In motion, channel 0 keeps the
kinematics module (the TCP transformation) in the multi-channel loops
as well.
nc_files/gen_impeller.py writes the programs: impeller.ngc (an
impeller D120 with 7 backswept blades: contour roughing in Z layers with
full circles, the channels roughed 5-axis with the ball mill leaning 25
degrees outward in arc strips from the outside in, the blade flanks
finished along their ruling lines; 8000 moves), impeller_stl.ngc (the
same on a preformed blank from impeller_rohteil.stl) and
impeller_kurz.ngc (one layer, one channel, one blade; the test
tests/multichannel/dmu60). The blank is defined in the program with
the SINUMERIK statement WORKPIECE (G-code chapter). For a table-table
machine a tool axis d = (sin b cos phi, sin b sin phi, cos b) in the
workpiece frame is programmed as B = b, C = 180 - phi degrees; the
generator writes C continuously.
Programs of the gantry
The sample programs in nc_files/ are generated by
tests/trajectory-planner/bench/gen_programs.py:
freeform_5axis.ngc-
Zig-zag finishing of a wavy surface with G1 segments of 0.2 to 2 mm, the tool axis follows the surface normal. B and C are derived from the normal in the 5axiskins convention (B polar angle from +Z, C azimuth, kept continuous, tilt limited to 25 degrees).
freeform_3axis.ngc-
The same path with the head fixed.
corner_g64.ngc-
Squares with 90 degree corners under
G64 P0.05.
Planner benchmark
tests/trajectory-planner/bench/run_bench.py runs these programs headless
on the gantry, records one sample per servo cycle with halsampler (path
speed, tool centre point, joints, program line, queue depth, servo thread
runtime) and evaluates them with analyze.py:
. scripts/rip-environment python3 tests/trajectory-planner/bench/run_bench.py --out /tmp/bench-before
The result results.md lists per program the duration, the mean and
minimum path speed, the share of time below 80 % and 50 % of the
programmed feed, the maximum acceleration and jerk of every joint against
the INI limits, the queue depth statistics and the servo thread load.
Two revisions are compared by running the benchmark into two directories.
The benchmark is not part of runtests.