Robowflex  v0.1
Making MoveIt Easy
geometry.cpp
Go to the documentation of this file.
1 /* Author: Zachary Kingston, Constantinos Chamzas */
2 
3 #include <geometric_shapes/shape_operations.h>
4 
6 #include <robowflex_library/io.h>
8 
9 using namespace robowflex;
10 
11 const unsigned int Geometry::ShapeType::MAX = (unsigned int)Geometry::ShapeType::MESH + 1;
12 const std::vector<std::string> Geometry::ShapeType::STRINGS({"box", "sphere", "cylinder", "cone", "mesh"});
13 
15 {
16  std::string lower(str);
17  std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
18 
19  Type type;
20 
21  unsigned int i = 0;
22  for (; i < MAX; ++i)
23  if (STRINGS[i].compare(lower) == 0)
24  {
25  type = (Type)i;
26  break;
27  }
28 
29  if (i == MAX)
30  throw Exception(1, "Invalid type for geometry.");
31 
32  return type;
33 }
34 
36 {
37  if (type > MAX)
38  throw Exception(1, "Invalid type for geometry.");
39 
40  return STRINGS[type];
41 }
42 
44 {
45  return std::make_shared<Geometry>(ShapeType::SPHERE, Eigen::Vector3d(radius, 0, 0));
46 }
47 
48 GeometryPtr Geometry::makeBox(double x, double y, double z)
49 {
50  return std::make_shared<Geometry>(ShapeType::BOX, Eigen::Vector3d(x, y, z));
51 }
52 
53 GeometryPtr Geometry::makeBox(const Eigen::Vector3d &dimensions)
54 {
55  return makeBox(dimensions[0], dimensions[1], dimensions[2]);
56 }
57 
58 GeometryPtr Geometry::makeCylinder(double radius, double length)
59 {
60  return std::make_shared<Geometry>(ShapeType::CYLINDER, Eigen::Vector3d(radius, length, 0));
61 }
62 
63 GeometryPtr Geometry::makeCone(double radius, double length)
64 {
65  return std::make_shared<Geometry>(ShapeType::CONE, Eigen::Vector3d(radius, length, 0));
66 }
67 
68 GeometryPtr Geometry::makeSolidPrimitive(const shape_msgs::SolidPrimitive &msg)
69 {
70  using sm = shape_msgs::SolidPrimitive;
71 
72  switch (msg.type)
73  {
74  case sm::BOX:
75  return makeBox(msg.dimensions[sm::BOX_X], //
76  msg.dimensions[sm::BOX_Y], //
77  msg.dimensions[sm::BOX_Z]);
78  case sm::SPHERE:
79  return makeSphere(msg.dimensions[sm::SPHERE_RADIUS]);
80  case sm::CYLINDER:
81  return makeCylinder(msg.dimensions[sm::CYLINDER_RADIUS], //
82  msg.dimensions[sm::CYLINDER_HEIGHT]);
83  case sm::CONE:
84  return makeCone(msg.dimensions[sm::CONE_RADIUS], //
85  msg.dimensions[sm::CONE_HEIGHT]);
86  default:
87  return nullptr;
88  }
89 }
90 
91 GeometryPtr Geometry::makeMesh(const std::string &resource, const Eigen::Vector3d &scale)
92 {
93  return std::make_shared<Geometry>(ShapeType::MESH, scale, resource);
94 }
95 
96 GeometryPtr Geometry::makeMesh(const EigenSTL::vector_Vector3d &vertices)
97 {
98  return std::make_shared<Geometry>(ShapeType::MESH, Eigen::Vector3d::Ones(), "", vertices);
99 }
100 
101 Geometry::Geometry(ShapeType::Type type, const Eigen::Vector3d &dimensions, const std::string &resource,
102  const EigenSTL::vector_Vector3d &vertices)
103  : type_(type)
104  , dimensions_(dimensions)
105  , vertices_(vertices)
106  , resource_((resource.empty()) ? "" : IO::resolvePath(resource))
107  , shape_(loadShape())
108  , body_(loadBody())
109 {
110 }
111 
112 Geometry::Geometry(const shapes::Shape &shape)
113 {
114  switch (shape.type)
115  {
116  case shapes::ShapeType::BOX:
117  {
119  const auto &box = static_cast<const shapes::Box &>(shape);
120  dimensions_ = Eigen::Vector3d{box.size[0], box.size[1], box.size[2]};
121  shape_.reset(loadShape());
122  break;
123  }
124  case shapes::ShapeType::SPHERE:
125  {
127  const auto &sphere = static_cast<const shapes::Sphere &>(shape);
128  dimensions_ = Eigen::Vector3d{sphere.radius, 0, 0};
129  shape_.reset(loadShape());
130  break;
131  }
132  case shapes::ShapeType::CYLINDER:
133  {
135  const auto &cylinder = static_cast<const shapes::Cylinder &>(shape);
136  dimensions_ = Eigen::Vector3d{cylinder.radius, cylinder.length, 0};
137  shape_.reset(loadShape());
138  break;
139  }
140  case shapes::ShapeType::CONE:
141  {
143  const auto &cone = static_cast<const shapes::Cone &>(shape);
144  dimensions_ = Eigen::Vector3d{cone.radius, cone.length, 0};
145  shape_.reset(loadShape());
146  break;
147  }
148  case shapes::ShapeType::MESH:
149  {
151  const auto &mesh = static_cast<const shapes::Mesh &>(shape);
152  shape_.reset(mesh.clone());
153  break;
154  }
155  default:
156  throw Exception(1, "Invalid type for geometry.");
157  }
158 
159  body_.reset(loadBody());
160 }
161 
162 Geometry::Geometry(const shape_msgs::SolidPrimitive &msg) : Geometry(*shapes::constructShapeFromMsg(msg))
163 {
164 }
165 
166 Geometry::Geometry(const shape_msgs::Mesh &msg) : Geometry(*shapes::constructShapeFromMsg(msg))
167 {
168 }
169 
170 shapes::Shape *Geometry::loadShape() const
171 {
172  switch (type_)
173  {
174  case ShapeType::BOX:
175  return new shapes::Box(dimensions_[0], dimensions_[1], dimensions_[2]);
176  break;
177 
178  case ShapeType::SPHERE:
179  return new shapes::Sphere(dimensions_[0]);
180  break;
181 
182  case ShapeType::CYLINDER:
183  return new shapes::Cylinder(dimensions_[0], dimensions_[1]);
184  break;
185 
186  case ShapeType::CONE:
187  return new shapes::Cone(dimensions_[0], dimensions_[1]);
188  break;
189 
190  case ShapeType::MESH:
191  if (!resource_.empty() && vertices_.empty())
192  return shapes::createMeshFromResource("file://" + resource_, dimensions_);
193  else if (resource_.empty() && !vertices_.empty())
194  return shapes::createMeshFromVertices(vertices_);
195  else
196  throw Exception(1, resource_.empty() ? "No vertices/resource specified for the mesh" :
197  "Both vertices/resource specified for the mesh");
198  break;
199 
200  default:
201  break;
202  }
203 
204  return nullptr;
205 }
206 
207 bodies::Body *Geometry::loadBody() const
208 {
209  switch (type_)
210  {
211  case ShapeType::BOX:
212  return new bodies::Box(shape_.get());
213  break;
214 
215  case ShapeType::SPHERE:
216  return new bodies::Sphere(shape_.get());
217  break;
218 
219  case ShapeType::CYLINDER:
220  return new bodies::Cylinder(shape_.get());
221  break;
222 
223  case ShapeType::MESH:
224  return new bodies::ConvexMesh(shape_.get());
225  break;
226 
227  case ShapeType::CONE:
228  default:
229  break;
230  }
231 
232  return nullptr;
233 }
234 
235 bool Geometry::contains(const Eigen::Vector3d &point) const
236 {
237  return body_->containsPoint(point[0], point[1], point[2]);
238 }
239 
240 std::pair<bool, Eigen::Vector3d> Geometry::sample(const unsigned int attempts) const
241 {
242  bool success;
243  Eigen::Vector3d point;
244  random_numbers::RandomNumberGenerator rng;
245 
246  if (!(success = body_->samplePointInside(rng, attempts, point)))
247  point = Eigen::Vector3d{0, 0, 0};
248 
249  return std::make_pair(success, point);
250 }
251 bool Geometry::isMesh() const
252 {
253  return type_ == ShapeType::MESH;
254 }
255 
256 const shape_msgs::SolidPrimitive Geometry::getSolidMsg() const
257 {
258  shapes::ShapeMsg msg;
259  if (!isMesh())
260  shapes::constructMsgFromShape(shape_.get(), msg);
261 
262  return boost::get<shape_msgs::SolidPrimitive>(msg);
263 }
264 
265 const shape_msgs::Mesh Geometry::getMeshMsg() const
266 {
267  shapes::ShapeMsg msg;
268  if (isMesh())
269  shapes::constructMsgFromShape(shape_.get(), msg);
270 
271  return boost::get<shape_msgs::Mesh>(msg);
272 }
273 
274 const shapes::ShapePtr &Geometry::getShape() const
275 {
276  return shape_;
277 }
278 
279 const bodies::BodyPtr &Geometry::getBody() const
280 {
281  return body_;
282 }
283 
285 {
286  return type_;
287 }
288 
290 {
291  return resource_;
292 }
293 
294 const EigenSTL::vector_Vector3d &Geometry::getVertices() const
295 {
296  return vertices_;
297 }
298 
299 const Eigen::Vector3d &Geometry::getDimensions() const
300 {
301  return dimensions_;
302 }
303 
304 Eigen::AlignedBox3d Geometry::getAABB(const RobotPose &pose) const
305 {
306  moveit::core::AABB aabb;
307 
308  const auto &extents = shapes::computeShapeExtents(shape_.get());
309  aabb.extendWithTransformedBox(pose, extents);
310 
311  return aabb;
312 }
T begin(T... args)
void extendWithTransformedBox(const Eigen::Isometry3d &transform, const Eigen::Vector3d &box)
Exception that contains a message and an error code.
Definition: util.h:15
A shared pointer wrapper for robowflex::Geometry.
static const std::string & toString(Type type)
Converts a ShapeType to its string.
Definition: geometry.cpp:35
@ CYLINDER
Solid primitive cylinder. Uses two dimensions (height, radius).
Definition: geometry.h:47
@ MESH
Mesh. Dimensions scale along x, y, z.
Definition: geometry.h:49
@ CONE
Solid primitive cone. Uses two dimensions (height, radius).
Definition: geometry.h:48
@ BOX
Solid primitive box. Uses three dimensions (x, y, z).
Definition: geometry.h:45
@ SPHERE
Solid primitive sphere. Uses one dimension (radius).
Definition: geometry.h:46
static Type toType(const std::string &str)
Converts a string into a ShapeType.
Definition: geometry.cpp:14
static const std::vector< std::string > STRINGS
Mapping of ShapeType to string.
Definition: geometry.h:53
static const unsigned int MAX
Maximum value of ShapeType.
Definition: geometry.h:52
A class that manages both solid and mesh geometry for various parts of the motion planning system.
Definition: geometry.h:36
const std::string & getResource() const
Gets the mesh resource of the geometry.
Definition: geometry.cpp:289
static GeometryPtr makeMesh(const std::string &resource, const Eigen::Vector3d &scale={1, 1, 1})
Create a mesh from resource file.
Definition: geometry.cpp:91
Geometry(ShapeType::Type type, const Eigen::Vector3d &dimensions, const std::string &resource="", const EigenSTL::vector_Vector3d &vertices=EigenSTL::vector_Vector3d{})
Constructor. Builds and loads the specified geometry.
Definition: geometry.cpp:101
Eigen::Vector3d dimensions_
Dimensions to scale geometry.
Definition: geometry.h:220
static GeometryPtr makeSphere(double radius)
Create a sphere.
Definition: geometry.cpp:43
static GeometryPtr makeBox(double x, double y, double z)
Create a box.
Definition: geometry.cpp:48
const EigenSTL::vector_Vector3d & getVertices() const
Gets the Vertices of the primitive.
Definition: geometry.cpp:294
const shape_msgs::Mesh getMeshMsg() const
Gets the message form of mesh geometry.
Definition: geometry.cpp:265
shapes::ShapePtr shape_
Loaded shape.
Definition: geometry.h:223
static GeometryPtr makeCone(double radius, double length)
Create a cone.
Definition: geometry.cpp:63
const Eigen::Vector3d & getDimensions() const
Gets the dimensions of the geometry.
Definition: geometry.cpp:299
bool isMesh() const
Checks if the geometry is a mesh geometry.
Definition: geometry.cpp:251
const shape_msgs::SolidPrimitive getSolidMsg() const
Gets the message form of solid primitive geometry (all but ShapeType::MESH).
Definition: geometry.cpp:256
Eigen::AlignedBox3d getAABB(const RobotPose &pose=RobotPose::Identity()) const
Compute the AABB (axis-aligned bounding box) of the geometry at a given pose.
Definition: geometry.cpp:304
const shapes::ShapePtr & getShape() const
Gets the underlying shape.
Definition: geometry.cpp:274
ShapeType::Type getType() const
Gets the type of the geometry.
Definition: geometry.cpp:284
bodies::BodyPtr body_
Body operation.
Definition: geometry.h:224
std::pair< bool, Eigen::Vector3d > sample(const unsigned int attempts=50) const
Tries to sample a point in the geometry.
Definition: geometry.cpp:240
shapes::Shape * loadShape() const
Loads a shape from the set type_ and dimensions_, and resource_ if a mesh.
Definition: geometry.cpp:170
bodies::Body * loadBody() const
Loads a body from the loaded shape_.
Definition: geometry.cpp:207
EigenSTL::vector_Vector3d vertices_
Vertices of the primitive.
Definition: geometry.h:221
static GeometryPtr makeCylinder(double radius, double length)
Create a cylinder.
Definition: geometry.cpp:58
std::string resource_
Resource locator for MESH types.
Definition: geometry.h:222
ShapeType::Type type_
Geometry Type.
Definition: geometry.h:219
const bodies::BodyPtr & getBody() const
Gets the underlying body.
Definition: geometry.cpp:279
static GeometryPtr makeSolidPrimitive(const shape_msgs::SolidPrimitive &msg)
Create a solid primitive.
Definition: geometry.cpp:68
bool contains(const Eigen::Vector3d &point) const
Checks if the geometry contains a point.
Definition: geometry.cpp:235
T empty(T... args)
T end(T... args)
T make_pair(T... args)
std::string resolvePath(const std::string &path)
Resolves package:// URLs and relative file paths to their canonical form.
Main namespace. Contains all library classes and functions.
Definition: scene.cpp:25
std::decay< decltype(std::declval< moveit::core::Transforms >().getTransform("")) >::type RobotPose
A pose (point in SE(3)) used in various functions. Defined from what MoveIt! uses.
Definition: adapter.h:24
T transform(T... args)