feat: Add Finally control node for guaranteed cleanup - #36
Draft
dv-picknik wants to merge 2 commits into
Draft
dv-picknik wants to merge 2 commits into
dv-picknik wants to merge 2 commits into
Conversation
Finally ticks its main child, then always ticks its cleanup child: after SUCCESS, FAILURE, or SKIPPED, after main throws (printed to stderr, surfaced as FAILURE), and synchronously when halted while main is RUNNING. It returns main's status, or FAILURE if cleanup fails. Refs PickNikRobotics/moveit_pro#20169 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
halt() also runs from ~Tree(), so a cleanup exception there is printed instead of propagated. A SKIPPED result leaves the node RUNNING in executeTick(), so the node resets itself, keeping a later halt from rerunning cleanup. Adds tests for async main and cleanup, halts in each phase, and SKIPPED main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Comment |
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.
[written by AI]
Adds a
Finallycontrol node with two children, main and cleanup. It ticks main, then always ticks cleanup, which gives Objectives try/finally semantics for resetting scene state such as collision rules.Cleanup runs in each of these cases:
what()to stderr, halts main, runs cleanup, and returns FAILURE.If cleanup fails, the node returns FAILURE even when main succeeded, because a failed cleanup can leave the scene dirty. An exception thrown by cleanup propagates from
tick(). Duringhalt()it is printed instead, because~Tree()callshaltTree()and a throw there would callstd::terminate. The XML loader rejects aFinallywithout exactly 2 children.Related: PickNikRobotics/moveit_pro#20169, milestone 10.2.0.
TryCatch, which arrived with the 4.9.0 port, doesn't cover this. It skips the catch child on SUCCESS and does not catch exceptions.Open for review:
NodeExecutionErrorbacktrace everywhere except stderr. The other option is to store astd::exception_ptrand rethrow once cleanup finishes. That keeps the diagnostics, but an outerFallbackcould no longer recover.Finallyexists only in our fork. It should go upstream as part of the BT.CPP unfork work.Validation:
behaviortree_cpp_picknik_testpasses all 542 tests locally (Release, GCC). That includes 17 newFinallyTestcases covering async main and cleanup, a halt in each phase, exceptions from main and from cleanup on both the tick and halt paths, SKIPPED main, and child-count validation.pre-commitpassed on the changed files.picknik:code-reviewerand the CodeRabbit CLI both flagged cleanup throwing during halt, and the second commit fixes it. Writing that SKIPPED test turned up a double cleanup:executeTick()leaves the node RUNNING after a SKIPPED return, so a later halt ran cleanup again. The node now resets itself before returning SKIPPED.🤖 Generated with Claude Code