Skip to content

dotbot/console-web: place pose waypoints and show the waypoint report in the dock - #302

Merged
geonnave merged 13 commits into
DotBots:mainfrom
geonnave:pose-waypoints
Sep 25, 2026
Merged

geonnave merged 13 commits into
DotBots:mainfrom
geonnave:pose-waypoints

Conversation

@geonnave

@geonnave geonnave commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Sits on main: #301 and #298 underneath it have merged. The robot side is DotBots/DotBot-libs#35 and DotBots/DotBot-firmware#428, both merged.

The console side of pose waypoints: a waypoint can now say where the robot stops and which way it faces, placed with one gesture on the map, edited after the fact, and followed in the dock through the robot's own waypoint report.

What changes

  • Every waypoint anchors on the robot's centre, the axle midpoint, as dotbot: send waypoint poses, batch ids and max speed, and read the waypoint report #301 defines it. A plain waypoint draws a centre dot and a faint ring of the robot's reach about its axle, and the robot's board glyph gains an axle dot so the two line up. The console centres a robot on its advertised axle_position when it has one, for turning in place and for placing the body, rather than expanding the fix with the 53.5 mm lever of the geometry record: the firmware's lever is 51.5 mm (fitted to spins), and the 2 mm difference showed on the floor.
  • Placing a pose. Alt + drag, or press and hold 350 ms and then drag, sets the position at the press and the heading along the drag; Shift snaps to 15 degrees. The waypoint is queued on release rather than on press, so Esc, a right-click, or a cancelled or lost pointer (a mouse moving with no button held included) leaves nothing behind; a touch long-press menu does not end a hold, and a press held in place without turning stays a position. The gesture is pure functions in poseGesture.ts; only the hold needs a timer, the ring fills by CSS animation. Starting on a selected robot pins the pose to that robot's axle; on any other robot it is a point on the floor.
  • Pose mode, for where Alt + drag is taken by the window manager and for touch: P or the Pose toggle in the waypoint group, with a visible chip on the map; a plain drag places a pose, Space + drag or two fingers pan, Esc leaves.
  • Editing. A queued pose turns with its nose knob or the mouse wheel over it (one notch or 60 px of trackpad scroll per step); its popover carries a heading field (arrows plus or minus 1 degree, Shift 15, empty or Delete for a plain position). Ctrl/Cmd+Z takes back the last queued waypoint. A queue holds at most 16 points, the firmware's limit, and says so when a 17th is refused. A pose shared by several robots shows a ×N badge and a warning.
  • How a pose looks. The robot's own body outline, turned to the pose, with its axle on the point, from 12 px on screen; below that a circle with an arrowhead, distinct from a plain waypoint's diamond. The shape comes from any robot's body and the orientation from the pose alone, so it no longer flips to the small marker when a robot's heading is unknown. Every waypoint has a hover line such as "Pose 2: face 120°, stop within 10 mm".
  • Waypoint settings in the queue popover: presets of 10, 5, 2 mm (precise) and 1 mm (slow); exact stop and pass radii from 1 to 500 mm; heading tolerance 1 to 45 degrees, or empty for the firmware's 3. Stored per browser. The default stop radius goes from 60 to 10 mm, with a 20 mm pass radius: the robot stops at the edge of the radius it is given, and at 60 mm that was the end-pose error seen on the floor (misses of 51 and 58 mm).
  • Status in the dock: Arrived, Failed or Aborted with the reason in words (the controller's name for it in the tooltip), and "waypoint i of n" while driving, from the robot's report. Robots on apps that send no report keep the old display.

Validation

  • vitest: 636 passed (578 before this work), including the gesture machine (click under 350 ms and 5 px queues a position; hold then drag right queues heading 270; a drag released inside 24 px queues a position; Esc queues nothing; Shift snaps 52 to 45), pose mode, the knob, the wheel steps, popover edits, undo, the settings and the dock status. tsc --noEmit, eslint and npm run build clean. One Python test checks a waypoint's heading survives into the controller's echo.
  • CI: all checks pass.
  • Bench, v3 robot 2426 on the dotbot-next firmware, driven through this branch's controller: 16 single-pose batches at headings 0, 90, 180 and 270, thresholds 10 and 2 mm, all ARRIVED. At 10 mm the axle miss averaged 4.0 mm against LH2 (2.5-6.0); at 2 mm, 2.9 mm (1.1-4.7). Those runs were on the firmware before its brake-aware final turn and showed a heading bias of about +2 degrees; with that fix (drv/steering: sequence waypoint batches with poses, a completion report and a speed limit DotBot-libs#35) 8 poses at 4 headings averaged +0.4 degrees with both signs.
  • Precise arrival from the settings presets, measured with the firmware PRs: mean axle miss 5.6 / 2.6 / 2.1 / 1.5 mm at 5 / 3 / 2 / 1 mm, 22 of 22 arrived.

Known limits and follow-ups

  • Not yet done: a by-hand pass with the browser's touch emulation, and the full pose bench protocol (16 runs per heading from fixed start poses, with a camera witness); the numbers above are 2 runs per heading.
  • With no robot pose on the map at all, a queued pose falls back to the circle-and-arrow, since the console has no built-in body geometry.
  • Docs pending: the console guide and the shortcuts page come with the docs pass after review.

Merge chain

Merged on 2026-09-25: DotBots/DotBot-libs#32, #298, DotBots/DotBot-firmware#425, DotBots/DotBot-libs#33, DotBots/DotBot-firmware#426, DotBots/DotBot-libs#34, DotBots/DotBot-firmware#427, DotBots/DotBot-libs#35, DotBots/DotBot-firmware#428 and #301. The rest go one PR at a time, in this order: this PR, DotBots/DotBot-libs#36, DotBots/DotBot-firmware#429, #303. Next to merge overall: #302, which completes the waypoint batches; then the cut-over, DotBots/DotBot-libs#36, DotBots/DotBot-firmware#429 and #303. Next after this one: DotBots/DotBot-libs#36. Each firmware PR gets a final dotbot-libs: bump to ... merge on main commit, moving its submodule to its libs PR's merge commit on DotBot-libs main, before it merges, as DotBots/DotBot-firmware#425 to DotBots/DotBot-firmware#428 did. The next firmware PR then conflicts on that submodule line, so it is rebased onto main when its turn comes.

+ - Files
Tests (9 console-web test files, dotbot/tests/test_server.py) +1023 -17 10 mapGestures.test.tsx +394 -6, poseQueue.test.tsx +305, poseGesture.test.ts +190
Source, all in dotbot/console-web/src +1714 -61 12 MapView.tsx +638 -23, Footer.tsx +311 -11, PoseMarker.tsx +236, poseGesture.ts +192, arrival.ts +82, App.tsx +75 -13, 6 smaller
Total against main +2737 -78 22

@codecov

codecov Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.25056% with 31 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.12%. Comparing base (20af47d) to head (25c170f).
⚠️ Report is 11 commits behind head on main.

Files with missing lines Patch % Lines
dotbot/console-web/src/MapView.tsx 98.12% 10 Missing ⚠️
dotbot/console-web/src/Footer.tsx 96.76% 8 Missing ⚠️
dotbot/console-web/src/App.tsx 93.84% 4 Missing ⚠️
dotbot/controller.py 95.45% 4 Missing ⚠️
dotbot/console-web/src/api.ts 0.00% 3 Missing ⚠️
dotbot/console-web/src/useFleet.ts 90.00% 1 Missing ⚠️
dotbot/models.py 96.87% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #302      +/-   ##
==========================================
+ Coverage   84.98%   86.12%   +1.14%     
==========================================
  Files         206      209       +3     
  Lines       26002    27904    +1902     
  Branches     1836     2127     +291     
==========================================
+ Hits        22098    24033    +1935     
+ Misses       3897     3864      -33     
  Partials        7        7              
Flag Coverage Δ
console 79.35% <97.97%> (+3.78%) ⬆️
frontend 97.80% <ø> (ø)
python 87.21% <98.97%> (+0.59%) ⬆️

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

Files with missing lines Coverage Δ
dotbot/console-web/src/BotGlyph.tsx 100.00% <100.00%> (ø)
dotbot/console-web/src/PoseMarker.tsx 100.00% <100.00%> (ø)
dotbot/console-web/src/arrival.ts 100.00% <100.00%> (ø)
dotbot/console-web/src/poseGesture.ts 100.00% <100.00%> (ø)
dotbot/console-web/src/shortcuts.ts 98.54% <100.00%> (+0.50%) ⬆️
dotbot/console-web/src/types.ts 100.00% <100.00%> (ø)
dotbot/protocol.py 100.00% <100.00%> (ø)
dotbot/server.py 93.58% <100.00%> (+0.66%) ⬆️
dotbot/tests/test_controller.py 100.00% <100.00%> (ø)
dotbot/tests/test_protocol.py 100.00% <100.00%> (ø)
... and 8 more

... and 1 file 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.

The waypoint now queues on release rather than on press. A waypoint with
a heading anchors on the axle midpoint, not the photodiode, which is how
the controller and the firmware's per-waypoint final heading read it.

AI-assisted: Claude Opus 5.5
A plain waypoint is now where the robot's axle midpoint stops, as a pose
already was, to match the firmware reading every waypoint as an axle
target. The robot's board marks its axle so the two line up.

AI-assisted: Claude Opus 5.5
The robot ends a mission at the edge of the terminal radius and turns
there for a pose, so the old 60 mm radius showed up as end-pose error.
Intermediate points now carry a 20 mm pass radius.

AI-assisted: Claude Opus 5.5
… heading

A pose borrowed its silhouette only from a robot whose pose had a
heading, so a robot reading direction -1000 (fresh start, kidnap) made
every pose fall back to the tick. The shape now comes from any robot's
body and the orientation from the pose alone; small ones are a circle
with an arrowhead, and every waypoint says what it asks on hover.

AI-assisted: Claude Opus 5.5
@geonnave
geonnave marked this pull request as ready for review September 25, 2026 08:23
@geonnave
geonnave merged commit 3a38ee1 into DotBots:main Sep 25, 2026
16 checks passed
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