Skip to content

Add dynamic scene recovery for atomic actions - #450

Open
yuecideng wants to merge 14 commits into
mainfrom
feat/atomic-action-pr2b-dynamic-scene
Open

Add dynamic scene recovery for atomic actions#450
yuecideng wants to merge 14 commits into
mainfrom
feat/atomic-action-pr2b-dynamic-scene

Conversation

@yuecideng

Copy link
Copy Markdown
Contributor

Description

This PR adds dynamic-scene recovery to the typed atomic-action execution stack.

It introduces a SceneProvider boundary, a RigidObjectSceneProvider, global/per-environment collision-world revisions, and collision-sensitive phase invalidation. AtomicAction.plan() now owns scene binding and delegates skill logic to _plan(), so current obstacle poses are injected into copied planner options instead of being repeated across individual skill parameters. cuRobo implements the dynamic-world bridge, and ExecutionSession emits collision_world_changed before bounded per-environment replanning.

The PR also adds runnable moving-target and dynamic-obstacle recovery tutorials, focused multi-environment recovery tests, planner/provider tests, and corresponding Sphinx and agent-context updates.

Dependencies: #449. This is a stacked PR whose base is feat/atomic-action-pr2a-execution-runner; commit 7cbba908 is the PR2B-only change.

Fixes: N/A (no linked issue).

Type of change

  • Breaking change (existing functionality will not work without user modification)

The extension hook for AtomicAction subclasses changes from overriding public plan() to implementing _plan(). This is intentional within the unmerged refactor stack and prevents actions from bypassing framework-owned scene binding.

Validation

  • black --check --diff --color ./ — 562 files unchanged
  • pytest -q tests/sim/atomic_actions tests/sim/planners/test_curobo_planner.py tests/sim/planners/test_motion_generator_batched.py — 181 passed, 4 skipped
  • python -m compileall -q embodichain/lab/sim/atomic_actions scripts/tutorials/atomic_action
  • agent_context/MAP.yaml YAML parsing
  • Moving-target headless simulation — dynamic_goal_changedreplanned → completed after 83 accepted commands
  • Dynamic-obstacle headless simulation — collision_world_changedreplanned → completed after 83 accepted commands
  • Sphinx HTML build completed; existing repository-wide autodoc warnings remain
  • Full test suite was not run; affected atomic-action and planner scopes were validated proportionally

Screenshots

Not applicable; this change adds runtime APIs and headless simulation tutorials.

Checklist

  • I have run the black . command to format the code base.
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • Dependencies have been updated, if applicable.

Add versioned scene providers, per-environment collision-world invalidation, and planner-side dynamic obstacle binding. Include bounded recovery tests plus runnable moving-target and cuRobo obstacle examples.
@yuecideng yuecideng added breaking enhancement New feature or request atomic action atomic action related functionality motion gen Things related to motion generation for robot labels Aug 2, 2026
@yuecideng
yuecideng force-pushed the feat/atomic-action-pr2a-execution-runner branch from 1794d02 to 00456c8 Compare August 3, 2026 03:37
@yuecideng
yuecideng force-pushed the feat/atomic-action-pr2a-execution-runner branch from 00456c8 to 0bbeb2d Compare August 9, 2026 12:17
@greptile-apps

greptile-apps Bot commented Aug 9, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds dynamic collision-scene binding and revision-based recovery to atomic-action execution.

  • Introduces scene providers and per-environment collision-world revisions.
  • Binds current obstacle poses through the motion-generator and cuRobo planner boundary.
  • Invalidates collision-sensitive phases and performs bounded replanning.
  • Moves action implementations to the framework-controlled _plan() hook.
  • Adds focused recovery, provider, planner, and tutorial coverage.

Confidence Score: 5/5

The PR appears safe to merge because no blocking failure remains within the eligible follow-up-review scope.

No blocking failure remains.

Important Files Changed

Filename Overview
embodichain/lab/sim/atomic_actions/core.py Converts public planning into a template method that binds current collision poses before delegating to _plan().
embodichain/lab/sim/atomic_actions/execution.py Adds collision-world revision validation, per-environment invalidation, and replanning events.
embodichain/lab/sim/atomic_actions/sim_adapter.py Adds the rigid-object scene provider and integrates provider-backed snapshots into simulation observation.
embodichain/lab/sim/atomic_actions/state.py Extends scene snapshots with collision entities, global or per-environment revisions, and batched obstacle-pose extraction.
embodichain/lab/sim/planners/curobo/curobo_planner.py Implements the planner option bridge for owned dynamic-obstacle pose updates.
embodichain/lab/sim/atomic_actions/policies.py Replaces the collision boolean with explicit off, automatic, and required dynamic-collision modes while retaining a deprecated alias.

Sequence Diagram

sequenceDiagram
    participant Adapter as SimulationExecutionAdapter
    participant Provider as SceneProvider
    participant Session as ExecutionSession
    participant Action as AtomicAction
    participant Generator as MotionGenerator
    participant Planner as cuRobo Planner

    Adapter->>Provider: snapshot(timestamp, env_ids)
    Provider-->>Adapter: SceneSnapshot(poses, revisions)
    Adapter->>Session: tick(PlanningContext)
    Session->>Session: compare planned and current revisions
    alt collision world changed
        Session->>Action: plan(request, current context)
        Action->>Generator: bind_collision_world(options, poses)
        Generator->>Planner: with_collision_world(options, poses)
        Planner-->>Action: scene-bound options
        Action-->>Session: replacement ActionPlan
        Session-->>Adapter: collision_world_changed and replanned events
    end
Loading

Reviews (4): Last reviewed commit: "refactor(atomic-actions): clarify dynami..." | Re-trigger Greptile

Base automatically changed from feat/atomic-action-pr2a-execution-runner to main August 9, 2026 16:10
Copilot AI lite review requested due to automatic review settings August 9, 2026 17:02

Copilot AI left a comment

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.

Pull request overview

This PR extends the typed atomic-action execution stack with dynamic-scene recovery by introducing a SceneProvider boundary, per-environment collision-world revision tracking, and collision-sensitive phase invalidation. It also formalizes controller-facing scheduling/ack handling via an ExecutionRunner, and updates atomic-action subclassing so framework-owned AtomicAction.plan() performs scene binding before delegating to _plan().

Changes:

  • Add SceneProvider + RigidObjectSceneProvider and propagate global/per-env collision_world_revision through SceneSnapshot to enable collision-world-triggered replanning.
  • Introduce ExecutionRunner (plus simulation adapters) to schedule commands from TimedTrajectory.dt, manage acknowledgements, and perform cancel-then-hold on failure.
  • Update primitives/tests/docs/tutorials to the new _plan() hook and add end-to-end tutorials + focused test coverage for dynamic-goal and dynamic-obstacle recovery.

Reviewed changes

Copilot reviewed 38 out of 38 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/sim/planners/test_curobo_planner.py Adds coverage for cuRobo obstacle-pose binding into per-plan options.
tests/sim/atomic_actions/test_tutorial_utils.py Adds unit tests for dynamic-obstacle tutorial helpers (animation, clearance metrics).
tests/sim/atomic_actions/test_sim_adapter.py Adds tests for the new simulation execution adapter and scene provider integration.
tests/sim/atomic_actions/test_runner.py Adds comprehensive tests for non-blocking/blocking ExecutionRunner scheduling and failure handling.
tests/sim/atomic_actions/test_engine.py Updates action hook to _plan() and validates subclasses cannot override framework plan().
tests/sim/atomic_actions/test_engine_per_env.py Adds per-env collision-world revision recovery tests and motion-policy motion-source coverage.
tests/sim/atomic_actions/test_core.py Adds tests for collision-world revision expansion/obstacle pose extraction and trajectory snapshot ownership.
tests/sim/atomic_actions/test_actions.py Extends PickUp tests to cover late-bound grasp resolution and dynamic-goal replanning events.
scripts/tutorials/atomic_action/moving_target_recovery.py New runnable tutorial demonstrating replanning when a visible grasp target moves.
scripts/tutorials/atomic_action/dynamic_obstacle_recovery.py New runnable tutorial demonstrating collision-world revision recovery with cuRobo dynamic obstacles.
embodichain/lab/sim/planners/curobo/curobo_planner.py Implements supports_collision_world_updates and binds dynamic obstacle poses into cuRobo plan options.
embodichain/lab/sim/planners/base_planner.py Adds generic collision-world update hook and capability flag to planner base API.
embodichain/lab/sim/atomic_actions/state.py Extends SceneSnapshot with collision-world revision + collision entities; adds helpers to expand revisions and extract obstacle poses.
embodichain/lab/sim/atomic_actions/sim_adapter.py Adds SimulationExecutionAdapter and RigidObjectSceneProvider for simulation observation/command/clock + scene revisions.
embodichain/lab/sim/atomic_actions/scene.py Introduces the SceneProvider protocol boundary for scene snapshot production.
embodichain/lab/sim/atomic_actions/runner.py Adds ExecutionRunner with acknowledgement handling, timing-based scheduling, and safe-stop behavior.
embodichain/lab/sim/atomic_actions/primitives/press.py Migrates primitive to _plan() hook.
embodichain/lab/sim/atomic_actions/primitives/place.py Migrates primitive to _plan() hook.
embodichain/lab/sim/atomic_actions/primitives/pick_up.py Extends GraspGoal.grasp_xpos to support late-bound SceneEntityPose via pose-goal utilities and migrates to _plan().
embodichain/lab/sim/atomic_actions/primitives/move_joints.py Migrates primitive to _plan() hook.
embodichain/lab/sim/atomic_actions/primitives/move_held_object.py Migrates primitive to _plan() hook.
embodichain/lab/sim/atomic_actions/primitives/move_end_effector.py Migrates primitive to _plan() hook.
embodichain/lab/sim/atomic_actions/primitives/hand_over.py Migrates primitive to _plan() hook.
embodichain/lab/sim/atomic_actions/primitives/coordinated_placement.py Migrates primitive to _plan() hook.
embodichain/lab/sim/atomic_actions/primitives/coordinated_pickment.py Migrates primitive to _plan() hook.
embodichain/lab/sim/atomic_actions/plans.py Adds TimedTrajectory.snapshot() and extends phase metadata with collision-world sensitivity and planned collision revision.
embodichain/lab/sim/atomic_actions/execution.py Adds collision-world change detection/replan events, exposes latest_context/active_trajectory, and refines command hold scheduling semantics.
embodichain/lab/sim/atomic_actions/engine.py Validates phases record the planned collision-world revision.
embodichain/lab/sim/atomic_actions/core.py Makes plan() framework-owned (template method), enforces _plan() override, and binds collision-world obstacle poses into copied plan options.
embodichain/lab/sim/atomic_actions/init.py Exposes new runner/scene/adapter APIs at the package boundary.
docs/source/tutorial/atomic_actions.rst Updates tutorial documentation to use runner + scene provider and documents new recovery flows and _plan() hook.
docs/source/overview/sim/atomic_actions/index.md Updates overview architecture docs to include runner, provider/ports, and collision-world revisions.
docs/source/overview/sim/atomic_actions/builtin_actions.md Updates PickUp documentation to reflect late-bound grasp poses and dependency-based recovery.
docs/source/api_reference/embodichain/embodichain.lab.sim.atomic_actions.rst Updates API reference exports to include the new runner/ports/adapters and execution enums.
agent_context/topics/motion-planning/motion-planning.md Documents the generic dynamic-world bridge (with_collision_world) and planner opt-in requirements.
agent_context/topics/atomic-actions/atomic-actions.md Updates agent context with runner/session/provider responsibilities and collision-world-driven recovery behavior.
agent_context/MAP.yaml Adds new atomic-action topic keywords and file references for runner/scene/sim_adapter.
.agents/skills/add-atomic-action/SKILL.md Updates the skill guidance to the new _plan() hook and documents runner/scene-provider considerations.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI review requested due to automatic review settings August 9, 2026 17:23

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 33 out of 33 changed files in this pull request and generated no new comments.

Suppressed comments (2)

embodichain/lab/sim/atomic_actions/sim_adapter.py:62

  • RigidObjectSceneProviderCfg.post_init only checks non-negativity; NaN/inf thresholds would silently disable pose-change detection (comparisons with NaN are always False). Validate finiteness as well so invalid configs fail fast.
    def __post_init__(self) -> None:
        if self.translation_threshold < 0.0:
            raise ValueError("translation_threshold must be non-negative.")
        if self.rotation_threshold < 0.0:
            raise ValueError("rotation_threshold must be non-negative.")

embodichain/lab/sim/atomic_actions/state.py:547

  • SceneSnapshot.collision_obstacle_poses() clones each pose, but planners that opt into collision-world updates (e.g., CuroboPlanner.with_collision_world) clone again to guarantee owned option storage. This double-cloning adds avoidable allocations on every (re)plan. Consider returning the (possibly expanded) pose tensor without cloning here and let the planner own the copy.
                    f"Collision entity {entity_id!r} pose must match planning "
                    f"batch size {batch_size}."
                )
            poses[entity_id] = pose.clone()
        return MappingProxyType(poses)

Copilot AI review requested due to automatic review settings August 9, 2026 18:02

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 36 out of 36 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

atomic action atomic action related functionality breaking enhancement New feature or request motion gen Things related to motion generation for robot

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants