bt_factory.h
Go to the documentation of this file.
1 /* Copyright (C) 2018 Michele Colledanchise - All Rights Reserved
2  * Copyright (C) 2018-2019 Davide Faconti, Eurecat - All Rights Reserved
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
5 * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
6 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
7 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
10 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
11 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12 */
13 
14 #ifndef BT_FACTORY_H
15 #define BT_FACTORY_H
16 
17 #include <functional>
18 #include <memory>
19 #include <unordered_map>
20 #include <unordered_set>
21 #include <cstring>
22 #include <algorithm>
23 #include <set>
24 
25 
27 
28 namespace BT
29 {
30 
32 typedef std::function<std::unique_ptr<TreeNode>(const std::string&, const NodeConfiguration&)>
34 
35 constexpr const char* PLUGIN_SYMBOL = "BT_RegisterNodesFromPlugin";
36 
37 #ifndef BT_PLUGIN_EXPORT
38 
39 /* Use this macro to automatically register one or more custom Nodes
40 into a factory. For instance:
41 
42 BT_REGISTER_NODES(factory)
43 {
44  factory.registerNodeType<MoveBaseAction>("MoveBase");
45 }
46 
47 IMPORTANT: this must funtion MUST be declared in a cpp file, NOT a header file.
48 See examples for more information about configuring CMake correctly
49 */
50 #define BT_REGISTER_NODES(factory) \
51  static void BT_RegisterNodesFromPlugin(BT::BehaviorTreeFactory& factory)
52 
53 #else
54 
55 #ifdef __linux__
56 
57 #define BT_REGISTER_NODES(factory) \
58  extern "C" void __attribute__((visibility("default"))) \
59  BT_RegisterNodesFromPlugin(BT::BehaviorTreeFactory& factory)
60 
61 #elif _WIN32
62 
63 #define BT_REGISTER_NODES(factory) \
64  __declspec(dllexport) void BT_RegisterNodesFromPlugin(BT::BehaviorTreeFactory& factory)
65 #endif
66 
67 #endif
68 
69 
78 struct Tree
79 {
81  std::vector<TreeNode::Ptr> nodes;
82  std::vector<Blackboard::Ptr> blackboard_stack;
83  std::unordered_map<std::string, TreeNodeManifest> manifests;
84 
85  Tree() : root_node(nullptr) { }
86  ~Tree();
87 
89 };
90 
99 {
100 public:
102 
104  bool unregisterBuilder(const std::string& ID);
105 
107  void registerBuilder(const TreeNodeManifest& manifest, const NodeBuilder& builder);
108 
109  template <typename T>
110  void registerBuilder(const std::string& ID, const NodeBuilder& builder )
111  {
112  auto manifest = BehaviorTreeFactory::buildManifest<T>(ID);
113  registerBuilder(manifest, builder);
114  }
115 
124  void registerSimpleAction(const std::string& ID,
125  const SimpleActionNode::TickFunctor& tick_functor,
126  PortsList ports = {});
135  void registerSimpleCondition(const std::string& ID,
136  const SimpleConditionNode::TickFunctor& tick_functor,
137  PortsList ports = {});
146  void registerSimpleDecorator(const std::string& ID,
147  const SimpleDecoratorNode::TickFunctor& tick_functor,
148  PortsList ports = {});
149 
155  void registerFromPlugin(const std::string &file_path);
156 
165  std::unique_ptr<TreeNode> instantiateTreeNode(const std::string& name, const std::string &ID,
166  const NodeConfiguration& config) const;
167 
173  template <typename T>
174  void registerNodeType(const std::string& ID)
175  {
176  static_assert(std::is_base_of<ActionNodeBase, T>::value ||
177  std::is_base_of<ControlNode, T>::value ||
178  std::is_base_of<DecoratorNode, T>::value ||
179  std::is_base_of<ConditionNode, T>::value,
180  "[registerBuilder]: accepts only classed derived from either ActionNodeBase, "
181  "DecoratorNode, ControlNode or ConditionNode");
182 
183  static_assert(!std::is_abstract<T>::value,
184  "[registerBuilder]: Some methods are pure virtual. "
185  "Did you override the methods tick() and halt()?");
186 
187  constexpr bool default_constructable = std::is_constructible<T, const std::string&>::value;
188  constexpr bool param_constructable =
189  std::is_constructible<T, const std::string&, const NodeConfiguration&>::value;
190  constexpr bool has_static_ports_list =
192 
193  static_assert(default_constructable || param_constructable,
194  "[registerBuilder]: the registered class must have at least one of these two "
195  "constructors: "
196  " (const std::string&, const NodeParameters&) or (const std::string&).");
197 
198  static_assert(!(param_constructable && !has_static_ports_list),
199  "[registerBuilder]: you MUST implement the static method: "
200  " PortsList providedPorts();\n");
201 
202  static_assert(!(has_static_ports_list && !param_constructable),
203  "[registerBuilder]: since you have a static method requiredNodeParameters(), "
204  "you MUST add a constructor sign signature (const std::string&, const "
205  "NodeParameters&)\n");
206 
207  registerNodeTypeImpl<T>(ID);
208  }
209 
211  const std::unordered_map<std::string, NodeBuilder>& builders() const;
212 
214  const std::unordered_map<std::string, TreeNodeManifest>& manifests() const;
215 
217  const std::set<std::string>& builtinNodes() const;
218 
219  Tree createTreeFromText(const std::string& text,
220  Blackboard::Ptr blackboard = Blackboard::create());
221 
222  Tree createTreeFromFile(const std::string& file_path,
223  Blackboard::Ptr blackboard = Blackboard::create());
224 
225  template <typename T> static
226  TreeNodeManifest buildManifest(const std::string& ID)
227  {
228  return { getType<T>(), ID, getProvidedPorts<T>() };
229  }
230 
231 private:
232  std::unordered_map<std::string, NodeBuilder> builders_;
233  std::unordered_map<std::string, TreeNodeManifest> manifests_;
234  std::set<std::string> builtin_IDs_;
235 
236  // template specialization = SFINAE + black magic
237 
238  // clang-format off
239  template <typename T>
240  using has_default_constructor = typename std::is_constructible<T, const std::string&>;
241 
242  template <typename T>
243  using has_params_constructor = typename std::is_constructible<T, const std::string&, const NodeConfiguration&>;
244 
245  template <typename T>
246  void registerNodeTypeImpl(const std::string& ID)
247  {
248  NodeBuilder builder = getBuilder<T>();
249  registerBuilder( buildManifest<T>(ID), builder);
250  }
251 
252  template <typename T> static
254  has_params_constructor<T>::value >::type* = nullptr)
255  {
256  return [](const std::string& name, const NodeConfiguration& config)
257  {
258  //TODO FIXME
259 
260  // Special case. Use default constructor if parameters are empty
261  if( config.input_ports.empty() &&
262  config.output_ports.empty() &&
264  {
265  return std::make_unique<T>(name);
266  }
267  return std::make_unique<T>(name, config);
268  };
269  }
270 
271  template <typename T> static
273  has_params_constructor<T>::value >::type* = nullptr)
274  {
275  return [](const std::string& name, const NodeConfiguration& params)
276  {
277  return std::unique_ptr<TreeNode>(new T(name, params));
278  };
279  }
280 
281  template <typename T> static
283  !has_params_constructor<T>::value >::type* = nullptr)
284  {
285  return [](const std::string& name, const NodeConfiguration&)
286  {
287  return std::unique_ptr<TreeNode>(new T(name));
288  };
289  }
290  // clang-format on
291 };
292 
293 } // end namespace
294 
295 #endif // BT_FACTORY_H
constexpr const char * PLUGIN_SYMBOL
Definition: bt_factory.h:35
static Blackboard::Ptr create(Blackboard::Ptr parent={})
Definition: blackboard.h:38
manifest
void registerNodeType(const std::string &ID)
Definition: bt_factory.h:174
std::function< NodeStatus(NodeStatus, TreeNode &)> TickFunctor
std::function< std::unique_ptr< TreeNode >const std::string &, const NodeConfiguration &)> NodeBuilder
The term "Builder" refers to the Builder Pattern (https://en.wikipedia.org/wiki/Builder_pattern) ...
Definition: bt_factory.h:33
void registerNodeTypeImpl(const std::string &ID)
Definition: bt_factory.h:246
std::unordered_map< std::string, NodeBuilder > builders_
Definition: bt_factory.h:232
std::set< std::string > builtin_IDs_
Definition: bt_factory.h:234
std::shared_ptr< Blackboard > Ptr
Definition: blackboard.h:26
This information is used mostly by the XMLParser.
Definition: tree_node.h:32
TreeNode * root_node
Definition: bt_factory.h:80
std::unordered_map< std::string, TreeNodeManifest > manifests_
Definition: bt_factory.h:233
static NodeBuilder getBuilder(typename std::enable_if< has_default_constructor< T >::value &&has_params_constructor< T >::value >::type *=nullptr)
Definition: bt_factory.h:253
void registerBuilder(const std::string &ID, const NodeBuilder &builder)
Definition: bt_factory.h:110
The BehaviorTreeFactory is used to create instances of a TreeNode at run-time.
Definition: bt_factory.h:98
std::vector< Blackboard::Ptr > blackboard_stack
Definition: bt_factory.h:82
typename std::is_constructible< T, const std::string & > has_default_constructor
Definition: bt_factory.h:240
builder
Definition: build.py:70
PortsRemapping output_ports
Definition: tree_node.h:49
Abstract base class for Behavior Tree Nodes.
Definition: tree_node.h:53
typename std::enable_if< Predicate::value >::type * enable_if
Definition: basic_types.h:159
std::function< NodeStatus(TreeNode &)> TickFunctor
Definition: action_node.h:84
std::unordered_map< std::string, PortInfo > PortsList
Definition: basic_types.h:316
std::vector< TreeNode::Ptr > nodes
Definition: bt_factory.h:81
static NodeBuilder getBuilder(typename std::enable_if<!has_default_constructor< T >::value &&has_params_constructor< T >::value >::type *=nullptr)
Definition: bt_factory.h:272
static TreeNodeManifest buildManifest(const std::string &ID)
Definition: bt_factory.h:226
Struct used to store a tree. If this object goes out of scope, the tree is destroyed.
Definition: bt_factory.h:78
std::unordered_map< std::string, TreeNodeManifest > manifests
Definition: bt_factory.h:83
PortsRemapping input_ports
Definition: tree_node.h:48
static NodeBuilder getBuilder(typename std::enable_if< has_default_constructor< T >::value &&!has_params_constructor< T >::value >::type *=nullptr)
Definition: bt_factory.h:282
std::function< NodeStatus(TreeNode &)> TickFunctor
Blackboard::Ptr rootBlackboard()
Definition: bt_factory.cpp:197
typename std::is_constructible< T, const std::string &, const NodeConfiguration & > has_params_constructor
Definition: bt_factory.h:243


behaviortree_cpp
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Sat Jun 8 2019 18:04:04