Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
125 commits
Select commit Hold shift + click to select a range
2213a8d
Phase 0: Tormach 9D Architecture Port
grandixximo Jan 25, 2026
8f2ed93
Phase 1: Move Kinematics to Userspace
grandixximo Feb 1, 2026
bf01634
Phase 3: Feed Override and Motion Planning Optimization
grandixximo Feb 13, 2026
d7ba515
Force Kin in Uspace for Planner Type 2
grandixximo Feb 13, 2026
63708e1
Fix freezing in place
grandixximo Feb 13, 2026
d0467ca
small cleanup
grandixximo Feb 13, 2026
87b9e0c
Derive feed override deferral timing from servo cycle and scale durat…
grandixximo Feb 13, 2026
cadd242
Proper state reset for each run
grandixximo Feb 13, 2026
739bf87
Chain-based downstream constraints and feed limiting for branch compu…
grandixximo Feb 14, 2026
097a9fa
fix end spike
grandixximo Feb 14, 2026
0a05e81
Fix Profile v0 Mismatch
grandixximo Feb 15, 2026
480c41e
Fix Centripetal Acceleration Bound to kink_vel
grandixximo Feb 15, 2026
5f9f15a
Fix velocity chain gaps at junctions and improve feed override stability
grandixximo Feb 15, 2026
888eefe
lines get kink vel like arcs
grandixximo Feb 15, 2026
4537992
Add alt-entry profiles and fix sub-cycle brake transitions
grandixximo Feb 16, 2026
4b2f184
Virtual arc for line-line junctions
grandixximo Feb 16, 2026
80979f9
Eliminate stale feed-override profiles with one-shot cursor and v0-aw…
grandixximo Feb 16, 2026
1e4b7f8
Remove the hardcoded kinematics_type_id_t enum that prevented custom
grandixximo Feb 17, 2026
cffa9cd
G64 first draft
grandixximo Feb 17, 2026
79f68de
Refactor Kinematics one file per module
grandixximo Feb 17, 2026
82931b6
refined kins docs
grandixximo Feb 17, 2026
f3707b8
Blending refinements
grandixximo Feb 18, 2026
21ec2ea
Joint-space feedforward via finite differences for planner type 2
grandixximo Feb 20, 2026
0313ea4
C2 curvature matching and path deviation for Bezier blends
grandixximo Feb 20, 2026
198f9e9
Curvature-matched blends and path deviation measurement
grandixximo Feb 20, 2026
48df81e
G0/G1 blend guard, kink_vel fix, and tangential jerk budget
grandixximo Feb 20, 2026
15452c4
Collinear segment consolidation for CAM toolpaths
grandixximo Feb 20, 2026
cea1d44
Queue depth gate: eliminate velocity spike at segment activation
grandixximo Feb 20, 2026
277db67
Fix abort freeze: bypass handoff margin for stop requests in computeB…
grandixximo Feb 21, 2026
0955f3a
Bidirectional reachability cap: eliminate Working profiles from fixup…
grandixximo Feb 21, 2026
0053e69
Fix split-cycle elapsed_time advance: prevent velocity dip on short s…
grandixximo Feb 21, 2026
ccbb989
attempt at fixing arm build
grandixximo Feb 21, 2026
202757e
Refactor blend projection calculations in tpSetupBlend9D to normalize…
grandixximo Feb 21, 2026
09427ee
Refactor bezier9PathDeviation to enforce distance to corner for stric…
grandixximo Feb 21, 2026
63ae4c6
Fix feed override junction velocity mismatches in downstream profile …
grandixximo Feb 22, 2026
6b3c16b
Add near-active v0 reconciliation (Step 4) to fix stale-predecessor j…
grandixximo Feb 23, 2026
3a0c459
Fix feed override crash/recovery spikes with alt-entry chain and clea…
grandixximo Feb 23, 2026
41403bb
Harden split-cycle junction velocity: jerk-based v0 cap, physical cla…
grandixximo Feb 23, 2026
9e5edc4
Fix alt-entry flythrough bail blocking junction segments during feed …
grandixximo Feb 23, 2026
aad4dde
Invalidate stale alt-entries at writeAltEntry convergence break
grandixximo Feb 23, 2026
7d4dc0d
Fix feed hold spill-over spikes with debounce exemption and branch-aw…
grandixximo Feb 24, 2026
3b50934
fix slowdown
grandixximo Feb 24, 2026
0a1de5a
Fix abort spill-over negative velocity with physics-based acceleratio…
grandixximo Feb 24, 2026
d1c7366
rolled back refactor of bezier9
grandixximo Feb 24, 2026
36c9c32
Fix Bezier 9D tangent weighting, arc-length parameterization, and G0↔…
grandixximo Feb 25, 2026
a95817b
Cubic Hermite arc-length interpolation for Bezier blends
grandixximo Feb 25, 2026
73bb605
Reject stale-feed alt-entry profiles at RT junction handoff
grandixximo Feb 25, 2026
269f585
spike prediction
grandixximo Feb 26, 2026
1da5b84
defer
grandixximo Feb 26, 2026
c189668
startup strategy
grandixximo Feb 26, 2026
2565247
guard on less than 0.001
grandixximo Feb 26, 2026
86f3e8c
dynamic debounce
grandixximo Feb 26, 2026
49a046f
accept closer vel
grandixximo Feb 26, 2026
cdb580a
fixed 183 pattern
grandixximo Feb 26, 2026
496d124
before rearch
grandixximo Feb 27, 2026
f7d215b
simplified
grandixximo Feb 27, 2026
4715662
fixed feed-override seeding spike
grandixximo Feb 27, 2026
5129353
new helper fixupPass
grandixximo Feb 27, 2026
6496c5d
pause and stop unified
grandixximo Feb 27, 2026
de30f5a
fix resume spikes: backward fixup end_idx covers full DS range
grandixximo Feb 28, 2026
e9c8101
refactor
grandixximo Feb 28, 2026
b1b4f8d
100% ok
grandixximo Feb 28, 2026
6340d63
200% ok
grandixximo Feb 28, 2026
2a2a24f
fix unable to start
grandixximo Feb 28, 2026
5d35044
feed override struct
grandixximo Feb 28, 2026
57e15d5
fix backward/forward velocity inconsistency at v_f≈0 junctions
grandixximo Feb 28, 2026
7cc8c30
fix abort rogue segment: reset compressor before stop branch
grandixximo Mar 1, 2026
4970634
fix feed-override velocity oscillation: remove self-reinforcing min caps
grandixximo Mar 1, 2026
6746547
remove backward pass depth limit: fix feed-change spikes on deep queues
grandixximo Mar 1, 2026
a774492
gate-based feed coalescing: eliminate cross-feed frontier spikes
grandixximo Mar 1, 2026
b30e2fc
better fail handling, better 10%
grandixximo Mar 2, 2026
246394d
drop feed to 10% ok
grandixximo Mar 2, 2026
2c0425b
90 and 100% ok
grandixximo Mar 2, 2026
a74b1ab
fix STOP/EXACT spike
grandixximo Mar 3, 2026
addf680
cleanup some debug
grandixximo Mar 3, 2026
1278f1c
fixed some spikes due to wrong capping
grandixximo Mar 3, 2026
8a4fe06
fix bidir spikes
grandixximo Mar 3, 2026
f68a5f1
fixed corridor-kink pattern spikes
grandixximo Mar 3, 2026
a3c67a0
better 0%
grandixximo Mar 3, 2026
549a247
removed debug
grandixximo Mar 3, 2026
ed787b9
fixed freezing up on non-tangent
grandixximo Mar 3, 2026
2dc0e22
FINALIZED gate: prevent segment activation before boundaries known
grandixximo Mar 4, 2026
f8e4fe7
removed spike debug
grandixximo Mar 4, 2026
399c8e8
chain-split: fix short-segment lost-time jerk spikes
grandixximo Mar 5, 2026
69922ec
reinstated cubic for planner type 2
grandixximo Mar 5, 2026
ac101d2
fix C1 discontinuity from collinear consolidation after blend trim
grandixximo Mar 5, 2026
ac8e58b
fix premature FINALIZED gate on G-code mode change
grandixximo Mar 6, 2026
c19ae47
fix include paths after upstream rebase (relative paths for non-INCLU…
grandixximo Mar 6, 2026
a2b00ed
fix ARM build: remove spurious SRCHEADERS (tp/kinematics headers cove…
grandixximo Mar 6, 2026
406adf7
fix initraj.cc: use qualified motion/motion.h path for ini/ directory
grandixximo Mar 6, 2026
ebe08c3
fix include paths in motion_planning: use relative ../tp/ and motion/…
grandixximo Mar 6, 2026
1d982c6
fix remaining flat includes in motion_planning: blendmath.h and motio…
grandixximo Mar 6, 2026
99f44fa
convert all kinematics modules to nonrt_attach architecture
grandixximo Mar 6, 2026
27c873f
replace hal_priv.h/SHMOFF/self_offset with hal_struct_newf/attach API
grandixximo Mar 7, 2026
3a59f24
refactor hal_struct to use a dedicated namespace
grandixximo Mar 7, 2026
c5b5bdd
fix hal_struct: indentation, comp->ready check, duplicate/detach errors
grandixximo Mar 8, 2026
b567d1f
hal_struct: add man3 pages and halcmd show/list struct support
grandixximo Mar 8, 2026
207e7f9
hal_struct: fix man page: use AsciiDoc source, not hand-written troff
grandixximo Mar 8, 2026
fb7fec8
fix velocity spikes at segment junctions under feed override
grandixximo Mar 8, 2026
f85a0e1
hal_struct man page: add volatile to example, ignore generated .3 files
grandixximo Mar 8, 2026
b6d2161
Add comp_kins_uspace.h glue for .comp kinematics planner type 2 support
grandixximo Mar 14, 2026
0d07c0d
Fix header-sanity: align with bertho's include isolation model
grandixximo Mar 14, 2026
e17cc0a
fix blend jerk overshoot: partition tangential+centripetal budget per…
grandixximo Apr 7, 2026
ca71459
port TP2 userspace planner from C++ Ruckig to cruckig
grandixximo Apr 7, 2026
b2575db
Build warning fix, and cruckig compatibility fix
grandixximo Apr 7, 2026
5de22f3
Register motion_planning public headers with HEADERS for make clean
grandixximo Apr 12, 2026
a27aef6
Bezier tolerance to match TP0 distance from corners and not just enti…
grandixximo Apr 7, 2026
7b35219
Fast bezier init for blend optimizer + skip RT ack for planner type 2
grandixximo Apr 9, 2026
c1878ff
Fix uninitialized read in bezier9MaxCurvature when called via bezier9…
grandixximo Apr 10, 2026
c1ff6a2
TP2: short-segment blend guard fix + blend sizing improvements
grandixximo Apr 12, 2026
b48d7e9
Move comp_kins_uspace.h from include/ to src/emc/kinematics/
grandixximo Apr 12, 2026
0770336
Fix author signatures: aitekcnc → LinuxCNC
grandixximo Apr 12, 2026
7124d30
Fix backward pass using wrong kink_vel junction — tc exit kink leaked…
grandixximo Apr 12, 2026
10df744
Add standalone TP2 jerk analysis tests
grandixximo Apr 13, 2026
a51b517
Fix blend velocity mismatch on short segments + simulator improvements
grandixximo Apr 13, 2026
e90cd80
Fix bezier blend maxvel exceeding curvature-jerk budget
grandixximo Apr 13, 2026
e2befbd
Fix build: don't wrap motion.h in extern "C" (pulls in <atomic>)
grandixximo Jun 24, 2026
f57e152
Fix -Werror build failures exposed by CI
grandixximo Jun 24, 2026
c12c247
Fix RT kernel-module build: drop userspace <string.h> from kinematics
grandixximo Jun 24, 2026
e7a7b56
Fix RTAI build and emcmot-error-mpsc test
grandixximo Jun 24, 2026
6020ee3
Fix RTAI cbrt and cppcheck redundant null-check warnings
grandixximo Jun 24, 2026
21adb91
Zero-init planner structs via value-init instead of memset
grandixximo Jun 24, 2026
eb172d4
check_ini: allow PLANNER_TYPE=2 (9D planner)
grandixximo Jun 26, 2026
035c899
motion_planning: blend segment inherits source line id from prev_tc
grandixximo Jul 5, 2026
6959043
motion_planning: fix chain-cap safe-endpoint test (stop-decel jerk sp…
grandixximo Jul 5, 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
1 change: 1 addition & 0 deletions docs/po4a.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@
[type: AsciiDoc_def] src/man/man3/hal_export_funct.3.adoc $lang:build/adoc/$lang/man/man3/hal_export_funct.3.adoc
[type: AsciiDoc_def] src/man/man3/hal_init.3.adoc $lang:build/adoc/$lang/man/man3/hal_init.3.adoc
[type: AsciiDoc_def] src/man/man3/hal_malloc.3.adoc $lang:build/adoc/$lang/man/man3/hal_malloc.3.adoc
[type: AsciiDoc_def] src/man/man3/hal_struct_newf.3.adoc $lang:build/adoc/$lang/man/man3/hal_struct_newf.3.adoc
[type: AsciiDoc_def] src/man/man3/hal_param_alias.3.adoc $lang:build/adoc/$lang/man/man3/hal_param_alias.3.adoc
[type: AsciiDoc_def] src/man/man3/hal_param_new.3.adoc $lang:build/adoc/$lang/man/man3/hal_param_new.3.adoc
[type: AsciiDoc_def] src/man/man3/hal_parport.3.adoc $lang:build/adoc/$lang/man/man3/hal_parport.3.adoc
Expand Down
104 changes: 102 additions & 2 deletions docs/src/config/ini-config.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -944,8 +944,13 @@ Finally, no amount of tweaking will speed up a tool path with lots of small, tig
* `MAX_LINEAR_VELOCITY = 5.0` - (((MAX VELOCITY))) The maximum velocity for any axis or coordinated move, in 'machine units' per second.
The value shown equals 300 units per minute.
* `MAX_LINEAR_ACCELERATION = 20.0` - (((MAX ACCELERATION))) The maximum acceleration for any axis or coordinated axis move, in 'machine units' per second per second.
* `PLANNER_TYPE = 0` - (((PLANNER TYPE))) Selects the trajectory planner type: 0 = trapezoidal (default), 1 = S-curve with jerk limiting.
S-curve planning is only active when `PLANNER_TYPE = 1` AND `MAX_LINEAR_JERK > 0`.
* `PLANNER_TYPE = 0` - (((PLANNER TYPE))) Selects the trajectory planner type:
** 0 = trapezoidal velocity profile (default)
** 1 = S-curve with jerk limiting
** 2 = 9D jerk-limited planner with Ruckig library (see <<sub:ini:sec:traj:9d-planner,9D Planner>>)
+
S-curve planning (type 1) is only active when `PLANNER_TYPE = 1` AND `MAX_LINEAR_JERK > 0`.
The 9D planner (type 2) provides time-optimal jerk-limited trajectories with responsive feed override handling.
* `MAX_LINEAR_JERK = 10000.0` - (((MAX JERK))) The maximum jerk (rate of change of acceleration) for coordinated moves, in 'machine units' per second cubed.
Default is 1e9 (1 billion) if not specified, which effectively disables jerk limiting while avoiding numerical instability.
Values are clamped to a maximum of 1e9 to prevent numerical issues in S-curve calculations.
Expand Down Expand Up @@ -980,6 +985,101 @@ LinuxCNC will not know your joint travel limits when using `NO_FORCE_HOMING = 1`
* `NO_PROBE_JOG_ERROR = 0` - Allow to bypass probe tripped check when you jog manually.
* `NO_PROBE_HOME_ERROR = 0` - Allow to bypass probe tripped check when homing is in progress.

[[sub:ini:sec:traj:9d-planner]]
==== 9D Jerk-Limited Planner (PLANNER_TYPE = 2)

The 9D planner is an advanced trajectory planning system that uses the Ruckig library
for time-optimal, jerk-limited motion profiles. It features a dual-layer architecture
with userspace planning and real-time execution, providing responsive feed override
handling without motion discontinuities.

[NOTE]
====
The 9D planner is an experimental feature. Use `PLANNER_TYPE = 2` to enable it.
This planner is recommended for machines that require smooth motion with jerk limiting,
and responsive feed override changes during motion.
====

===== Basic 9D Planner Parameters

* `PLANNER_TYPE = 2` - Selects the 9D jerk-limited trajectory planner.
This enables the Ruckig-based motion planning with userspace optimization.
* `OPTIMIZATION_DEPTH = 8` - Number of segments to look ahead for velocity optimization (range: 4-200, default: 8).
Higher values allow the planner to achieve higher velocities on longer paths
by planning deceleration further in advance.
* `RAMP_FREQUENCY = 10.0` - Cutoff frequency in Hz for ramped velocity mode (range: 1.0-1000.0, default: 10.0).
Segments shorter than 1/RAMP_FREQUENCY seconds use constant acceleration instead
of trapezoidal profiles to reduce jerk on very short moves.
* `SMOOTHING_PASSES = 2` - Number of velocity smoothing passes (range: 1-10, default: 2).
Additional passes reduce velocity peaks but may slightly reduce maximum throughput.
* `TC_QUEUE_SIZE = 50` - Size of the trajectory queue (range: 32-400, default: 50).
Larger queues allow more look-ahead but use more memory.
===== Predictive Feed Override Handoff Parameters

These parameters control the branch/merge architecture for handling feed override changes.
When the operator adjusts the feed override, the planner computes a new trajectory
branch in userspace and hands it off to the real-time layer at a predicted future time.
This allows smooth velocity transitions without motion discontinuities.

* `HANDOFF_HORIZON_MS = 100` - How far ahead (in milliseconds) to predict the handoff point (range: 1-1000, default: 100).
This value must exceed the worst-case userspace latency to ensure the new trajectory
is ready before the real-time layer reaches the handoff point.
Typical values: 50-200ms depending on system load.
* `BRANCH_WINDOW_MS = 50` - Window size (in milliseconds) for RT to accept the branch (range: 10-500, default: 50).
The real-time layer must reach the handoff point within this window after HANDOFF_HORIZON_MS
to accept the new trajectory. If the window expires, the branch is discarded.
* `MIN_BUFFER_TIME_MS = 100` - Minimum buffered motion time before alarm (range: 10-1000, default: 100).
If the motion buffer drops below this value, a warning is generated.
Very short buffer times risk motion starvation.
* `TARGET_BUFFER_TIME_MS = 200` - Target buffered motion time (range: MIN_BUFFER_TIME_MS-2000, default: 200).
The optimizer aims to maintain at least this much motion in the buffer.
* `MAX_BUFFER_TIME_MS = 500` - Maximum buffered motion time (range: TARGET_BUFFER_TIME_MS-5000, default: 500).
The optimizer stops adding new segments when the buffer exceeds this value.
* `FEED_OVERRIDE_DEBOUNCE_MS = 50` - Minimum time between branch computations (range: 1-500, default: 50).
When the operator rapidly changes the feed override (e.g., with a rotary knob),
this debounce prevents excessive recomputation. After computing a branch,
the planner waits this long before computing another.

===== Example 9D Planner Configuration

[source,{ini}]
----
[TRAJ]
# Basic trajectory settings
LINEAR_UNITS = mm
ANGULAR_UNITS = degree
MAX_LINEAR_VELOCITY = 100.0
MAX_LINEAR_ACCELERATION = 2000.0
MAX_LINEAR_JERK = 50000.0

# Enable 9D planner
PLANNER_TYPE = 2

# 9D planner tuning
OPTIMIZATION_DEPTH = 16
RAMP_FREQUENCY = 20.0
SMOOTHING_PASSES = 2
TC_QUEUE_SIZE = 100

# Predictive handoff tuning (optional - defaults work well for most systems)
# HANDOFF_HORIZON_MS = 100
# BRANCH_WINDOW_MS = 50
# MIN_BUFFER_TIME_MS = 100
# TARGET_BUFFER_TIME_MS = 200
# MAX_BUFFER_TIME_MS = 500
# FEED_OVERRIDE_DEBOUNCE_MS = 50
----

[NOTE]
====
The 9D planner automatically uses the servo cycle time from `[EMCMOT]SERVO_PERIOD`
and jerk limits from `MAX_LINEAR_JERK`. If `MAX_LINEAR_JERK` is not specified,
a default of 50000 (units per second cubed) is used.

Per-joint jerk limits can also be specified in `[JOINT_N]MAX_JERK` sections.
The planner uses the most restrictive limit for each move.
====


[[sub:ini:sec:kins]]
=== [KINS] Section(((INI File,Sections,KINS Section)))
Expand Down
110 changes: 110 additions & 0 deletions docs/src/man/man3/hal_struct_newf.3.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
:manvolnum: 3

= hal_struct_newf(3)

== NAME

hal_struct_newf, hal_struct_attach, hal_struct_detach - named opaque blobs in HAL shared memory

== SYNTAX

int hal_struct_newf(int _comp_id_, long int _size_, const void *_defval_, const char *_fmt_, _..._)

int hal_struct_attach(const char *_name_, void **_memptr_)

int hal_struct_detach(const char *_name_)

== ARGUMENTS

_comp_id_::
A HAL component identifier returned by an earlier call to *hal_init*.

_size_::
The number of bytes to allocate in HAL shared memory for the data blob.

_defval_::
A pointer to an initialiser of _size_ bytes that is copied into the
newly allocated blob. If NULL the blob is zero-initialised.

_fmt, ..._::
A printf-style format string and arguments that form the name of the entry.
The resulting name must be no longer than HAL_NAME_LEN characters.

_name_::
The name of the struct entry to find, as passed to *hal_struct_newf*.

_memptr_::
Address of a pointer that will be set to point at the data blob on success.

== DESCRIPTION

HAL struct entries are named, reference-counted opaque blobs that live in HAL
shared memory. They occupy a separate namespace from pins, signals, and
parameters and are therefore not visible in *halcmd show pin* or
*halcmd show param* output. Use *halcmd show struct* to inspect them.

*hal_struct_newf* allocates _size_ bytes from HAL shared memory, optionally
initialises the region from _defval_ (or zeroes if NULL), and registers it
under the printf-formatted name. The function must be called before
*hal_ready(3)*. There is no corresponding delete function; the data lives for
the lifetime of the HAL shared memory block. The entry metadata is reclaimed
automatically when the owning component calls *hal_exit(3)*.

*hal_struct_attach* finds the entry by name, increments its reference count,
and stores a pointer to the data blob in _*memptr_. It may be called from
both realtime and userspace contexts after *hal_init(3)*.

*hal_struct_detach* decrements the reference count. Calling it when the
reference count is already zero is an error. The data is not freed.

== RETURN VALUE

All three functions return 0 on success. On failure they return a negative
HAL status code:

*-EINVAL*::
Bad argument, duplicate name (*hal_struct_newf*), component is already ready
(*hal_struct_newf*), or detach underflow (*hal_struct_detach*).

*-ENOMEM*::
Name too long, or HAL shared memory exhausted.

*-ENOENT*::
No entry with the given name found (*hal_struct_attach* or *hal_struct_detach*).

== EXAMPLE

RT side (in _rtapi_app_main_):

----
typedef struct { double value; int count; } my_params_t;
static volatile my_params_t *params;

my_params_t defaults = { 1.0, 0 };
if (hal_struct_newf(comp_id, sizeof(*params), &defaults,
"%s.params", prefix) < 0)
return -1;
if (hal_struct_attach(prefix ".params", (void **)&params) < 0)
return -1;
----

Userspace side:

----
volatile my_params_t *params;
if (hal_struct_attach("mycomp.params", (void **)&params) < 0)
return -1;
/* read params->value, params->count ... */
hal_struct_detach("mycomp.params");
----

The pointer should be declared `volatile` on both sides so the compiler does
not cache fields across accesses. Note that `volatile` alone does not
guarantee memory ordering between threads or processes. For fields that must
be read and written atomically (for example a sequence-lock head/tail pair),
use C11 `_Atomic` or explicit `__atomic_*` intrinsics with an appropriate
memory order.

== SEE ALSO

hal_init(3), hal_malloc(3), hal_exit(3), halcmd(1)
Loading
Loading