26 #include <boost/bind.hpp> 27 #include <boost/thread/mutex.hpp> 29 #include <gazebo/common/common.hh> 36 static std::string
get_id(
const physics::LinkPtr &link) {
37 return link->GetModel()->GetName() +
"." + link->GetName();
52 #if GAZEBO_MAJOR_VERSION >= 8 69 this->
world_ = _model->GetWorld();
74 if (_sdf->HasElement(
"robotNamespace")) {
75 this->
robot_namespace_ = _sdf->GetElement(
"robotNamespace")->Get<std::string>() +
"/";
80 if (!_sdf->HasElement(
"robotName")) {
83 this->
robot_name_ = _sdf->GetElement(
"robotName")->Get<std::string>();
86 if (!_sdf->HasElement(
"topicName")) {
89 this->
topic_name_ = _sdf->GetElement(
"topicName")->Get<std::string>();
92 if (!_sdf->HasElement(
"sceneName")) {
95 this->
scene_name_ = _sdf->GetElement(
"sceneName")->Get<std::string>();
98 if (!_sdf->HasElement(
"updatePeriod")) {
108 ROS_FATAL_STREAM(
"A ROS node for Gazebo has not been initialized, unable to load plugin. " 109 <<
"Load the Gazebo system plugin 'libgazebo_ros_api_plugin.so' in the gazebo_ros package)");
127 boost::function<bool(std_srvs::Empty::Request&, std_srvs::Empty::Response&)> srv_cb =
129 aso.
init(
"publish_planning_scene", srv_cb);
146 boost::mutex::scoped_lock lock(this->
mutex_);
153 std_srvs::Empty::Request& req,
154 std_srvs::Empty::Response& resp)
156 boost::mutex::scoped_lock lock(this->
mutex_);
168 boost::mutex::scoped_lock lock(this->
mutex_);
170 using namespace gazebo::common;
171 using namespace gazebo::physics;
183 for(std::map<std::string,moveit_msgs::CollisionObject>::iterator object_it =
collision_object_map_.begin();
188 moveit_msgs::CollisionObject &
object = object_it->second;
191 object.operation = moveit_msgs::CollisionObject::REMOVE;
194 object.primitives.clear();
195 object.primitive_poses.clear();
197 object.meshes.clear();
198 object.mesh_poses.clear();
200 object.planes.clear();
201 object.plane_poses.clear();
205 #if GAZEBO_MAJOR_VERSION >= 8 206 std::vector<ModelPtr> models = this->
world_->Models();
208 std::vector<ModelPtr> models = this->
world_->GetModels();
210 for(std::vector<ModelPtr>::const_iterator model_it = models.begin();
211 model_it != models.end();
214 const ModelPtr &model = *model_it;
215 const std::string model_name = model->GetName();
227 std::vector<LinkPtr> links = model->GetLinks();
228 for(std::vector<LinkPtr>::const_iterator link_it = links.begin();
229 link_it != links.end();
232 const LinkPtr &link = *link_it;
233 const std::string
id =
get_id(link);
236 std::map<std::string, moveit_msgs::CollisionObject>::iterator found_collision_object =
242 ROS_INFO(
"Creating collision object for model %s, this=%s, objects=%u",
247 moveit_msgs::CollisionObject new_object;
249 new_object.header.frame_id =
"world";
250 new_object.operation = moveit_msgs::CollisionObject::ADD;
262 #if GAZEBO_MAJOR_VERSION >= 8 263 ignition::math::Pose3d link_pose = link->WorldPose();
265 ignition::math::Pose3d link_pose = link->GetWorldPose().Ign();
267 geometry_msgs::Pose link_pose_msg;
268 link_pose_msg.position.x = link_pose.Pos().X();
269 link_pose_msg.position.y = link_pose.Pos().Y();
270 link_pose_msg.position.z = link_pose.Pos().Z();
271 link_pose_msg.orientation.x = link_pose.Rot().X();
272 link_pose_msg.orientation.y = link_pose.Rot().Y();
273 link_pose_msg.orientation.z = link_pose.Rot().Z();
274 link_pose_msg.orientation.w = link_pose.Rot().W();
278 std::vector<CollisionPtr> collisions = link->GetCollisions();
279 for(std::vector<CollisionPtr>::const_iterator coll_it = collisions.begin();
280 coll_it != collisions.end();
283 const CollisionPtr &collision = *coll_it;
284 const ShapePtr shape = collision->GetShape();
287 #if GAZEBO_MAJOR_VERSION >= 8 288 ignition::math::Pose3d collision_pose = collision->InitialRelativePose() + link_pose;
290 ignition::math::Pose3d collision_pose = collision->GetInitialRelativePose().Ign() + link_pose;
292 geometry_msgs::Pose collision_pose_msg;
293 collision_pose_msg.position.x = collision_pose.Pos().X();
294 collision_pose_msg.position.y = collision_pose.Pos().Y();
295 collision_pose_msg.position.z = collision_pose.Pos().Z();
296 collision_pose_msg.orientation.x = collision_pose.Rot().X();
297 collision_pose_msg.orientation.y = collision_pose.Rot().Y();
298 collision_pose_msg.orientation.z = collision_pose.Rot().Z();
299 collision_pose_msg.orientation.w = collision_pose.Rot().W();
303 if(shape->HasType(Base::MESH_SHAPE)) {
306 std::string uri = mesh_shape->GetMeshURI();
307 const Mesh *mesh = MeshManager::Instance()->GetMesh(uri);
309 gzwarn <<
"Shape has mesh type but mesh could not be retried from the MeshManager. Loading ad-hoc!" << std::endl;
310 gzwarn <<
" mesh uri: " <<uri<< std::endl;
314 mesh = MeshManager::Instance()->Load(uri);
317 gzwarn <<
"Mesh could not be loded: " << uri << std::endl;
323 unsigned n_submeshes = mesh->GetSubMeshCount();
325 for(
unsigned m=0; m < n_submeshes; m++) {
327 const SubMesh *submesh = mesh->GetSubMesh(m);
328 unsigned n_vertices = submesh->GetVertexCount();
330 switch(submesh->GetPrimitiveType())
332 case SubMesh::POINTS:
334 case SubMesh::LINESTRIPS:
337 case SubMesh::TRIANGLES:
338 case SubMesh::TRISTRIPS:
339 object.mesh_poses.push_back(collision_pose_msg);
341 case SubMesh::TRIFANS:
343 gzerr <<
"TRIFANS not supported yet." << std::endl;
347 }
else if(shape->HasType(Base::PLANE_SHAPE)) {
348 object.plane_poses.push_back(collision_pose_msg);
350 object.primitive_poses.push_back(collision_pose_msg);
354 if(
object.operation == moveit_msgs::CollisionObject::ADD ||
object.operation == moveit_msgs::CollisionObject::APPEND)
356 if(shape->HasType(Base::MESH_SHAPE))
360 std::string name = mesh_shape->GetName();
361 std::string uri = mesh_shape->GetMeshURI();
362 #if GAZEBO_MAJOR_VERSION >= 8 363 ignition::math::Vector3d scale = mesh_shape->Scale();
365 ignition::math::Vector3d scale = mesh_shape->GetScale().Ign();
367 const Mesh *mesh = MeshManager::Instance()->GetMesh(uri);
369 gzwarn <<
" mesh scale: " <<scale<< std::endl;
371 gzwarn <<
"Shape has mesh type but mesh could not be retried from the MeshManager. Loading ad-hoc!" << std::endl;
372 gzwarn <<
" mesh uri: " <<uri<< std::endl;
376 mesh = MeshManager::Instance()->Load(uri);
379 gzwarn <<
"Mesh could not be loded: " << uri << std::endl;
385 unsigned n_submeshes = mesh->GetSubMeshCount();
387 for(
unsigned m=0; m < n_submeshes; m++) {
389 const SubMesh *submesh = mesh->GetSubMesh(m);
390 unsigned n_vertices = submesh->GetVertexCount();
392 switch(submesh->GetPrimitiveType())
394 case SubMesh::POINTS:
396 case SubMesh::LINESTRIPS:
399 case SubMesh::TRIANGLES:
402 shape_msgs::Mesh mesh_msg;
403 mesh_msg.vertices.resize(n_vertices);
404 mesh_msg.triangles.resize(n_vertices/3);
406 for(
size_t v=0; v < n_vertices; v++) {
408 const int index = submesh->GetIndex(v);
409 const ignition::math::Vector3d vertex = submesh->Vertex(v);
411 mesh_msg.vertices[index].x = vertex.X() * scale.X();
412 mesh_msg.vertices[index].y = vertex.Y() * scale.Y();
413 mesh_msg.vertices[index].z = vertex.Z() * scale.Z();
415 mesh_msg.triangles[v/3].vertex_indices[v%3] = index;
418 object.meshes.push_back(mesh_msg);
422 case SubMesh::TRISTRIPS:
425 shape_msgs::Mesh mesh_msg;
426 mesh_msg.vertices.resize(n_vertices);
427 mesh_msg.triangles.resize(n_vertices-2);
429 for(
size_t v=0; v < n_vertices; v++) {
430 const int index = submesh->GetIndex(v);
431 const ignition::math::Vector3d vertex = submesh->Vertex(v);
433 mesh_msg.vertices[index].x = vertex.X() * scale.X();
434 mesh_msg.vertices[index].y = vertex.Y() * scale.Y();
435 mesh_msg.vertices[index].z = vertex.Z() * scale.Z();
437 if(v < n_vertices-2) mesh_msg.triangles[v].vertex_indices[0] = index;
438 if(v > 0 && v < n_vertices-1) mesh_msg.triangles[v-1].vertex_indices[1] = index;
439 if(v > 1) mesh_msg.triangles[v-2].vertex_indices[2] = index;
442 object.meshes.push_back(mesh_msg);
446 case SubMesh::TRIFANS:
448 gzerr <<
"TRIFANS not supported yet." << std::endl;
453 else if(shape->HasType(Base::PLANE_SHAPE))
457 shape_msgs::Plane plane_msg;
459 #if GAZEBO_MAJOR_VERSION >= 8 460 plane_msg.coef[0] = plane_shape->Normal().X();
461 plane_msg.coef[1] = plane_shape->Normal().Y();
462 plane_msg.coef[2] = plane_shape->Normal().Z();
464 plane_msg.coef[0] = plane_shape->GetNormal().Ign().X();
465 plane_msg.coef[1] = plane_shape->GetNormal().Ign().Y();
466 plane_msg.coef[2] = plane_shape->GetNormal().Ign().Z();
468 plane_msg.coef[3] = 0;
470 object.planes.push_back(plane_msg);
475 shape_msgs::SolidPrimitive primitive_msg;
477 if(shape->HasType(Base::BOX_SHAPE)) {
481 primitive_msg.type = primitive_msg.BOX;
482 primitive_msg.dimensions.resize(3);
483 #if GAZEBO_MAJOR_VERSION >= 8 484 primitive_msg.dimensions[0] = box_shape->Size().X();
485 primitive_msg.dimensions[1] = box_shape->Size().Y();
486 primitive_msg.dimensions[2] = box_shape->Size().Z();
488 primitive_msg.dimensions[0] = box_shape->GetSize().Ign().X();
489 primitive_msg.dimensions[1] = box_shape->GetSize().Ign().Y();
490 primitive_msg.dimensions[2] = box_shape->GetSize().Ign().Z();
492 }
else if(shape->HasType(Base::CYLINDER_SHAPE)) {
496 primitive_msg.type = primitive_msg.CYLINDER;
497 primitive_msg.dimensions.resize(2);
498 primitive_msg.dimensions[0] = cylinder_shape->GetLength();
499 primitive_msg.dimensions[1] = cylinder_shape->GetRadius();
501 }
else if(shape->HasType(Base::SPHERE_SHAPE)) {
505 primitive_msg.type = primitive_msg.SPHERE;
506 primitive_msg.dimensions.resize(1);
507 primitive_msg.dimensions[0] = sphere_shape->GetRadius();
515 object.primitives.push_back(primitive_msg);
517 ROS_INFO(
"model %s has %zu links",model_name.c_str(),links.size());
518 ROS_INFO(
"model %s has %zu meshes, %zu mesh poses",
520 object.meshes.size(),
521 object.mesh_poses.size());
534 for(std::map<std::string,moveit_msgs::CollisionObject>::iterator object_it =
collision_object_map_.begin();
543 if(object_it->second.operation == moveit_msgs::CollisionObject::REMOVE) {
564 static const double timeout = 0.01;
CallbackQueueInterface * callback_queue
ros::Time last_publish_time_
ros::CallbackQueue queue_
static std::string get_id(const physics::LinkPtr &link)
void init(const std::string &_service, const boost::function< bool(MReq &, MRes &)> &_callback)
#define ROS_DEBUG_STREAM_NAMED(name, args)
void publish(const boost::shared_ptr< M > &message) const
ROSCPP_DECL bool isInitialized()
bool PublishPlanningSceneCB(std_srvs::Empty::Request &req, std_srvs::Empty::Response &resp)
publish the complete planning scene
ros::Publisher planning_scene_pub_
event::ConnectionPtr update_connection_
moveit_msgs::PlanningScene planning_scene_msg_
Container for the planning scene.
boost::mutex mutex_
A mutex to lock access to fields that are used in ROS message callbacks.
physics::WorldPtr world_
A pointer to the gazebo world.
GZ_REGISTER_MODEL_PLUGIN(GazeboRosF3D)
std::string robot_namespace_
for setting ROS name space
#define ROS_FATAL_STREAM(args)
std::string scene_name_
The MoveIt scene name.
std::string topic_name_
ROS topic name inputs.
void QueueThread()
The custom callback queue thread function.
boost::scoped_ptr< ros::NodeHandle > rosnode_
A pointer to the ROS node. A node will be instantiated if it does not exist.
std::map< std::string, moveit_msgs::CollisionObject > collision_object_map_
ros::ServiceServer publish_planning_scene_service_
void subscriber_connected()
void Load(physics::ModelPtr _model, sdf::ElementPtr _sdf)
GazeboRosMoveItPlanningScene()
Constructor.
virtual ~GazeboRosMoveItPlanningScene()
Destructor.
ros::Duration publish_period_
boost::thread callback_queue_thread_
Thead object for the running callback Thread.