Skip to content

Commit fc0b0f6

Browse files
committed
add TickMonitorCallback
1 parent d8cd725 commit fc0b0f6

File tree

2 files changed

+54
-35
lines changed

2 files changed

+54
-35
lines changed

include/behaviortree_cpp/tree_node.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ class TreeNode
164164

165165
using PreTickCallback = std::function<NodeStatus(TreeNode&)>;
166166
using PostTickCallback = std::function<NodeStatus(TreeNode&, NodeStatus)>;
167+
using TickMonitorCallback =
168+
std::function<void(TreeNode&, NodeStatus, std::chrono::microseconds)>;
167169

168170
/**
169171
* @brief subscribeToStatusChange is used to attach a callback to a status change.
@@ -179,9 +181,9 @@ class TreeNode
179181

180182
/** This method attaches to the TreeNode a callback with signature:
181183
*
182-
* Optional<NodeStatus> myCallback(TreeNode& node)
184+
* NodeStatus callback(TreeNode& node)
183185
*
184-
* This callback is executed BEFORE the tick() and, if it returns a valid Optional<NodeStatus>,
186+
* This callback is executed BEFORE the tick() and, if it returns SUCCESS or FAILURE,
185187
* the actual tick() will NOT be executed and this result will be returned instead.
186188
*
187189
* This is useful to inject a "dummy" implementation of the TreeNode at run-time
@@ -191,13 +193,23 @@ class TreeNode
191193
/**
192194
* This method attaches to the TreeNode a callback with signature:
193195
*
194-
* Optional<NodeStatus> myCallback(TreeNode& node, NodeStatus new_status)
196+
* NodeStatus myCallback(TreeNode& node, NodeStatus status)
195197
*
196-
* This callback is executed AFTER the tick() and, if it returns a valid Optional<NodeStatus>,
198+
* This callback is executed AFTER the tick() and, if it returns SUCCESS or FAILURE,
197199
* the value returned by the actual tick() is overriden with this one.
198200
*/
199201
void setPostTickFunction(PostTickCallback callback);
200202

203+
/**
204+
* This method attaches to the TreeNode a callback with signature:
205+
*
206+
* void myCallback(TreeNode& node, NodeStatus status, std::chrono::microseconds duration)
207+
*
208+
* This callback is executed AFTER the tick() and will inform the user about its status and
209+
* the execution time. Works only if the tick was not substituted by a pre-condition.
210+
*/
211+
void setTickMonitorCallback(TickMonitorCallback callback);
212+
201213
/// The unique identifier of this instance of treeNode.
202214
/// It is assigneld by the factory
203215
[[nodiscard]] uint16_t UID() const;

src/tree_node.cpp

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ struct TreeNode::PImpl
3838

3939
std::string registration_ID;
4040

41-
PreTickCallback substitution_callback;
42-
43-
PostTickCallback post_condition_callback;
41+
PreTickCallback pre_tick_callback;
42+
PostTickCallback post_tick_callback;
43+
TickMonitorCallback tick_monitor_callback;
4444

4545
std::mutex callback_injection_mutex;
4646

@@ -70,6 +70,7 @@ TreeNode::~TreeNode()
7070

7171
NodeStatus TreeNode::executeTick()
7272
{
73+
std::unique_lock lk(_p->callback_injection_mutex);
7374
auto new_status = _p->status;
7475

7576
// a pre-condition may return the new status.
@@ -82,48 +83,48 @@ NodeStatus TreeNode::executeTick()
8283
{
8384
// injected pre-callback
8485
bool substituted = false;
85-
if(!isStatusCompleted(_p->status))
86+
if(_p->pre_tick_callback && !isStatusCompleted(_p->status))
8687
{
87-
PreTickCallback callback;
88-
{
89-
std::unique_lock lk(_p->callback_injection_mutex);
90-
callback = _p->substitution_callback;
91-
}
92-
if(callback)
88+
auto override_status = _p->pre_tick_callback(*this);
89+
if(isStatusCompleted(override_status))
9390
{
94-
auto override_status = callback(*this);
95-
if(isStatusCompleted(override_status))
96-
{
97-
// don't execute the actual tick()
98-
substituted = true;
99-
new_status = override_status;
100-
}
91+
// don't execute the actual tick()
92+
substituted = true;
93+
new_status = override_status;
10194
}
10295
}
10396

10497
// Call the ACTUAL tick
10598
if(!substituted)
10699
{
107-
new_status = tick();
100+
if(_p->tick_monitor_callback)
101+
{
102+
using namespace std::chrono;
103+
auto t1 = steady_clock::now();
104+
new_status = tick();
105+
auto t2 = steady_clock::now();
106+
_p->tick_monitor_callback(*this, new_status,
107+
duration_cast<microseconds>(t2 - t1));
108+
}
109+
else
110+
{
111+
new_status = tick();
112+
}
108113
}
109114
}
110115

111116
// injected post callback
112117
if(isStatusCompleted(new_status))
113118
{
114119
checkPostConditions(new_status);
115-
PostTickCallback callback;
116-
{
117-
std::unique_lock lk(_p->callback_injection_mutex);
118-
callback = _p->post_condition_callback;
119-
}
120-
if(callback)
120+
}
121+
122+
if(_p->post_tick_callback)
123+
{
124+
auto override_status = _p->post_tick_callback(*this, new_status);
125+
if(isStatusCompleted(override_status))
121126
{
122-
auto override_status = callback(*this, new_status);
123-
if(isStatusCompleted(override_status))
124-
{
125-
new_status = override_status;
126-
}
127+
new_status = override_status;
127128
}
128129
}
129130

@@ -308,13 +309,19 @@ TreeNode::subscribeToStatusChange(TreeNode::StatusChangeCallback callback)
308309
void TreeNode::setPreTickFunction(PreTickCallback callback)
309310
{
310311
std::unique_lock lk(_p->callback_injection_mutex);
311-
_p->substitution_callback = callback;
312+
_p->pre_tick_callback = callback;
312313
}
313314

314315
void TreeNode::setPostTickFunction(PostTickCallback callback)
315316
{
316317
std::unique_lock lk(_p->callback_injection_mutex);
317-
_p->post_condition_callback = callback;
318+
_p->post_tick_callback = callback;
319+
}
320+
321+
void TreeNode::setTickMonitorCallback(TickMonitorCallback callback)
322+
{
323+
std::unique_lock lk(_p->callback_injection_mutex);
324+
_p->tick_monitor_callback = callback;
318325
}
319326

320327
uint16_t TreeNode::UID() const

0 commit comments

Comments
 (0)