Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit aed23b7

Browse files
author
Davide Faconti
committed
addrss problem with ReactiveSequence
1 parent c1acda0 commit aed23b7

File tree

3 files changed

+91
-2
lines changed

3 files changed

+91
-2
lines changed

include/behaviortree_cpp/controls/reactive_sequence.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,12 @@ class ReactiveSequence : public ControlNode
3838
ReactiveSequence(const std::string& name):
3939
ControlNode(name, {}) {}
4040

41+
virtual void halt() override;
42+
4143
private:
4244

4345
virtual BT::NodeStatus tick() override;
46+
std::vector<bool> is_asynch_child_;
4447
};
4548

4649
}

src/controls/reactive_sequence.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,42 @@
1515
namespace BT
1616
{
1717

18+
void ReactiveSequence::halt()
19+
{
20+
std::fill(is_asynch_child_.begin(), is_asynch_child_.end(), false );
21+
ControlNode::halt();
22+
}
23+
1824
NodeStatus ReactiveSequence::tick()
1925
{
26+
is_asynch_child_.resize(childrenCount(), false);
2027
size_t success_count = 0;
2128
size_t running_count = 0;
2229

2330
for (size_t index = 0; index < childrenCount(); index++)
2431
{
2532
TreeNode* current_child_node = children_nodes_[index];
33+
if( is_asynch_child_[index] && current_child_node->status() == NodeStatus::SUCCESS )
34+
{
35+
success_count++;
36+
continue; // skip already executed asynch children
37+
}
38+
2639
const NodeStatus child_status = current_child_node->executeTick();
2740

2841
switch (child_status)
2942
{
3043
case NodeStatus::RUNNING:
3144
{
45+
is_asynch_child_[index] = true;
3246
running_count++;
3347
haltChildren(index+1);
3448
return NodeStatus::RUNNING;
3549
}
3650

3751
case NodeStatus::FAILURE:
3852
{
39-
haltChildren(0);
53+
halt();
4054
return NodeStatus::FAILURE;
4155
}
4256
case NodeStatus::SUCCESS:
@@ -53,7 +67,7 @@ NodeStatus ReactiveSequence::tick()
5367

5468
if( success_count == childrenCount())
5569
{
56-
haltChildren(0);
70+
halt();
5771
return NodeStatus::SUCCESS;
5872
}
5973
return NodeStatus::RUNNING;

tests/gtest_sequence.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,34 @@ struct ComplexSequenceTest : testing::Test
6767
}
6868
};
6969

70+
struct ReactiveSequenceTest : testing::Test
71+
{
72+
BT::ReactiveSequence root;
73+
BT::AsyncActionTest action_1;
74+
BT::AsyncActionTest action_2;
75+
BT::ConditionTestNode condition_1;
76+
BT::ConditionTestNode condition_2;
77+
78+
ReactiveSequenceTest()
79+
: root("root")
80+
, action_1("action_1", milliseconds(100))
81+
, action_2("action_1", milliseconds(100))
82+
, condition_1("condition_1")
83+
, condition_2("condition_2")
84+
{
85+
root.addChild(&condition_1);
86+
root.addChild(&action_1);
87+
root.addChild(&condition_2);
88+
root.addChild(&action_2);
89+
90+
}
91+
~ReactiveSequenceTest()
92+
{
93+
haltAllActions(&root);
94+
}
95+
};
96+
97+
7098
struct SequenceTripleActionTest : testing::Test
7199
{
72100
BT::SequenceNode root;
@@ -348,6 +376,50 @@ TEST_F(ComplexSequenceTest, ComplexSequenceConditions2ToFalse)
348376
ASSERT_EQ(NodeStatus::IDLE, action_1.status());
349377
}
350378

379+
TEST_F(ReactiveSequenceTest, ReactiveSequence)
380+
{
381+
// actions take 100 ms, therefore a succesfull sequence should take 200 ms
382+
BT::NodeStatus state = root.executeTick();
383+
ASSERT_EQ(NodeStatus::RUNNING, state);
384+
385+
auto begin_time = std::chrono::steady_clock::now();
386+
while( state == NodeStatus::RUNNING)
387+
{
388+
state = root.executeTick();
389+
std::this_thread::sleep_for( milliseconds(5) );
390+
}
391+
auto end_time = std::chrono::steady_clock::now();
392+
int elapsed_ms = std::chrono::duration_cast<milliseconds>(end_time - begin_time).count();
393+
394+
ASSERT_EQ(NodeStatus::SUCCESS, state);
395+
ASSERT_GE( elapsed_ms, 200 );
396+
ASSERT_LE( elapsed_ms, 220 );
397+
398+
//---------------------
399+
root.halt();
400+
// action_1 is executed, but action_2 isn't. Total expected time 100 ms
401+
condition_2.setBoolean( false );
402+
403+
state = root.executeTick();
404+
ASSERT_EQ(NodeStatus::RUNNING, state);
405+
406+
begin_time = std::chrono::steady_clock::now();
407+
while( state == NodeStatus::RUNNING)
408+
{
409+
state = root.executeTick();
410+
std::this_thread::sleep_for( milliseconds(5) );
411+
}
412+
end_time = std::chrono::steady_clock::now();
413+
elapsed_ms = std::chrono::duration_cast<milliseconds>(end_time - begin_time).count();
414+
415+
ASSERT_EQ(NodeStatus::FAILURE, state);
416+
ASSERT_GE( elapsed_ms, 100 );
417+
ASSERT_LE( elapsed_ms, 120 );
418+
419+
}
420+
421+
422+
351423
TEST_F(SimpleSequenceWithMemoryTest, ConditionTrue)
352424
{
353425
BT::NodeStatus state = root.executeTick();

0 commit comments

Comments
 (0)