Add dynamic scene recovery for atomic actions - #450
Conversation
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.
1794d02 to
00456c8
Compare
00456c8 to
0bbeb2d
Compare
…2a-execution-runner
…mic-action-pr2b-dynamic-scene
Greptile SummaryThe PR adds dynamic collision-scene binding and revision-based recovery to atomic-action execution.
Confidence Score: 5/5The PR appears safe to merge because no blocking failure remains within the eligible follow-up-review scope. No blocking failure remains.
|
| 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
Reviews (4): Last reviewed commit: "refactor(atomic-actions): clarify dynami..." | Re-trigger Greptile
There was a problem hiding this comment.
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+RigidObjectSceneProviderand propagate global/per-envcollision_world_revisionthroughSceneSnapshotto enable collision-world-triggered replanning. - Introduce
ExecutionRunner(plus simulation adapters) to schedule commands fromTimedTrajectory.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.
There was a problem hiding this comment.
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)
Description
This PR adds dynamic-scene recovery to the typed atomic-action execution stack.
It introduces a
SceneProviderboundary, aRigidObjectSceneProvider, 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, andExecutionSessionemitscollision_world_changedbefore 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; commit7cbba908is the PR2B-only change.Fixes: N/A (no linked issue).
Type of change
The extension hook for
AtomicActionsubclasses changes from overriding publicplan()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 unchangedpytest -q tests/sim/atomic_actions tests/sim/planners/test_curobo_planner.py tests/sim/planners/test_motion_generator_batched.py— 181 passed, 4 skippedpython -m compileall -q embodichain/lab/sim/atomic_actions scripts/tutorials/atomic_actionagent_context/MAP.yamlYAML parsingdynamic_goal_changed→replanned→ completed after 83 accepted commandscollision_world_changed→replanned→ completed after 83 accepted commandsScreenshots
Not applicable; this change adds runtime APIs and headless simulation tutorials.
Checklist
black .command to format the code base.