tree_node.h
Go to the documentation of this file.
1 /* Copyright (C) 2015-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 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 
83  void setStatus(NodeStatus new_status);
84 
86  const std::string& name() const;
87 
90  BT::NodeStatus waitValidStatus();
91 
92  virtual NodeType type() const = 0;
93 
97 
107  StatusChangeSubscriber subscribeToStatusChange(StatusChangeCallback callback);
108 
109  // get an unique identifier of this instance of treeNode
110  uint16_t UID() const;
111 
113  const std::string& registrationName() const;
114 
117  const NodeConfiguration& config() const;
118 
126  template <typename T>
127  Result getInput(const std::string& key, T& destination) const;
128 
132  template <typename T>
133  Optional<T> getInput(const std::string& key) const
134  {
135  T out;
136  auto res = getInput(key, out);
137  return (res) ? Optional<T>(out) : nonstd::make_unexpected(res.error());
138  }
139 
140  template <typename T>
141  Result setOutput(const std::string& key, const T& value);
142 
145  static bool isBlackboardPointer(StringView str);
146 
147  static StringView stripBlackboardPointer(StringView str);
148 
149  static Optional<StringView> getRemappedKey(StringView port_name, StringView remapping_value);
150 
151  protected:
153  virtual BT::NodeStatus tick() = 0;
154 
155  friend class BehaviorTreeFactory;
156 
157  // Only BehaviorTreeFactory should call this
159  {
160  registration_ID_.assign(ID.data(), ID.size());
161  }
162 
163  void modifyPortsRemapping(const PortsRemapping& new_remapping);
164 
165  private:
166  const std::string name_;
167 
169 
170  std::condition_variable state_condition_variable_;
171 
173 
175 
176  const uint16_t uid_;
177 
179 
180  std::string registration_ID_;
181 };
182 
183 //-------------------------------------------------------
184 template <typename T>
185 inline Result TreeNode::getInput(const std::string& key, T& destination) const
186 {
187  auto remap_it = config_.input_ports.find(key);
188  if (remap_it == config_.input_ports.end())
189  {
190  return nonstd::make_unexpected(StrCat("getInput() failed because "
191  "NodeConfiguration::input_ports "
192  "does not contain the key: [",
193  key, "]"));
194  }
195  auto remapped_res = getRemappedKey(key, remap_it->second);
196  try
197  {
198  if (!remapped_res)
199  {
200  destination = convertFromString<T>(remap_it->second);
201  return {};
202  }
203  const auto& remapped_key = remapped_res.value();
204 
205  if (!config_.blackboard)
206  {
207  return nonstd::make_unexpected("getInput() trying to access a Blackboard(BB) entry, "
208  "but BB is invalid");
209  }
210 
211  const Any* val = config_.blackboard->getAny(remapped_key.to_string());
212  if (val && val->empty() == false)
213  {
214  if (std::is_same<T, std::string>::value == false && val->type() == typeid(std::string))
215  {
216  destination = convertFromString<T>(val->cast<std::string>());
217  }
218  else
219  {
220  destination = val->cast<T>();
221  }
222  return {};
223  }
224 
225  return nonstd::make_unexpected(StrCat("getInput() failed because it was unable to find the "
226  "key [",
227  key, "] remapped to [", remapped_key, "]"));
228  }
229  catch (std::exception& err)
230  {
231  return nonstd::make_unexpected(err.what());
232  }
233 }
234 
235 template <typename T>
236 inline Result TreeNode::setOutput(const std::string& key, const T& value)
237 {
238  if (!config_.blackboard)
239  {
240  return nonstd::make_unexpected("setOutput() failed: trying to access a "
241  "Blackboard(BB) entry, but BB is invalid");
242  }
243 
244  auto remap_it = config_.output_ports.find(key);
245  if (remap_it == config_.output_ports.end())
246  {
247  return nonstd::make_unexpected(StrCat("setOutput() failed: NodeConfiguration::output_ports "
248  "does not "
249  "contain the key: [",
250  key, "]"));
251  }
252  StringView remapped_key = remap_it->second;
253  if (remapped_key == "=")
254  {
255  remapped_key = key;
256  }
257  if (isBlackboardPointer(remapped_key))
258  {
259  remapped_key = stripBlackboardPointer(remapped_key);
260  }
261  const auto& key_str = remapped_key.to_string();
262 
263  config_.blackboard->set(key_str, value);
264 
265  return {};
266 }
267 
268 // Utility function to fill the list of ports using T::providedPorts();
269 template <typename T>
271 {
272  for (const auto& it : getProvidedPorts<T>())
273  {
274  const auto& port_name = it.first;
275  const auto direction = it.second.direction();
276  if (direction != PortDirection::OUTPUT)
277  {
278  config.input_ports[port_name] = "=";
279  }
280  if (direction != PortDirection::INPUT)
281  {
282  config.output_ports[port_name] = "=";
283  }
284  }
285 }
286 
287 } // namespace BT
288 
289 #endif
std::string registration_ID_
Definition: tree_node.h:180
std::condition_variable state_condition_variable_
Definition: tree_node.h:170
NodeConfiguration config_
Definition: tree_node.h:178
T cast() const
Definition: safe_any.hpp:119
const uint16_t uid_
Definition: tree_node.h:176
StatusChangeSignal::Subscriber StatusChangeSubscriber
Definition: tree_node.h:95
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:166
StatusChangeSignal::CallableFunction StatusChangeCallback
Definition: tree_node.h:96
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:236
std::mutex state_mutex_
Definition: tree_node.h:172
Blackboard::Ptr blackboard
Definition: tree_node.h:47
Optional< void > Result
Definition: basic_types.h:201
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:98
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:168
const char * str
Definition: util.h:257
Result getInput(const std::string &key, T &destination) const
Definition: tree_node.h:185
PortsRemapping output_ports
Definition: tree_node.h:49
Abstract base class for Behavior Tree Nodes.
Definition: tree_node.h:53
std::unordered_map< std::string, PortInfo > PortsList
Definition: basic_types.h:316
StatusChangeSignal state_change_signal_
Definition: tree_node.h:174
Optional< T > getInput(const std::string &key) const
Definition: tree_node.h:133
nonstd::expected< T, std::string > Optional
Definition: basic_types.h:181
void setRegistrationID(StringView ID)
Definition: tree_node.h:158
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:270
std::unordered_map< std::string, std::string > PortsRemapping
Definition: tree_node.h:39


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