Skip to content

Add a behavior-tree recovery example (manipulation/37)#13

Merged
rsasaki0109 merged 1 commit into
mainfrom
add-behavior-tree-recovery
Jun 5, 2026
Merged

Add a behavior-tree recovery example (manipulation/37)#13
rsasaki0109 merged 1 commit into
mainfrom
add-behavior-tree-recovery

Conversation

@rsasaki0109

Copy link
Copy Markdown
Owner

What

A new example, examples/manipulation/37_behavior_tree_recovery.py, that drives the tabletop pick with a reactive behavior tree instead of imperative if/else recovery.

The repo's whole thesis is what the robot does after it fails. Behavior trees are the pattern roboticists actually reach for to structure that recovery — BehaviorTree.CPP, py_trees, the ROS 2 Nav2 BT Navigator — yet the repo had no BT example. This fills that gap with the smallest honest version.

The lesson

Same task, same world (Tabletop2D) as the hero loop 01_pick_and_retry.py, but the recovery is declarative:

Fallback "pick the block"
├── Condition  object_in_gripper?            # already holding -> whole tree SUCCESS
└── Fallback   "grasp or recover"
    ├── Sequence "confident grasp"
    │   ├── Condition  belief_confident?
    │   └── Action     grasp_at_belief
    └── Action     relook_to_refine           # recovery: scan a new viewpoint

A grasp miss is not handled by a special branch — it just grows the belief radius, flips belief_confident? to false, and the same fallback re-runs active perception before retrying. Occlusion and grasp-miss recovery share one declarative branch. Recovery is a property of the tree's shape, not a hand-written routine.

Contents

  • Minimal three-status BT engine (Status / Sequence / Fallback / Condition / Action) inline — no external library; one tick yields exactly one env action (the RUNNING leaf).
  • A belief-tracking BehaviorTreeAgent (mean + shrinking radius, EMA over detections), mirroring 01's belief so the contrast is purely structural.
  • Two smoke tests: root reports SUCCESS on the hero seed; a miss-heavy seed falls back through relook_to_refine after a grasp_miss and still succeeds.
  • examples/README.md row + a full examples/manipulation/README.md section; example count 39→40 and test count 111→113 in README.md / docs/status.md.

Verification

  • Headless across seeds 0–7: all succeed; re-looks interleave with grasps, retries on miss (e.g. seed 4 → 3 grasps / 2 retries, seed 3 → clean).
  • Full suite green (126 passed); matplotlib render path confirmed under Agg.

References

  • M. Colledanchise & P. Ögren, Behavior Trees in Robotics and AI: An Introduction, CRC Press 2018 (arXiv:1709.00084).
  • BehaviorTree.CPP, py_trees.

🤖 Generated with Claude Code

The repo's thesis is "what the robot does after it fails." Behavior trees are
the pattern roboticists actually reach for to structure that recovery
(BehaviorTree.CPP, py_trees, the ROS 2 Nav2 BT Navigator), yet there was no BT
example. This adds one.

`37_behavior_tree_recovery.py` runs the *same* tabletop pick as the hero loop
`01_pick_and_retry.py`, on the *same* `Tabletop2D`, but expresses the recovery
declaratively: a reactive Sequence/Fallback tree (minimal three-status engine,
no external library) ticked once per control step, each tick yielding exactly
one environment action. A single `Fallback` holds the primary grasp first and a
`relook_to_refine` recovery leaf second; a grasp miss grows the belief radius,
flips the `belief_confident?` precondition to false, and the same fallback
re-runs active perception before retrying. Occlusion and grasp-miss recovery
share one declarative branch instead of two imperative `if` blocks — the lesson
is that recovery is a property of the tree's shape.

- example with inline Status/Sequence/Fallback/Condition/Action + a
  belief-tracking agent and a References section
- two smoke tests: SUCCESS at the root on the hero seed, and a fallback-to-relook
  after a grasp miss on a miss-heavy seed
- examples index + manipulation README section; example/test counts bumped

Verified headless across seeds 0-7 (all succeed; relooks interleave with grasps,
retries on miss) and the matplotlib render path under Agg.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@rsasaki0109 rsasaki0109 merged commit 400b851 into main Jun 5, 2026
3 checks passed
@rsasaki0109 rsasaki0109 deleted the add-behavior-tree-recovery branch June 5, 2026 00:55
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