Repository navigation
Changelog: 4.11.0 (since 4.10.0)
77 merged PRs: two new XML features for writing trees (the Finally node and the _onlyIf / _onStart preconditions), XML schema validation, input port subscriptions, and a large batch of robustness fixes, many of them found by fuzzing.
ABI: 4.11.0 is binary compatible with 4.10.0. We checked the class layouts against 4.10.0, and restored the timer nodes' layout that an earlier fix had changed (#1283). A few fixes change behavior, though; see Behavior changes below.
Highlights
-
New
Finallycontrol node: guaranteed cleanup. It ticks its first child ("main") and then its second child ("cleanup"), like try/finally. Cleanup runs whether main succeeds, fails, throws, or is halted. The node returns main's status, or FAILURE if cleanup fails. By default, a halt gives cleanup a single tick. Sethalt_timeout_msecto let an asynchronous cleanup finish. This blocks the halting parent for up to that long, so keep it short. Issue #1228, PR #1229.<Finally halt_timeout_msec="500"> <MoveArm/> <EnableCollisions/> </Finally>
-
New preconditions
_onlyIfand_onStart._onlyIf="<script>"skips the node unless the condition is true (the readable opposite of_skipIf)._onStart="<script>"runs a script right before the node's first tick, which is handy to initialize or reset blackboard entries. Issues #820, #895, PR #1261.<MoveBase _onlyIf="battery > 20" _onStart="attempts := 0" goal="{target}"/>
-
XML validation with XSD and Schematron.
writeTreeXSD(factory, generic)can emit a lax schema that accepts unknown custom nodes. The newwriteTreeSchematron()checks what XSD can't: every custom node used in a tree has aTreeNodesModelentry, every<SubTree ID>resolves, andmain_tree_to_executeexists. Ready-made schemas for the built-in nodes are intools/generated/, andtools/validate_xml.pyvalidates a file against both. Thanks @vivoeiva. PR #1146. -
Input port update subscriptions.
TreeNode::subscribeToInputPort("port", callback)calls back when the blackboard entry behind an input port is written, so a node can react before its next tick instead of polling. It follows SubTree remapping, and it is notified byset(),setOutput(), scripts, JSON import and snapshot restore. PR #1247. -
BTCPP_versionin generated XML.WriteTreeToXML()andwriteTreeNodesModelXML()write the library version in<root>, so tools such as Groot2 know which built-in nodes and attributes the file targets. PR #1264. -
Groot2Publisher bind address. The new constructor
Groot2Publisher(tree, port, bind_address)lets you listen on"127.0.0.1"only. The Groot2 protocol has no authentication, and a reachable port allows inserting hooks that replace node results. The existing constructor keeps binding to all interfaces. PR #1251. -
Use the system nlohmann_json. With
-DUSE_VENDORED_JSON=OFF, the library builds and exports againstfind_package(nlohmann_json), so it no longer clashes with another copy of the header in your project. The default stays ON. Issue #959, PR #1235. -
Smaller API additions:
Robustness
Many of these were found by fuzzing and code review.
haltTree()from another thread now stopstickWhileRunning(). Before, the loop restarted the tree that had just been halted. Issue #686, PR #1201.- Timer nodes (Sleep, Delay, Timeout):
- Stack overflows → errors:
- Data races and use-after-free:
- Numeric conversions: overflow and undefined behavior in safe casts, float narrowing, uint16 parsing and JSON integers (#1238, #1239, #1240, #1242, #1249), plus locale-independent number parsing (#1218).
- Halting:
Behavior changes
_onlyIf,_onStartandFinallyare now reserved names. A node registered asFinallygets a duplicate-registration error.- SubTree literals are stored as strings again, as before 4.9.1. In script arithmetic, a numeric string is converted when mixed with a number. Two literal operands stay strings, so
"1" + "2"is"12"(issue #1246, PR #1254). - With
_autoremap="true", SubTree model defaults are now applied when the parent has no such entry at tree creation (#1272). - Writes through a SubTree remapping follow the same type rules as local writes (#1232).
- Now rejected at load time instead of being accepted:
- Now throw instead of silently wrapping or truncating:
- A BehaviorTree ID that replaces one from another file now prints a warning (#1133).
The full list is in CHANGELOG.rst.
Contributors
Thanks to Arthur Chan, Aysha Afrah Ziya, Azer Ben Ali, David Vadovszki, Golitsin Vyacheslav, Igor Stadnyk, Jonas Otto, KImanalieva, Lim Jooyoung, Nikola Kachmaryk, Varun Kumar, Victor Voronin, ktyang and simobenziane.