Skip to content

S-curve planner (PLANNER_TYPE=1): velocity/acceleration "peaking" on dense micro-segment G-code, worse on 2nd+ run of the same file #4194

Description

@greatEndian

Environment

  • LinuxCNC master (853878b, also reproduces on 2.10.0~pre1)
  • Realtime: uspace (POSIX), RIP build
  • Config: stock configs/sim/axis/axis_mm_scurve.ini, PLANNER_TYPE=1, MAX_LINEAR_JERK=10000, MAX_VELOCITY=300, MAX_ACCELERATION=1000, SERVO_PERIOD=1000000 (1 ms), ARC_BLEND_ENABLE=1, ARC_BLEND_RAMP_FREQ=20 (default)

Description

With the S-curve planner enabled, running a dense micro-segment program (CAM output — thousands of short consecutive G1 segments along a smooth contour) produces a ragged, oscillating commanded joint velocity and acceleration ("peaking"), instead of the smooth profile the S-curve should give.

Two distinct, reproducible characteristics:

  1. Run-to-run difference: the first run after startup is smooth; the 2nd and subsequent runs of the same file are visibly rough/"clingy", with the same G-code, same machine, same start.
  2. Accumulation: on a longer run, even the first run is smooth at the start and degrades toward the end; reruns are rough from the start.

PLANNER_TYPE=0 (trapezoidal) does not show the dramatic peaking — only a small, comparable ripple. So this is specific to the S-curve path.

Steps to reproduce

  1. axis_mm_scurve.ini, PLANNER_TYPE=1, defaults as above.
  2. Load a dense micro-segment .ngc (many short G1 moves forming a curve; happy to attach the test file).
  3. Scope joint.N.vel-cmd on halscope.
  4. Run the file; note it is smooth. Run it again — the velocity command is now rough/oscillating.

Expected vs actual

  • Expected: smooth, jerk-limited velocity/accel, identical run-to-run.
  • Actual: oscillating velocity/accel that differs between the first and subsequent runs and worsens over long runs.

Ruled out during investigation

  • Not RT latency: servo-thread.time is stable throughout (no growth/jitter increase) while the velocity is ragged — the planner is genuinely commanding the rough velocity.
  • Not following-error-driven, not config feed-override/timing (changing feed override does not affect it), not homing state.

Investigation notes (hypothesis — for maintainers)

The roughness is in the per-segment target/acceleration handling of short tangent segments:

  • tpActivateSegment() sets accel_mode = TC_ACCEL_RAMP for tangent segments whose segment_time = 2·length/(currentvel + finalvel) is below cutoff_time = 1/ARC_BLEND_RAMP_FREQ. This decision uses the live entry velocity (currentvel), so borderline short segments flip between ramp and non-ramp mode run-to-run (entry velocity differs slightly), which matches the run-to-run nondeterminism.
  • tpCalculateRampAccel() applies a constant acceleration and is not jerk-limited, so ramp-mode segments inject acceleration steps on the S-curve path.
  • Empirically, raising ARC_BLEND_RAMP_FREQ (e.g. to 250) — which makes far fewer segments use ramp mode — substantially reduces the peaking, supporting the above, but it does not fully eliminate it on longer programs.

Possible directions: don't use the non-jerk-limited ramp accel_mode when PLANNER_TYPE==1; and/or make the ramp/no-ramp decision independent of live currentvel so it is deterministic across runs.

Image Image

1_1001.txt

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions