Skip to content

FEAT: swap cost model core - #193

Merged
decay71 merged 1 commit into
mainfrom
feat/estimate-engine-core
Oct 24, 2026
Merged

decay71 merged 1 commit into
mainfrom
feat/estimate-engine-core

Conversation

@stefanodangelo

Copy link
Copy Markdown
Collaborator

Estimate lane, slice E1a of 2.

Adds multiace/tools/swap_cost.py, the first half of the swap cost model: how many seconds one swap adds to a print.

  • Mechanical time is computed from ace.cfg (length / speed): the retract, the load and the seat overshoot. Per-ACE and per-slot overrides follow the same precedence as get_swap_retract_length.
  • The terms that can't be computed (tip forming, the ACE's own spool change, heat settle and so on) are named constants in UNMEASURED_S. They are guesses, not measurements. With the shipped ace.cfg defaults they reproduce the existing BG_SWAP_COST_INLINE_S = 210 and BG_SWAP_COST_BG_S = 30.
  • Measured medians take over from the constants only after 5 samples per swap kind. Until then the confidence reads "modelled".
  • Pure stdlib, no imports from ace.py or the post-processor, so the same file can later run in the backend and in the browser worker.

Nothing imports the module yet, so there is no behaviour change. The purge model, header parser and estimate block follow in E1b.

Tests: 16 new tests in tests/unit/test_swap_cost.py (arithmetic from config, background vs inline, overrides, calibration). pytest tests/unit: 257 passed.
Size: 223 lines of code, 117 lines of tests.

@stefanodangelo

Copy link
Copy Markdown
Collaborator Author

What's coming after this PR

This is the first of a stack that builds a preflight time and cost estimate on top of swap_cost.py. I'd send the PRs one at a time, each after the previous one merges, with no more than two open at once. Here is the whole plan so you can say now if you want something dropped or changed.

1. Rest of the engine (next PR)

  • Purge model: the length for each swap comes from a pair override, the colour-aware guess, the slicer's flush matrix, swap_purge_length or the stock 80 mm, in that order. Then the scale, swap_purge_max and purge-bin clamps apply.
  • Slicer header parser.
  • build_estimate, which produces totals, a per-colour breakdown and swap counts.
  • The tools/swap_cost.py line in managed/manifest.json.
  • About 860 lines of code. That is over the usual size, but it is one cohesive file and I'd rather not split it into half-working pieces.

2. Estimate data in preflight (backend only, no UI)

  • Attach the estimate to each plan in preflight_core.py.
  • Cover multifilament copy plans and mixed nozzles.
  • POST /api/preflight/reestimate, so a plan can be recomputed after edits.
  • Serve swap_cost.py from /api/preflight/pysrc so the browser worker can recompute too.

3. Estimate card in the preflight dialog (first UI)

  • Multiace time against the slicer's time, plus filament and purge grams.
  • Cost. Spools with no price are shown at a flagged 20 €/kg.
  • Styled for the classic, dark and light themes.

4. Swap timeline and live recompute

  • A timeline of the swaps.
  • An "estimated" label, since nothing here is measured.
  • The estimate recomputes on every mapping edit.

5. Purge controls (only if you want them)

  • A purge volume scale, per-pair purge overrides, and a slider and grid in Config.
  • The same controls inside the estimate card.
  • I know this overlaps with the flush-matrix purge you already have, so I'd like your call before writing it. It could be an extension of the flush matrix, or it could stay out of upstream.

6. Purge guard (only if you want it)

  • A min/max clamp on every resolved purge.
  • Optional colour-aware scaling, off by default.
  • Purge-bin capacity tracking with a reset command, and the Config controls.
  • It depends on 5, and it also overlaps the existing top-up clamp, so I'm holding it until we've talked.

Groups 2 to 4 come with tests, and the UI ones with screenshots. Nothing changes for users until group 3. Everything in this PR and in group 1 is library code that nothing calls yet.

Happy to reorder, merge or drop any of these. Groups 5 and 6 are the ones where your steer matters most.

@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.

Thank you, merged!

@decay71
decay71 merged commit efe0e0d into main Oct 24, 2026
7 checks passed
@decay71
decay71 deleted the feat/estimate-engine-core branch October 24, 2026 16:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants