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
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
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
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
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
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 }
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 else if (geom.has_sphere())
00143 {
00144
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
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
00188
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
00198
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
00209
00210
00211
00212 GzPose3 coll_pose=rel_pose+link_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
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