-
Notifications
You must be signed in to change notification settings - Fork 135
Visualizer Update v1.0 #864
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
multi-channel wip, integrated arm wip
previously described as "modules" but there are so many meaning of modules and it has no self-explaining connotation
…zation - LiquidHandler: replace single `_resource_pickup` with `_resource_pickups` dict keyed by arm index, with backward-compatible property for arm 0 - LiquidHandler: only create head96 trackers when `core96_head_installed` is True - LiquidHandler: serialize head96_state and arm_state (resource name, type, direction, dimensions) for downstream consumers (e.g. visualizer) - LiquidHandler: register _state_updated callback on head/head96 trackers, and fire it on pick_up_resource / drop_resource - LiquidHandler: guard pick_up_resource with RuntimeError if no arm installed - Backends: add `num_arms` attribute to STARBackend, ChatterboxBackend, STARChatterboxBackend (configurable `iswap_installed` param) - TipTracker: propagate state-update callback to tip's volume tracker on commit() Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…robot into pr/multi-arm-head96
Resource names flow from the Python backend into innerHTML, allowing vectors like <img src=x onerror=...> to execute arbitrary JS. Use textContent + DOM element creation instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
_handle_state_update_callback wrote to _pending_state_updates from arbitrary threads while _flush_state_updates read it on the event loop. This could lose updates when a thread wrote to the dict between the flush clearing it and resetting _flush_scheduled. Move all dict writes onto the event loop via call_soon_threadsafe so both enqueue and flush are single-threaded. Preserves batching behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
set_state was calling buildResourceTree() which destroys and recreates the entire sidebar DOM on every state change (e.g. a single well volume update). Use the existing updateSidepanelState() for each changed resource instead, which does a targeted DOM update via querySelector. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
setup() was globally enabling tip and volume tracking, silently overriding user settings. This is the caller's responsibility. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
inspect.signature was called for every method of every resource instance. For a 96-well plate that's 97 × ~50 calls. Take the class as argument instead and cache with lru_cache since all instances share the same methods. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The string-replace approach (': Infinity' -> ': "Infinity"') could
false-positive on resource names containing that substring. Use
allow_nan=False with a custom default handler instead.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The allow_nan=False + default handler approach doesn't work because
float('inf') is a native float type — json raises ValueError before
the default handler is ever called. Revert to the original string
replacement which handles this correctly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Updates the PyLabRobot Visualizer UI and backend event/serialization to support a richer interface (toolbars/sidepanel, source name + favicon, actuator panels) and reduce UI churn by batching state updates.
Changes:
- Enrich resource serialization with public method signatures and recursively serialized children.
- Add configurable visualizer header name/favicon and an optional “show actuators at start” event.
- Update JS/HTML/CSS for a revamped layout (toolbars, sidepanel/tree, zoom controls) and more defensive state handling.
Reviewed changes
Copilot reviewed 5 out of 10 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| pylabrobot/visualizer/visualizer_tests.py | Updates tests to match new serialization helper and additional startup event. |
| pylabrobot/visualizer/visualizer.py | Adds method-enriched serialization, UI metadata injection (name/favicon), actuator startup event, and batched state updates. |
| pylabrobot/visualizer/vis.js | Updates root rendering workflow, sidepanel/tree updates, snapshots on unassign, and handles new show_actuators event. |
| pylabrobot/visualizer/main.css | Major UI styling additions for new navbar/toolbars/sidepanel and overlays. |
| pylabrobot/visualizer/index.html | Adds favicon link, cache-busting query params, new toolbar/sidepanel layout, and new UI panels/controls. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
No description provided.