Skip to content

LinuxCNC 2.10 - Acceleration limit violations during blending of small G3 segments #3773

@thomam04

Description

@thomam04

Summary:
I am observing significant acceleration limit violations during the execution of small G3 segments (Radius ~4mm) in LinuxCNC 2.10 Master. The trajectory planner generates commands that exceed the MAX_ACCELERATION limit by up to 8x.

Environment:
Version: 2.10 Master (latest as of Feb 1st 2026)
Servo Cycle: 1 kHz (1000 µs)
EtherCAT in CSP Mode
Setup: Bench test (motors not mounted). This allows for clearly audible "knocking" sounds during the spikes, indicating extreme jerk levels.
GCode: 5114.txt (change G64 Pxxx during testing)

5114.txt

Observed Data:
Measurements were taken via a HAL component monitoring joint.N.vel-cmd.
INI Limit: 1750 mm/s²
At G64 P0.01: Peak Accel ~3381 mm/s² (1.9x limit)

Image

At G64 P0.1: Peak Accel 14219.86 mm/s² (8.1x limit)
Max Jerk (P0.1): 14,137,730 mm/s³

Image

Key Findings:
P-Value Paradox: Increasing the blending tolerance (P) correlates with significantly higher acceleration spikes rather than smoother motion.
Software-Side Issue: The spikes originate in the velocity command, ruling out drive tuning or hardware latency.
Reproducibility: The error is consistent and occurs at the same coordinates (e.g., X87.89 Y147.45) in every run.

Please review if the blending logic in v2.10 Master is correctly enforcing acceleration invariants for small arc segments. Problem does not exist in 2.98

HAL Connections:

loadrt spike_tester names=spike

addf spike.fp servo-thread

net x-joint-cmd joint.0.pos-cmd => spike.current-x
net y-joint-cmd joint.1.pos-cmd => spike.current-y
net y-vel-cmd joint.1.vel-cmd => spike.vel-cmd

Set "spike.accel-limit" in HALSHOW during testing or via setp spike.accel-limit

Measurement Tool (HAL Component)

component spike_tester "Detects velocity/acceleration spikes in physical units";

/* Measurement tool for LinuxCNC 2.10 Trajectory Planner stability.
   Calculates real-time acceleration (mm/s2) and jerk (mm/s3). */

include <rtapi_math.h>;

pin in float vel_cmd "joint.N.vel-cmd (mm/s)";
pin in float current_x "Current X (G54 incl.)";
pin in float current_y "Current Y (G54 incl.)";
pin in float accel_limit "INI Limit (mm/s2)";

pin out float max_accel_mms2 "Peak acceleration (mm/s2)";
pin out float max_jerk_mms3 "Peak jerk (mm/s3)";
pin out float fault_x "X at first violation";
pin out float fault_y "Y at first violation";
pin out u32 spike_count "Number of violations";
pin io bit reset "Reset peaks and counters";

variable double last_v;
variable double last_a;

function fp;
license "GPL";
;;

FUNCTION(fp) {
    double cur_a = fabs(vel_cmd - last_v) / fperiod;
    double cur_j = fabs(cur_a - last_a) / fperiod;

    if (reset) {
        max_accel_mms2 = max_jerk_mms3 = spike_count = fault_x = fault_y = 0;
        reset = 0;
    }

    if (cur_a > max_accel_mms2) max_accel_mms2 = cur_a;
    if (cur_j > max_jerk_mms3) max_jerk_mms3 = cur_j;

    if (cur_a > accel_limit) {
        spike_count++;
        if (fault_x == 0 && fault_y == 0) {
            fault_x = current_x;
            fault_y = current_y;
        }
    }
    last_v = vel_cmd;
    last_a = cur_a;
}





Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions