Robowflex  v0.1
Making MoveIt Easy
structure.cpp
Go to the documentation of this file.
1 /* Author: Zachary Kingston */
2 
3 #include <assimp/Importer.hpp>
4 #include <assimp/postprocess.h>
5 #include <assimp/scene.h>
6 
7 #include <geometric_shapes/shape_operations.h>
8 
9 #include <dart/dynamics/BodyNode.hpp>
10 #include <dart/dynamics/WeldJoint.hpp>
11 
13 #include <robowflex_library/io.h>
14 #include <robowflex_library/log.h>
16 
17 #include <robowflex_dart/acm.h>
19 
20 using namespace robowflex::darts;
21 
22 ///
23 /// Structure
24 ///
25 
27  : name_(name), skeleton_(dart::dynamics::Skeleton::create(name_)), acm_(std::make_shared<ACM>(this))
28 {
29  skeleton_->setSelfCollisionCheck(true);
30 }
31 
33 {
34  dart::dynamics::WeldJoint::Properties properties;
35  dart::dynamics::BodyNode::Properties node;
36 
37  node.mName = properties.mName = "root";
38  properties.mT_ParentBodyToJoint = robowflex::TF::identity();
39  const auto &pair =
40  skeleton_->createJointAndBodyNodePair<dart::dynamics::WeldJoint>(nullptr, properties, node);
41  const auto &root = pair.second;
42 
43  const auto &objects = scene->getCollisionObjects();
44  for (const auto &object : objects)
45  {
46  const auto &geometry = scene->getObjectGeometry(object);
47  const auto &pose = scene->getObjectPose(object);
48 
49  dart::dynamics::FreeJoint::Properties joint;
50  joint.mName = object;
51  joint.mT_ParentBodyToJoint = robowflex::TF::identity();
52 
53  auto shape = makeGeometry(geometry);
54 
55  auto pair = addFreeFrame(joint, shape, root);
56  setJointParentTransform(object, pose);
57  setColor(pair.second, dart::Color::Blue(0.2));
58  }
59 
60  const auto &acm = scene->getACMConst();
62  acm.getAllEntryNames(names);
63 
65  for (const auto &name1 : names)
66  for (const auto &name2 : names)
67  if (acm.getEntry(name1, name2, type))
68  {
70  acm_->enableCollision(name1, name2);
72  acm_->disableCollision(name1, name2);
73  }
74 }
75 
77 {
78  auto structure = std::make_shared<Structure>(newName);
79  structure->setSkeleton(skeleton_->cloneSkeleton(newName));
80 
81  for (const auto &pair : acm_->getDisabledPairsConst())
82  structure->getACM()->disableCollision(pair.first, pair.second);
83 
84  return structure;
85 }
86 
88 {
89  return name_;
90 }
91 
93 {
94  return acm_;
95 }
96 
98 {
99  return acm_;
100 }
101 
102 void Structure::setSkeleton(const dart::dynamics::SkeletonPtr &skeleton)
103 {
104  skeleton_ = skeleton;
105  skeleton_->setName(name_);
106 }
107 
108 dart::dynamics::SkeletonPtr &Structure::getSkeleton()
109 {
110  return skeleton_;
111 }
112 
113 const dart::dynamics::SkeletonPtr &Structure::getSkeletonConst() const
114 {
115  return skeleton_;
116 }
117 
118 void Structure::dumpGraphViz(std::ostream &out, bool standalone)
119 {
120  if (standalone)
121  out << "digraph {" << std::endl;
122 
123  const std::string &sname = skeleton_->getName();
124  for (const auto &node : skeleton_->getBodyNodes())
125  {
126  const std::string &name = node->getName();
127  const std::size_t index = node->getIndexInSkeleton();
128 
129  out << sname << "_" << index << "[label=\"" << name << "\"]" << std::endl;
130 
131  const auto &joint = node->getParentJoint();
132  const std::string &jname = joint->getName();
133  const std::string &type = joint->getType();
134 
135  const auto &parent = joint->getParentBodyNode();
136  if (parent)
137  {
138  const auto &pindex = parent->getIndexInSkeleton();
139  out << sname << "_" << pindex << "->" //
140  << sname << "_" << index //
141  << "[label=\"" << jname << std::endl
142  << type << "\"]" << std::endl;
143  }
144  }
145 
146  if (standalone)
147  out << "}" << std::endl;
148 }
149 
150 void Structure::createShapeNode(dart::dynamics::BodyNode *body, const dart::dynamics::ShapePtr &shape)
151 {
152  if (not shape)
153  return;
154 
155  body->createShapeNodeWith<dart::dynamics::VisualAspect, //
156  dart::dynamics::CollisionAspect, //
157  dart::dynamics::DynamicsAspect>(shape);
158 
159  dart::dynamics::Inertia inertia;
160  double mass = magic::DEFAULT_DENSITY * shape->getVolume();
161  if (mass <= 0)
162  mass = 1.;
163 
164  inertia.setMass(mass);
165  inertia.setMoment(shape->computeInertia(mass));
166 
167  if (not inertia.verify(false))
168  inertia = dart::dynamics::Inertia(mass);
169 
170  body->setInertia(inertia);
171  body->setRestitutionCoeff(magic::DEFAULT_RESTITUTION);
172 
173  auto *joint = body->getParentJoint();
174  if (joint)
175  for (std::size_t i = 0; i < joint->getNumDofs(); ++i)
176  joint->getDof(i)->setDampingCoefficient(magic::DEFAULT_DAMPING);
177 }
178 
180 Structure::addRevoluteFrame(const dart::dynamics::RevoluteJoint::Properties &properties, //
181  const dart::dynamics::ShapePtr &shape, //
182  dart::dynamics::BodyNode *parent)
183 {
184  dart::dynamics::BodyNode::Properties node;
185  node.mName = properties.mName;
186 
187  auto pair =
188  skeleton_->createJointAndBodyNodePair<dart::dynamics::RevoluteJoint>(parent, properties, node);
189  createShapeNode(pair.second, shape);
190 
191  pair.first->setPositionLimitEnforced(true);
192  return pair;
193 }
194 
196 Structure::addPrismaticFrame(const dart::dynamics::PrismaticJoint::Properties &properties, //
197  const dart::dynamics::ShapePtr &shape, //
198  dart::dynamics::BodyNode *parent)
199 {
200  dart::dynamics::BodyNode::Properties node;
201  node.mName = properties.mName;
202 
203  auto pair =
204  skeleton_->createJointAndBodyNodePair<dart::dynamics::PrismaticJoint>(parent, properties, node);
205  createShapeNode(pair.second, shape);
206 
207  pair.first->setPositionLimitEnforced(true);
208  return pair;
209 }
210 
212 Structure::addFreeFrame(const dart::dynamics::FreeJoint::Properties &properties, //
213  const dart::dynamics::ShapePtr &shape, //
214  dart::dynamics::BodyNode *parent)
215 {
216  dart::dynamics::BodyNode::Properties node;
217  node.mName = properties.mName;
218 
219  auto pair = skeleton_->createJointAndBodyNodePair<dart::dynamics::FreeJoint>(parent, properties, node);
220  createShapeNode(pair.second, shape);
221 
222  pair.first->setPositionLimitEnforced(true);
223  return pair;
224 }
225 
227 Structure::addWeldedFrame(const dart::dynamics::WeldJoint::Properties &properties, //
228  const dart::dynamics::ShapePtr &shape, //
229  dart::dynamics::BodyNode *parent)
230 {
231  dart::dynamics::BodyNode::Properties node;
232  node.mName = properties.mName;
233 
234  auto pair = skeleton_->createJointAndBodyNodePair<dart::dynamics::WeldJoint>(parent, properties, node);
235  createShapeNode(pair.second, shape);
236 
237  return pair;
238 }
239 
240 void Structure::addGround(double z, double radius)
241 {
242  const double thickness = 0.01;
243 
244  dart::dynamics::WeldJoint::Properties joint;
245  joint.mName = "ground";
246  joint.mT_ParentBodyToJoint.translation() = Eigen::Vector3d(0, 0, z - thickness);
247 
248  auto ground = makeBox(radius, radius, thickness);
249  auto pair = addWeldedFrame(joint, ground);
250 
251  setColor(pair.second, dart::Color::Blue(0.2));
252 }
253 
254 void Structure::setJoint(const std::string &name, double value)
255 {
256  setJoint(name, Eigen::VectorXd::Constant(1, value));
257 }
258 
259 void Structure::setJoint(const std::string &name, const Eigen::Ref<const Eigen::VectorXd> &value)
260 {
261  auto *joint = skeleton_->getJoint(name);
262  joint->setPositions(value);
263 }
264 
266 {
267  auto ik = skeleton_->getIK(true);
268  // ik->getSolver()->setTolerance(1e-9);
269  // ik->getSolver()->setNumMaxIterations(100);
270  return ik->solveAndApply(true);
271 }
272 
273 void Structure::setDof(unsigned int index, double value)
274 {
275  skeleton_->getDof(index)->setPosition(value);
276 }
277 
279 {
281  for (const auto *joint : skeleton_->getJoints())
282  names.emplace_back(joint->getName());
283 
284  return names;
285 }
286 
287 dart::dynamics::Joint *Structure::getJoint(const std::string &joint_name) const
288 {
289  return skeleton_->getJoint(joint_name);
290 }
291 
292 dart::dynamics::BodyNode *Structure::getFrame(const std::string &name) const
293 {
294  return skeleton_->getBodyNode(name);
295 }
296 
297 void Structure::reparentFreeFrame(dart::dynamics::BodyNode *child, const std::string &parent)
298 {
299  auto *frame = getFrame(parent);
300 
301  RobotPose tf;
302  if (frame)
303  tf = child->getTransform(frame);
304  else
305  tf = child->getWorldTransform();
306 
307  dart::dynamics::FreeJoint::Properties joint;
308  joint.mName = child->getName();
309  auto *jt = child->moveTo<dart::dynamics::FreeJoint>(skeleton_, frame, joint);
310 
311  setJointParentTransform(joint.mName, tf);
312 }
313 
315 {
316  auto *joint = skeleton_->getJoint(name);
317  if (joint == nullptr)
318  RBX_ERROR("Cannot find joint named %s to set TF!", name);
319 
320  joint->setTransformFromParentBodyNode(tf);
321 }
322 
323 void Structure::updateCollisionObject(const std::string &name, const GeometryPtr &geometry,
324  const robowflex::RobotPose &pose)
325 {
326  auto nodes = skeleton_->getBodyNodes(name); // Get all nodes with this name
327  if (!nodes.empty())
328  setJointParentTransform(name, pose);
329  else
330  {
331  dart::dynamics::FreeJoint::Properties joint;
332  joint.mName = name;
333  joint.mT_ParentBodyToJoint = robowflex::TF::identity();
334 
335  auto shape = makeGeometry(geometry);
336 
337  auto pair = addFreeFrame(joint, shape);
338  setJointParentTransform(name, pose);
339  setColor(pair.second, dart::Color::Blue(0.2));
340  }
341 }
342 
343 dart::dynamics::BodyNode *Structure::getRootFrame() const
344 {
345  return skeleton_->getRootBodyNode();
346 }
347 
348 dart::dynamics::ShapePtr robowflex::darts::makeGeometry(const GeometryPtr &geometry)
349 {
350  const auto &dimensions = geometry->getDimensions();
351 
352  switch (geometry->getType())
353  {
355  return makeBox(dimensions);
357  return makeSphere(dimensions[0]);
359  return makeCylinder(dimensions[0], dimensions[1]);
361  return makeMesh(geometry);
362  default:
363  break;
364  }
365 
366  return nullptr;
367 }
368 
370 robowflex::darts::makeBox(const Eigen::Ref<const Eigen::Vector3d> &v)
371 {
372  return std::make_shared<dart::dynamics::BoxShape>(v);
373 }
374 
376 {
377  return makeBox(Eigen::Vector3d{x, y, z});
378 }
379 
381 {
382  return std::make_shared<dart::dynamics::CylinderShape>(radius, height);
383 }
384 
386 {
387  return std::make_shared<dart::dynamics::SphereShape>(radius);
388 }
389 
391 {
392  std::string uri = geometry->getResource();
393  Eigen::Vector3d dimensions = geometry->getDimensions();
394 
395  if (uri.empty())
396  {
397  const auto &temp_file_name = ".robowflex_tmp.stl";
398 
399  auto shape = std::dynamic_pointer_cast<shapes::Mesh>(geometry->getShape());
400 
401  std::vector<char> buffer;
402  shapes::writeSTLBinary(shape.get(), buffer);
403 
404  std::ofstream out;
405  out.open(temp_file_name, std::ofstream::out | std::ofstream::binary);
406  out.write(buffer.data(), buffer.size());
407  out.close();
408 
409  uri = temp_file_name;
410  }
411 
412  const auto &file = robowflex::IO::resolvePackage(uri);
413  const auto &aiscene = dart::dynamics::MeshShape::loadMesh(file);
414 
415  auto mesh = std::make_shared<dart::dynamics::MeshShape>(dimensions, aiscene);
416  return mesh;
417 }
418 
420  double inner_radius,
421  double outer_radius,
422  std::size_t resolution)
423 {
424  if (resolution < 1)
425  throw std::runtime_error("Invalid resolution.");
426 
427  if (inner_radius > outer_radius)
428  throw std::runtime_error("Invalid radii.");
429 
430  if (low > high)
431  low = high;
432 
433  const double interval = high - low;
434  const double step = interval / resolution;
435 
436  auto *mesh = new aiMesh;
437  mesh->mMaterialIndex = (unsigned int)(-1);
438 
439  // number of segments, *2 for inner & outer, *2 for front & back
440  const std::size_t n_seg = resolution + 1;
441  const std::size_t n_v_face = n_seg * 2;
442  const std::size_t n_vert = n_v_face * 2;
443 
444  const std::size_t n_face = resolution * 2;
445 
446  mesh->mNumVertices = n_vert;
447  mesh->mVertices = new aiVector3D[n_vert];
448  mesh->mNormals = new aiVector3D[n_vert];
449  mesh->mColors[0] = new aiColor4D[n_vert];
450 
451  const double vx = 0;
452  aiVector3D vertex;
453 
454  const aiVector3D fnormal(1.0f, 0.0f, 0.0f);
455  const aiVector3D bnormal(-1.0f, 0.0f, 0.0f);
456  const aiColor4D color(0.0f, 0.0f, 0.0f, 1.0f);
457 
458  // Vertices
459  for (std::size_t i = 0; i <= resolution; ++i)
460  {
461  const double theta = low + step * i;
462 
463  // Inner Radius
464  const double yi = inner_radius * std::cos(theta);
465  const double zi = inner_radius * std::sin(theta);
466  vertex.Set(vx, yi, zi);
467 
468  // front
469  const std::size_t ifv = 2 * i;
470  mesh->mVertices[ifv] = vertex;
471  mesh->mNormals[ifv] = fnormal;
472  mesh->mColors[0][ifv] = color;
473 
474  // back
475  const std::size_t ibv = ifv + n_v_face;
476  mesh->mVertices[ibv] = vertex;
477  mesh->mNormals[ibv] = bnormal;
478  mesh->mColors[0][ibv] = color;
479 
480  // Outer Radius
481  const double yo = outer_radius * std::cos(theta);
482  const double zo = outer_radius * std::sin(theta);
483  vertex.Set(vx, yo, zo);
484 
485  // front
486  const std::size_t ofv = ifv + 1;
487  mesh->mVertices[ofv] = vertex;
488  mesh->mNormals[ofv] = fnormal;
489  mesh->mColors[0][ofv] = color;
490 
491  // back
492  const std::size_t obv = ofv + n_v_face;
493  mesh->mVertices[obv] = vertex;
494  mesh->mNormals[obv] = bnormal;
495  mesh->mColors[0][obv] = color;
496  }
497 
498  mesh->mNumFaces = n_face;
499  mesh->mFaces = new aiFace[n_face];
500 
501  // Faces
502  for (std::size_t i = 1; i <= resolution; ++i)
503  {
504  // front
505  const std::size_t ifv = 2 * i;
506  const std::size_t ifvp = 2 * (i - 1);
507  const std::size_t ofv = ifv + 1;
508  const std::size_t ofvp = ifvp + 1;
509 
510  aiFace *fface = &mesh->mFaces[i - 1];
511  fface->mNumIndices = 4;
512  fface->mIndices = new unsigned int[4];
513  fface->mIndices[0] = ifv;
514  fface->mIndices[1] = ifvp;
515  fface->mIndices[2] = ofvp;
516  fface->mIndices[3] = ofv;
517 
518  // back
519  const std::size_t ibv = ifv + n_v_face;
520  const std::size_t ibvp = ifvp + n_v_face;
521  const std::size_t obv = ofv + n_v_face;
522  const std::size_t obvp = ofvp + n_v_face;
523 
524  aiFace *bface = &mesh->mFaces[i + resolution - 1];
525  bface->mNumIndices = 4;
526  bface->mIndices = new unsigned int[4];
527  bface->mIndices[0] = obv;
528  bface->mIndices[1] = obvp;
529  bface->mIndices[2] = ibvp;
530  bface->mIndices[3] = ibv;
531  }
532 
533  auto *node = new aiNode;
534  node->mNumMeshes = 1;
535  node->mMeshes = new unsigned int[1];
536  node->mMeshes[0] = 0;
537 
538  auto *scene = new aiScene;
539  scene->mNumMeshes = 1;
540  scene->mMeshes = new aiMesh *[1];
541  scene->mMeshes[0] = mesh;
542  scene->mRootNode = node;
543 
544  auto shape = std::make_shared<dart::dynamics::MeshShape>(Eigen::Vector3d::Ones(), scene);
545  shape->setColorMode(dart::dynamics::MeshShape::SHAPE_COLOR);
546 
547  return shape;
548 }
549 
550 void robowflex::darts::setColor(dart::dynamics::BodyNode *node, const Eigen::Vector4d &color)
551 {
552  for (const auto &shape : node->getShapeNodes())
553  shape->getVisualAspect()->setColor(color);
554 }
A shared pointer wrapper for robowflex::Geometry.
@ 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
@ 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
A const shared pointer wrapper for robowflex::Scene.
A shared pointer wrapper for robowflex::darts::ACM.
Allowable collision matrix for robowflex::darts::Structure.
Definition: acm.h:34
A shared pointer wrapper for robowflex::darts::Structure.
Definition: structure.h:34
Wrapper class for a dart::dynamics::Skeleton.
Definition: structure.h:53
void dumpGraphViz(std::ostream &out, bool standalone=true)
Dumps the structure of the skeleton to a GraphViz file.
Definition: structure.cpp:118
StructurePtr cloneStructure(const std::string &newName) const
Clones this structure with a new name.
Definition: structure.cpp:76
void setJoint(const std::string &name, double value)
Set the value of a 1-DoF joint in the structure.
Definition: structure.cpp:254
void setJointParentTransform(const std::string &name, const RobotPose &tf)
Set the transform from a joint to its parent.
Definition: structure.cpp:314
bool solveIK()
Solve the current whole-body IK problem imposed on the structure.
Definition: structure.cpp:265
Structure(const std::string &name)
Create an empty structure.
Definition: structure.cpp:26
ACMPtr getACM()
Get the ACM for the structure.
Definition: structure.cpp:92
void updateCollisionObject(const std::string &name, const GeometryPtr &geometry, const robowflex::RobotPose &pose)
Update or add a collision object.
Definition: structure.cpp:323
std::pair< dart::dynamics::PrismaticJoint *, dart::dynamics::BodyNode * > addPrismaticFrame(const dart::dynamics::PrismaticJoint::Properties &properties, const dart::dynamics::ShapePtr &shape, dart::dynamics::BodyNode *parent=nullptr)
Add a new frame attached to a prismatic joint to this structure.
Definition: structure.cpp:196
const std::string & getName() const
Get the name of this structure.
Definition: structure.cpp:87
std::vector< std::string > getJointNames() const
Get the joint names for this structure.
Definition: structure.cpp:278
void createShapeNode(dart::dynamics::BodyNode *body, const dart::dynamics::ShapePtr &shape)
Create a shape node on a body.
Definition: structure.cpp:150
std::pair< dart::dynamics::FreeJoint *, dart::dynamics::BodyNode * > addFreeFrame(const dart::dynamics::FreeJoint::Properties &properties, const dart::dynamics::ShapePtr &shape, dart::dynamics::BodyNode *parent=nullptr)
Add a new frame attached to a free joint to this structure.
Definition: structure.cpp:212
ACMPtr acm_
ACM for structure.
Definition: structure.h:262
void reparentFreeFrame(dart::dynamics::BodyNode *child, const std::string &parent="")
Reparents the child node to the parent node.
Definition: structure.cpp:297
std::pair< dart::dynamics::WeldJoint *, dart::dynamics::BodyNode * > addWeldedFrame(const dart::dynamics::WeldJoint::Properties &properties, const dart::dynamics::ShapePtr &shape, dart::dynamics::BodyNode *parent=nullptr)
Add a new frame attached to a fixed joint to this structure.
Definition: structure.cpp:227
const dart::dynamics::SkeletonPtr & getSkeletonConst() const
Get the underlying skeleton for the structure.
Definition: structure.cpp:113
void setSkeleton(const dart::dynamics::SkeletonPtr &skeleton)
Set the skeleton for the structure.
Definition: structure.cpp:102
dart::dynamics::SkeletonPtr skeleton_
Underlying skeleton.
Definition: structure.h:261
const std::string name_
Name of the structure.
Definition: structure.h:260
void addGround(double z=0., double radius=10.)
Add a ground plane.
Definition: structure.cpp:240
dart::dynamics::SkeletonPtr & getSkeleton()
Get the underlying skeleton for the structure.
Definition: structure.cpp:108
std::pair< dart::dynamics::RevoluteJoint *, dart::dynamics::BodyNode * > addRevoluteFrame(const dart::dynamics::RevoluteJoint::Properties &properties, const dart::dynamics::ShapePtr &shape, dart::dynamics::BodyNode *parent=nullptr)
Add a new frame attached to a revolute joint to this structure.
Definition: structure.cpp:180
void setDof(unsigned int index, double value)
Set the DoF at index to value.
Definition: structure.cpp:273
dart::dynamics::BodyNode * getRootFrame() const
Get the root frame of this structure.
Definition: structure.cpp:343
dart::dynamics::BodyNode * getFrame(const std::string &name="") const
Get a body node within the structure.
Definition: structure.cpp:292
const ACMPtr & getACMConst() const
Get the ACM for the structure.
Definition: structure.cpp:97
dart::dynamics::Joint * getJoint(const std::string &joint_name) const
Get a reference to the joint in the structure.
Definition: structure.cpp:287
T close(T... args)
T cos(T... args)
T data(T... args)
T emplace_back(T... args)
T empty(T... args)
T endl(T... args)
#define RBX_ERROR(fmt,...)
Output a error logging message.
Definition: log.h:102
std::string resolvePackage(const std::string &path)
Resolves package:// URLs to their canonical form. The path does not need to exist,...
RobotPose identity()
Creates the Identity pose.
Definition: tf.cpp:9
static const double DEFAULT_RESTITUTION
Definition: structure.h:33
static const double DEFAULT_DAMPING
Definition: structure.h:32
static const double DEFAULT_DENSITY
Definition: structure.h:31
DART-based robot modeling and planning.
Definition: acm.h:16
std::shared_ptr< dart::dynamics::CylinderShape > makeCylinder(double radius, double height)
Create a cylinder.
Definition: structure.cpp:380
void setColor(dart::dynamics::BodyNode *node, const Eigen::Vector4d &color)
Sets the color of the shapes on a body node.
Definition: structure.cpp:550
std::shared_ptr< dart::dynamics::MeshShape > makeArcsegment(double low, double high, double inner_radius, double outer_radius, std::size_t resolution=32)
Create a circle's arcsector from one angle to another, with a specified radius.
Definition: structure.cpp:419
std::shared_ptr< dart::dynamics::SphereShape > makeSphere(double radius)
Create a sphere.
Definition: structure.cpp:385
dart::dynamics::ShapePtr makeGeometry(const GeometryPtr &geometry)
Convert a robowflex::Geometry to a Dart Shape.
Definition: structure.cpp:348
std::shared_ptr< dart::dynamics::MeshShape > makeMesh(const GeometryPtr &geometry)
Create a mesh from a robowflex::Geometry that contains a mesh.
Definition: structure.cpp:390
std::shared_ptr< dart::dynamics::BoxShape > makeBox(const Eigen::Ref< const Eigen::Vector3d > &v)
Create a box.
Definition: structure.cpp:370
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
Functions for loading and animating scenes in Blender.
T open(T... args)
T sin(T... args)
T size(T... args)
T write(T... args)