38 #include <geometric_shapes/check_isometry.h>
39 #include <rclcpp/logger.hpp>
40 #include <rclcpp/logging.hpp>
59 objects_ = other.objects_;
64 while (!observers_.empty())
68 inline void World::addToObjectInternal(
const ObjectPtr& obj,
const shapes::ShapeConstPtr& shape,
69 const Eigen::Isometry3d& shape_pose)
71 obj->shapes_.push_back(shape);
72 ASSERT_ISOMETRY(shape_pose)
73 obj->shape_poses_.push_back(shape_pose);
74 obj->global_shape_poses_.push_back(obj->pose_ * shape_pose);
78 const std::vector<shapes::ShapeConstPtr>&
shapes,
79 const EigenSTL::vector_Isometry3d& shape_poses)
81 if (
shapes.size() != shape_poses.size())
84 "Number of shapes and number of poses do not match. Not adding this object to collision world.");
93 ObjectPtr& obj = objects_[object_id];
96 obj = std::make_shared<Object>(object_id);
103 for (std::size_t i = 0; i <
shapes.size(); ++i)
104 addToObjectInternal(obj,
shapes[i], shape_poses[i]);
111 std::vector<std::string> ids;
112 for (
const auto&
object : objects_)
113 ids.push_back(
object.first);
119 const auto it = objects_.find(object_id);
120 if (it == objects_.end())
122 return ObjectConstPtr();
130 void World::ensureUnique(ObjectPtr& obj)
132 if (obj && !obj.unique())
133 obj = std::make_shared<Object>(*obj);
138 return objects_.find(object_id) != objects_.end();
144 const std::map<std::string, ObjectPtr>::const_iterator it = objects_.find(
name);
145 if (it != objects_.end())
151 for (
const std::pair<const std::string, ObjectPtr>&
object : objects_)
155 if (
name.rfind(
object.first, 0) == 0 &&
name[
object.first.length()] ==
'/')
157 return object.second->global_subframe_poses_.find(
name.substr(
object.first.length() + 1)) !=
158 object.second->global_subframe_poses_.end();
170 throw std::runtime_error(
"No transform found with name: " +
name);
179 const std::map<std::string, ObjectPtr>::const_iterator it = objects_.find(
name);
180 if (it != objects_.end())
182 return it->second->pose_;
186 for (
const std::pair<const std::string, ObjectPtr>&
object : objects_)
190 if (
name.rfind(
object.first, 0) == 0 &&
name[
object.first.length()] ==
'/')
192 const auto it =
object.second->global_subframe_poses_.find(
name.substr(
object.first.length() + 1));
193 if (it !=
object.second->global_subframe_poses_.end())
202 static const Eigen::Isometry3d IDENTITY_TRANSFORM = Eigen::Isometry3d::Identity();
204 return IDENTITY_TRANSFORM;
209 const auto it = objects_.find(object_id);
210 if (it != objects_.end())
212 return it->second->global_shape_poses_[shape_index];
216 RCLCPP_ERROR_STREAM(
getLogger(),
"Could not find global shape transform for object " << object_id);
217 static const Eigen::Isometry3d IDENTITY_TRANSFORM = Eigen::Isometry3d::Identity();
218 return IDENTITY_TRANSFORM;
224 const auto it = objects_.find(object_id);
225 if (it != objects_.end())
227 return it->second->global_shape_poses_;
231 RCLCPP_ERROR_STREAM(
getLogger(),
"Could not find global shape transforms for object " << object_id);
232 static const EigenSTL::vector_Isometry3d IDENTITY_TRANSFORM_VECTOR;
233 return IDENTITY_TRANSFORM_VECTOR;
238 const Eigen::Isometry3d& shape_pose)
240 const auto it = objects_.find(object_id);
241 if (it != objects_.end())
243 const unsigned int n = it->second->shapes_.size();
244 for (
unsigned int i = 0; i < n; ++i)
246 if (it->second->shapes_[i] == shape)
248 ensureUnique(it->second);
249 ASSERT_ISOMETRY(shape_pose)
250 it->second->shape_poses_[i] = shape_pose;
251 it->second->global_shape_poses_[i] = it->second->pose_ * shape_pose;
263 const auto it = objects_.find(object_id);
264 if (it == objects_.end())
266 if (transform.isApprox(Eigen::Isometry3d::Identity()))
269 ASSERT_ISOMETRY(transform)
270 return setObjectPose(object_id, transform * it->second->pose_);
275 ASSERT_ISOMETRY(pose);
276 ObjectPtr& obj = objects_[object_id];
280 obj = std::make_shared<Object>(object_id);
290 updateGlobalPosesInternal(obj);
297 const auto it = objects_.find(object_id);
298 if (it != objects_.end())
300 const unsigned int n = it->second->shapes_.size();
301 for (
unsigned int i = 0; i < n; ++i)
303 if (it->second->shapes_[i] == shape)
305 ensureUnique(it->second);
306 it->second->shapes_.erase(it->second->shapes_.begin() + i);
307 it->second->shape_poses_.erase(it->second->shape_poses_.begin() + i);
308 it->second->global_shape_poses_.erase(it->second->global_shape_poses_.begin() + i);
310 if (it->second->shapes_.empty())
328 const auto it = objects_.find(object_id);
329 if (it != objects_.end())
346 const auto obj_pair = objects_.find(object_id);
347 if (obj_pair == objects_.end())
351 for (
const auto& t : subframe_poses)
353 ASSERT_ISOMETRY(t.second)
355 obj_pair->second->subframe_poses_ = subframe_poses;
356 obj_pair->second->global_subframe_poses_ = subframe_poses;
357 updateGlobalPosesInternal(obj_pair->second,
false,
true);
361 void World::updateGlobalPosesInternal(ObjectPtr& obj,
bool update_shape_poses,
bool update_subframe_poses)
364 if (update_shape_poses)
366 for (
unsigned int i = 0; i < obj->global_shape_poses_.size(); ++i)
367 obj->global_shape_poses_[i] = obj->pose_ * obj->shape_poses_[i];
371 if (update_subframe_poses)
373 for (
auto it_global_pose = obj->global_subframe_poses_.begin(), it_local_pose = obj->subframe_poses_.begin(),
374 end_poses = obj->global_subframe_poses_.end();
375 it_global_pose != end_poses; ++it_global_pose, ++it_local_pose)
377 it_global_pose->second = obj->pose_ * it_local_pose->second;
384 const auto o =
new Observer(callback);
385 observers_.push_back(o);
391 for (
auto obs = observers_.begin(); obs != observers_.end(); ++obs)
393 if (*obs == observer_handle.observer_)
396 observers_.erase(obs);
402 void World::notifyAll(Action
action)
404 for (std::map<std::string, ObjectPtr>::const_iterator it = objects_.begin(); it != objects_.end(); ++it)
405 notify(it->second,
action);
408 void World::notify(
const ObjectConstPtr& obj, Action
action)
410 for (Observer* observer : observers_)
411 observer->callback_(obj,
action);
416 for (
auto observer : observers_)
418 if (observer == observer_handle.observer_)
421 for (
const auto&
object : objects_)
422 observer->callback_(
object.second,
action);
Represents an action that occurred on an object in the world. Several bits may be set indicating seve...
Maintain a representation of the environment.
const Eigen::Isometry3d & getTransform(const std::string &name) const
Get the transform to an object or subframe with given name. If name does not exist,...
void removeObserver(const ObserverHandle observer_handle)
remove a notifier callback
std::function< void(const ObjectConstPtr &, Action)> ObserverCallbackFn
bool hasObject(const std::string &object_id) const
Check if a particular object exists in the collision world.
bool removeObject(const std::string &object_id)
Remove a particular object. If there are no external pointers to the corresponding instance of Object...
bool moveShapeInObject(const std::string &object_id, const shapes::ShapeConstPtr &shape, const Eigen::Isometry3d &shape_pose)
Update the pose of a shape in an object. Shape equality is verified by comparing pointers....
void notifyObserverAllObjects(const ObserverHandle observer_handle, Action action) const
bool removeShapeFromObject(const std::string &object_id, const shapes::ShapeConstPtr &shape)
Remove shape from object. Shape equality is verified by comparing pointers. Ownership of the object i...
const Eigen::Isometry3d & getGlobalShapeTransform(const std::string &object_id, int shape_index) const
Get the global transform to a shape of an object with multiple shapes. shape_index is the index of th...
void addToObject(const std::string &object_id, const Eigen::Isometry3d &pose, const std::vector< shapes::ShapeConstPtr > &shapes, const EigenSTL::vector_Isometry3d &shape_poses)
Add a pose and shapes to an object in the map. This function makes repeated calls to addToObjectInter...
bool moveObject(const std::string &object_id, const Eigen::Isometry3d &transform)
Move the object pose (thus moving all shapes and subframes in the object) according to the given tran...
ObserverHandle addObserver(const ObserverCallbackFn &callback)
register a callback function for notification of changes. callback will be called right after any cha...
bool setObjectPose(const std::string &object_id, const Eigen::Isometry3d &pose)
Set the pose of an object. The pose is specified in the world frame.
bool setSubframesOfObject(const std::string &object_id, const moveit::core::FixedTransformsMap &subframe_poses)
Set subframes on an object. The frames are relative to the object pose.
bool knowsTransform(const std::string &name) const
Check if an object or subframe with given name exists in the collision world. A subframe name needs t...
void clearObjects()
Clear all objects. If there are no other pointers to corresponding instances of Objects,...
ObjectConstPtr getObject(const std::string &object_id) const
Get a particular object.
const EigenSTL::vector_Isometry3d & getGlobalShapeTransforms(const std::string &object_id) const
Get the global transforms to the shapes of an object. This function is used to construct the collisio...
std::vector< std::string > getObjectIds() const
Get the list of Object ids.
rclcpp::Logger getLogger()
std::map< std::string, Eigen::Isometry3d, std::less< std::string >, Eigen::aligned_allocator< std::pair< const std::string, Eigen::Isometry3d > > > FixedTransformsMap
Map frame names to the transformation matrix that can transform objects from the frame name to the pl...
rclcpp::Logger getLogger(const std::string &name)
Creates a namespaced logger.