BehaviorTree
Core Library to create and execute Behavior Trees
Loading...
Searching...
No Matches
abstract_logger.h
1#ifndef ABSTRACT_LOGGER_H
2#define ABSTRACT_LOGGER_H
3
4#include "behaviortree_cpp/behavior_tree.h"
5#include "behaviortree_cpp/bt_factory.h"
6
7namespace BT
8{
9enum class TimestampType
10{
11 absolute,
12 relative
13};
14
16{
17public:
18 /// Construct and immediately subscribe to status changes.
19 StatusChangeLogger(TreeNode* root_node);
20
21 virtual ~StatusChangeLogger() = default;
22
23 StatusChangeLogger(const StatusChangeLogger& other) = delete;
24 StatusChangeLogger& operator=(const StatusChangeLogger& other) = delete;
25
26 StatusChangeLogger(StatusChangeLogger&& other) = delete;
27 StatusChangeLogger& operator=(StatusChangeLogger&& other) = delete;
28
29 virtual void callback(BT::Duration timestamp, const TreeNode& node,
30 NodeStatus prev_status, NodeStatus status) = 0;
31
32 virtual void flush() = 0;
33
34 void setEnabled(bool enabled)
35 {
36 enabled_ = enabled;
37 }
38
39 void setTimestampType(TimestampType type)
40 {
41 type_ = type;
42 }
43
44 bool enabled() const
45 {
46 return enabled_;
47 }
48
49 // false by default.
50 bool showsTransitionToIdle() const
51 {
52 return show_transition_to_idle_;
53 }
54
55 void enableTransitionToIdle(bool enable)
56 {
57 show_transition_to_idle_ = enable;
58 }
59
60protected:
61 /// Default constructor for deferred subscription. Call subscribeToTreeChanges() when ready.
62 StatusChangeLogger() = default;
63
64 /// Subscribe to status changes. Call at end of constructor for deferred subscription.
65 void subscribeToTreeChanges(TreeNode* root_node);
66
67private:
68 bool enabled_ = true;
69 bool show_transition_to_idle_ = true;
70 std::vector<TreeNode::StatusChangeSubscriber> subscribers_;
71 TimestampType type_ = TimestampType::absolute;
72 BT::TimePoint first_timestamp_ = {};
73 std::mutex callback_mutex_;
74};
75
76//--------------------------------------------
77
79{
81}
82
84{
85 first_timestamp_ = std::chrono::high_resolution_clock::now();
86
87 auto subscribeCallback = [this](TimePoint timestamp, const TreeNode& node,
88 NodeStatus prev, NodeStatus status) {
89 // Copy state under lock, then release before calling user code
90 // This prevents recursive mutex locking when multiple nodes change status
91 bool should_callback = false;
92 Duration adjusted_timestamp;
93 {
94 std::unique_lock lk(callback_mutex_);
95 if(enabled_ && (status != NodeStatus::IDLE || show_transition_to_idle_))
96 {
97 should_callback = true;
98 adjusted_timestamp = (type_ == TimestampType::absolute) ?
99 timestamp.time_since_epoch() :
100 (timestamp - first_timestamp_);
101 }
102 }
103 if(should_callback)
104 {
105 this->callback(adjusted_timestamp, node, prev, status);
106 }
107 };
108
109 auto visitor = [this, subscribeCallback](TreeNode* node) {
110 subscribers_.push_back(node->subscribeToStatusChange(std::move(subscribeCallback)));
111 };
112
113 applyRecursiveVisitor(root_node, visitor);
114}
115} // namespace BT
116
117#endif // ABSTRACT_LOGGER_H
Definition: abstract_logger.h:16
void subscribeToTreeChanges(TreeNode *root_node)
Subscribe to status changes. Call at end of constructor for deferred subscription.
Definition: abstract_logger.h:83
StatusChangeLogger(TreeNode *root_node)
Construct and immediately subscribe to status changes.
Definition: abstract_logger.h:78
StatusChangeLogger()=default
Default constructor for deferred subscription. Call subscribeToTreeChanges() when ready.
Abstract base class for Behavior Tree Nodes.
Definition: tree_node.h:154
Definition: action_node.h:24
NodeStatus
Definition: basic_types.h:34