/// Determines whether a pair of geometries is checked for collision detection
bool CollisionDetection::is_checked(CollisionGeometryPtr cg1, CollisionGeometryPtr cg2) const
{
  // if both geometries belong to one rigid body, don't check
  RigidBodyPtr rb1 = dynamic_pointer_cast<RigidBody>(cg1->get_single_body());
  RigidBodyPtr rb2 = dynamic_pointer_cast<RigidBody>(cg2->get_single_body());
  if (rb1 && rb2 && rb1 == rb2)
    return false;

  // check the geometries
  return (is_enabled(cg1) && is_enabled(cg2) && is_enabled(cg1, cg2));
}
/// Calculates the velocity expanded bounding volume for the bounding sphere (calculates an OBB)
BVPtr BoundingSphere::calc_swept_BV(CollisionGeometryPtr g, const SVelocityd& v) const
{
  // get the corresponding body
  SingleBodyPtr b = g->get_single_body();

  // if the body does not move, just return the bounding sphere 
  if (!b->is_enabled())
  {
    FILE_LOG(LOG_BV) << "BoundingSphere::calc_swept_BV() entered" << endl;
    FILE_LOG(LOG_BV) << "  -- using original bounding sphere" << endl;
    FILE_LOG(LOG_BV) << "BoundingSphere::calc_swept_BV() exited" << endl;

    return const_pointer_cast<BoundingSphere>(get_this());
  }

  // get the velocity in the proper frame
  SVelocityd vx = Pose3d::transform(get_relative_pose(), v); 

  // otherwise, create a SSL 
  shared_ptr<SSL> ssl(new SSL);
  ssl->p1 = this->center;
  ssl->p2 = this->center + vx.get_linear();
  ssl->radius = this->radius;
  return ssl;
}
Example #3
0
void ColdetPlugin::add_collision_geometry(CollisionGeometryPtr cg)
{
  RigidBodyPtr rb = dynamic_pointer_cast<RigidBody>(cg->get_single_body());
  if (rb->id.find("box") != std::string::npos)
  {
    // add the box
    _boxes.push_back(cg);

    // sort all collision geometries
    std::map<std::string, CollisionGeometryPtr> geoms;
    for (unsigned i=0; i< _boxes.size(); i++)
      geoms[_boxes[i]->get_single_body()->id] = _boxes[i];

    // clear the boxes
    _boxes.clear();
    for (std::map<std::string, CollisionGeometryPtr>::const_iterator i = geoms.begin(); i != geoms.end(); i++)
      _boxes.push_back(i->second);
  }
  else
  {
    assert(rb->id == "ground");
    _ground = cg;
  }
}
Example #4
0
/// Calculates the signed distances between two geometries and returns closest points if geometries are not interpenetrating
double CollisionGeometry::calc_signed_dist(CollisionGeometryPtr gA, CollisionGeometryPtr gB, Point3d& pA, Point3d& pB) 
{
  // get the two primitives
  PrimitivePtr primA = gA->get_geometry();
  PrimitivePtr primB = gB->get_geometry();

  // setup poses for the points
  pA.pose = primA->get_pose(gA);
  pB.pose = primB->get_pose(gB);

  FILE_LOG(LOG_COLDET) << "CollisionGeometry::calc_signed_dist() - computing signed distance between " << gA->get_single_body()->id << " and " << gB->get_single_body()->id << std::endl;

  // now compute the signed distance
  return primA->calc_signed_dist(primB, pA, pB);
}
Example #5
0
/**
 * This method looks for contact data not only between the pair of geometries, but also
 * the rigid bodies that the geometries belong to, and any articulated bodies as well.
 * The search proceeds in the following manner: <br />
 * <ol>
 *  <li>two collision geometries</li>
 *  <li>one collision geometry, one rigid body</li>
 *  <li>two rigid bodies</li>
 *  <li>one collision geometry, one articulated body</li>
 *  <li>one rigid body, one articulated body</li>
 *  <li>two articulated bodies</li>
 * </ol>
 * The search order allows for multiple granularities; for example, a collision can easily
 * be specified between two geometries of two of a robot's links (i.e., representing different
 * surfaces on the links), between two links, or between two robots.
 * \param g1 the first collision geometry
 * \param g2 the second collision geometry
 * \return a pointer to the contact data, if any, found
 */
shared_ptr<ContactParameters> EventDrivenSimulator::get_contact_parameters(CollisionGeometryPtr geom1, CollisionGeometryPtr geom2) const
{
  map<sorted_pair<BasePtr>, shared_ptr<ContactParameters> >::const_iterator iter;

  // search for the two contact geometries first
  if ((iter = contact_params.find(make_sorted_pair(geom1, geom2))) != contact_params.end())
    return iter->second;

  // get the geometries as base pointers
  BasePtr g1(geom1);
  BasePtr g2(geom2);
  
  // get the two single bodies
  assert(geom1->get_single_body());
  assert(geom2->get_single_body());
  SingleBodyPtr singlebody1 = geom1->get_single_body();
  SingleBodyPtr singlebody2 = geom2->get_single_body();
  BasePtr sb1 = singlebody1;
  BasePtr sb2 = singlebody2;

  // search for contact geometry 1 and rigid body 2
  if ((iter = contact_params.find(make_sorted_pair(g1, sb2))) != contact_params.end())
    return iter->second;

  // search for contact geometry 2 and rigid body 1
  if ((iter = contact_params.find(make_sorted_pair(g2, sb1))) != contact_params.end())
    return iter->second;

  // search for both rigid bodies
  if ((iter = contact_params.find(make_sorted_pair(sb1, sb2))) != contact_params.end())
    return iter->second;

  // get the articulated bodies, if any
  RigidBodyPtr rb1 = dynamic_pointer_cast<RigidBody>(singlebody1);
  RigidBodyPtr rb2 = dynamic_pointer_cast<RigidBody>(singlebody2);
  BasePtr ab1, ab2;
  if (rb1)
    ab1 = rb1->get_articulated_body();
  if (rb2)
    ab2 = rb2->get_articulated_body();

  // check collision geometry 2 and rigid body 2 against articulated body 1
  if (ab1)
  {
    if ((iter = contact_params.find(make_sorted_pair(g2, ab1))) != contact_params.end())
      return iter->second;
    if ((iter = contact_params.find(make_sorted_pair(sb2, ab1))) != contact_params.end())
      return iter->second;
  }

  // check collision geometry 1 and rigid body 1 against articulated body 2
  if (ab2)
  {
    if ((iter = contact_params.find(make_sorted_pair(g1, ab2))) != contact_params.end())
      return iter->second;
    if ((iter = contact_params.find(make_sorted_pair(sb1, ab2))) != contact_params.end())
      return iter->second;
  }

  // check the two articulated bodies against articulated body 2
  if (ab1 && ab2)
    if ((iter = contact_params.find(make_sorted_pair(ab1, ab2))) != contact_params.end())
      return iter->second;
  
  // still here?  no contact data found
  return shared_ptr<ContactParameters>();
}