Skip to content

dotbot/console-web: draw live robots and turn the site on the floor in the site editor - #346

Open
geonnave wants to merge 86 commits into
DotBots:mainfrom
geonnave:site-editor-live-turn
Open

geonnave wants to merge 86 commits into
DotBots:mainfrom
geonnave:site-editor-live-turn

Conversation

@geonnave

Copy link
Copy Markdown
Contributor

Stacked on #345 (station boxes), and through it on #330, #329, #328, #327, #326, #315 and the LH2 stack to #343. Merges after #345; until then the diff also carries their commits.

Two additions to the site editor, both aimed at fitting a site to the robots as they actually sit on the floor.

Live robots in the console panel. When the editor is opened from the console, it draws the console's robots over the site: positions and headings from the fleet stream the console already has, no new subscription. Positions are only meaningful in the frame of the calibration that produced them, so the layer is hidden, with a note saying why, when the calibration the controller serves records another site or another anchor; robots holding a calibration of another site are left out and counted in the note. With a station box selected (#345), robots are tinted by whether they sit inside it. To make the frame check possible, GET /controller/site now names the served calibration's site and anchor in its calibration block. The standalone dotbot site edit has no fleet, so it has no layer.

Turn site on floor. A site is sometimes drawn rotated relative to how it sits in the room. Turning it moves the frame with everything in it, so no number in site.toml changes except the anchor line: the anchor describes where zero is, and zero has moved. What does change is every calibration of the site, since each maps sweeps to site coordinates. Each chosen calibration is re-expressed by the inverse rigid move (homographies and placement points; station rectangles and fence are site numbers and stay) and saved as a new calibration with edited_from set and a -turned tag. The source files are never written.

  • Tool (key T): angle, pivot (default the middle of the extent), the new anchor text or an appended note of the turn, and which calibrations to turn (default all in the site's frame).
  • CLI: dotbot site turn [SITE] --rotate DEG [--about x,y] (--anchor TEXT | --note) [--calibration ID|TAG ...] [-y].
  • Refusals: no calibration to turn, a 0 degree turn, an anchor text unchanged, a calibration not in the site's frame or hand-edited, a spin centre or placement point landing below zero, and (in the editor) site.toml changed since the page loaded it. Nothing is written unless every chosen calibration can be turned, and the calibrations are written before site.toml, so a failure part way leaves the anchor, and so the frame, as it was.
  • Floor-mark warning: when the anchor is not self-defined, or a calibration was collected at points measured from it, the turn takes zero off something measured in the room. The CLI asks (or takes -y); the editor asks for a confirmation. Points landing outside the extent, and boxes leaving out spin circles, are warnings.
  • It sends nothing. Each new calibration's calibrate-lh2 push line is printed; robots keep the old frame until those are pushed.

Validation. pytest (the reframing math round-trips, every refusal, nothing written on refusal, the anchor-only site.toml edit, CLI and route) and vitest (live layer frame check and hiding note, the turn panel flow); typecheck, lint and build pass. Two failures in the full run are not from this branch: test_camera_service::test_a_registration_without_controls_warns_about_nothing, and nine test_calibration_session tests that need opencv-python, which the local venv lacks; both fail on the base too. By hand: headless browser smoke tests of the live layer and the turn on copies of a real two-station site, with the simulator running 6 robots. The developer then used the turn on a real site, producing calibration 806d1242; beyond that there was no robot-side test of these features.

+ - Files
#345 and everything under it (#330 down to #315 and the LH2 stack to #343), carried underneath (merge separately) +13939 -421 110
This PR, tests +512 -0 5
This PR, source +1121 -45 14
This PR's files + -
dotbot/tests/test_site_turn.py +272 -0
dotbot/calibration/site_turn.py +229 -0
dotbot/console-web/src/siteEditor/TurnPanel.tsx +190 -0
dotbot/console-web/src/siteEditor/siteEditor.test.tsx +187 -0
dotbot/cli/site_cmd.py +159 -24
dotbot/console-web/src/siteEditor/Canvas.tsx +142 -8
dotbot/console-web/src/siteEditor/SiteEditor.tsx +142 -7
dotbot/site_placement.py +100 -3
dotbot/console-web/src/siteEditor/live.ts +37 -0
dotbot/console-web/src/siteEditor/live.test.ts +33 -0
dotbot/console-web/src/siteEditor/types.ts +33 -0
dotbot/console-web/src/siteEditor/api.ts +30 -0
7 small files: App.tsx, Inspector.tsx, types.ts, models.py, site_editor.py, site_toml.py, test_server.py +79 -3
Total, 19 files +1633 -45

AI-assisted: Claude Opus 5.5
AI-assisted: Claude Opus 5.5
… page

Any web page in the browser can send requests to 127.0.0.1 with a valid
Host header, and behind a permissive CORS policy read the replies, so the
Host check alone let it save site.toml; a server bound beyond loopback
took any Host. The peer address, Origin and Sec-Fetch-Site are checked.

AI-assisted: Claude Opus 5.5
…ng tables

A patched file is read back and must give the model that was sent, so a
layout the patcher does not follow is refused rather than written.

AI-assisted: Claude Opus 5.5
Breaking: schema 3 calibration files are refused, so a calibration is
collected again. swarmit's own calibration reader still expects schema 3
and needs its matching change before the dashboard reads these files.

AI-assisted: Claude Opus 5.5
…tangle

Breaking, cross-repo: the messages and the config page (magic SWRP, 872
bytes) only match a swarmit bootloader and net core that store stations
by mask, and swarmit's Python must accept mask messages before it relays
them. Robots below device info 4 are refused with a reflash.

AI-assisted: Claude Opus 5.5
Breaking wire change, landing with DotBot-libs' 16-bit calibrated field:
every advertisement field after the mask moves by one byte and the
vendored dotbot_control.wasm is rebuilt at ABI 3 from that change. With
the one-byte mask, a calibration naming station 8 or above read every
sandbox robot as missing it and resent homographies on each advert.

AI-assisted: Claude Opus 5.5
AI-assisted: Claude Opus 5.5
…leave omitted tables

AI-assisted: Claude Opus 5.5
…anged

placed_from keeps naming the free-frame spin calibration that `--append`
points back to; the calibration an edit was made from is edited_from.

AI-assisted: Claude Opus 5.5
AI-assisted: Claude Opus 5.5
AI-assisted: Claude Opus 5.5
@codecov

codecov Bot commented Oct 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.23778% with 316 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.56%. Comparing base (ddc43f7) to head (af99986).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
dotbot/console-web/src/siteEditor/Canvas.tsx 86.80% 112 Missing ⚠️
dotbot/console-web/src/siteEditor/SiteEditor.tsx 87.31% 110 Missing ⚠️
dotbot/console-web/src/App.tsx 48.97% 23 Missing and 2 partials ⚠️
dotbot/console-web/src/siteEditor/api.ts 88.28% 15 Missing ⚠️
dotbot/console-web/src/siteEditor/main.tsx 0.00% 8 Missing and 1 partial ⚠️
dotbot/console-web/src/siteEditor/Inspector.tsx 98.50% 7 Missing ⚠️
dotbot/console-web/src/siteEditor/edit.ts 96.58% 7 Missing ⚠️
dotbot/cli/swarm_lh2.py 91.80% 5 Missing ⚠️
dotbot/tests/lh2_multi_fixture.py 94.80% 4 Missing ⚠️
dotbot/console-web/dev/fake_swarmit_server.py 0.00% 3 Missing ⚠️
... and 9 more
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #346      +/-   ##
==========================================
+ Coverage   88.21%   88.56%   +0.35%     
==========================================
  Files         227      245      +18     
  Lines       36147    40086    +3939     
  Branches     2324     3126     +802     
==========================================
+ Hits        31886    35502    +3616     
- Misses       4257     4577     +320     
- Partials        4        7       +3     
Flag Coverage Δ
console 84.04% <91.06%> (+2.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
dotbot/cli/main.py 95.83% <ø> (ø)
dotbot/cli/site_cmd.py 91.54% <ø> (-0.04%) ⬇️
dotbot/config.py 98.59% <ø> (-0.29%) ⬇️
dotbot/console-web/src/BotMarker.tsx 100.00% <100.00%> (ø)
dotbot/console-web/src/GridView.tsx 88.20% <100.00%> (-0.22%) ⬇️
dotbot/console-web/src/ListView.tsx 88.78% <100.00%> (+0.64%) ⬆️
dotbot/console-web/src/LocalizationPanel.tsx 86.09% <100.00%> (ø)
dotbot/console-web/src/MapView.tsx 97.63% <100.00%> (+0.09%) ⬆️
dotbot/console-web/src/RightPane.tsx 97.39% <100.00%> (+0.08%) ⬆️
dotbot/console-web/src/botFacts.ts 98.10% <100.00%> (+0.66%) ⬆️
... and 55 more

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

This branch has not been deployed

No deployments
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.

1 participant