t15_nodes_mocking.cpp
Go to the documentation of this file.
2 #include "dummy_nodes.h"
3 
4 // clang-format off
5 
6 static const char* xml_text = R"(
7 <root BTCPP_format="4">
8 
9  <BehaviorTree ID="MainTree">
10  <Sequence>
11  <SaySomething name="talk" message="hello world"/>
12 
13  <SubTree ID="MySub" name="mysub"/>
14 
15  <Script name="set_message" code="msg:= 'the original message' "/>
16  <SaySomething message="{msg}"/>
17 
18  <Sequence name="counting">
19  <SaySomething message="1"/>
20  <SaySomething message="2"/>
21  <SaySomething message="3"/>
22  </Sequence>
23  </Sequence>
24  </BehaviorTree>
25 
26  <BehaviorTree ID="MySub">
27  <Sequence>
28  <AlwaysSuccess name="action_subA"/>
29  <AlwaysSuccess name="action_subB"/>
30  </Sequence>
31  </BehaviorTree>
32 
33 </root>
34  )";
35 
36 // clang-format on
37 
46 int main(int argc, char** argv)
47 {
48  using namespace DummyNodes;
50  factory.registerNodeType<SaySomething>("SaySomething");
52 
53  // let's check what the "original" tree should return
54  {
55  auto tree = factory.createTree("MainTree");
56 
57  std::cout << "----- Nodes fullPath() -------\n";
58  // as a reminder, let's print the full names of all the nodes
59  tree.applyVisitor(
60  [](BT::TreeNode* node) { std::cout << node->fullPath() << std::endl; });
61 
62  std::cout << "\n------ Output (original) ------\n";
63  tree.tickWhileRunning();
64  }
65 
66  // We have three mechanisms to create Nodes to be used as "mocks".
67  // We will see later how to use them.
68 
69  //---------------------------------------------------------------
70  // Mock type 1: register a specific "dummy" Node into the factory
71  // You can use any registration method, but to keep this short,
72  // we use registerSimpleAction()
73 
74  factory.registerSimpleAction("DummyAction", [](BT::TreeNode& self) {
75  std::cout << "DummyAction substituting node with fullPath(): " << self.fullPath()
76  << std::endl;
78  });
79 
80  factory.registerSimpleAction("DummySaySomething", [](BT::TreeNode& self) {
81  auto msg = self.getInput<std::string>("message");
82  std::cout << "DummySaySomething: " << msg.value() << std::endl;
84  });
85 
86  //---------------------------------------------------------------
87  // Mock type 2: Use our configurable BT::TestNode
88 
89  // This is the configuration passed to the TestNode
90  BT::TestNodeConfig test_config;
91  // we want this to return always SUCCESS
93  // Convert the node in asynchronous and wait 2000 ms
94  test_config.async_delay = std::chrono::milliseconds(2000);
95  // Execute this postcondition, once completed
96  test_config.post_script = "msg := 'message SUBSTITUTED' ";
97 
98  // this will be synchronous (async_delay is 0)
99  BT::TestNodeConfig counting_config;
101 
102  //---------------------------------------------------------------
103  // Next, we want to substitute one or more of out Nodes with this mocks
104  // The simplest way is to use a JSON file, otherwise we can do it manually.
105  bool const USE_JSON = true;
106 
107  if(!USE_JSON) // manually add substitution rules
108  {
109  // Substitute nodes which match the wildcard pattern "mysub/action_*"
110  // with DummyAction
111  factory.addSubstitutionRule("mysub/action_*", "DummyAction");
112 
113  // Substitute the node with name "talk" with DummySaySomething
114  factory.addSubstitutionRule("talk", "DummySaySomething");
115 
116  // Substitute the node with name "set_message" with
117  // the a BT::TestNode with the give configuration
118  factory.addSubstitutionRule("set_message", test_config);
119 
120  // we can also substitute entire branches, for instance the Sequence "counting"
121  factory.addSubstitutionRule("counting", counting_config);
122  }
123  else // use a JSON file to apply substitution rules programmatically
124  {
125  // this JSON is equivalent to the code we wrote above
126  const char* json_text = R"(
127  {
128  "TestNodeConfigs": {
129  "NewMessage": {
130  "async_delay": 2000,
131  "return_status": "SUCCESS",
132  "post_script": "msg ='message SUBSTITUTED'"
133  },
134  "NoCounting": {
135  "return_status": "SUCCESS"
136  }
137  },
138 
139  "SubstitutionRules": {
140  "mysub/action_*": "DummyAction",
141  "talk": "DummySaySomething",
142  "set_message": "NewMessage",
143  "counting": "NoCounting"
144  }
145  })";
146 
148  }
149  //---------------------------------------------------------------
150  // IMPORTANT: all substiutions must be done BEFORE creating the tree
151  // During the construction phase of the tree, the substitution
152  // rules will be used to instantiate the test nodes, instead of the
153  // original ones.
154  auto tree = factory.createTree("MainTree");
155  std::cout << "\n------ Output (substituted) ------\n";
156  tree.tickWhileRunning();
157 
158  return 0;
159 }
160 
161 /* Expecte output:
162 
163 ----- Nodes fullPath() -------
164 Sequence::1
165 talk
166 mysub
167 mysub/Sequence::4
168 mysub/action_subA
169 mysub/action_subB
170 set_message
171 SaySomething::8
172 counting
173 SaySomething::10
174 SaySomething::11
175 SaySomething::12
176 
177 ------ Output (original) ------
178 Robot says: hello world
179 Robot says: the original message
180 Robot says: 1
181 Robot says: 2
182 Robot says: 3
183 
184 ------ Output (substituted) ------
185 DummySaySomething: hello world
186 DummyAction substituting node with fullPath(): mysub/action_subA
187 DummyAction substituting node with fullPath(): mysub/action_subB
188 Robot says: message SUBSTITUTED
189 
190 */
BT::TestNodeConfig::async_delay
std::chrono::milliseconds async_delay
if async_delay > 0, this action become asynchronous and wait this amount of time
Definition: test_node.h:38
BT::BehaviorTreeFactory::createTree
Tree createTree(const std::string &tree_name, Blackboard::Ptr blackboard=Blackboard::create())
Definition: bt_factory.cpp:432
BT::BehaviorTreeFactory::loadSubstitutionRuleFromJSON
void loadSubstitutionRuleFromJSON(const std::string &json_text)
loadSubstitutionRuleFromJSON will parse a JSON file to create a set of substitution rules....
Definition: bt_factory.cpp:480
BT::TreeNode
Abstract base class for Behavior Tree Nodes.
Definition: tree_node.h:118
bt_factory.h
DummyNodes
Definition: dummy_nodes.cpp:10
BT::Tree::tickWhileRunning
NodeStatus tickWhileRunning(std::chrono::milliseconds sleep_time=std::chrono::milliseconds(10))
Definition: bt_factory.cpp:609
dummy_nodes.h
BT::TestNodeConfig
Definition: test_node.h:23
json_text
static const char * json_text
Definition: gtest_substitution.cpp:6
BT::BehaviorTreeFactory::registerNodeType
void registerNodeType(const std::string &ID, const PortsList &ports, ExtraArgs... args)
Definition: bt_factory.h:322
main
int main(int argc, char **argv)
In this example we will see how we can substitute some nodes in the Tree above with.
Definition: t15_nodes_mocking.cpp:46
BT::TestNodeConfig::return_status
NodeStatus return_status
status to return when the action is completed.
Definition: test_node.h:26
xml_text
static const char * xml_text
Definition: t15_nodes_mocking.cpp:6
DummyNodes::SaySomething
Definition: dummy_nodes.h:47
BT::BehaviorTreeFactory
The BehaviorTreeFactory is used to create instances of a TreeNode at run-time.
Definition: bt_factory.h:205
BT::NodeStatus::SUCCESS
@ SUCCESS
BT::BehaviorTreeFactory::registerBehaviorTreeFromText
void registerBehaviorTreeFromText(const std::string &xml_text)
Definition: bt_factory.cpp:277
BT::TreeNode::fullPath
const std::string & fullPath() const
Definition: tree_node.cpp:335
BT::TestNodeConfig::post_script
std::string post_script
script to execute when actions is completed
Definition: test_node.h:35
BT::BehaviorTreeFactory::addSubstitutionRule
void addSubstitutionRule(StringView filter, SubstitutionRule rule)
addSubstitutionRule replace a node with another one when the tree is created. If the rule ia a string...
Definition: bt_factory.cpp:475
BT::Tree::applyVisitor
void applyVisitor(const std::function< void(const TreeNode *)> &visitor)
Definition: bt_factory.cpp:623
BT::BehaviorTreeFactory::registerSimpleAction
void registerSimpleAction(const std::string &ID, const SimpleActionNode::TickFunctor &tick_functor, PortsList ports={})
registerSimpleAction help you register nodes of type SimpleActionNode.
Definition: bt_factory.cpp:166


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Fri Jun 28 2024 02:20:08