Repository navigation
Conversation
A septic time scaling of the path coordinate whose velocity, acceleration and jerk are all zero at both ends, alongside the existing profiles: the trajectory builder, the profile command, the error catalogue, the state and streaming executors, both clients and the README, with tests. It is what par6 moves on too, so the two backends offer the same profile set. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MozxHZWkbgHcaRGMkHnJe9 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016uVshJDKTz7nCqrMGVxVJU
Timed as one polynomial along a cartesian path, SEPTIC sized the whole move from its steepest row. From standby the wrist's turn off its singularity leaves a few degrees of J4 in the path's first row, so a 40 mm MoveL planned 24 s against TOPPRA's 2 s; along a bent path its jerk bound did not hold either. SEPTIC now runs a straight joint run only, on the per-joint polynomial builder it shares with QUINTIC, and a cartesian path or a blended chain is timed by TOPPRA, as with RUCKIG and as par6 does. - VALID_PROFILES and the invalid-profile remedy come from ProfileType. - The async client's robot setter takes any waldoctl Robot, as the interface declares; ty 0.0.86 refuses the narrower one. - The limit test runs a move the jerk limit times, and the velocity test differentiates at the tick the rows are played at. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016uVshJDKTz7nCqrMGVxVJU
Played one row per tick, a bend between rows is a change of joint velocity within a tick, however smoothly a profile times the path coordinate. _enforce_segment_limits sized its acceleration stretch from the velocity-limited segment time, usually far under a tick, so it seldom stretched anything, and TOPP-RA's rows were never checked: a 40 mm MoveL from standby ran J4 at 2.6-4.2x the hard acceleration limit and a blended joint chain its corner at 4-5x, under every path-following profile. Each segment between rows now gets the shortest time, never under a tick, that keeps every joint under its velocity limit and its velocity change between neighbouring segments within a tick of its acceleration limit: a forward and a backward pass over the rows, repeated until neither lowers a rate. TOPP-RA's rows go through it too. A wrist turn ahead of a cartesian path keeps the rest row it ends on, so a joint the path drives back the way the turn came does not reverse within a tick. The async client's robot setter takes any waldoctl Robot, as the interface declares; ty 0.0.86 refuses the narrower one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016uVshJDKTz7nCqrMGVxVJU
A piecewise-linear path tells TOPP-RA its second derivative is zero, so it timed every bend as a straight run, and slowing the sampled rows afterwards could only slow them: a sharp joint-space corner took 4.26 s against 1.44 s for its two legs run apart. As TOTG blends its waypoints, each corner is now a parabolic blend in the path's own parameter, no further from the row than half the finest motor step, so the solver sees the curvature and times it: the corner takes 1.42 s within the limits. - Gridpoints are toppra's proposal joined with the rows, every blend's ends and the midpoints between, and the solution is sampled with ParametrizeConstAccel. - A requested duration stretches the time-optimal solution evenly instead of TOPPRAsd, whose fixed speed margin clamped the narrow blends to a stop. - The row pass stays as a safeguard; it now fires on 1 of 14 measured moves, not 10. - A process move is slowed evenly, keeping its one tool speed, and a requested duration the bends overran is met by the fastest timing slowed evenly when it fits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Co-Authored-By: Codex <noreply@openai.com> Claude-Session: https://claude.ai/code/session_016uVshJDKTz7nCqrMGVxVJU
Reviews found the half-step blends made TOPP-RA crawl through blended MoveJ chains, left LINEAR/TRAPEZOID/QUINTIC to a post-pass that timed bent paths up to 3.6x slower than feasible, and let process moves dip at every corner. - Blends are sized by the tick the rows are played at, and every along-path profile samples the blended path. - A process move's speed cap includes the bends, so it holds one feasible tool speed under every profile. - A requested duration is applied once in build(), as a uniform stretch of the fastest timing; the post-pass runs once on the final rows, prefix seam included. - Corner blends turn the tool at a continuous rate, so a leg that turns the tool no longer forces a constant-speed move to crawl. - Cartesian constraints are evaluated vectorized over fewer gridpoints: MoveL from standby plans in 34 ms, down from 213 ms. - _segment_rates is compiled at warmup. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016uVshJDKTz7nCqrMGVxVJU
A bent path under RUCKIG is timed by TOPPRA, so exempting the RUCKIG profile from the duration stretch dropped the request: 5 s ran in 1 s. Ruckig itself now gets the duration as its minimum. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016uVshJDKTz7nCqrMGVxVJU
…ampling - A requested duration re-times the fastest rows through a C2 spline, so acceleration scales down smoothly instead of arriving in pulses. - QUINTIC along a path eases acceleration in and out at both ends. - Blends on densely sampled smooth paths reach half the knot interval, so process-move timing no longer depends on the sampling pitch. - MoveS eases its turn rate to zero at each waypoint along the geodesic, so it no longer nearly stops where the tool's turn changes. - A timed RUCKIG move lands on the requested tick count without a spurious extension warning. - A blend's curvature holds at its trailing break, so TOP-PRA's own rows stay within the acceleration limit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016uVshJDKTz7nCqrMGVxVJU
Jepson2k
added a commit
that referenced
this pull request
Oct 15, 2026
The interface declares robot as a waldoctl Robot, so a setter narrowed to parol6's Robot is an invalid override to current ty. Same change as #55. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016uVshJDKTz7nCqrMGVxVJU
SEPTIC builds its fastest profile and build() stretches it to a requested duration, the same path QUINTIC now takes, so the _requested_or helper and the old row-by-row duration are gone. The duration-stretch regression test covers SEPTIC beside QUINTIC. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q4aXBLJyxHmGVUxK4KJqgn
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The player plays one row per tick. Wherever the path bends between rows, the joint velocity changes within a single tick, however smoothly a profile times the path coordinate. Every profile that follows a path let joints exceed their acceleration limit at those bends:
_enforce_segment_limitssized its acceleration stretch from the velocity-limited segment time. That time is usually far shorter than a tick, so the check rarely stretched anything.Peak joint acceleration as a multiple of the hard limit, with
accel=0.5, so the allowed peak is 0.5× (shown as before → after):These figures come from the dry-run plan record, whose rows are two ticks apart. At tick resolution, which is what the new test checks, every move stays within the acceleration it asks for.
Changes
_BlendedPath(one degree-2PPoly) turns each corner into a parabolic blend, sized by the tick the rows are played at. TOPP-RA times its curvature, and LINEAR, TRAPEZOID and QUINTIC sample their path coordinate on it rather than on the polyline. A MoveJ chain's path parameter is its joint-space distance, so the density of the Bézier samples doesn't create speed changes.build(). Each profile times its fastest; the post-pass runs once on the final rows, including the seam after a wrist-turn prefix; then a longer request re-times the result through a C2 spline, so acceleration scales down smoothly. Ruckig gets the request as itsminimum_duration._segment_ratesis a safeguard. This forward/backward pass over the played rows guarantees the tick-level limits. Its "Extending duration" message is a WARNING when it adds more than 10%._segment_ratesis compiled at warmup.robotsetter takes any waldoctlRobot(ty 0.0.86), the same change as in Add the SEPTIC motion profile #54.Timing
Every row below stays within the acceleration limit (worst 0.99× the requested acceleration).
Jerk is not bounded here. TOPPRA, LINEAR, TRAPEZOID and QUINTIC have unbounded jerk by design; RUCKIG and (after #54) SEPTIC bound it on the straight joint runs they time.
Tests
All of these enter through
DryRunRobotClient, and the first three fail on the first version of this PR:test_blended_chain_is_no_slower_than_stops_and_respects_acceleration, parametrized over TOPPRA, LINEAR, TRAPEZOID and QUINTIC.test_process_move_holds_a_feasible_tool_speed, parametrized over the same four profiles.test_a_chain_along_one_line_takes_as_long_as_the_one_move: replacestest_blended_chain_is_longer_than_one_move, whose three waypoints lie on one joint-space line.A test that a MoveP whose leg turns the tool plans within 2× the same legs as a MoveL chain. It fails without the rotation blend.
TestDryRunTimingRegressions, added after the second review round. Each test fails on 149c2ca:Locally: 450 passed, 8 skipped. The one failure,
test_msg_mounts_on_the_flange_not_inside_the_wrist, comes fromrtreemissing in the local venv; the dev extra installs it.🤖 Generated with Claude Code
https://claude.ai/code/session_016uVshJDKTz7nCqrMGVxVJU