tree_node.h
Go to the documentation of this file.
1 /* Copyright (C) 2015-2018 Michele Colledanchise - All Rights Reserved
2 * Copyright (C) 2018-2020 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 BEHAVIORTREECORE_TREENODE_H
15 #define BEHAVIORTREECORE_TREENODE_H
16 
17 #include <condition_variable>
18 #include <mutex>
24 
25 #ifdef _MSC_VER
26 #pragma warning(disable : 4127)
27 #endif
28 
29 namespace BT
30 {
33 {
35  std::string registration_ID;
37 };
38 
39 typedef std::unordered_map<std::string, std::string> PortsRemapping;
40 
42 {
44  {
45  }
46 
48  PortsRemapping input_ports;
49  PortsRemapping output_ports;
50 };
51 
53 class TreeNode
54 {
55  public:
56  typedef std::shared_ptr<TreeNode> Ptr;
57 
68  TreeNode(std::string name, NodeConfiguration config);
69 
70  virtual ~TreeNode() = default;
71 
73  virtual BT::NodeStatus executeTick();
74 
77  virtual void halt() = 0;
78 
79  bool isHalted() const;
80 
81  NodeStatus status() const;
82 
84  const std::string& name() const;
85 
88  BT::NodeStatus waitValidStatus();
89 
90  virtual NodeType type() const = 0;
91 
95 
105  StatusChangeSubscriber subscribeToStatusChange(StatusChangeCallback callback);
106 
107  // get an unique identifier of this instance of treeNode
108  uint16_t UID() const;
109 
111  const std::string& registrationName() const;
112 
115  const NodeConfiguration& config() const;
116 
124  template <typename T>
125  Result getInput(const std::string& key, T& destination) const;
126 
130  template <typename T>
131  Optional<T> getInput(const std::string& key) const
132  {
133  T out;
134  auto res = getInput(key, out);
135  return (res) ? Optional<T>(out) : nonstd::make_unexpected(res.error());
136  }
137 
138  template <typename T>
139  Result setOutput(const std::string& key, const T& value);
140 
141  // function provide mostrly for debugging purpose to see the raw value
142  // in the port (no remapping and no conversion to a type)
143  StringView getRawPortValue(const std::string &key) const;
144 
147  static bool isBlackboardPointer(StringView str);
148 
149  static StringView stripBlackboardPointer(StringView str);
150 
151  static Optional<StringView> getRemappedKey(StringView port_name, StringView remapping_value);
152 
153  protected:
155  virtual BT::NodeStatus tick() = 0;
156 
157  friend class BehaviorTreeFactory;
158  friend class DecoratorNode;
159  friend class ControlNode;
160  friend class Tree;
161 
162  // Only BehaviorTreeFactory should call this
164  {
165  registration_ID_.assign(ID.data(), ID.size());
166  }
167 
168  void modifyPortsRemapping(const PortsRemapping& new_remapping);
169 
170  void setStatus(NodeStatus new_status);
171 
172  private:
173  const std::string name_;
174 
176 
177  std::condition_variable state_condition_variable_;
178 
180 
182 
183  const uint16_t uid_;
184 
186 
187  std::string registration_ID_;
188 };
189 
190 //-------------------------------------------------------
191 template <typename T>
192 inline Result TreeNode::getInput(const std::string& key, T& destination) const
193 {
194  auto remap_it = config_.input_ports.find(key);
195  if (remap_it == config_.input_ports.end())
196  {
197  return nonstd::make_unexpected(StrCat("getInput() failed because "
198  "NodeConfiguration::input_ports "
199  "does not contain the key: [",
200  key, "]"));
201  }
202  auto remapped_res = getRemappedKey(key, remap_it->second);
203  try
204  {
205  if (!remapped_res)
206  {
207  destination = convertFromString<T>(remap_it->second);
208  return {};
209  }
210  const auto& remapped_key = remapped_res.value();
211 
212  if (!config_.blackboard)
213  {
214  return nonstd::make_unexpected("getInput() trying to access a Blackboard(BB) entry, "
215  "but BB is invalid");
216  }
217 
218  const Any* val = config_.blackboard->getAny(static_cast<std::string>(remapped_key));
219  if (val && val->empty() == false)
220  {
221  if (std::is_same<T, std::string>::value == false && val->type() == typeid(std::string))
222  {
223  destination = convertFromString<T>(val->cast<std::string>());
224  }
225  else
226  {
227  destination = val->cast<T>();
228  }
229  return {};
230  }
231 
232  return nonstd::make_unexpected(StrCat("getInput() failed because it was unable to find the "
233  "key [",
234  key, "] remapped to [", remapped_key, "]"));
235  }
236  catch (std::exception& err)
237  {
238  return nonstd::make_unexpected(err.what());
239  }
240 }
241 
242 template <typename T>
243 inline Result TreeNode::setOutput(const std::string& key, const T& value)
244 {
245  if (!config_.blackboard)
246  {
247  return nonstd::make_unexpected("setOutput() failed: trying to access a "
248  "Blackboard(BB) entry, but BB is invalid");
249  }
250 
251  auto remap_it = config_.output_ports.find(key);
252  if (remap_it == config_.output_ports.end())
253  {
254  return nonstd::make_unexpected(StrCat("setOutput() failed: NodeConfiguration::output_ports "
255  "does not "
256  "contain the key: [",
257  key, "]"));
258  }
259  StringView remapped_key = remap_it->second;
260  if (remapped_key == "=")
261  {
262  remapped_key = key;
263  }
264  if (isBlackboardPointer(remapped_key))
265  {
266  remapped_key = stripBlackboardPointer(remapped_key);
267  }
268  config_.blackboard->set(static_cast<std::string>(remapped_key), value);
269 
270  return {};
271 }
272 
273 // Utility function to fill the list of ports using T::providedPorts();
274 template <typename T>
276 {
277  for (const auto& it : getProvidedPorts<T>())
278  {
279  const auto& port_name = it.first;
280  const auto direction = it.second.direction();
281  if (direction != PortDirection::OUTPUT)
282  {
283  config.input_ports[port_name] = "=";
284  }
285  if (direction != PortDirection::INPUT)
286  {
287  config.output_ports[port_name] = "=";
288  }
289  }
290 }
291 
292 } // namespace BT
293 
294 #endif
std::string registration_ID_
Definition: tree_node.h:187
std::condition_variable state_condition_variable_
Definition: tree_node.h:177
NodeConfiguration config_
Definition: tree_node.h:185
T cast() const
Definition: safe_any.hpp:119
const uint16_t uid_
Definition: tree_node.h:183
StatusChangeSignal::Subscriber StatusChangeSubscriber
Definition: tree_node.h:93
std::function< void(CallableArgs...)> CallableFunction
Definition: signal.h:18
const std::type_info & type() const noexcept
Definition: safe_any.hpp:140
const std::string name_
Definition: tree_node.h:173
StatusChangeSignal::CallableFunction StatusChangeCallback
Definition: tree_node.h:94
static pthread_mutex_t mutex
Definition: minitrace.cpp:61
std::shared_ptr< Blackboard > Ptr
Definition: blackboard.h:26
This information is used mostly by the XMLParser.
Definition: tree_node.h:32
Result setOutput(const std::string &key, const T &value)
Definition: tree_node.h:243
std::mutex state_mutex_
Definition: tree_node.h:179
Blackboard::Ptr blackboard
Definition: tree_node.h:47
Optional< void > Result
Definition: basic_types.h:210
std::shared_ptr< CallableFunction > Subscriber
Definition: signal.h:19
The BehaviorTreeFactory is used to create instances of a TreeNode at run-time.
Definition: bt_factory.h:207
bool empty() const noexcept
Definition: safe_any.hpp:150
std::string StrCat()
Definition: strcat.hpp:47
nonstd::string_view StringView
Definition: basic_types.h:50
std::string registration_ID
Definition: tree_node.h:35
NodeStatus status_
Definition: tree_node.h:175
Result getInput(const std::string &key, T &destination) const
Definition: tree_node.h:192
PortsRemapping output_ports
Definition: tree_node.h:49
Struct used to store a tree. If this object goes out of scope, the tree is destroyed.
Definition: bt_factory.h:130
Abstract base class for Behavior Tree Nodes.
Definition: tree_node.h:53
std::unordered_map< std::string, PortInfo > PortsList
Definition: basic_types.h:317
StatusChangeSignal state_change_signal_
Definition: tree_node.h:181
Optional< T > getInput(const std::string &key) const
Definition: tree_node.h:131
nonstd::expected< T, std::string > Optional
Definition: basic_types.h:190
void setRegistrationID(StringView ID)
Definition: tree_node.h:163
NodeStatus
Definition: basic_types.h:35
std::shared_ptr< TreeNode > Ptr
Definition: tree_node.h:56
NodeType
Enumerates the possible types of nodes.
Definition: basic_types.h:22
PortsRemapping input_ports
Definition: tree_node.h:48
void assignDefaultRemapping(NodeConfiguration &config)
Definition: tree_node.h:275
std::unordered_map< std::string, std::string > PortsRemapping
Definition: tree_node.h:39


behaviotree_cpp_v3
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Tue May 4 2021 02:56:25