Skip to content

feat: roboplan integration#2478

Merged
mustafab0 merged 51 commits into
mainfrom
cc/feat/roboplan-integration
Jun 26, 2026
Merged

feat: roboplan integration#2478
mustafab0 merged 51 commits into
mainfrom
cc/feat/roboplan-integration

Conversation

@TomCC7

@TomCC7 TomCC7 commented Jun 12, 2026

Copy link
Copy Markdown
Member

Integrate roboplan into manipulation module. One class implements roboplan's worldspec+plannerspec, achieving composition of roboplan world+roboplan planner/generic planner.

Better merge after #2413 since we resurfaced creation of world/planner specs.

Design choices:

  1. roboplan python binding installed through custom fork, which is uv-installable (https://github.com/TomCC7/roboplan).
  2. Single class implements both world/planner specs to make planner impl more compact.
  3. A default srdf are generated for roboplan. Can formalize in later movegroup concept introduction.

How to Test

launch coordinator and pass argument for roboplan world/planner.

# roboplan planner
uv run dimos run xarm7-planner-coordinator \
  -o manipulationmodule.world_backend=roboplan \
  -o manipulationmodule.planner_name=roboplan
# generic planner
uv run dimos run xarm7-planner-coordinator \
  -o manipulationmodule.world_backend=roboplan \
  -o manipulationmodule.planner_name=rrt_connect
# and client in a different terminal...
uv run python -i -m dimos.manipulation.planning.examples.manipulation_client

Contributor License Agreement

  • I have read and approved the CLA.

@codecov

codecov Bot commented Jun 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.86449% with 121 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...imos/manipulation/planning/world/roboplan_world.py 74.92% 58 Missing and 31 partials ⚠️
dimos/manipulation/planning/factory.py 65.78% 7 Missing and 6 partials ⚠️
dimos/manipulation/test_roboplan_world.py 95.89% 12 Missing ⚠️
dimos/robot/cli/dimos.py 70.58% 4 Missing and 1 partial ⚠️
dimos/manipulation/test_planning_factory.py 97.89% 1 Missing and 1 partial ⚠️
@@            Coverage Diff             @@
##             main    #2478      +/-   ##
==========================================
+ Coverage   71.01%   71.09%   +0.08%     
==========================================
  Files         892      897       +5     
  Lines       79232    80151     +919     
  Branches     7077     7214     +137     
==========================================
+ Hits        56267    56987     +720     
- Misses      21123    21295     +172     
- Partials     1842     1869      +27     
Flag Coverage Δ
OS-ubuntu-24.04-arm 63.50% <85.39%> (+0.19%) ⬆️
OS-ubuntu-latest 66.22% <85.74%> (+0.15%) ⬆️
Py-3.10 66.21% <85.74%> (+0.15%) ⬆️
Py-3.11 66.21% <85.74%> (+0.15%) ⬆️
Py-3.12 66.22% <85.74%> (+0.15%) ⬆️
Py-3.13 66.21% <85.74%> (+0.14%) ⬆️
Py-3.14 66.22% <85.74%> (+0.15%) ⬆️
Py-3.14t 66.21% <85.74%> (+0.14%) ⬆️
SelfHosted-Large 30.07% <29.74%> (+0.05%) ⬆️
SelfHosted-Linux 37.50% <30.53%> (-0.09%) ⬇️
SelfHosted-macOS 36.33% <30.53%> (-0.07%) ⬇️

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

Files with missing lines Coverage Δ
dimos/manipulation/manipulation_module.py 48.05% <100.00%> (+0.60%) ⬆️
...s/manipulation/planning/kinematics/test_pink_ik.py 97.98% <100.00%> (-0.07%) ⬇️
...anipulation/planning/monitor/test_world_monitor.py 71.54% <100.00%> (ø)
dimos/manipulation/test_manipulation_unit.py 99.75% <ø> (ø)
dimos/manipulation/visualization/viser/config.py 94.73% <ø> (-0.27%) ⬇️
dimos/manipulation/visualization/viser/gui.py 73.45% <ø> (-0.15%) ⬇️
...ation/visualization/viser/test_operation_worker.py 98.26% <ø> (ø)
...on/visualization/viser/test_viser_visualization.py 97.84% <100.00%> (ø)
dimos/robot/manipulators/common/blueprints.py 86.66% <100.00%> (+1.48%) ⬆️
dimos/robot/manipulators/test_blueprints.py 100.00% <100.00%> (ø)
... and 6 more

... and 7 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@TomCC7 TomCC7 changed the title WIP: roboplan integration feat: roboplan integration Jun 12, 2026
@TomCC7 TomCC7 marked this pull request as ready for review June 12, 2026 23:08
@greptile-apps

greptile-apps Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR integrates RoboPlan as an optional manipulation planning backend, addressing all issues flagged in the previous review rounds. RoboPlanWorld implements both WorldSpec and PlannerSpec, allowing it to serve as both the world/scene manager and the native RRT planner. The factory layer gains a world_backend parameter and a validate_backend_combination helper that enforces valid backend/planner/kinematics combinations at startup.

  • RoboPlanWorld manages SRDF generation via tempfile.TemporaryDirectory, handles URDF-derived adjacent-link collision exclusions, and wraps RoboPlan's native RRT through a clean plan_joint_path interface.
  • pyproject.toml adds roboplan (now on PyPI as v0.0.100) to the manipulation extra; stubs cover roboplan.core and roboplan.rrt for type checking.
  • The blueprints.planner helper drops its hardcoded meshcat default so callers that omit visualization now get NoManipulationVisualizationConfig rather than unexpected meshcat startup.

Confidence Score: 5/5

Safe to merge; all previously flagged issues have been resolved in this version.

Every issue raised in prior review rounds — the missing replace import, empty-path silent success, SRDF tempdir accumulation, MD5 FIPS exposure, TypeError cascade in collision-check fallback, unnamed path waypoints, and SSH-only dependency — is addressed in the current diff. No new functional defects are introduced. The two remaining comments are quality nits (a default-value mismatch in a validation helper and a double URDF parse) that do not affect correctness. The new RoboPlanWorld is well-tested with a 549-line fake-binding test suite, and the factory changes carry their own focused tests.

dimos/manipulation/planning/factory.py — the validate_backend_combination default for kinematics_name is worth aligning with DEFAULT_KINEMATICS_NAME before the function's public surface grows.

Important Files Changed

Filename Overview
dimos/manipulation/planning/world/roboplan_world.py New 655-line RoboPlan adapter implementing WorldSpec + PlannerSpec; all previously flagged issues (empty-path silent SUCCESS, SRDF tempdir leak, unnamed path waypoints, TypeError cascades, missing replace import) are resolved in this version.
dimos/manipulation/planning/factory.py Adds world_backend routing, validate_backend_combination, and roboplan-native planner wiring; minor inconsistency: validate_backend_combination's default kinematics_name differs from DEFAULT_KINEMATICS_NAME.
dimos/manipulation/manipulation_module.py Threads world_backend and PlannerName/WorldBackend/KinematicsName type aliases into ManipulationModuleConfig; changes are minimal and correct.
dimos/robot/manipulators/common/blueprints.py Drops hardcoded visualization={"backend": "meshcat"} default from the planner helper; callers that previously relied on implicit meshcat now get NoManipulationVisualizationConfig, which is the tested and intended new behaviour.
pyproject.toml Adds roboplan (no version pin; pinned to 0.0.100 in lock) to the manipulation extra from PyPI; the exclude-newer-package entry correctly exempts roboplan from the 7-day freshness window.
stubs/roboplan/core/init.pyi New partial stubs for roboplan.core; covers Scene, JointConfiguration, JointPath, geometry primitives, and hasCollisionsAlongPath — sufficient for type checking the adapter.
dimos/robot/cli/dimos.py Removes the click dependency for KEY=VALUE parsing; replaces _KeyValueType with a plain _parse_key_value_arg function and a _validate_key_value_args typer callback — functionally equivalent and cleaner.
dimos/manipulation/test_roboplan_world.py 549-line test file using a fully fake roboplan binding injected via monkeypatch; covers robot registration, SRDF generation, collision checking, obstacle management, FK, Jacobian, native and generic RRT planning, and empty-path handling.
dimos/manipulation/test_planning_factory.py New factory unit tests covering backend validation, roboplan-as-planner wiring, lazy roboplan import, and ManipulationModule integration; good coverage of the new factory combinatorics.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant MM as ManipulationModule
    participant F as factory.py
    participant RPW as RoboPlanWorld
    participant RP as roboplan C++ binding

    MM->>F: "create_world(backend="roboplan")"
    F->>RPW: RoboPlanWorld()
    MM->>RPW: add_robot(config)
    RPW->>RP: Scene(urdf, srdf, pkg_paths)
    RPW-->>MM: robot_id

    MM->>RPW: finalize()

    alt "planner_name="roboplan""
        MM->>F: "create_planner(name="roboplan", world=RPW)"
        F-->>MM: returns RPW (PlannerSpec)
        MM->>RPW: "plan_joint_path(world=self, ...)"
        RPW->>RP: RRT.plan(start, goal)
        RP-->>RPW: JointPath
        RPW-->>MM: PlanningResult(SUCCESS)
    else "planner_name="rrt_connect""
        MM->>F: "create_planner(name="rrt_connect")"
        F-->>MM: RRTConnectPlanner
        MM->>RRTConnectPlanner: "plan_joint_path(world=RPW, ...)"
        RRTConnectPlanner->>RPW: check_config_collision_free(...)
        RPW->>RP: hasCollisions(q)
        RP-->>RPW: bool
        RPW-->>RRTConnectPlanner: bool
        RRTConnectPlanner-->>MM: PlanningResult(SUCCESS)
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant MM as ManipulationModule
    participant F as factory.py
    participant RPW as RoboPlanWorld
    participant RP as roboplan C++ binding

    MM->>F: "create_world(backend="roboplan")"
    F->>RPW: RoboPlanWorld()
    MM->>RPW: add_robot(config)
    RPW->>RP: Scene(urdf, srdf, pkg_paths)
    RPW-->>MM: robot_id

    MM->>RPW: finalize()

    alt "planner_name="roboplan""
        MM->>F: "create_planner(name="roboplan", world=RPW)"
        F-->>MM: returns RPW (PlannerSpec)
        MM->>RPW: "plan_joint_path(world=self, ...)"
        RPW->>RP: RRT.plan(start, goal)
        RP-->>RPW: JointPath
        RPW-->>MM: PlanningResult(SUCCESS)
    else "planner_name="rrt_connect""
        MM->>F: "create_planner(name="rrt_connect")"
        F-->>MM: RRTConnectPlanner
        MM->>RRTConnectPlanner: "plan_joint_path(world=RPW, ...)"
        RRTConnectPlanner->>RPW: check_config_collision_free(...)
        RPW->>RP: hasCollisions(q)
        RP-->>RPW: bool
        RPW-->>RRTConnectPlanner: bool
        RRTConnectPlanner-->>MM: PlanningResult(SUCCESS)
    end
Loading

Reviews (26): Last reviewed commit: "Merge branch 'main' into cc/feat/robopla..." | Re-trigger Greptile

Comment thread dimos/manipulation/planning/world/roboplan_world.py Outdated
Comment thread dimos/manipulation/planning/world/roboplan_world.py Outdated
Comment thread dimos/manipulation/planning/world/roboplan_world.py
@github-actions github-actions Bot added the ready-to-merge Required CI checks have passed on this PR label Jun 12, 2026
@github-actions github-actions Bot added ready-to-merge Required CI checks have passed on this PR and removed ready-to-merge Required CI checks have passed on this PR labels Jun 12, 2026
Comment thread dimos/manipulation/planning/world/roboplan_world.py Outdated
@github-actions github-actions Bot removed the ready-to-merge Required CI checks have passed on this PR label Jun 13, 2026
Comment thread dimos/manipulation/planning/world/roboplan_world.py
@github-actions github-actions Bot added ready-to-merge Required CI checks have passed on this PR and removed ready-to-merge Required CI checks have passed on this PR labels Jun 25, 2026
@mustafab0 mustafab0 enabled auto-merge (squash) June 25, 2026 19:47
@github-actions github-actions Bot removed the ready-to-merge Required CI checks have passed on this PR label Jun 25, 2026
paul-nechifor and others added 14 commits June 25, 2026 23:29
Replace the str-plus-comment config fields with Literal type aliases
(WorldBackend / PlannerName / KinematicsName) so Pydantic validates the
values. The SUPPORTED_* tuples are now derived from the aliases via
get_args, removing the chance of the two drifting.
plan_joint_path wrapped the whole _run_native_rrt call in
except Exception and stringified the error, losing the traceback for
unexpected failures. Catch the ValueError that _run_native_rrt raises for
the known no-path case and let anything else propagate, matching the
sibling RRTConnectPlanner.
A rejected collision-exclusion pair is safety-relevant, so log it at
warning rather than debug. Detect a missing setCollisions API once
up-front and warn instead of silently returning out of the loop on the
first AttributeError.
PlannerSpec is a @runtime_checkable Protocol declaring plan_joint_path
and get_name, so isinstance both validates the world and narrows the type
for the return -- replacing the hasattr check and the
type: ignore[return-value]. The test double now uses spec=PlannerSpec so
it actually satisfies the protocol under Python 3.12's getattr_static
check.
validate_backend_combination and create_planner raised the identical
'planner_name="roboplan" requires world_backend="roboplan"' message;
hoist it to a module constant so the two can't drift.
Move ManipulationModule construction into a make_module factory fixture
that stops every built module on teardown, so cleanup runs even when the
test body fails -- replacing the hand-rolled try/finally: module.stop().
The manipulation extra depends on the roboplan package (pyproject.toml),
not roboplan-dimos, which exists nowhere in the repo.
_has_collisions took a ctx it never read, and model_handle (config.name)
was threaded through _extract_joint_limits and _query_scene_joint_limits
without being used. Remove the dead parameters and the now-unused
_RoboPlanRobotData.model_handle field.
_run_native_rrt already raises when planner.plan returns None before
calling _extract_native_path, so the identical check inside
_extract_native_path is dead.
Add the missing -> None return annotations (and a pytest.MonkeyPatch
hint) so the suite matches the rest of the repo, and assert the factory
return types with isinstance instead of comparing type(...).__name__ to a
string.
The test parametrized a single base_pose case, with its
type: ignore[call-arg] stranded on the tuple paren. Inline it as one
direct test and move the ignore onto the PoseStamped call it applies to.
Drop the stray double blank line after the manipulation extra and add the
missing space before the closing brace of exclude-newer-package.
create_kinematics's default and the create_planning_specs fallback both
hardcoded "pink"; route both through a DEFAULT_KINEMATICS_NAME constant
so they can't drift.
@github-actions github-actions Bot added the ready-to-merge Required CI checks have passed on this PR label Jun 25, 2026
…ion-autofixes

Auto-fixes for cc/feat/roboplan-integration
@github-actions github-actions Bot added ready-to-merge Required CI checks have passed on this PR and removed ready-to-merge Required CI checks have passed on this PR labels Jun 25, 2026
@github-actions github-actions Bot removed the ready-to-merge Required CI checks have passed on this PR label Jun 25, 2026
@github-actions github-actions Bot added the ready-to-merge Required CI checks have passed on this PR label Jun 25, 2026
@mustafab0 mustafab0 merged commit f7ccf77 into main Jun 26, 2026
27 checks passed
@mustafab0 mustafab0 deleted the cc/feat/roboplan-integration branch June 26, 2026 18:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge Required CI checks have passed on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants