Add configurable robot protrusions to canvas perimeter rendering#9
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Free Tier Details
You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
Bugbot Autofix prepared fixes for both issues found in the latest run.
- ✅ Fixed: Protrusion config changes skip live canvas update
- Added protrusion config keys to the condition in _on_config_live_change to trigger _apply_robot_dims_from_config for live visual feedback.
- ✅ Fixed: Sim triangle offset uses protrusion-inclusive width
- Changed _build_triangle calls to pass robot body dimensions instead of rect dimensions to keep the direction indicator within the robot body.
Or push these changes by commenting:
@cursor push a31fd4865b
Preview (a31fd4865b)
diff --git a/ui/canvas/items/sim.py b/ui/canvas/items/sim.py
--- a/ui/canvas/items/sim.py
+++ b/ui/canvas/items/sim.py
@@ -49,7 +49,7 @@
self.setFlag(QGraphicsItem.ItemIsMovable, False)
self.setFlag(QGraphicsItem.ItemIsSelectable, False)
self.triangle_item = QGraphicsPolygonItem(self)
- self._build_triangle(float(self.rect().width()), float(self.rect().height()))
+ self._build_triangle(robot_length_m, robot_width_m)
self._angle_radians = 0.0
def set_dimensions(
@@ -66,7 +66,7 @@
y_min = -(width_m / 2.0) - max(0.0, protrusion_right_m)
y_max = (width_m / 2.0) + max(0.0, protrusion_left_m)
self.setRect(x_min, y_min, x_max - x_min, y_max - y_min)
- self._build_triangle(float(self.rect().width()), float(self.rect().height()))
+ self._build_triangle(length_m, width_m)
def _build_triangle(self, robot_length_m: float, robot_width_m: float):
if not self.triangle_item:
diff --git a/ui/main_window/window.py b/ui/main_window/window.py
--- a/ui/main_window/window.py
+++ b/ui/main_window/window.py
@@ -586,7 +586,7 @@
# Track that we had at least one live change during this session
self._config_undo_recorded = True
- if key in ("robot_length_meters", "robot_width_meters"):
+ if key in ("robot_length_meters", "robot_width_meters", "robot_protrusion_front_meters", "robot_protrusion_back_meters", "robot_protrusion_left_meters", "robot_protrusion_right_meters"):
self._apply_robot_dims_from_config(self.project_manager.config)
# Config changes affect simulation constraints/gains; rebuild sim
self.canvas.request_simulation_rebuild()| "robot_protrusion_front_meters": "Robot Protrusion Front", | ||
| "robot_protrusion_back_meters": "Robot Protrusion Back", | ||
| "robot_protrusion_left_meters": "Robot Protrusion Left", | ||
| "robot_protrusion_right_meters": "Robot Protrusion Right", |
There was a problem hiding this comment.
Protrusion config changes skip live canvas update
Medium Severity
The protrusion config keys are added to _get_config_key_label and the config dialog spinners, but _on_config_live_change at line 589 only triggers _apply_robot_dims_from_config when key in ("robot_length_meters", "robot_width_meters"). When a user changes any robot_protrusion_*_meters spinner, the value is saved to disk but _apply_robot_dims_from_config is never called, so the canvas view's robot_protrusion_*_m attributes remain stale, items aren't rebuilt, and the sim robot item isn't resized — no live visual feedback occurs for protrusion changes unlike dimension changes.
| self.setFlag(QGraphicsItem.ItemIsSelectable, False) | ||
| self.triangle_item = QGraphicsPolygonItem(self) | ||
| self._build_triangle(robot_length_m, robot_width_m) | ||
| self._build_triangle(float(self.rect().width()), float(self.rect().height())) |
There was a problem hiding this comment.
Sim triangle offset uses protrusion-inclusive width
Low Severity
_build_triangle is now called with self.rect().width() and self.rect().height() which include protrusions. Inside _build_triangle, triangle_offset = robot_length_m * 0.3 uses this inflated value to position the direction indicator. With asymmetric protrusions, the triangle shifts away from the robot body center into the protrusion area, since the rect origin (0,0) is the body center but the offset is scaled to the full protrusion-inclusive extent. Previously, the actual body dimensions were passed, keeping the triangle within the robot body.



Motivation
Description
robot_protrusion_{front,back,left,right}_meterspersisted inProjectConfigand exposed in the config dialog via new spinners.RobotSimItemto size its rectangle and orientation using protrusion-inclusive extents and add aset_dimensionssignature supporting protrusions._clamp_scene_coords_with_robot_perimeter) so placements are limited by the outermost robot geometry, and adjust sidebar non-overlap sizing to include protrusions when proposing positions.Testing
python -m pytest -q, which completed successfully (4 passed).Codex Task
Note
Medium Risk
Updates multiple geometry paths (canvas element rects, drag constraints, and simulation overlay sizing) to account for new protrusion configuration, which could change on-canvas placement behavior. Risk is limited to UI/visualization and coordinate clamping logic (no auth/data concerns).
Overview
Adds four new robot protrusion config values (
robot_protrusion_{front,back,left,right}_meters) persisted inProjectConfigand editable in the config dialog.Updates rectangle-based canvas items and the simulation overlay to size/position their rectangles (and direction triangles) using protrusion-inclusive extents, and threads these values through
CanvasView.set_robot_dimensions()/RobotSimItem.set_dimensions().Tightens placement constraints by clamping translation/waypoint movement (and rotation/event-trigger projection results) to field bounds including the robot’s full perimeter, and updates sidebar non-overlap positioning to use the protrusion-adjusted footprint.
Written by Cursor Bugbot for commit 53be673. This will update automatically on new commits. Configure here.