Add a behavior-tree recovery example (manipulation/37)#13
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A new example,
examples/manipulation/37_behavior_tree_recovery.py, that drives the tabletop pick with a reactive behavior tree instead of imperativeif/elserecovery.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 loop01_pick_and_retry.py, but the recovery is declarative: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
Status/Sequence/Fallback/Condition/Action) inline — no external library; one tick yields exactly one env action (the RUNNING leaf).BehaviorTreeAgent(mean + shrinking radius, EMA over detections), mirroring01's belief so the contrast is purely structural.relook_to_refineafter agrasp_missand still succeeds.examples/README.mdrow + a fullexamples/manipulation/README.mdsection; example count 39→40 and test count 111→113 inREADME.md/docs/status.md.Verification
126 passed); matplotlib render path confirmed underAgg.References
🤖 Generated with Claude Code