00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef MOVEIT_COLLISION_DETECTION_FCL_COLLISION_COMMON_
00038 #define MOVEIT_COLLISION_DETECTION_FCL_COLLISION_COMMON_
00039
00040 #include <moveit/collision_detection/world.h>
00041 #include <moveit/collision_detection/collision_world.h>
00042 #include <fcl/broadphase/broadphase.h>
00043 #include <fcl/collision.h>
00044 #include <fcl/distance.h>
00045 #include <set>
00046
00047 namespace collision_detection
00048 {
00049
00050 struct CollisionGeometryData
00051 {
00052 CollisionGeometryData(const robot_model::LinkModel *link, int index)
00053 : type(BodyTypes::ROBOT_LINK)
00054 , shape_index(index)
00055 {
00056 ptr.link = link;
00057 }
00058
00059 CollisionGeometryData(const robot_state::AttachedBody *ab, int index)
00060 : type(BodyTypes::ROBOT_ATTACHED)
00061 , shape_index(index)
00062 {
00063 ptr.ab = ab;
00064 }
00065
00066 CollisionGeometryData(const World::Object *obj, int index)
00067 : type(BodyTypes::WORLD_OBJECT)
00068 , shape_index(index)
00069 {
00070 ptr.obj = obj;
00071 }
00072
00073 const std::string& getID() const
00074 {
00075 switch (type)
00076 {
00077 case BodyTypes::ROBOT_LINK:
00078 return ptr.link->getName();
00079 case BodyTypes::ROBOT_ATTACHED:
00080 return ptr.ab->getName();
00081 default:
00082 break;
00083 }
00084 return ptr.obj->id_;
00085 }
00086
00087 std::string getTypeString() const
00088 {
00089 switch (type)
00090 {
00091 case BodyTypes::ROBOT_LINK:
00092 return "Robot link";
00093 case BodyTypes::ROBOT_ATTACHED:
00094 return "Robot attached";
00095 default:
00096 break;
00097 }
00098 return "Object";
00099 }
00100
00102 bool sameObject(const CollisionGeometryData &other) const
00103 {
00104 return type == other.type && ptr.raw == other.ptr.raw;
00105 }
00106
00107 BodyType type;
00108 int shape_index;
00109 union
00110 {
00111 const robot_model::LinkModel *link;
00112 const robot_state::AttachedBody *ab;
00113 const World::Object *obj;
00114 const void *raw;
00115 } ptr;
00116 };
00117
00118 struct CollisionData
00119 {
00120 CollisionData() : req_(NULL), active_components_only_(NULL), res_(NULL), acm_(NULL), done_(false)
00121 {
00122 }
00123
00124 CollisionData(const CollisionRequest *req, CollisionResult *res,
00125 const AllowedCollisionMatrix *acm) : req_(req), active_components_only_(NULL), res_(res), acm_(acm), done_(false)
00126 {
00127 }
00128
00129 ~CollisionData()
00130 {
00131 }
00132
00134 void enableGroup(const robot_model::RobotModelConstPtr &kmodel);
00135
00137 const CollisionRequest *req_;
00138
00141 const std::set<const robot_model::LinkModel*>
00142 *active_components_only_;
00143
00145 CollisionResult *res_;
00146
00148 const AllowedCollisionMatrix *acm_;
00149
00151 bool done_;
00152 };
00153
00154
00155 struct FCLGeometry
00156 {
00157 FCLGeometry()
00158 {
00159 }
00160
00161 FCLGeometry(fcl::CollisionGeometry *collision_geometry, const robot_model::LinkModel *link, int shape_index) :
00162 collision_geometry_(collision_geometry), collision_geometry_data_(new CollisionGeometryData(link, shape_index))
00163 {
00164 collision_geometry_->setUserData(collision_geometry_data_.get());
00165 }
00166
00167 FCLGeometry(fcl::CollisionGeometry *collision_geometry, const robot_state::AttachedBody *ab, int shape_index) :
00168 collision_geometry_(collision_geometry), collision_geometry_data_(new CollisionGeometryData(ab, shape_index))
00169 {
00170 collision_geometry_->setUserData(collision_geometry_data_.get());
00171 }
00172
00173 FCLGeometry(fcl::CollisionGeometry *collision_geometry, const World::Object *obj, int shape_index) :
00174 collision_geometry_(collision_geometry), collision_geometry_data_(new CollisionGeometryData(obj, shape_index))
00175 {
00176 collision_geometry_->setUserData(collision_geometry_data_.get());
00177 }
00178
00179 template<typename T>
00180 void updateCollisionGeometryData(const T* data, int shape_index, bool newType)
00181 {
00182 if (!newType && collision_geometry_data_)
00183 if (collision_geometry_data_->ptr.raw == reinterpret_cast<const void*>(data))
00184 return;
00185 collision_geometry_data_.reset(new CollisionGeometryData(data, shape_index));
00186 collision_geometry_->setUserData(collision_geometry_data_.get());
00187 }
00188
00189 boost::shared_ptr<fcl::CollisionGeometry> collision_geometry_;
00190 boost::shared_ptr<CollisionGeometryData> collision_geometry_data_;
00191 };
00192
00193 typedef boost::shared_ptr<FCLGeometry> FCLGeometryPtr;
00194 typedef boost::shared_ptr<const FCLGeometry> FCLGeometryConstPtr;
00195
00196 struct FCLObject
00197 {
00198 void registerTo(fcl::BroadPhaseCollisionManager *manager);
00199 void unregisterFrom(fcl::BroadPhaseCollisionManager *manager);
00200 void clear();
00201
00202 std::vector<boost::shared_ptr<fcl::CollisionObject> > collision_objects_;
00203 std::vector<FCLGeometryConstPtr> collision_geometry_;
00204 };
00205
00206 struct FCLManager
00207 {
00208 FCLObject object_;
00209 boost::shared_ptr<fcl::BroadPhaseCollisionManager> manager_;
00210 };
00211
00212 bool collisionCallback(fcl::CollisionObject *o1, fcl::CollisionObject *o2, void *data);
00213
00214 bool distanceCallback(fcl::CollisionObject* o1, fcl::CollisionObject* o2, void *data, double& min_dist);
00215
00216 FCLGeometryConstPtr createCollisionGeometry(const shapes::ShapeConstPtr &shape,
00217 const robot_model::LinkModel *link,
00218 int shape_index);
00219 FCLGeometryConstPtr createCollisionGeometry(const shapes::ShapeConstPtr &shape,
00220 const robot_state::AttachedBody *ab,
00221 int shape_index);
00222 FCLGeometryConstPtr createCollisionGeometry(const shapes::ShapeConstPtr &shape,
00223 const World::Object *obj);
00224
00225 FCLGeometryConstPtr createCollisionGeometry(const shapes::ShapeConstPtr &shape, double scale, double padding,
00226 const robot_model::LinkModel *link, int shape_index);
00227 FCLGeometryConstPtr createCollisionGeometry(const shapes::ShapeConstPtr &shape, double scale, double padding,
00228 const robot_state::AttachedBody *ab, int shape_index);
00229 FCLGeometryConstPtr createCollisionGeometry(const shapes::ShapeConstPtr &shape, double scale, double padding,
00230 const World::Object *obj);
00231 void cleanCollisionGeometryCache();
00232
00233 inline void transform2fcl(const Eigen::Affine3d &b, fcl::Transform3f &f)
00234 {
00235 Eigen::Quaterniond q(b.rotation());
00236 f.setTranslation(fcl::Vec3f(b.translation().x(), b.translation().y(), b.translation().z()));
00237 f.setQuatRotation(fcl::Quaternion3f(q.w(), q.x(), q.y(), q.z()));
00238 }
00239
00240 inline fcl::Transform3f transform2fcl(const Eigen::Affine3d &b)
00241 {
00242 fcl::Transform3f t;
00243 transform2fcl(b, t);
00244 return t;
00245 }
00246
00247 inline void fcl2contact(const fcl::Contact &fc, Contact &c)
00248 {
00249 c.pos = Eigen::Vector3d(fc.pos[0], fc.pos[1], fc.pos[2]);
00250 c.normal = Eigen::Vector3d(fc.normal[0], fc.normal[1], fc.normal[2]);
00251 c.depth = fc.penetration_depth;
00252 const CollisionGeometryData *cgd1 = static_cast<const CollisionGeometryData*>(fc.o1->getUserData());
00253 c.body_name_1 = cgd1->getID();
00254 c.body_type_1 = cgd1->type;
00255 const CollisionGeometryData *cgd2 = static_cast<const CollisionGeometryData*>(fc.o2->getUserData());
00256 c.body_name_2 = cgd2->getID();
00257 c.body_type_2 = cgd2->type;
00258 }
00259
00260 inline void fcl2costsource(const fcl::CostSource &fcs, CostSource& cs)
00261 {
00262 cs.aabb_min[0] = fcs.aabb_min[0];
00263 cs.aabb_min[1] = fcs.aabb_min[1];
00264 cs.aabb_min[2] = fcs.aabb_min[2];
00265
00266 cs.aabb_max[0] = fcs.aabb_max[0];
00267 cs.aabb_max[1] = fcs.aabb_max[1];
00268 cs.aabb_max[2] = fcs.aabb_max[2];
00269
00270 cs.cost = fcs.cost_density;
00271 }
00272
00273 }
00274
00275 #endif