Skip to content

WIP: Bowden path calibration - reworked flow, encoder-based distance, new-design theming - #168

Open
physicsG wants to merge 15 commits into
decay71:mainfrom
physicsG:feat/bowden-path-calibration
Open

physicsG wants to merge 15 commits into
decay71:mainfrom
physicsG:feat/bowden-path-calibration

Conversation

@physicsG

@physicsG physicsG commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Work in progress. This runs on my U1 (one ACE 2 Pro, head mode), but it still needs more testing before it should be merged. See "Testing" at the bottom. Opening it as a draft so you can look at the direction.

It builds on my previous bowden-path calibration work that was ported into main, is merged up to 1.27b, and does three things: it answers the feedback on the first version, it fixes a few problems that turned up while doing so, and it aligns the calibration tab with the new design.

The feedback this started from

The length measurement worked well. These were the issues, each with what this PR does about it:

Issue Resolution
Splitter retract only goes backwards; an overshoot means starting over. The forward steps are already in main. Added: a hold-to-pull-back button for the long stretch, labelled steps in both directions, a Stop that keeps the distance covered, and undo for the hub mark.
Verification needs manual jogging to the toolhead in small steps. The verification feed carries on by itself, up to 200 mm past the saved distance, until the toolhead sensor trips. Manual steps are only the fallback after that.
The jogged distance is not added to the saved value. A sensor position more than 10 mm from the saved distance replaces it for the rest of the round trip and in the values offered for saving.
The second verification round did not reach the toolhead and aborted. Two causes, two fixes. The search above covers a shortfall. And on ACE 2 Pro the distance now comes from the lane encoder, which removes the over-retract behind the shortfall (see below). On ACE Pro, without an encoder, the over-retract remains and only the search helps.
Re-measurement is not automatic. It is now: same mechanism as the two rows above. The result panel then says "Verification changed the values".
Measuring one slot still requires checking the others. Not sure I understood this one. Setup now only picks ACE, slot and toolhead, a measurement starts with one click, the two confirmation steps are gone and reinserting the filament is a hint. I did not find a step that makes you check other slots, so tell me where it happens if this is not it.
The flow assumes centimetre accuracy that ACE transport does not deliver. Handled with margins rather than with more precision: see the next two rows. The full retract is the one value saved exactly as measured.
Load length has no margin on top of the measured value. Default margin is 150 mm (was 20). The feed stops at the toolhead sensor anyway.
Swap retract risks stopping short of the splitter. Default margin is 100 mm (was 20), capped below the full retract with a note when that happens. At the hub stop during verification you can pull back further, and that distance is added to the saved value.

What else turned up

  • The measured distance was rounded up to the step size. Position was commanded speed x elapsed time, counted from when the command was queued. The ACE starts late, so the estimate ran ahead and was capped at the chunk length: results landed on the 100 mm grid, and the return then over-retracted by the same amount (my verification needed 50 to 60 mm more than the measurement). On V2 the lane encoder is now the position source in the feed direction, with one more reading after the lane has stopped. V1 keeps the time estimate.
  • The encoder restarts with every motion command, and a reading requested right behind the command can still hold the previous move's value. That inflated the return span (1976 counts for 1400 mm in my log). Those readings are now ignored, and each move logs commanded vs encoder distance.
  • A stopped, cancelled or failed run left the filament in the tube with no way back, and the UI then allowed a new measurement from there. New: ACE_CALIBRATION_STOP / RESUME / HOME, a recovery bar in the UI ("Carry on" / "Return filament to the ACE"), and a new run or an ACE_LOAD_HEAD is refused while calibration filament is still in the tube.
  • ACE_UNLOAD_HEAD CALIBRATION_PREPARE=1 was not wired up in main. The web UI sends it and the helpers exist, but cmd_ACE_UNLOAD_HEAD never read it, so the preparation unload could not be cancelled. Restored, together with the cancel checkpoints in _run_tipform and the abort on print start and Klippy disconnect.
  • A standstill-guard failure could be overwritten by the state that followed it.
  • After saving, "verify saved values" ran on the values Klipper still had loaded. Verification is now blocked until the printer has restarted, and the result panel has a restart button.
  • The measuring feed limit hung on the configured load_length (+300 mm), the very value being measured. It is now +1000 mm.
  • Verification no longer stops at the toolhead (the sensor has already confirmed it). It stops once, at the hub, where you can answer "not clear, pull back more"; that distance is added to the hub clearance.

Theme alignment

The calibration tab was painted with style.css's fixed dark colours and rounded cards in every design. style-new.css now has a calibration section under html[data-theme="new"]:

  • square, line-drawn surfaces and the heading sizes of the Spools and Config tabs;
  • colours only through the design tokens, so the light shade needs no rules of its own;
  • outlined buttons, accent fill for the one next step;
  • a phone-width layout (vertical route, table that fits) for the classic and the new design.

The classic design is unchanged apart from the phone-width rules. All calibration strings are in the en and de catalogs; zh has no calibration section and falls back to English.

Open questions

  • When to switch CALIBRATION_TAB? It is set to true now.
  • Vocabulary in the UI is now: park position, hub, toolhead distance, hub clearance, margin (was preload reference / splitter / anchor / allowance).

Testing

Run on one U1 with one ACE 2 Pro in head mode. Not tested yet:

  • ACE Pro (V1, no encoder) on hardware
  • multi mode and more than one ACE

Screenshots

From the web UI on the printer. The setup and "check this route" screens are live; the mid-run screens were captured with a test state injected into the page, no filament was moved for them.

Setup: only the route
Setup

Measure, step 2: clear the hub
Clear the hub

Verify: ready
Verify ready

Verify: the one stop, at the hub, with "pull back more"
Verify hub stop

Results: saved, measured, margin, will save
Results

Stopped mid-run, light shade of the new design
Stopped, light shade

physicsG added 15 commits August 7, 2026 14:11
Upstream absorbed the bowden-path calibration feature in cf4e538 and
extended it (FEED_JOG, i18n, generic sensor discovery), so main's
versions are taken for every conflicted file.

Re-applied on top of main's ace.py, since upstream's copy lacks them
while its web UI still sends them:
- ACE_UNLOAD_HEAD CALIBRATION_PREPARE=1 ACE= SLOT= handling (route
  validation, unknown-source recovery, cancellable preparation unload)
- cancel checkpoints in _run_tipform
- calibration abort on print start and klippy disconnect
Upstream ships the tab hidden behind CALIBRATION_TAB = false.
…gins

Verification no longer stops dead at the saved toolhead distance. It runs
one long move to 150 mm short of it, then 50 mm steps up to 200 mm past
it until the toolhead sensor trips. A sensor position more than 10 mm
from the saved distance replaces it for the rest of the round trip and
for the proposed config values; manual jogging remains only as the
fallback after the automatic search.

Default margins on the saved values go from 20/20 mm to 150 mm (load)
and 100 mm (swap retract), the swap retract is capped below the full
retract, and a session primed from saved values no longer adds the swap
margin a second time on apply.
The measuring feed and the verification feed booked distance as commanded
speed x elapsed time, counted from when the command was queued. The ACE
starts late, so the estimate ran ahead and was capped at the chunk length:
results landed on the 100 mm (measure) / 50 mm (verify) grid, rounded up,
and the return then over-retracted by the same amount.

On V2 the per-command lane encoder is now the position source in the feed
direction, with one more reading after the lane has stopped at the sensor.
A reading requested right behind a motion command can still hold the
previous command's value; those are ignored, which also fixes the inflated
return encoder span. With a working encoder the verification feed is one
continuous move again. V1 keeps the time estimate.

Also: a standstill-guard failure is no longer overwritten by the state
that follows it, reset is refused during a forward jog, each move logs
commanded vs encoder distance, and the UI marks a time-estimated tip as
such and holds it back instead of showing the splitter as passed early.
Printer side
- ACE_CALIBRATION_STOP halts any calibration move and books the distance
  it covered; ACE_CALIBRATION_RESUME carries on a stopped feed, return or
  verification.
- ACE_CALIBRATION_HOME pulls the filament back to the ACE from wherever a
  stopped, cancelled or failed run left it. A new run is refused while
  calibration filament is still in the tube, and so is ACE_LOAD_HEAD.
- RETRACT accepts long pulls (hold-to-pull-back), MARK=undo removes the
  hub mark, the return is one move.
- Verification no longer stops at the toolhead; at the hub stop the user
  can pull back further (ACTION=hub_jog) and that distance is added to
  the hub clearance.
- The measuring feed is one move once the lane encoder has reported, and
  its limit no longer hangs on the configured load length (+1000 mm).

Web UI
- Setup only picks the route; where the result is saved is chosen in
  Results, next to the save button.
- One click starts a measurement; reinserting the filament is a hint.
- Hub step: hold-to-pull-back, labelled steps in both directions, one
  button that marks and returns, undo during the return.
- A recovery bar offers carry on / return filament to the ACE whenever a
  run is stopped.
- Results: one table (saved, measured, margin, will save), a note when
  the hub clearance is capped or slots keep their own values, a restart
  button after saving, and no save button when nothing changed.
- Route diagram drawn to scale, one vocabulary, all strings in the en/de
  catalogs.
The calibration tab was painted with style.css's fixed dark colours and
rounded cards in every design. style-new.css now gives it the square,
line-drawn look of the other tabs under html[data-theme="new"], using
only the design tokens, so the light shade follows without rules of its
own. The classic design is unchanged.

Also: while the hub position has not been measured yet, the diagram
treats the two tubes as the two halves of the route and marks the hub as
not measured, instead of drawing the tip before a hub it may have passed.
Below 560 px the route runs top to bottom; the new design's 2 px tube
rule had collapsed the tubes there. Tubes get a fixed height again with
their lengths beside them, the step chips stay in one row, and the
results table drops the "saved now" column and the sub-lines so it fits
without scrolling sideways. Applies to the classic and the new design.
@decay71

decay71 commented Oct 13, 2026

Copy link
Copy Markdown
Owner

Direction looks right, thanks. I have pulled the branch onto my dev tree for hardware tests (ACE Pro, multi mode, stop/resume/home); results in a few days. The missing CALIBRATION_PREPARE handling is a real gap on my side, good catch. Tab on is fine. Ping me when it is out of draft.

@physicsG physicsG added the enhancement New feature or request label Oct 13, 2026
@decay71
decay71 marked this pull request as ready for review October 17, 2026 10:24
@decay71
decay71 self-requested a review as a code owner October 17, 2026 10:24

@decay71 decay71 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, the encoder rework does what it should, the measurement on the ACE 2 is spot on. Here is what came up on the rest of our rig (2x ACE 2 Pro, 2x ACE Pro, head mode, build 256eaa1b):

  1. ACE 2: measurement works. Encoder distance 1749 mm, verify found the toolhead sensor at exactly 1749, 100 mm retract steps count 97 to 98. The 100 mm grid problem is gone.
  2. ACE Pro: the hold button unloaded the spool. Pressing it sent unwind_filament len=2297, the release 0.7 s later sent stop_feed_filament (answered success), but the ACE Pro kept unwinding the full length: on V1 that command stops a feed, not an unwind. The calibration assumed ~21 mm, so "Return filament to the ACE" unwound another 2276 mm and the filament left the unit (gate went empty). Please stop unwinds on V1 with stop_unwind_filament (not used anywhere in multiACE yet, so verify it on hardware), or drop the hold button on V1 and keep the bounded steps.
  3. After that the session was stuck. Starting the next calibration (ACE 2) ended in splitter checkpoint must be before the ACE preload reference: the old session still held the inflated retract count. A failed or abandoned run should reset cleanly. Also, the web showed the raw Moonraker JSON with the traceback instead of just the message.
  4. The "Coarse" row is not understandable. Nothing says it is a hold button until it is pressed; it reads like a step size next to the 5/10/25/100 buttons. Please label it as what it is. Or make it a start / stop, i can't press my mouse and check the printers cabling, they are not next to each other. Suggestion: one line for the path from the ACE to the head with a handle at the current tip position. Drag it left or right to the target and on release move exactly that difference as one bounded command. Easier to read, and it also removes the unbounded V1 unwind from point 2.
  5. Verify checks the raw measurement, not what gets saved. It feeds load_length and retracts swap_retract_length without the margins. It should run the values that will be written (load +150, swap retract +100), the swap retract is the one used on every swap.
  6. Saving forces a restart flow that does not fit. After saving you confirm a restart twice, but no restart happens, and until one does you cannot get back into the calibration. A restart is not needed right away anyway. Please just save, show a note that the new values apply to loads and swaps after the next restart, and let the user go on with the next ACE or slot. Then everything gets calibrated and the printer restarts once at the end.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants