Skip to content

feat(blackboard): add GetBlackboardByKey and SetBlackboardByKey for dynamic-key access#11

Merged
WillYingling merged 5 commits into
mainfrom
feat/get-blackboard-by-key
May 5, 2026
Merged

feat(blackboard): add GetBlackboardByKey and SetBlackboardByKey for dynamic-key access#11
WillYingling merged 5 commits into
mainfrom
feat/get-blackboard-by-key

Conversation

@WillYingling

@WillYingling WillYingling commented Apr 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a pair of behaviors for reading/writing blackboard entries under runtime-computed keys — the missing primitives for dynamic-key access in BT.CPP v4.

  • GetBlackboardByKey — reads an entry whose key is resolved at tick time (typically built via a Script node from other blackboard variables). Mirrors the shape of BT.CPP's native SetBlackboard, which already supports a dynamic output_key port but has no read-side complement. Value copy goes through setOutput<BT::Any> so SubTree auto-remap sentinels ({=}/=) and blackboard-pointer validation are handled by BT.CPP's canonical helper.
  • SetBlackboardByKey — write-side complement. Not just a wrapper around SetBlackboard: BT.CPP's native action runs TypeInfo::parseString whenever the source is a string and the destination type is not std::string. Destinations created implicitly by a Script := assignment carry AnyTypeAllowed and have no registered converter, so parseString returns an empty Any and silently clobbers the write. SetBlackboardByKey copies the source Any directly, preserving both type and value.

The @ prefix for root-scope blackboard access is honored transparently in both behaviors (handled inside Blackboard::getEntry / createEntry).

Why

No native dynamic-key read/write pair exists in BT.CPP v4. The conversion bug in SetBlackboard (see above) makes it unsafe for caching script-produced values regardless of whether the key is static or dynamic. These two small primitives fill both gaps.

Motivating use case

Caching pre-computed motion trajectories on the root blackboard during a pre-flight planning pass, then retrieving them during execution in a separate subtree — eliminating duplicated planning calls. Landing in a separate PR against autowash_config.

Test plan

  • Registration/instantiation test covers pluginlib loading (test_load_behavior_plugins).
  • Functional tick-path tests intentionally deferred — this package currently has no tick-test harness precedent. Validation via the downstream autowash_config regression suite.
  • Manual regression confirmed: caching pre-flight trajectories and retrieving them in execution now works end-to-end with SetBlackboardByKey in place (native SetBlackboard produced the empty-Any bug described above).

🤖 Generated with Claude Code

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new BehaviorTree.CPP behavior node to read a blackboard value using a key computed at tick time, enabling dynamic-key cache lookups (including root-scope @ keys).

Changes:

  • Introduces GetBlackboardByKey SyncActionNode with key input and value output.
  • Registers the new behavior in the plugin loader and library build.
  • Extends the existing plugin-load test to instantiate the new node.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/get_blackboard_by_key.cpp Implements tick-time dynamic-key blackboard read and output propagation.
include/experimental_behaviors/get_blackboard_by_key.hpp Declares the new behavior and documents its ports/semantics.
src/register_behaviors.cpp Registers GetBlackboardByKey with the behavior factory.
CMakeLists.txt Adds the new source file to the shared library build.
test/test_behavior_plugins.cpp Adds instantiation coverage for the new node in the plugin-load test.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/get_blackboard_by_key.cpp Outdated
@WillYingling WillYingling changed the title feat(blackboard): add GetBlackboardByKey for dynamic-key reads feat(blackboard): add GetBlackboardByKey and SetBlackboardByKey for dynamic-key access Apr 20, 2026
@WillYingling WillYingling marked this pull request as ready for review April 20, 2026 21:34
WillYingling and others added 4 commits April 21, 2026 10:17
- Replace hand-rolled brace-stripping with setOutput<BT::Any> to handle
  SubTree auto-remap sentinels and whitespace correctly.
- Document that empty-valued entries are reported as FAILURE.
- Correct port type in docstring (AnyTypeAllowed, not BT::Any).
Write-side complement to GetBlackboardByKey. BT.CPP's native SetBlackboard
passes string-typed sources through TypeInfo::parseString when the
destination is not std::string; for AnyTypeAllowed destinations (entries
created implicitly by Script `:=` on subtree ports) no converter is
registered, so parseString returns an empty Any and silently clobbers
the write. SetBlackboardByKey copies the source Any directly, preserving
both type and value.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
v0.0.6 sources /opt/underlay_ws/install/setup.sh, which no longer
exists in the picknikciuser/moveit-studio:main-humble image, so the
Install rosdeps step fails before build or test run. v0.0.7 is the
upstream fix that removes those three sourcing lines.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@WillYingling WillYingling force-pushed the feat/get-blackboard-by-key branch from cf0b93f to 6101af1 Compare April 21, 2026 16:39

@henrygerardmoore henrygerardmoore 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.

LGTM other than one thing; works well where you use it in the autowash config

Comment thread src/get_blackboard_by_key.cpp Outdated
…Key description

Description previously only mentioned the missing-entry case, but tick() also
returns FAILURE for a missing/empty `key` port and for entries that exist but
hold no value. Update the description string so the UI help text matches the
actual semantics.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@henrygerardmoore henrygerardmoore 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.

LGTM

@WillYingling WillYingling merged commit a372a57 into main May 5, 2026
4 checks passed
@nbbrooks

nbbrooks commented May 7, 2026

Copy link
Copy Markdown
Member

To confirm, when this gets merged into core, SetBlackboard should be marked as deprecated?

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.

4 participants