Skip to content

refactor: make MovementManager click limits configurable (#2013)#2116

Open
JoeCardoso13 wants to merge 2 commits into
dimensionalOS:mainfrom
JoeCardoso13:refactor/movement-manager-configurable-click-limits
Open

refactor: make MovementManager click limits configurable (#2013)#2116
JoeCardoso13 wants to merge 2 commits into
dimensionalOS:mainfrom
JoeCardoso13:refactor/movement-manager-configurable-click-limits

Conversation

@JoeCardoso13
Copy link
Copy Markdown

Problem

MAX_CLICK_HORIZONTAL_M / MAX_CLICK_VERTICAL_M in MovementManager were
module-level constants, so users rendering very large maps couldn't raise the
click-to-goal clamp without editing source.

Solution

Move both into MovementManagerConfig (defaults unchanged: 500.0 / 50.0), and
read them via self.config.* in _on_click. No behavior change at default
settings.

Addresses the first item of #2013. The other two bullets of #2013
(locks → async, publish-only-to goal) are intentionally left out to keep this
PR single-purpose;

Breaking Changes

None.

How to Test

uv run pytest dimos/navigation/movement_manager/test_movement_manager.py
(7 pass, including 2 new tests covering lowered/raised limits).

Contributor License Agreement

  • I have read and approved the CLA.

MAX_CLICK_HORIZONTAL_M / MAX_CLICK_VERTICAL_M were module-level constants. Move them into MovementManagerConfig so they can be set per-run for users rendering very large maps. Defaults unchanged.

Addresses the first item of dimensionalOS#2013.
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 16, 2026

Greptile Summary

This PR moves MAX_CLICK_HORIZONTAL_M and MAX_CLICK_VERTICAL_M from module-level constants into MovementManagerConfig, making them runtime-configurable while preserving the existing defaults (500.0 m and 50.0 m). Pydantic Field(gt=0) guards are added to prevent zero/negative values from silently dropping all clicks at construction time.

  • Removes two module-level constants and adds max_click_horizontal_m / max_click_vertical_m as Field(gt=0) fields on MovementManagerConfig, with _on_click now reading self.config.*.
  • Adds three new pytest cases covering lower-limit rejection for both axes and upper-limit acceptance for the horizontal axis, bringing the total suite to 7 passing tests.

Confidence Score: 5/5

This PR is safe to merge. It is a mechanical refactor with no logic changes at default settings, protected by a Pydantic field constraint and backed by 7 passing tests.

The change is narrow and well-contained: two constants move into config, the consuming code is updated in one place, defaults are identical, and both previously flagged issues (missing lower-bound guard and missing vertical-axis test coverage) have been addressed by this revision.

No files require special attention.

Important Files Changed

Filename Overview
dimos/navigation/movement_manager/movement_manager.py Removes two module-level constants and adds them as Pydantic Field(gt=0) fields on MovementManagerConfig; _on_click now references self.config.*. Default values are unchanged, no behavior change at defaults.
dimos/navigation/movement_manager/test_movement_manager.py Adds three new tests covering lowered/raised horizontal limit and lowered vertical limit, bringing total to 7 tests; all pass.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[clicked_point stream] --> B[_on_click]
    B --> C{all coords finite?}
    C -- No --> D[log warning: invalid click\nreturn]
    C -- Yes --> E{abs x or y > max_click_horizontal_m\nor abs z > max_click_vertical_m?}
    E -- Yes --> F[log warning: out-of-range click\nreturn]
    E -- No --> G[publish to way_point]
    G --> H[publish to goal]

    style D fill:#f99,stroke:#c00
    style F fill:#f99,stroke:#c00
    style H fill:#9f9,stroke:#090
Loading

Reviews (2): Last reviewed commit: "refactor: constrain click limits to posi..." | Re-trigger Greptile

Comment on lines +46 to +49
# Clamp clicked goals so a stray click can't send the planner toward infinity in
# rerun. Configurable for people rendering very large maps.
max_click_horizontal_m: float = 500.0
max_click_vertical_m: float = 50.0
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 No lower-bound guard on the new config fields means a user can set max_click_horizontal_m or max_click_vertical_m to 0.0 or any negative value and silently disable all click-based navigation — abs(msg.x) > 0.0 is True for every non-zero coordinate, so every click gets dropped without an obvious error. A Pydantic Field(gt=0) constraint would surface the mistake at config-parse time instead of at runtime.

Suggested change
# Clamp clicked goals so a stray click can't send the planner toward infinity in
# rerun. Configurable for people rendering very large maps.
max_click_horizontal_m: float = 500.0
max_click_vertical_m: float = 50.0
# Clamp clicked goals so a stray click can't send the planner toward infinity in
# rerun. Configurable for people rendering very large maps.
max_click_horizontal_m: float = Field(default=500.0, gt=0)
max_click_vertical_m: float = Field(default=50.0, gt=0)

Comment on lines +127 to +143
def test_click_limit_rejects_when_lowered(manager_and_captured):
"""A click within the default range is rejected once the limit is lowered below it."""
manager, captured = manager_and_captured
manager.config.max_click_horizontal_m = 10.0
manager._on_click(_click(x=50.0, y=0.0, z=0.0))
assert captured.goal == []
assert captured.way_point == []


def test_click_limit_accepts_when_raised(manager_and_captured):
"""A click beyond the default range is accepted once the limit is raised above it."""
manager, captured = manager_and_captured
manager.config.max_click_horizontal_m = 1000.0
far_click = _click(x=600.0, y=0.0, z=0.0)
manager._on_click(far_click)
assert captured.goal == [far_click]
assert captured.way_point == [far_click]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The two new tests only exercise max_click_horizontal_m; max_click_vertical_m has no equivalent coverage for the dynamic-config path. A click like _click(x=0.0, y=0.0, z=30.0) with max_click_vertical_m lowered to 10.0 would be a symmetric counterpart and would guard against a future regression where only one field gets wired to self.config.

…imit

Address review feedback on dimensionalOS#2116: add Field(gt=0) so a zero/negative
config override can't silently reject every click, and add a test
exercising the dynamic max_click_vertical_m path.
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