GazeboObjectInfo.cpp
Go to the documentation of this file.
00001 #include <gazebo_state_plugins/GazeboObjectInfo.h>
00002 #include <gazebo_version_helpers/GazeboVersionHelpers.h>
00003 #include <object_msgs_tools/ObjectFunctions.h>
00004 #include <gazebo/physics/Link.hh>
00005 #include <gazebo/physics/BoxShape.hh>
00006 #include <gazebo/physics/SphereShape.hh>
00007 #include <gazebo/physics/CylinderShape.hh>
00008 #include <gazebo/physics/Collision.hh>
00009 #include <gazebo/physics/World.hh>
00010 
00011 #define DEFAULT_PUBLISH_OBJECTS false
00012 #define DEFAULT_WORLD_OBJECTS_TOPIC "world/objects"
00013 #define DEFAULT_REQUEST_OBJECTS_TOPIC "world/request_object"
00014 #define DEFAULT_ROOT_FRAME_ID "world"
00015 
00016 //publishing rate
00017 #define UPDATE_RATE 5
00018 
00019 #define OBJECT_QUEUE_SIZE 100
00020 
00021 using gazebo::GazeboObjectInfo;
00022 using gazebo::GzVector3;
00023 
00024 GZ_REGISTER_WORLD_PLUGIN(GazeboObjectInfo)
00025 
00026 GazeboObjectInfo::GazeboObjectInfo() : 
00027     WorldPlugin(){
00028     reGenerateObjects=true;
00029 }
00030 
00031 void GazeboObjectInfo::Load(physics::WorldPtr _world, sdf::ElementPtr _sdf){
00032     ros::NodeHandle node("/gazebo_state_plugins");
00033 
00034     node.param<bool>("publish_world_objects", PUBLISH_OBJECTS, DEFAULT_PUBLISH_OBJECTS);
00035     ROS_INFO("GazeboObjInfo: Got objects publish flag: <%i>", PUBLISH_OBJECTS);
00036 
00037     node.param<std::string>("world_objects_topic", WORLD_OBJECTS_TOPIC, DEFAULT_WORLD_OBJECTS_TOPIC);
00038     ROS_INFO("GazeboObjInfo: Got objects topic name: <%s>", WORLD_OBJECTS_TOPIC.c_str());
00039     
00040     node.param<std::string>("request_object_service", REQUEST_OBJECTS_TOPIC, DEFAULT_REQUEST_OBJECTS_TOPIC);
00041     ROS_INFO("GazeboObjInfo: Got objects topic name: <%s>", REQUEST_OBJECTS_TOPIC.c_str());
00042     
00043     node.param<std::string>("objects_frame_id", ROOT_FRAME_ID, DEFAULT_ROOT_FRAME_ID);
00044     ROS_INFO("GazeboObjInfo: Got objects frame id: <%s>", ROOT_FRAME_ID.c_str());
00045     
00046     world=_world;    
00047 
00048     if (PUBLISH_OBJECTS){
00049         update_connection = event::Events::ConnectWorldUpdateBegin(boost::bind(&GazeboObjectInfo::onWorldUpdate, this));
00050         object_pub = node.advertise<GazeboObjectInfo::ObjectMsg>(WORLD_OBJECTS_TOPIC, OBJECT_QUEUE_SIZE);
00051     }
00052 
00053     ros::Rate rate(UPDATE_RATE);
00054     publishTimer=node.createTimer(rate,&GazeboObjectInfo::advertEvent, this);
00055 
00056     request_object_srv = node.advertiseService(REQUEST_OBJECTS_TOPIC, &GazeboObjectInfo::requestObject,this);
00057 }
00058 
00059 bool GazeboObjectInfo::requestObject(object_msgs::ObjectInfo::Request &req, object_msgs::ObjectInfo::Response &res) {
00060 
00061     std::string modelName = req.name;
00062     physics::ModelPtr model = gazebo::GetModelByName(world, modelName);
00063 
00064     if (!model.get()) {
00065         // ROS_ERROR("Model %s not found",modelName.c_str());
00066         res.success=false;
00067         res.error_code=object_msgs::ObjectInfo::Response::OBJECT_NOT_FOUND;
00068         return true;
00069     }
00070         
00071     res.error_code=object_msgs::ObjectInfo::Response::NO_ERROR;
00072     res.success=true;
00073     res.object=createBoundingBoxObject(model,req.get_geometry);
00074     //ROS_INFO("Received service request for object info!");
00075     return true;
00076 }
00077 
00078 void GazeboObjectInfo::advertEvent(const ros::TimerEvent& e) {
00079     if (object_pub.getNumSubscribers()==0) return;
00080     std::vector<GazeboObjectInfo::ObjectMsg>::iterator it;
00081     for (it=lastGeneratedObjects.begin(); it!=lastGeneratedObjects.end(); ++it) {
00082         object_pub.publish(*it);
00083     }
00084     lastGeneratedObjects.clear();
00085     reGenerateObjects=true;
00086 }
00087 
00088 
00089 void GazeboObjectInfo::onWorldUpdate() {
00090     if (object_pub.getNumSubscribers()==0) return;
00091 
00092     if (!reGenerateObjects) return;
00093 
00094     physics::Model_V models = gazebo::GetModels(world);
00095     physics::Model_V::iterator m_it;
00096 
00097     bool send_shape=false;
00098     for (m_it=models.begin(); m_it!=models.end(); ++m_it) {
00099         //ROS_INFO_STREAM("Have model "<<(*m_it)->GetName());
00100         GazeboObjectInfo::ObjectMsg obj=createBoundingBoxObject(*m_it,send_shape);
00101         lastGeneratedObjects.push_back(obj);
00102     }
00103 
00104     reGenerateObjects=false;
00105 }
00106 
00107 
00108 shape_msgs::SolidPrimitive * GazeboObjectInfo::getSolidPrimitive(physics::CollisionPtr& c) {
00109     shape_msgs::SolidPrimitive solid;
00110     msgs::Geometry geom;
00111     physics::ShapePtr shape=c->GetShape();
00112     shape->FillMsg(geom);
00113     if (geom.has_box()) {
00114         //ROS_INFO("shape type %i of collision %s is a box! ", c->GetShapeType(), c->GetName().c_str());
00115 
00116         const gazebo::physics::BoxShape * box=dynamic_cast<const physics::BoxShape*>(shape.get());
00117         if (!box) {
00118             ROS_ERROR("Dynamic cast failed for box shape");
00119             return NULL;
00120         }
00121         GzVector3 bb = gazebo::GetSize3(*box);
00122         if ((GetX(bb) < 1e-05) || (GetY(bb) < 1e-05) || (GetZ(bb) < 1e-05)){
00123             ROS_WARN_ONCE("Skipping coll %s because its bounding box is flat",c->GetName().c_str());
00124             return NULL;
00125         }
00126         solid.type=shape_msgs::SolidPrimitive::BOX;
00127         solid.dimensions.resize(3);
00128         solid.dimensions[shape_msgs::SolidPrimitive::BOX_X]=GetX(bb);
00129         solid.dimensions[shape_msgs::SolidPrimitive::BOX_Y]=GetY(bb);
00130         solid.dimensions[shape_msgs::SolidPrimitive::BOX_Z]=GetZ(bb);
00131     }/*else if (geom.has_cylinder()) {
00132         ROS_INFO("shape type %i of collision %s is a cylinder! ", c->GetShapeType(), c->GetName().c_str());
00133         const gazebo::physics::CylinderShape * cyl=dynamic_cast<const physics::CylinderShape*>(shape.get());
00134         if (!cyl) {
00135             ROS_ERROR("Dynamic cast failed for cylinder shape");
00136             return NULL;
00137         }
00138         solid.type=shape_msgs::SolidPrimitive::CYLINDER;
00139         solid.dimensions[shape_msgs::SolidPrimitive::CYLINDER_HEIGHT]=cyl->GetLength();
00140         solid.dimensions[shape_msgs::SolidPrimitive::CYLINDER_RADIUS]=cyl->GetRadius();
00141     }*/
00142     else if (geom.has_sphere())
00143     {
00144         //ROS_INFO("shape type %i of collision %s is a sphere! ", c->GetShapeType(), c->GetName().c_str());
00145 
00146         const gazebo::physics::SphereShape * sp
00147           = dynamic_cast<const physics::SphereShape*>(shape.get());
00148         if (!sp)
00149         {
00150             ROS_ERROR("Dynamic cast failed for cylinder shape");
00151             return NULL;
00152         }
00153 
00154         solid.type=shape_msgs::SolidPrimitive::SPHERE;
00155         solid.dimensions[shape_msgs::SolidPrimitive::SPHERE_RADIUS] = sp->GetRadius();
00156     }
00157     else
00158     {
00159         ROS_WARN("shape type %i of collision %s not supported. Using bounding box instead. ", c->GetShapeType(),c->GetName().c_str());
00160         gz_math::Box box = GetBoundingBox(*c);
00161         GzVector3 bb = GetBoundingBoxDimensions(box);
00162         if ((GetX(bb) < 1e-05) || (GetY(bb) < 1e-05) || (GetZ(bb) < 1e-05)){
00163             ROS_WARN_ONCE("Skipping coll %s because its bounding box is flat",c->GetName().c_str());
00164             return NULL;
00165         }
00166         solid.type=shape_msgs::SolidPrimitive::BOX;
00167         solid.dimensions.resize(3);
00168         solid.dimensions[shape_msgs::SolidPrimitive::BOX_X]=GetX(bb);
00169         solid.dimensions[shape_msgs::SolidPrimitive::BOX_Y]=GetY(bb);
00170         solid.dimensions[shape_msgs::SolidPrimitive::BOX_Z]=GetZ(bb);
00171     }
00172     //ROS_INFO_STREAM("Solid computed."<<std::endl<<solid);
00173     return new shape_msgs::SolidPrimitive(solid);
00174 }
00175 
00176 
00177 GazeboObjectInfo::ObjectMsg GazeboObjectInfo::createBoundingBoxObject(physics::ModelPtr& model, bool include_shape)
00178 {
00179     GazeboObjectInfo::ObjectMsg obj;
00180 
00181     physics::Link_V links=model->GetLinks();
00182     physics::Link_V::iterator l_it;
00183         
00184     obj.name=model->GetName();
00185     obj.header.stamp=ros::Time::now();
00186     obj.header.frame_id=ROOT_FRAME_ID;
00187     // obj.type =  no object type given
00188     // the custum origin (Object::origin) is going to be set to the first link encountered
00189     bool origin_init = false;
00190     for (l_it=links.begin(); l_it!=links.end(); ++l_it)
00191     {
00192         physics::LinkPtr link=*l_it;
00193         
00194         std::string linkName=link->GetName();
00195         
00196         GzPose3 link_pose=GetWorldPose(link);
00197         //ROS_INFO("Link for model %s: %s, pos %f %f %f",model->GetName().c_str(),link->GetName().c_str(),link_pose.pos.x,link_pose.pos.y,link_pose.pos.z);
00198         //ROS_INFO("Link found for model %s: %s",model->GetName().c_str(),link->GetName().c_str());
00199 
00200         physics::Collision_V colls=link->GetCollisions();
00201         physics::Collision_V::iterator cit;
00202         for (cit=colls.begin(); cit!=colls.end(); ++cit)
00203         {
00204             physics::CollisionPtr c=*cit;
00205             
00206             GzPose3 rel_pose = GetRelativePose(*c);
00207 
00208             //ROS_INFO("Collision for model %s: %s, pos %f %f %f",model->GetName().c_str(),link->GetName().c_str(),rel_pose.pos.x,rel_pose.pos.y,rel_pose.pos.z);
00209             //GzPose3 w_pose=c->GetWorldPose();
00210             //ROS_INFO("World pos for model %s: %s, pos %f %f %f",model->GetName().c_str(),link->GetName().c_str(),w_pose.pos.x,w_pose.pos.y,w_pose.pos.z);
00211 
00212             GzPose3 coll_pose=rel_pose+link_pose; //XXX c->GetWorldPose() does not work for non-static objects, so it has to be relative pose and link world pose
00213             geometry_msgs::Pose pose;
00214             pose.position.x = GetX(GetPos(coll_pose));
00215             pose.position.y = GetY(GetPos(coll_pose));
00216             pose.position.z = GetZ(GetPos(coll_pose));
00217             pose.orientation.x = GetX(GetRot(coll_pose));
00218             pose.orientation.y = GetY(GetRot(coll_pose));
00219             pose.orientation.z = GetZ(GetRot(coll_pose));
00220             pose.orientation.w = GetW(GetRot(coll_pose));
00221 
00222             obj.primitive_poses.push_back(pose);
00223         
00224             if (!origin_init)
00225             {
00226                 obj.origin = pose;
00227             }
00228     
00229             if (include_shape) {
00230 
00231                 shape_msgs::SolidPrimitive * solid=getSolidPrimitive(c);
00232                 if (!solid) {
00233                     ROS_WARN("Skipping coll %s of link %s of model %s, could not get SolidPrimitive. ",c->GetName().c_str(),linkName.c_str(),obj.name.c_str());
00234                     continue;
00235                 }
00236 
00237                 obj.primitives.push_back(*solid);
00238                 delete solid;
00239                 obj.content=GazeboObjectInfo::ObjectMsg::SHAPE;
00240             }else {
00241                 obj.content=GazeboObjectInfo::ObjectMsg::POSE;
00242                 //ROS_INFO("Pub pose for %s (%s %s)",c->GetName().c_str(),link->GetName().c_str(),model->GetName().c_str());
00243             }
00244         }
00245     }
00246 
00247     obj.primitive_origin = GazeboObjectInfo::ObjectMsg::ORIGIN_AVERAGE;
00248     obj.mesh_origin = GazeboObjectInfo::ObjectMsg::ORIGIN_UNDEFINED;
00249 
00250     return obj;
00251 }
00252 
00253 


gazebo_state_plugins
Author(s): Jennifer Buehler
autogenerated on Tue May 7 2019 03:29:35