Robowflex  v0.1
Making MoveIt Easy
world.cpp
Go to the documentation of this file.
1 /* Author: Zachary Kingston */
2 
3 #include <dart/collision/CollisionObject.hpp>
4 #include <dart/constraint/ConstraintSolver.hpp>
5 
6 #include <dart/gui/osg/osg.hpp>
7 
9 
10 #include <robowflex_dart/acm.h>
11 #include <robowflex_dart/robot.h>
12 #include <robowflex_dart/world.h>
13 
14 using namespace robowflex::darts;
15 
16 ///
17 /// DistanceCollisionWrapper
18 ///
19 
22  : filter_(filter)
23 {
24 }
25 
26 bool DistanceCollisionWrapper::needDistance(const dart::collision::CollisionObject *object1,
27  const dart::collision::CollisionObject *object2) const
28 {
29  return not filter_->ignoresCollision(object1, object2);
30 }
31 
32 ///
33 /// World
34 ///
35 
37  : world_(dart::simulation::World::create(name))
38  , filter_(std::make_shared<dart::collision::CompositeCollisionFilter>())
39  , name_(name)
40 {
41  world_->setGravity(Eigen::Vector3d(0, 0, -9.81));
42 
43  auto *solver = world_->getConstraintSolver();
44 
45  auto &opt = solver->getCollisionOption();
46  opt.collisionFilter = filter_;
47 
48  collider_ = solver->getCollisionDetector();
49 
50  // world_->getConstraintSolver()->setCollisionDetector(collider_->cloneWithoutCollisionObjects());
51 
52  all_ = collider_->createCollisionGroupAsSharedPtr();
53 }
54 
55 WorldPtr World::clone(const std::string &suffix) const
56 {
57  auto world = std::make_shared<World>(name_ + suffix);
58 
59  for (const auto &robot : robots_)
60  world->addRobot(robot.second->cloneRobot(robot.first + suffix));
61 
62  for (const auto &structure : structures_)
63  world->addStructure(structure.second->cloneStructure(structure.first + suffix));
64 
65  // for (std::size_t i = 0; i < world_->getNumSkeletons(); ++i)
66  // {
67  // auto skel = world_->getSkeleton(i);
68  // auto state = skel->getState();
69  // auto other_skel = world->getSim()->getSkeleton(skel->getName() + suffix);
70  // other_skel->setState(state);
71  // }
72 
73  return world;
74 }
75 
77 {
78  return name_;
79 }
80 
81 void World::addSkeletonCollider(const std::string &name, const dart::dynamics::SkeletonPtr &skeleton)
82 {
83  // Collect collision groups
84  CollisionInfo info;
85  info.self = collider_->createCollisionGroupAsSharedPtr();
86  info.self->addShapeFramesOf(skeleton.get());
87  all_->addShapeFramesOf(skeleton.get());
88 
89  info.others = collider_->createCollisionGroupAsSharedPtr();
90  for (const auto &entry : collision_)
91  info.others->addShapeFramesOf(entry.second.self.get());
92 
93  collision_.emplace(name, info);
94 }
95 
96 void World::removeSkeletonCollider(const std::string &name, const dart::dynamics::SkeletonPtr &skeleton)
97 {
98  // Remove from collision groups
99  auto ic = collision_.find(name);
100  collision_.erase(ic);
101 
102  for (auto &entry : collision_)
103  entry.second.others->removeShapeFramesOf(skeleton.get());
104 
105  all_->removeShapeFramesOf(skeleton.get());
106 }
107 
109 {
110  auto it = robots_.find(robot->getName());
111  if (it == robots_.end())
112  {
113  // Add robot to world
114  robots_.emplace(robot->getName(), robot);
115  world_->addSkeleton(robot->getSkeleton());
116 
117  // Add ACM to collision filter
118  filter_->addCollisionFilter(robot->getACM()->getFilter().get());
119  addSkeletonCollider(robot->getName(), robot->getSkeletonConst());
120  }
121 }
122 
124 {
125  auto it = robots_.find(name);
126  if (it != robots_.end())
127  {
128  // Remove robot from world
129  auto robot = it->second;
130  world_->removeSkeleton(robot->getSkeleton());
131 
132  // Remove ACM from filter
133  filter_->removeCollisionFilter(robot->getACM()->getFilter().get());
134  removeSkeletonCollider(robot->getName(), robot->getSkeletonConst());
135 
136  robots_.erase(it);
137  }
138 }
139 
141 {
142  removeRobot(robot->getName());
143 }
144 
146 {
147  auto it = robots_.find(name);
148  if (it != robots_.end())
149  return it->second;
150 
151  return nullptr;
152 }
153 
155 {
156  auto it = robots_.find(name);
157  if (it != robots_.end())
158  return it->second;
159 
160  return nullptr;
161 }
162 
164 {
165  auto it = structures_.find(structure->getName());
166  if (it == structures_.end())
167  {
168  structures_.emplace(structure->getName(), structure);
169  world_->addSkeleton(structure->getSkeleton());
170 
171  filter_->addCollisionFilter(structure->getACM()->getFilter().get());
172  addSkeletonCollider(structure->getName(), structure->getSkeletonConst());
173  }
174 }
175 
177 {
178  auto it = structures_.find(name);
179  if (it != structures_.end())
180  {
181  auto structure = it->second;
182  world_->removeSkeleton(structure->getSkeleton());
183 
184  filter_->removeCollisionFilter(structure->getACM()->getFilter().get());
185  removeSkeletonCollider(structure->getName(), structure->getSkeletonConst());
186 
187  structures_.erase(it);
188  }
189 }
190 
191 void World::removeStructure(const StructurePtr &structure)
192 {
193  removeStructure(structure->getName());
194 }
195 
197 {
198  auto it = structures_.find(name);
199  if (it != structures_.end())
200  return it->second;
201 
202  return nullptr;
203 }
204 
206 {
207  auto it = structures_.find(name);
208  if (it != structures_.end())
209  return it->second;
210 
211  return nullptr;
212 }
213 
215 {
216  return structures_;
217 }
218 
220 {
221  return std::make_pair(low_, high_);
222 }
223 
224 Eigen::Vector3d &World::getWorkspaceLow()
225 {
226  return low_;
227 }
228 
229 const Eigen::Vector3d &World::getWorkspaceLowConst() const
230 {
231  return low_;
232 }
233 
234 Eigen::Vector3d &World::getWorkspaceHigh()
235 {
236  return high_;
237 }
238 
239 const Eigen::Vector3d &World::getWorkspaceHighConst() const
240 {
241  return high_;
242 }
243 
244 dart::simulation::WorldPtr World::getSim()
245 {
246  return world_;
247 }
248 
249 const dart::simulation::WorldPtr &World::getSimConst() const
250 {
251  return world_;
252 }
253 
254 unsigned int World::getSkeletonIndex(const dart::dynamics::SkeletonPtr &skeleton) const
255 {
256  for (unsigned int i = 0; i < world_->getNumSkeletons(); ++i)
257  {
258  if (skeleton == world_->getSkeleton(i))
259  return i;
260  }
261 
262  return -1;
263 }
264 
266 {
267  auto filter = std::make_shared<dart::collision::BodyNodeCollisionFilter>();
268  for (unsigned int i = 0; i < world_->getNumSkeletons(); ++i)
269  {
270  const auto &si = world_->getSkeleton(i);
271 
272  // Ignore collisions internally
273  for (unsigned int ii = 0; ii < si->getNumBodyNodes(); ++ii)
274  for (unsigned int ij = ii + 1; ij < si->getNumBodyNodes(); ++ij)
275  filter->addBodyNodePairToBlackList(si->getBodyNode(ii), si->getBodyNode(ij));
276 
277  // Ignore collisions on other skeletons
278  for (unsigned int j = i + 1; j < world_->getNumSkeletons(); ++j)
279  {
280  const auto &sj = world_->getSkeleton(j);
281  for (unsigned int ii = 0; ii < si->getNumBodyNodes(); ++ii)
282  for (unsigned int jj = 0; jj < sj->getNumBodyNodes(); ++jj)
283  filter->addBodyNodePairToBlackList(si->getBodyNode(ii), sj->getBodyNode(jj));
284  }
285  }
286 
287  return filter;
288 }
289 
291 {
292  auto filter = std::make_shared<dart::collision::BodyNodeCollisionFilter>();
293  for (const auto &[name, robot] : robots_)
294  for (const auto &[b1, b2] : robot->getACM()->getDisabledPairs())
295  filter->addBodyNodePairToBlackList(robot->getFrame(b1), robot->getFrame(b2));
296 
297  for (const auto &[name, structure] : structures_)
298  for (const auto &[b1, b2] : structure->getACM()->getDisabledPairs())
299  filter->addBodyNodePairToBlackList(structure->getFrame(b1), structure->getFrame(b2));
300 
301  return filter;
302 }
303 
305 {
306  dart::collision::CollisionOption option;
307  option.collisionFilter = (filter) ? filter : filter_;
308 
309  return collider_->collide(all_.get(), option, nullptr);
310 }
311 
313 {
314  dart::collision::DistanceOption option;
315  option.distanceLowerBound = -std::numeric_limits<double>::infinity();
316  option.distanceFilter = std::make_shared<DistanceCollisionWrapper>(filter_);
317 
318  dart::collision::DistanceResult result;
319  double d = collider_->distance(all_.get(), option, &result);
320 
321  const auto &shape_node1 = result.shapeFrame1->asShapeNode();
322  const auto &shape_node2 = result.shapeFrame2->asShapeNode();
323 
324  const auto &body_node1 = shape_node1->getBodyNodePtr();
325  const auto &body_node2 = shape_node2->getBodyNodePtr();
326 
327  RBX_INFO("Distance B1:%s:%s -> B2:%s:%s = %d", //
328  shape_node1->getName(), body_node1->getName(), //
329  shape_node2->getName(), body_node2->getName(), //
330  d);
331 
332  return d;
333 }
334 
336 {
337  ::osg::ref_ptr<dart::gui::osg::RealTimeWorldNode> node = new dart::gui::osg::RealTimeWorldNode(world_);
338 
339  auto viewer = dart::gui::osg::Viewer();
340  viewer.addWorldNode(node);
341 
342  viewer.setUpViewInWindow(0, 0, 1080, 1080);
343  viewer.getCameraManipulator()->setHomePosition(
344  ::osg::Vec3(2.57, 3.14, 1.64), ::osg::Vec3(0.00, 0.00, 0.00), ::osg::Vec3(-0.24, -0.25, 0.94));
345  viewer.setCameraManipulator(viewer.getCameraManipulator());
346  viewer.run();
347 }
348 
350 {
351  for (std::size_t i = 0; i < world_->getNumSkeletons(); ++i)
352  world_->getSkeleton(i)->computeForwardKinematics();
353 }
354 
356 {
357  for (std::size_t i = 0; i < world_->getNumSkeletons(); ++i)
358  {
359  auto skel = world_->getSkeleton(i);
360  skel->clearIK();
361 
362  for (auto *bn : skel->getBodyNodes())
363  bn->clearIK();
364  }
365 }
366 
368 {
369  mutex_.lock();
370 }
371 
373 {
374  mutex_.unlock();
375 }
376 
378 {
379  return collision_.at(name).self;
380 }
381 
383 {
384  return collision_.at(name).others;
385 }
386 
388 {
389  return collision_.at(name);
390 }
391 
393 {
394  if (filter_ == nullptr)
395  {
396  throw std::runtime_error("World collision filter is not initialized!");
397  }
398 
399  return filter_;
400 }
A const shared pointer wrapper for robowflex::Robot.
A shared pointer wrapper for robowflex::Robot.
DistanceCollisionWrapper(const std::shared_ptr< dart::collision::CollisionFilter > &filter)
Constructor.
Definition: world.cpp:20
std::shared_ptr< dart::collision::CollisionFilter > filter_
Wrapped collision filter.
Definition: world.h:40
bool needDistance(const dart::collision::CollisionObject *object1, const dart::collision::CollisionObject *object2) const override
Definition: world.cpp:26
A const shared pointer wrapper for robowflex::darts::Structure.
A shared pointer wrapper for robowflex::darts::Structure.
Definition: structure.h:34
A shared pointer wrapper for robowflex::darts::World.
Wrapper for a dart::simulation::World, which contains a set of skeletons (i.e., Robots and Structures...
Definition: world.h:58
std::shared_ptr< dart::collision::CollisionGroup > getSelfCollisionGroup(const std::string &name) const
Get the self-collision group for a skeleton in this world.
Definition: world.cpp:377
double distanceToCollision() const
Gets the current signed distance to collision in the world.
Definition: world.cpp:312
dart::simulation::WorldPtr getSim()
Get the Dart world.
Definition: world.cpp:244
RobotPtr getRobot(const std::string &name)
Get a robot in the world.
Definition: world.cpp:145
WorldPtr clone(const std::string &suffix="") const
Clone this world.
Definition: world.cpp:55
void removeRobot(const std::string &name)
Remove a robot from the world.
Definition: world.cpp:123
void removeSkeletonCollider(const std::string &name, const dart::dynamics::SkeletonPtr &skeleton)
Remove a collision filter (ACM).
Definition: world.cpp:96
dart::simulation::WorldPtr world_
Underlying world.
Definition: world.h:294
std::shared_ptr< dart::collision::BodyNodeCollisionFilter > getDefaultFilter() const
Get a collision filter that is a copy of the default filter.
Definition: world.cpp:290
unsigned int getSkeletonIndex(const dart::dynamics::SkeletonPtr &skeleton) const
Get the index in the world of a skeleton.
Definition: world.cpp:254
std::map< std::string, RobotPtr > robots_
Robots in world.
Definition: world.h:299
std::shared_ptr< dart::collision::CollisionGroup > getOtherCollisionGroup(const std::string &name) const
Get the group for everything other than a given skeleton in this world.
Definition: world.cpp:382
std::shared_ptr< dart::collision::CompositeCollisionFilter > & getWorldCollisionFilter()
Get the current world collision filter (composite of all skeleton filters). This is more efficient th...
Definition: world.cpp:392
std::recursive_mutex mutex_
Internal lock.
Definition: world.h:312
const std::map< std::string, StructurePtr > & getStructures()
Get the set of structures in the world.
Definition: world.cpp:214
StructurePtr getStructure(const std::string &name)
Get a structure in the world.
Definition: world.cpp:196
World(const std::string &name="world")
Create an empty world.
Definition: world.cpp:36
void openOSGViewer()
Open the Open Scene Graph visualization for this world.
Definition: world.cpp:335
dart::collision::CollisionDetectorPtr collider_
Collision checker.
Definition: world.h:309
Eigen::Vector3d high_
Upper workspace bounds.
Definition: world.h:297
std::map< std::string, CollisionInfo > collision_
Definition: world.h:303
CollisionInfo getCollisionInfo(const std::string &name) const
Get the collision info (self and other collision groups) for a skeleton in this world.
Definition: world.cpp:387
std::pair< Eigen::Vector3d, Eigen::Vector3d > getWorkspaceBounds() const
Get the bounds on the workspace.
Definition: world.cpp:219
const Eigen::Vector3d & getWorkspaceHighConst() const
Get the upper bounds of the workspace.
Definition: world.cpp:239
void addSkeletonCollider(const std::string &name, const dart::dynamics::SkeletonPtr &skeleton)
Add a new collision filter (ACM) for a skeleton.
Definition: world.cpp:81
Eigen::Vector3d & getWorkspaceLow()
Get the lower bounds of the workspace.
Definition: world.cpp:224
std::shared_ptr< dart::collision::BodyNodeCollisionFilter > getAllValidFilter() const
Get a collision filter that allows collisions between all body nodes. Useful for constructing a custo...
Definition: world.cpp:265
RobotConstPtr getRobotConst(const std::string &name) const
Get a robot in the world.
Definition: world.cpp:154
void addRobot(RobotPtr robot)
Add a robot to the world.
Definition: world.cpp:108
const std::string name_
Name of world.
Definition: world.h:310
void addStructure(StructurePtr structure)
Add a structure to the world.
Definition: world.cpp:163
std::shared_ptr< dart::collision::CompositeCollisionFilter > filter_
Definition: world.h:306
const Eigen::Vector3d & getWorkspaceLowConst() const
Get the lower bounds of the workspace.
Definition: world.cpp:229
void lock()
Grab internal recursive lock for world.
Definition: world.cpp:367
Eigen::Vector3d low_
Lower workspace bounds.
Definition: world.h:296
std::map< std::string, StructurePtr > structures_
Structures in world.
Definition: world.h:300
StructureConstPtr getStructureConst(const std::string &name) const
Get a structure in the world.
Definition: world.cpp:205
const std::string & getName() const
Get the name of this world.
Definition: world.cpp:76
void clearIKModules()
Clear all IK modules created in skeletons in the world.
Definition: world.cpp:355
dart::collision::CollisionGroupPtr all_
All collision groups in world.
Definition: world.h:302
Eigen::Vector3d & getWorkspaceHigh()
Get the upper bounds of the workspace.
Definition: world.cpp:234
const dart::simulation::WorldPtr & getSimConst() const
Get the Dart world.
Definition: world.cpp:249
void unlock()
Unlock internal recursive world lock.
Definition: world.cpp:372
void removeStructure(const std::string &name)
Remove a structure from the world.
Definition: world.cpp:176
void forceUpdate()
Force forward kinematics to update.
Definition: world.cpp:349
bool inCollision(const std::shared_ptr< dart::collision::CollisionFilter > &filter=nullptr) const
Checks if world is currently in collision.
Definition: world.cpp:304
T infinity(T... args)
#define RBX_INFO(fmt,...)
Output a info logging message.
Definition: log.h:118
T make_pair(T... args)
Functions for loading and animating robots in Blender.
DART-based robot modeling and planning.
Definition: acm.h:16
Collision filter information.
Definition: world.h:261
std::shared_ptr< dart::collision::CollisionGroup > others
All other nodes in world.
Definition: world.h:264
std::shared_ptr< dart::collision::CollisionGroup > self
Definition: world.h:262
T unlock(T... args)