Go to the documentation of this file.
28 #pragma warning(disable : 4127)
57 "_failureIf",
"_successIf",
"_skipIf",
"_while"
71 "_onHalted",
"_onFailure",
"_onSuccess",
"_post"
75 [[nodiscard]] std::string toStr<BT::PostCond>(
const BT::PostCond& cond);
78 [[nodiscard]] std::string toStr<BT::PreCond>(
const BT::PreCond& cond);
90 std::shared_ptr<ScriptingEnumsRegistry>
enums;
117 template <
typename T>
123 template <
typename T,
typename... ExtraArgs>
127 ExtraArgs...>::value;
134 typedef std::shared_ptr<TreeNode>
Ptr;
161 [[nodiscard]]
bool isHalted()
const;
166 [[nodiscard]]
const std::string&
name()
const;
228 [[nodiscard]] uint16_t
UID()
const;
232 [[nodiscard]]
const std::string&
fullPath()
const;
249 template <
typename T>
260 template <
typename T>
262 T& destination)
const;
269 template <
typename T>
274 return (res) ?
Expected<T>(out) : nonstd::make_unexpected(res.error());
282 template <
typename T>
293 return nonstd::make_unexpected(res.error());
303 template <
typename T>
359 template <
class DerivedT,
typename... ExtraArgs>
364 static_assert(hasNodeFullCtor<DerivedT, ExtraArgs...>() ||
365 hasNodeNameCtor<DerivedT>());
367 if constexpr(hasNodeFullCtor<DerivedT, ExtraArgs...>())
369 return std::make_unique<DerivedT>(
name,
config, args...);
371 else if constexpr(hasNodeNameCtor<DerivedT>())
373 auto node_ptr =
new DerivedT(
name, args...);
374 node_ptr->config() =
config;
375 return std::unique_ptr<DerivedT>(node_ptr);
413 template <
typename T>
418 std::unique_ptr<PImpl>
_p;
425 virtual void halt() = 0;
430 template <
typename T>
433 if constexpr(std::is_enum_v<T> && !std::is_same_v<T, NodeStatus>)
437 if(it !=
config().enums->end())
439 return static_cast<T
>(it->second);
444 return static_cast<T
>(convertFromString<int>(str));
447 return convertFromString<T>(str);
450 template <
typename T>
452 T& destination)
const
454 std::string port_value_str;
457 if(input_port_it !=
config().input_ports.end())
459 port_value_str = input_port_it->second;
463 return nonstd::make_unexpected(
StrCat(
"getInput() of node '",
fullPath(),
464 "' failed because the manifest is "
465 "nullptr (WTF?) and the key: [",
466 key,
"] is missing"));
474 return nonstd::make_unexpected(
StrCat(
"getInput() of node '",
fullPath(),
475 "' failed because the manifest doesn't "
476 "contain the key: [",
479 const auto& port_info = port_manifest_it->second;
481 if(port_info.defaultValue().empty())
483 return nonstd::make_unexpected(
StrCat(
"getInput() of node '",
fullPath(),
484 "' failed because nor the manifest or the "
485 "XML contain the key: [",
488 if(port_info.defaultValue().isString())
490 port_value_str = port_info.defaultValue().cast<std::string>();
494 destination = port_info.defaultValue().cast<T>();
507 destination = parseString<T>(port_value_str);
509 catch(std::exception& ex)
511 return nonstd::make_unexpected(
StrCat(
"getInput(): ", ex.what()));
515 const auto& blackboard_key = blackboard_ptr.value();
519 return nonstd::make_unexpected(
"getInput(): trying to access "
520 "an invalid Blackboard");
523 if(
auto entry =
config().blackboard->getEntry(std::string(blackboard_key)))
525 std::unique_lock lk(entry->entry_mutex);
526 auto& any_value = entry->value;
529 if constexpr(std::is_same_v<T, Any>)
531 destination = any_value;
532 return Timestamp{ entry->sequence_id, entry->stamp };
535 if(!entry->value.empty())
537 if(!std::is_same_v<T, std::string> && any_value.isString())
539 destination = parseString<T>(any_value.cast<std::string>());
543 destination = any_value.cast<T>();
545 return Timestamp{ entry->sequence_id, entry->stamp };
549 return nonstd::make_unexpected(
StrCat(
"getInput() failed because it was unable to "
551 key,
"] remapped to [", blackboard_key,
"]"));
553 catch(std::exception& err)
555 return nonstd::make_unexpected(err.what());
559 template <
typename T>
565 return nonstd::make_unexpected(res.error());
570 template <
typename T>
575 return nonstd::make_unexpected(
"setOutput() failed: trying to access a "
576 "Blackboard(BB) entry, but BB is invalid");
580 if(remap_it ==
config().output_ports.end())
582 return nonstd::make_unexpected(
StrCat(
"setOutput() failed: "
583 "NodeConfig::output_ports "
584 "does not contain the key: [",
588 if(remapped_key ==
"{=}" || remapped_key ==
"=")
596 return nonstd::make_unexpected(
"setOutput requires a blackboard pointer. Use {}");
599 if constexpr(std::is_same_v<BT::Any, T>)
604 throw LogicError(
"setOutput<Any> is not allowed, unless the port "
605 "was declared using OutputPort<Any>");
616 template <
typename T>
619 for(
const auto& it : getProvidedPorts<T>())
621 const auto& port_name = it.first;
622 const auto direction = it.second.direction();
Result getInput(const std::string &key, T &destination) const
std::shared_ptr< CallableFunction > Subscriber
NodeType
Enumerates the possible types of nodes.
bool requiresWakeUp() const
std::map< PreCond, std::string > pre_conditions
const NodeConfig & config() const
void emitWakeUpSignal()
Notify that the tree should be ticked again()
StatusChangeSignal::Subscriber StatusChangeSubscriber
std::function< void(TreeNode &, NodeStatus, std::chrono::microseconds)> TickMonitorCallback
constexpr bool hasNodeFullCtor()
nonstd::expected< T, std::string > Expected
virtual BT::NodeStatus executeTick()
The method that should be used to invoke tick() and setStatus();.
std::string_view StringView
PortsRemapping input_ports
std::function< Any(Ast::Environment &env)> ScriptFunction
void setPreTickFunction(PreTickCallback callback)
Abstract base class for Behavior Tree Nodes.
Struct used to store a tree. If this object goes out of scope, the tree is destroyed.
std::shared_ptr< TreeNode > Ptr
std::function< void(CallableArgs...)> CallableFunction
std::function< NodeStatus(TreeNode &)> PreTickCallback
constexpr E value(std::size_t i) noexcept
std::unordered_map< std::string, std::string > NonPortAttributes
const std::string & registrationName() const
registrationName is the ID used by BehaviorTreeFactory to create an instance.
std::array< ScriptFunction, size_t(PostCond::COUNT_)> PostScripts
constexpr auto callback(Fns &&... fns)
Creates a callback.
std::shared_ptr< Blackboard > Ptr
Blackboard::Ptr blackboard
std::unordered_map< std::string, PortInfo > PortsList
NodeStatus status() const
void setPostTickFunction(PostTickCallback callback)
BT::NodeStatus waitValidStatus()
std::string registration_ID
void setStatus(NodeStatus new_status)
setStatus changes the status of the node. it will throw if you try to change the status to IDLE,...
void setTickMonitorCallback(TickMonitorCallback callback)
StringView getRawPortValue(const std::string &key) const
T parseString(const std::string &str) const
Expected< StampedValue< T > > getInputStamped(const std::string &key) const
static std::unique_ptr< TreeNode > Instantiate(const std::string &name, const NodeConfig &config, ExtraArgs... args)
This information is used mostly by the XMLParser.
static const std::array< std::string, 4 > PostCondNames
virtual NodeType type() const =0
std::unordered_map< std::string, int > ScriptingEnumsRegistry
PostScripts & postConditionsScripts()
AnyPtrLocked getLockedPortContent(const std::string &key)
getLockedPortContent should be used when:
The LockedPtr class is used to share a pointer to an object and a mutex that protects the read/write ...
void setRegistrationID(StringView ID)
The BehaviorTreeFactory is used to create instances of a TreeNode at run-time.
void checkPostConditions(NodeStatus status)
std::vector< std::pair< std::string, std::string > > KeyValueVector
Result setOutput(const std::string &key, const T &value)
setOutput modifies the content of an Output port
const TreeNodeManifest * manifest
Expected< T > getInput(const std::string &key) const
const std::string & name() const
Name of the instance, not the type.
virtual BT::NodeStatus tick()=0
Method to be implemented by the user.
void modifyPortsRemapping(const PortsRemapping &new_remapping)
TreeNode & operator=(const TreeNode &other)=delete
PreScripts & preConditionsScripts()
std::unordered_map< std::string, std::string > PortsRemapping
static Expected< StringView > getRemappedKey(StringView port_name, StringView remapped_port)
void setWakeUpInstance(std::shared_ptr< WakeUpSignal > instance)
Expected< Timestamp > getInputStamped(const std::string &key, T &destination) const
getInputStamped is similar to getInput(dey, destination), but it returne also the Timestamp object,...
StatusChangeSubscriber subscribeToStatusChange(StatusChangeCallback callback)
subscribeToStatusChange is used to attach a callback to a status change. When StatusChangeSubscriber ...
void assignDefaultRemapping(NodeConfig &config)
std::map< PostCond, std::string > post_conditions
TreeNode(std::string name, NodeConfig config)
TreeNode main constructor.
std::unique_ptr< PImpl > _p
void resetStatus()
Set the status to IDLE.
constexpr auto is_constructible
std::array< ScriptFunction, size_t(PreCond::COUNT_)> PreScripts
const std::string & fullPath() const
constexpr bool hasNodeNameCtor()
Expected< NodeStatus > checkPreConditions()
std::function< NodeStatus(TreeNode &, NodeStatus)> PostTickCallback
PortsRemapping output_ports
static const std::array< std::string, 4 > PreCondNames
Expected< std::monostate > Result
static bool isBlackboardPointer(StringView str, StringView *stripped_pointer=nullptr)
Check a string and return true if it matches the pattern: {...}.
std::shared_ptr< ScriptingEnumsRegistry > enums
StatusChangeSignal::CallableFunction StatusChangeCallback
static StringView stripBlackboardPointer(StringView str)
NonPortAttributes other_attributes