dotbot: report every robot a camera sees, paced to a share of a core - #300
Merged
Merged
Conversation
AI-assisted: Claude Opus 5.5
AI-assisted: Claude Opus 5.5
AI-assisted: Claude Opus 5.5
Breaking: a camera detection record carries `robots`, a list of
{address, status, timestamp, pose}, in place of the single `pose`. The
camera CSV writes one row per robot with cam_address, cam_status and
cam_timestamp under schema_version 2, so an older log is not appended to.
AI-assisted: Claude Opus 5.5
…spector AI-assisted: Claude Opus 5.5
A greedy nearest-first pairing lets a lagging fix take the neighbour's candidate and leaves the robot's own fix to split that neighbour, so two robots swap names. A fix sharing a component too small for two robots now names nothing instead of copying its host's pose. AI-assisted: Claude Opus 5.5
A robot is marked lost only after 60 s of silence, and until then its last fix could name whichever robot now stands where it was. Each fix is also read once, since the position is replaced whole by another thread. AI-assisted: Claude Opus 5.5
AI-assisted: Claude Opus 5.5
AI-assisted: Claude Opus 5.5
A reader slower than the stream that keeps every part builds a backlog in the socket buffers, seconds deep, and stamping at receipt hides it. The X-Timestamp header lets a reader age each frame and drop stale ones. AI-assisted: Claude Opus 5.5
AI-assisted: Claude Opus 5.5
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #300 +/- ##
==========================================
+ Coverage 84.65% 84.98% +0.32%
==========================================
Files 204 206 +2
Lines 25336 26002 +666
Branches 1822 1836 +14
==========================================
+ Hits 21449 22098 +649
- Misses 3880 3897 +17
Partials 7 7
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
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 camera detector used to report one robot per frame. It now fits every robot-shaped candidate on a frame and names each from the robots' lighthouse (LH2) fixes, reporting up to
camera_max_robotsof them (2 by default). Robots whose fix stands on a candidate are kept first. The console draws every camera robot and its heading, on the map and in the inspector.Detection rate held to a share of a core
Detection cost grows with the number of robots on the frame, so a fixed rate either wastes the idle case or saturates the busy one. The detector now measures its own cost (smoothed) and schedules the next run so that it holds, on average,
camera_detect_shareof one core (0.4 by default): rate = share / cost, capped at 10 Hz and floored at 0.5 Hz. The rate falls as robots are added or the machine gets busy and recovers when either goes away.Measured cost on a real bench frame:
OpenCV runs some of this multithreaded, so process CPU is about 1.2x the wall time measured here; the share is a wall-time budget, not an exact CPU cap.
Both knobs are
[controller]config keys anddotbot run controllerflags (--camera-max-robots,--camera-detect-share), bounded to>= 1and(0, 1].Naming robots correctly
Review of the first cut turned up ways two robots could swap or copy names, fixed here:
Frame capture time
Each part of the MJPEG camera stream now carries an
X-Timestampheader, the time the frame was read off the device. A reader slower than the stream builds a backlog in the socket buffers that can be seconds deep, and stamping on receipt hides it; with the capture time a reader can age each frame and drop stale ones.Breaking change
A camera detection record carries
robots, a list of{address, status, timestamp, pose}, in place of the singlepose. The camera CSV writes one row per robot withcam_address,cam_statusandcam_timestampunderschema_version2, so an older log is not appended to. Anything reading the oldposefield or the schema 1 CSV needs updating.Changes
dotbot/camera/detection/robot.pydotbot/camera/detection/pose.pydotbot/camera/rate.pydotbot/camera/service.pydotbot/controller.pydotbot/controller_app.pydotbot/csv_data_logger.pydotbot/models.pydotbot/console-web/src/MapView.tsxdotbot/console-web/src/Inspector.tsxtest_camera_detection.py,test_camera_rate.py,test_camera_service.py,test_controller.py,test_csv_data_logger.py,test_server.py,cameraLayer.test.tsx,inspector.test.tsdetection/__init__.py,config.py,server.py,test_config.py,RightPane.tsx,cameraLayer.ts,localization.ts,localization.test.ts,types.ts,useFleet.test.tsValidation
dotbot/testspass, including new tests for the matcher, the rate controller, the service and the CSV schema. The only local failures are environment ones unrelated to this branch (a user config file present, port 8000 taken).tsc --noEmit, eslint, vitest (578 tests) andvite buildpass.