se2ez
yaml.cpp
Go to the documentation of this file.
1 #include <se2ez/core/io.h>
2 // #include <se2ez/core/log.h>
3 // #include <se2ez/core/math.h>
4 #include <se2ez/core/yaml.h>
6 
8 
9 using namespace se2ez;
10 
11 namespace
12 {
13  ompl::base::ConstraintPtr YAMLToPointConstraint(const RobotPtr &robot, const YAML::Node &node)
14  {
15  if (!io::isNode(node["name"]))
16  io::throwParsingError(node, "\"name\" entry in YAML does not exist");
17 
18  if (!io::isNode(node["point"]))
19  io::throwParsingError(node, "\"point\" entry in YAML does not exist");
20 
21  if (!io::isNode(node["ee"]))
22  io::throwParsingError(node, "\"ee\" entry in YAML does not exist");
23 
24  std::string base = "root";
25  if (io::isNode(node["base"]))
26  base = node["base"].as<std::string>();
27 
28  return std::make_shared<plan::PointConstraint>(node["name"].as<std::string>(), robot,
29  node["ee"].as<std::string>(), base,
30  io::toVector(node["point"]));
31  }
32 
33  ompl::base::ConstraintPtr YAMLToLineConstraint(const RobotPtr &robot, const YAML::Node &node)
34  {
35  if (!io::isNode(node["name"]))
36  io::throwParsingError(node, "\"name\" entry in YAML does not exist");
37 
38  if (!io::isNode(node["a"]))
39  io::throwParsingError(node, "\"a\" entry in YAML does not exist");
40 
41  if (!io::isNode(node["b"]))
42  io::throwParsingError(node, "\"b\" entry in YAML does not exist");
43 
44  if (!io::isNode(node["ee"]))
45  io::throwParsingError(node, "\"ee\" entry in YAML does not exist");
46 
47  std::string base = "root";
48  if (io::isNode(node["base"]))
49  base = node["base"].as<std::string>();
50 
51  auto constraint = std::make_shared<plan::LineConstraint>(
52  node["name"].as<std::string>(), robot, node["ee"].as<std::string>(), base,
53  io::toVector(node["a"]), io::toVector(node["b"]));
54 
55  if (io::isNode(node["draw"]))
56  constraint->setDrawOffset(io::toVector(node["draw"]));
57 
58  return constraint;
59  }
60 
61  ompl::base::ConstraintPtr YAMLToCircleConstraint(const RobotPtr &robot, const YAML::Node &node)
62  {
63  if (!io::isNode(node["name"]))
64  io::throwParsingError(node, "\"name\" entry in YAML does not exist");
65 
66  if (!io::isNode(node["p"]))
67  io::throwParsingError(node, "\"a\" entry in YAML does not exist");
68 
69  if (!io::isNode(node["r"]))
70  io::throwParsingError(node, "\"b\" entry in YAML does not exist");
71 
72  if (!io::isNode(node["ee"]))
73  io::throwParsingError(node, "\"ee\" entry in YAML does not exist");
74 
75  unsigned int exp = 2;
76  if (io::isNode(node["exp"]))
77  exp = node["exp"].as<unsigned int>();
78 
79  std::string base = "root";
80  if (io::isNode(node["base"]))
81  base = node["base"].as<std::string>();
82 
83  auto constraint = std::make_shared<plan::CircleConstraint>(
84  node["name"].as<std::string>(), robot, node["ee"].as<std::string>(), base,
85  io::toVector(node["p"]), io::toVector(node["r"]), exp);
86 
87  if (io::isNode(node["draw"]))
88  constraint->setDrawOffset(io::toVector(node["draw"]));
89 
90  return constraint;
91  }
92 
93 
94 
95  void YAMLToConstraint(const RobotPtr &robot, std::map<std::string, ompl::base::ConstraintPtr> &map,
96  const YAML::Node &node)
97  {
98  if (!io::isNode(node["type"]))
99  io::throwParsingError(node, "\"type\" entry in YAML does not exist");
100 
101  std::string type = node["type"].as<std::string>();
102 
103  if (!io::isNode(node["name"]))
104  io::throwParsingError(node, "\"name\" entry in YAML does not exist");
105 
106  std::string name = node["name"].as<std::string>();
107 
108  if (type == "line")
109  map.emplace(name, YAMLToLineConstraint(robot, node));
110 
111  else if (type == "point")
112  map.emplace(name, YAMLToPointConstraint(robot, node));
113 
114  else if (type == "circle")
115  map.emplace(name, YAMLToCircleConstraint(robot, node));
116 
117  else
118  io::throwParsingError(node["type"], "\"type\" entry in YAML is not valid!");
119  }
120 
121  void YAMLToConstraints(const RobotPtr &robot, std::map<std::string, ompl::base::ConstraintPtr> &map,
122  const YAML::Node &node)
123  {
124  if (!io::isNode(node["constraints"]))
125  return;
126 
127  if (!node["constraints"].IsSequence())
128  io::throwParsingError(node["constraints"], "\"constraints\" entry in YAML not a sequence");
129 
130  for (const auto &constraint : node["constraints"])
131  YAMLToConstraint(robot, map, constraint);
132  }
133 } // namespace
134 
136  const std::string &filename)
137 {
139  const auto &result = io::loadFileToYAML(filename);
140 
141  if (result.first)
142  {
143  try
144  {
145  YAMLToConstraints(robot, map, result.second);
146  }
147  catch (std::exception &e)
148  {
149  SE2EZ_ERROR("In YAML File %1%: %2%", io::resolvePath(filename), e.what());
150  map.clear();
151  }
152  }
153  else
154  SE2EZ_ERROR("Failed to load file \"%1%\"", filename);
155 
156  return map;
157 }
Eigen::VectorXd toVector(const YAML::Node &node)
Convert a sequence of doubles in YAML to an Eigen vector.
Definition: yaml.cpp:282
void throwParsingError(const YAML::Node &node, const std::string &fmt, Args &&... args)
Convenience function to print out a YAML error message with line and column information.
Definition: utility.h:42
T exp(T... args)
const std::pair< bool, YAML::Node > loadFileToYAML(const std::string &path)
Loads a file to a YAML node.
Definition: io.cpp:123
T what(T... args)
T clear(T... args)
std::map< std::string, ompl::base::ConstraintPtr > loadConstraints(const RobotPtr &robot, const std::string &filename)
Definition: yaml.cpp:135
A shared pointer wrapper for se2ez::Robot.
T emplace(T... args)
Main namespace.
Definition: collision.h:11
#define SE2EZ_ERROR(fmt,...)
Definition: log.h:39
bool isNode(const YAML::Node &node)
Returns true if node is a valid YAML node.
Definition: yaml.cpp:258
const std::string resolvePath(const std::string &path)
Resolves file paths to their canonical form.
Definition: io.cpp:79