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())
68inline 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())
83 RCLCPP_ERROR(getLogger(),
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]);
106 notify(obj,
Action(action));
111 std::vector<std::string> ids;
112 ids.reserve(objects_.size());
113 for (
const auto&
object : objects_)
114 ids.push_back(
object.first);
120 const auto it = objects_.find(object_id);
121 if (it == objects_.end())
123 return ObjectConstPtr();
131void World::ensureUnique(ObjectPtr& obj)
133 if (obj && !obj.unique())
134 obj = std::make_shared<Object>(*obj);
139 return objects_.find(object_id) != objects_.end();
145 const std::map<std::string, ObjectPtr>::const_iterator it = objects_.find(name);
146 if (it != objects_.end())
152 for (
const std::pair<const std::string, ObjectPtr>&
object : objects_)
156 if (name.rfind(
object.first, 0) == 0 && name[
object.first.length()] ==
'/')
158 return object.second->global_subframe_poses_.find(name.substr(
object.first.length() + 1)) !=
159 object.second->global_subframe_poses_.end();
169 const Eigen::Isometry3d& result =
getTransform(name, found);
171 throw std::runtime_error(
"No transform found with name: " + name);
180 const std::map<std::string, ObjectPtr>::const_iterator it = objects_.find(name);
181 if (it != objects_.end())
183 return it->second->pose_;
187 for (
const std::pair<const std::string, ObjectPtr>&
object : objects_)
191 if (name.rfind(
object.first, 0) == 0 && name[
object.first.length()] ==
'/')
193 const auto it =
object.second->global_subframe_poses_.find(name.substr(
object.first.length() + 1));
194 if (it !=
object.second->global_subframe_poses_.end())
203 static const Eigen::Isometry3d IDENTITY_TRANSFORM = Eigen::Isometry3d::Identity();
205 return IDENTITY_TRANSFORM;
210 const auto it = objects_.find(object_id);
211 if (it != objects_.end())
213 return it->second->global_shape_poses_[shape_index];
217 RCLCPP_ERROR_STREAM(getLogger(),
"Could not find global shape transform for object " << object_id);
218 static const Eigen::Isometry3d IDENTITY_TRANSFORM = Eigen::Isometry3d::Identity();
219 return IDENTITY_TRANSFORM;
225 const auto it = objects_.find(object_id);
226 if (it != objects_.end())
228 return it->second->global_shape_poses_;
232 RCLCPP_ERROR_STREAM(getLogger(),
"Could not find global shape transforms for object " << object_id);
233 static const EigenSTL::vector_Isometry3d IDENTITY_TRANSFORM_VECTOR;
234 return IDENTITY_TRANSFORM_VECTOR;
239 const Eigen::Isometry3d& shape_pose)
241 const auto it = objects_.find(object_id);
242 if (it != objects_.end())
244 const unsigned int n = it->second->shapes_.size();
245 for (
unsigned int i = 0; i < n; ++i)
247 if (it->second->shapes_[i] == shape)
249 ensureUnique(it->second);
250 ASSERT_ISOMETRY(shape_pose)
251 it->second->shape_poses_[i] = shape_pose;
252 it->second->global_shape_poses_[i] = it->second->pose_ * shape_pose;
264 auto it = objects_.find(object_id);
265 if (it != objects_.end())
267 if (shape_poses.size() == it->second->shapes_.size())
269 for (std::size_t i = 0; i < shape_poses.size(); ++i)
271 ASSERT_ISOMETRY(shape_poses[i])
272 it->second->shape_poses_[i] = shape_poses[i];
273 it->second->global_shape_poses_[i] = it->second->pose_ * shape_poses[i];
284 const auto it = objects_.find(object_id);
285 if (it == objects_.end())
287 if (transform.isApprox(Eigen::Isometry3d::Identity()))
290 ASSERT_ISOMETRY(transform)
291 return setObjectPose(object_id, transform * it->second->pose_);
296 ASSERT_ISOMETRY(pose);
297 ObjectPtr& obj = objects_[object_id];
301 obj = std::make_shared<Object>(object_id);
307 action = obj->shapes_.empty() ? 0 :
MOVE_SHAPE;
311 updateGlobalPosesInternal(obj);
312 notify(obj,
Action(action));
318 const auto it = objects_.find(object_id);
319 if (it != objects_.end())
321 const unsigned int n = it->second->shapes_.size();
322 for (
unsigned int i = 0; i < n; ++i)
324 if (it->second->shapes_[i] == shape)
326 ensureUnique(it->second);
327 it->second->shapes_.erase(it->second->shapes_.begin() + i);
328 it->second->shape_poses_.erase(it->second->shape_poses_.begin() + i);
329 it->second->global_shape_poses_.erase(it->second->global_shape_poses_.begin() + i);
331 if (it->second->shapes_.empty())
349 const auto it = objects_.find(object_id);
350 if (it != objects_.end())
367 const auto obj_pair = objects_.find(object_id);
368 if (obj_pair == objects_.end())
372 for (
const auto& t : subframe_poses)
374 ASSERT_ISOMETRY(t.second)
376 obj_pair->second->subframe_poses_ = subframe_poses;
377 obj_pair->second->global_subframe_poses_ = subframe_poses;
378 updateGlobalPosesInternal(obj_pair->second,
false,
true);
382void World::updateGlobalPosesInternal(ObjectPtr& obj,
bool update_shape_poses,
bool update_subframe_poses)
385 if (update_shape_poses)
387 for (
unsigned int i = 0; i < obj->global_shape_poses_.size(); ++i)
388 obj->global_shape_poses_[i] = obj->pose_ * obj->shape_poses_[i];
392 if (update_subframe_poses)
394 for (
auto it_global_pose = obj->global_subframe_poses_.begin(), it_local_pose = obj->subframe_poses_.begin(),
395 end_poses = obj->global_subframe_poses_.end();
396 it_global_pose != end_poses; ++it_global_pose, ++it_local_pose)
398 it_global_pose->second = obj->pose_ * it_local_pose->second;
405 const auto o =
new Observer(callback);
406 observers_.push_back(o);
412 for (
auto obs = observers_.begin(); obs != observers_.end(); ++obs)
414 if (*obs == observer_handle.observer_)
417 observers_.erase(obs);
423void World::notifyAll(Action action)
425 for (std::map<std::string, ObjectPtr>::const_iterator it = objects_.begin(); it != objects_.end(); ++it)
426 notify(it->second, action);
429void World::notify(
const ObjectConstPtr& obj, Action action)
431 for (Observer* observer : observers_)
432 observer->callback_(obj, action);
437 for (
auto observer : observers_)
439 if (observer == observer_handle.observer_)
442 for (
const auto&
object : objects_)
443 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 moveShapesInObject(const std::string &object_id, const EigenSTL::vector_Isometry3d &shape_poses)
Update the pose of all shapes in an object. Shape size is verified. Returns true on success.
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.