Sarafun Behavior Trees package  1
Behavior trees for the SARAFun project
 All Data Structures Namespaces Functions Variables Enumerations Enumerator
parse_tree.cpp
1 #include <sarafun_tree/parse_tree.h>
2 
3 namespace bt_parser {
4 
5 Parser::Parser(std::string filepath) { file_.open(filepath); }
6 Parser::~Parser() { file_.close(); }
7 
8 void Parser::verifyNode(json node) {
9  if (!node.count("name")) {
10  std::string id = node["id"];
11  std::string error_message("The BT JSON file nodes must all have the 'name' "
12  "member! Offending node has id: ");
13 
14  error_message = error_message + id;
15 
16  throw std::logic_error(error_message);
17  }
18  if (!node.count("id") || !node.count("type")) {
19  std::string name = node["name"];
20  std::string error_message("The BT JSON file nodes must all have the 'id', "
21  "'type' members! Offending node has name: ");
22 
23  error_message = error_message + name;
24 
25  throw std::logic_error(error_message);
26  }
27 }
28 
29 BT::TreeNode *Parser::parseTree() {
30  try {
31  current_id_ = "root";
32  file_ >> tree_j_;
33 
34  if (!tree_j_.count("root") || !tree_j_.count("nodes")) {
35  throw std::logic_error(
36  std::string("The tree file must declare 'root' and 'nodes' members "
37  "at the base level!"));
38  }
39  std::string root_id = tree_j_["root"];
40 
41  json root_node = tree_j_["nodes"][root_id];
42 
43  return parseTree(root_node);
44 
45  } catch (const std::invalid_argument &e) {
46  ROS_ERROR("Error parsing BT json file: %s. Current id: %s", e.what(),
47  current_id_.c_str());
48  } catch (const std::logic_error &e) {
49  ROS_ERROR("Error with BT Node: %s.", e.what());
50  } catch (const std::exception &e) {
51  ROS_ERROR("Unknown exception: %s.", e.what());
52  }
53  return nullptr;
54 }
55 
56 BT::TreeNode *Parser::parseTree(json node) {
57  verifyNode(node);
58 
59  std::string type = node["type"];
60  std::string id = node["id"];
61  current_id_ = id;
62 
63  bool is_leaf = false;
64  BT::TreeNode *bt_node;
65 
66  if (type == std::string("Selector")) {
67  bt_node = new BT::SelectorNode(id);
68  } else if (type == std::string("SelectorStar")) {
69  bt_node = new BT::SelectorStarNode(id);
70  } else if (type == std::string("Sequence")) {
71  bt_node = new BT::SequenceNode(id);
72  } else if (type == std::string("SequenceStar")) {
73  bt_node = new BT::SequenceStarNode(id);
74  } else if (type == std::string("Action")) {
75  is_leaf = true;
76  std::string name = node["name"];
77  bt_node = new BT::ROSAction(name);
78  } else if (type == std::string("Condition")) {
79  is_leaf = true;
80  std::string name = node["name"];
81  bt_node = new BT::ROSCondition(name);
82  } else {
83  std::string error_message("BT input file includes an unknown node type: ");
84  error_message = error_message + type;
85  throw std::logic_error(error_message);
86  }
87 
88  if (!is_leaf) {
89  std::vector<std::string> children = node["children"];
90 
91  for (std::vector<std::string>::iterator i = children.begin();
92  i != children.end(); i++) {
93  bt_node->AddChild(parseTree(tree_j_["nodes"][*i]));
94  }
95  }
96 
97  return bt_node;
98 }
99 }
void verifyNode(json node)
Definition: parse_tree.cpp:8
BT::TreeNode * parseTree()
Definition: parse_tree.cpp:29
std::string current_id_
Definition: parse_tree.h:36
std::ifstream file_
Definition: parse_tree.h:34
Parser(std::string filepath)
Definition: parse_tree.cpp:5