Ejemplo n.º 1
0
// show the state of the current query
void collision_detection::CollisionRobotDistanceField::dumpQuery(const WorkArea& work, const char *descrip) const
{
  logInform("CollisionRobotDistanceField Query %s", descrip);

  std::stringstream ss_cost;
  ss_cost << ", cost(max=" << work.req_->max_cost_sources << ", dens=" << work.req_->min_cost_density << ")";
  std::stringstream ss_contacts;
  ss_contacts << ", contact(max=" << work.req_->max_contacts << ", cpp=" << work.req_->max_contacts_per_pair << ")";
  std::stringstream ss_acm;
  if (work.acm_)
  {
    std::vector<std::string> names;
    work.acm_->getAllEntryNames(names);
    ss_acm << ", acm(nnames=" << names.size() << ", sz=" << work.acm_->getSize() << ")";
  }
  if (0)
  {
    logInform("   request: result%s%s%s%s%s%s",
      work.req_->distance ? ", distance" : "",
      work.req_->cost ? ss_cost.str().c_str() : "",
      work.req_->contacts ? ss_contacts.str().c_str() : "",
      work.req_->is_done ? ", is_done-func" : "",
      work.req_->verbose ? ", VERBOSE" : "",
      ss_acm.str().c_str());
  }
}
void ompl_interface::ConstraintsLibrary::loadConstraintApproximations(const std::string &path)
{
  constraint_approximations_.clear();
  std::ifstream fin((path + "/manifest").c_str());
  if (!fin.good())
  {
    logDebug("Manifest not found in folder '%s'. Not loading constraint approximations.", path.c_str());
    return;
  }
  
  logInform("Loading constrained space approximations from '%s'", path.c_str());
  
  while (fin.good() && !fin.eof())
  {
    std::string group, state_space_parameterization, serialization, filename;
    fin >> group;
    if (fin.eof())
      break;
    fin >> state_space_parameterization;
    if (fin.eof())
      break;
    fin >> serialization;    
    if (fin.eof())
      break;
    fin >> filename;
    const ModelBasedPlanningContextPtr &pc = context_manager_.getPlanningContext(group, state_space_parameterization);
    if (pc)
    {
      moveit_msgs::Constraints msg;
      hexToMsg(serialization, msg);
      ConstraintApproximationStateStorage *cass = new ConstraintApproximationStateStorage(pc->getOMPLSimpleSetup().getStateSpace());
      cass->load((path + "/" + filename).c_str());
      ConstraintApproximationPtr cap;
      if (constraint_factories_.find(msg.name) != constraint_factories_.end())
        cap = constraint_factories_[msg.name]->allocApproximation(context_manager_.getRobotModel(),
                                                                  group, state_space_parameterization, msg, filename, ompl::base::StateStoragePtr(cass));
      else
        cap.reset(new ConstraintApproximation(context_manager_.getRobotModel(),
                                              group, state_space_parameterization, msg, filename, ompl::base::StateStoragePtr(cass)));
      if (cap)
      {
        if (constraint_approximations_.find(cap->getName()) != constraint_approximations_.end())
          logWarn("Overwriting constraint approximation named '%s'", cap->getName().c_str());
        
        constraint_approximations_[cap->getName()] = cap;
        std::size_t sum = 0;
        for (std::size_t i = 0 ; i < cass->size() ; ++i)
          sum += cass->getMetadata(i).size();
        logInform("Loaded %lu states and %lu connections (%0.1lf per state) from %s", cass->size(), sum, (double)sum / (double)cass->size(), filename.c_str());
      }
    }
  }
}
// helper function to avoid code duplication
static inline
kinematic_constraints::ConstraintEvaluationResult finishPositionConstraintDecision(const Eigen::Vector3d &pt, const Eigen::Vector3d &desired, const std::string &name,
                                                                                   double weight, bool result, bool verbose)
{
  double dx = desired.x() - pt.x();
  double dy = desired.y() - pt.y();
  double dz = desired.z() - pt.z();
  if (verbose)
  {
    logInform("Position constraint %s on link '%s'. Desired: %f, %f, %f, current: %f, %f, %f",
             result ? "satisfied" : "violated", name.c_str(), desired.x(), desired.y(), desired.z(), pt.x(), pt.y(), pt.z());
    logInform("Differences %g %g %g",dx,dy, dz);
  }
  return ConstraintEvaluationResult(result, weight * sqrt(dx * dx + dy * dy + dz * dz));
}
void ompl_interface::ConstraintsLibrary::saveConstraintApproximations(const std::string &path)
{
  logInform("Saving %u constrained space approximations to '%s'", (unsigned int)constraint_approximations_.size(), path.c_str());
  try
  {
    boost::filesystem::create_directories(path);
  }
  catch(...)
  {
  }
  
  std::ofstream fout((path + "/manifest").c_str());
  if (fout.good())
    for (std::map<std::string, ConstraintApproximationPtr>::const_iterator it = constraint_approximations_.begin() ; it != constraint_approximations_.end() ; ++it)
    {
      fout << it->second->getGroup() << std::endl;
      fout << it->second->getStateSpaceParameterization() << std::endl;
      std::string serialization;
      msgToHex(it->second->getConstraintsMsg(), serialization);
      fout << serialization << std::endl;
      fout << it->second->getFilename() << std::endl;
      if (it->second->getStateStorage())
        it->second->getStateStorage()->store((path + "/" + it->second->getFilename()).c_str());
    }
  else
    logError("Unable to save constraint approximation to '%s'", path.c_str());
  fout.close();
}
Ejemplo n.º 5
0
void collision_detection::CollisionRobotAllValid::checkOtherCollision(const CollisionRequest &req, CollisionResult &res, const robot_state::RobotState &state1, const robot_state::RobotState &state2,
                                                                      const CollisionRobot &other_robot, const robot_state::RobotState &other_state1, const robot_state::RobotState &other_state2) const
{
  res.collision = false;
  if (req.verbose)
    logInform("Using AllValid collision detection. No collision checking is performed.");
}
Ejemplo n.º 6
0
void moveit::tools::Profiler::console(void)
{
  std::stringstream ss;
  ss << std::endl;
  status(ss, true);
  logInform(ss.str().c_str());
}
moveit_rviz_plugin::PerLinkSubProperty::PerLinkSubProperty(
      PerLinkProperty* parent,
      PerLinkSubObjBase* sub_obj)
  : PropertyHolder(sub_obj, parent)
  , parent_(parent)
  , sub_obj_(sub_obj)
  , modified_(false)
{
logInform(" construct PerLinkSubProperty %s at %d",name_.c_str(), __LINE__);
  sub_obj_->addProp(this);
  if (flags_ & PF_NOT_PERLINK)
    property_->hide();
}
moveit_rviz_plugin::PropertyHolder::PropertyHolder(
      rviz::Property *parent_property,
      const PropertyHolder* clone)
  : name_(clone->name_)
  , type_(clone->type_)
  , flags_(clone->flags_)
  , property_(NULL)
{
logInform(" construct PropertyHolder %s at %d (clone)",name_.c_str(), __LINE__);
  createProperty(parent_property,
                 clone->property_->getDescription().toStdString(),
                 clone->property_->getValue());
}
kinematic_constraints::ConstraintEvaluationResult kinematic_constraints::JointConstraint::decide(const robot_state::RobotState &state, bool verbose) const
{
  if (!joint_model_)
    return ConstraintEvaluationResult(true, 0.0);

  const robot_state::JointState *joint = state.getJointState(joint_model_->getName());

  if (!joint)
  {
    logWarn("No joint in state with name '%s'", joint_model_->getName().c_str());
    return ConstraintEvaluationResult(true, 0.0);
  }

  double current_joint_position = joint->getVariableValues()[0];
  if (!local_variable_name_.empty())
  {
    const std::map<std::string, unsigned int> &index_map = joint->getVariableIndexMap();
    std::map<std::string, unsigned int>::const_iterator it = index_map.find(joint_variable_name_);
    if (it == index_map.end())
    {
      logWarn("Local name '%s' is not known to joint state with name '%s'", local_variable_name_.c_str(), joint_model_->getName().c_str());
      return ConstraintEvaluationResult(true, 0.0);
    }
    else
      current_joint_position = joint->getVariableValues()[it->second];
  }

  double dif = 0.0;

  // compute signed shortest distance for continuous joints
  if (joint_is_continuous_)
  {
    dif = normalizeAngle(current_joint_position) - joint_position_;

    if (dif > boost::math::constants::pi<double>())
      dif = 2.0*boost::math::constants::pi<double>() - dif;
    else
      if (dif < -boost::math::constants::pi<double>())
        dif += 2.0*boost::math::constants::pi<double>(); // we include a sign change to have dif > 0
  }
  else
    dif = current_joint_position - joint_position_;

  // check bounds
  bool result = dif <= (joint_tolerance_above_+2*std::numeric_limits<double>::epsilon()) && dif >= (-joint_tolerance_below_-2*std::numeric_limits<double>::epsilon());
  if (verbose)
    logInform("Constraint %s:: Joint name: '%s', actual value: %f, desired value: %f, tolerance_above: %f, tolerance_below: %f",
              result ? "satisfied" : "violated", joint_variable_name_.c_str(),
              current_joint_position, joint_position_, joint_tolerance_above_, joint_tolerance_below_);
  return ConstraintEvaluationResult(result, constraint_weight_ * fabs(dif));
}
moveit_rviz_plugin::PerLinkProperty::PerLinkProperty(
      PerLinkObjBase* obj,
      const std::string& name,
      const std::string& descr,
      PropertyType type,
      QVariant value,
      unsigned int flags)
  : PropertyHolder(obj, name, descr, type, value, flags)
  , obj_(obj)
{
logInform(" construct PerLinkProperty %s at %d",name.c_str(), __LINE__);
  obj_->addProp(this);
  if (flags_ & PF_NOT_GLOBAL)
    property_->hide();
}
moveit_rviz_plugin::PropertyHolder::PropertyHolder(
      rviz::Property *parent_property,
      const std::string& name,
      const std::string& descr,
      PropertyType type,
      QVariant value,
      unsigned int flags)
  : name_(name)
  , type_(type)
  , flags_(flags)
  , property_(NULL)
{
logInform(" construct PropertyHolder %s at %d (full)",name_.c_str(), __LINE__);
  createProperty(parent_property, descr, value);
}
void moveit_rviz_plugin::PropertyHolder::createProperty(
      rviz::Property *parent_property,
      const std::string& descr,
      QVariant value)
{
  switch(type_)
  {
    case PT_EMPTY:
      property_ = new rviz::Property(
                             name_.c_str(),
                             QVariant(),
                             descr.c_str(),
                             parent_property);
      break;
    case PT_INT:
      property_ = new rviz::IntProperty(
                             name_.c_str(),
                             value.toInt(),
                             descr.c_str(),
                             parent_property,
                             SLOT( changedSlot() ),
                             this );
      break;
    case PT_FLOAT:
      property_ = new rviz::FloatProperty(
                             name_.c_str(),
                             value.toDouble(),
                             descr.c_str(),
                             parent_property,
                             SLOT( changedSlot() ),
                             this );
      break;
    case PT_BOOL:
    default:
      type_ = PT_BOOL;
      property_ = new rviz::BoolProperty(
                             name_.c_str(),
                             value.toBool(),
                             descr.c_str(),
                             parent_property,
                             SLOT( changedSlot() ),
                             this );
      break;
  }
logInform(" createProperty %08lx",long(property_));
  if (flags_ & PF_READ_ONLY)
    property_->setReadOnly(true);
}
kinematic_constraints::ConstraintEvaluationResult kinematic_constraints::OrientationConstraint::decide(const robot_state::RobotState &state, bool verbose) const
{
  if (!link_model_)
    return ConstraintEvaluationResult(true, 0.0);

  const robot_state::LinkState *link_state = state.getLinkState(link_model_->getName());

  if (!link_state)
  {
    logWarn("No link in state with name '%s'", link_model_->getName().c_str());
    return ConstraintEvaluationResult(false, 0.0);
  }

  Eigen::Vector3d xyz;
  if (mobile_frame_)
  {
    Eigen::Matrix3d tmp;
    tf_->transformRotationMatrix(state, desired_rotation_frame_id_, desired_rotation_matrix_, tmp);
    Eigen::Affine3d diff(tmp.inverse() * link_state->getGlobalLinkTransform().rotation());
    xyz = diff.rotation().eulerAngles(0, 1, 2);
    // 0,1,2 corresponds to ZXZ, the convention used in sampling constraints
  }
  else
  {
    Eigen::Affine3d diff(desired_rotation_matrix_inv_ * link_state->getGlobalLinkTransform().rotation());
    xyz = diff.rotation().eulerAngles(0, 1, 2); // 0,1,2 corresponds to ZXZ, the convention used in sampling constraints
  }

  xyz(0) = std::min(fabs(xyz(0)), boost::math::constants::pi<double>() - fabs(xyz(0)));
  xyz(1) = std::min(fabs(xyz(1)), boost::math::constants::pi<double>() - fabs(xyz(1)));
  xyz(2) = std::min(fabs(xyz(2)), boost::math::constants::pi<double>() - fabs(xyz(2)));
  bool result = xyz(2) < absolute_z_axis_tolerance_+std::numeric_limits<double>::epsilon()
    && xyz(1) < absolute_y_axis_tolerance_+std::numeric_limits<double>::epsilon()
    && xyz(0) < absolute_x_axis_tolerance_+std::numeric_limits<double>::epsilon();

  if (verbose)
  {
    Eigen::Quaterniond q_act(link_state->getGlobalLinkTransform().rotation());
    Eigen::Quaterniond q_des(desired_rotation_matrix_);
    logInform("Orientation constraint %s for link '%s'. Quaternion desired: %f %f %f %f, quaternion actual: %f %f %f %f, error: x=%f, y=%f, z=%f, tolerance: x=%f, y=%f, z=%f",
             result ? "satisfied" : "violated", link_model_->getName().c_str(),
             q_des.x(), q_des.y(), q_des.z(), q_des.w(),
             q_act.x(), q_act.y(), q_act.z(), q_act.w(), xyz(0), xyz(1), xyz(2),
             absolute_x_axis_tolerance_, absolute_y_axis_tolerance_, absolute_z_axis_tolerance_);
  }

  return ConstraintEvaluationResult(result, constraint_weight_ * (xyz(0) + xyz(1) + xyz(2)));
}
TEST_F(FclCollisionDetectionTester, TestCollisionMapAdditionSpeed)
{
  EigenSTL::vector_Affine3d poses;
  std::vector<shapes::ShapeConstPtr> shapes;
  for(unsigned int i = 0; i < 10000; i++) {
    poses.push_back(Eigen::Affine3d::Identity());
    shapes.push_back(shapes::ShapeConstPtr(new shapes::Box(.01, .01, .01)));
  }
  ros::WallTime start = ros::WallTime::now();
  cworld_->getWorld()->addToObject("map", shapes, poses);
  double t = (ros::WallTime::now()-start).toSec();
  EXPECT_GE(1.0, t);
  // this is not really a failure; it is just that slow;
  // looking into doing collision checking with a voxel grid.
  logInform("Adding boxes took %g", t);
}
ompl_interface::ConstraintApproximationConstructionResults
ompl_interface::ConstraintsLibrary::addConstraintApproximation(const moveit_msgs::Constraints &constr_sampling, const moveit_msgs::Constraints &constr_hard,
                                                               const std::string &group, const std::string &state_space_parameterization,
                                                               const planning_scene::PlanningSceneConstPtr &scene, unsigned int samples, unsigned int edges_per_sample)
{ 
  ConstraintApproximationConstructionResults res;
  ModelBasedPlanningContextPtr pc = context_manager_.getPlanningContext(group, state_space_parameterization);
  if (pc)
  {                                             
    pc->clear();
    pc->setPlanningScene(scene);
    pc->setCompleteInitialState(scene->getCurrentState());

    std::map<std::string, ConstraintApproximationFactoryPtr>::const_iterator it = constraint_factories_.find(constr_hard.name);
    ConstraintApproximationFactory *fct = NULL;
    ConstraintStateStorageOrderFn order;
    if (it != constraint_factories_.end())
    {
      fct = it->second.get();
      order = fct->getOrderFunction();
    }
    
    ros::WallTime start = ros::WallTime::now();
    ompl::base::StateStoragePtr ss = constructConstraintApproximation(pc, constr_sampling, constr_hard, order, samples, edges_per_sample, res);
    logInform("Spent %lf seconds constructing the database", (ros::WallTime::now() - start).toSec());
    if (ss)
    {
      ConstraintApproximationPtr ca;
      if (fct)
        ca = fct->allocApproximation(context_manager_.getRobotModel(), group, state_space_parameterization, constr_hard, group + "_" + 
                                     boost::posix_time::to_iso_extended_string(boost::posix_time::microsec_clock::universal_time()) + ".ompldb", ss);
      else
        ca.reset(new ConstraintApproximation(context_manager_.getRobotModel(), group, state_space_parameterization, constr_hard, group + "_" + 
                                             boost::posix_time::to_iso_extended_string(boost::posix_time::microsec_clock::universal_time()) + ".ompldb", ss));
      if (ca)
      {
        if (constraint_approximations_.find(ca->getName()) != constraint_approximations_.end())
          logWarn("Overwriting constraint approximation named '%s'", ca->getName().c_str());
        constraint_approximations_[ca->getName()] = ca;
        res.approx = ca;
      }
    }
    else
      logError("Unable to construct constraint approximation for group '%s'", group.c_str());
  }
  return res;
}
void collision_detection::StaticDistanceField::initialize(
      const bodies::Body& body,
      double resolution,
      double space_around_body,
      bool save_points)
{
  points_.clear();
  inv_twice_resolution_ = 1.0 / (2.0 * resolution);


  logInform("    create points at res=%f",resolution);
  EigenSTL::vector_Vector3d points;
  determineCollisionPoints(body, resolution, points);

  if (points.empty())
  {
    logWarn("    StaticDistanceField::initialize: No points in body. Using origin.");
    points.push_back(body.getPose().translation());

    if (body.getType() == shapes::MESH)
    {
      const bodies::ConvexMesh& mesh = dynamic_cast<const bodies::ConvexMesh&>(body);
      const EigenSTL::vector_Vector3d& verts = mesh.getVertices();
      logWarn("    StaticDistanceField::initialize: also using %d vertices.", int(verts.size()));

      EigenSTL::vector_Vector3d::const_iterator it = verts.begin();
      EigenSTL::vector_Vector3d::const_iterator it_end = verts.end();
      for ( ; it != it_end ; ++it)
      {
        points.push_back(*it);
      }
    }
  }
  logInform("    StaticDistanceField::initialize: Using %d points.", points.size());

  AABB aabb;
  aabb.add(points);

  logInform("    space_around_body = %f",space_around_body);
  logInform("    DF: min=(%7.3f %7.3f %7.3f)  max=(%7.3f %7.3f %7.3f) (pre-space)",
                              aabb.min_.x(),
                              aabb.min_.y(),
                              aabb.min_.z(),
                              aabb.max_.x(),
                              aabb.max_.y(),
                              aabb.max_.z());

  aabb.min_ -= Eigen::Vector3d(space_around_body, space_around_body, space_around_body);
  aabb.max_ += Eigen::Vector3d(space_around_body, space_around_body, space_around_body);

  logInform("    DF: min=(%7.3f %7.3f %7.3f)  max=(%7.3f %7.3f %7.3f) (pre-adjust)",
                              aabb.min_.x(),
                              aabb.min_.y(),
                              aabb.min_.z(),
                              aabb.max_.x(),
                              aabb.max_.y(),
                              aabb.max_.z());

  aabb.min_.x() = std::floor(aabb.min_.x() / resolution) * resolution;
  aabb.min_.y() = std::floor(aabb.min_.y() / resolution) * resolution;
  aabb.min_.z() = std::floor(aabb.min_.z() / resolution) * resolution;

  logInform("    DF: min=(%7.3f %7.3f %7.3f)  max=(%7.3f %7.3f %7.3f) (post-adjust)",
                              aabb.min_.x(),
                              aabb.min_.y(),
                              aabb.min_.z(),
                              aabb.max_.x(),
                              aabb.max_.y(),
                              aabb.max_.z());

  Eigen::Vector3d size = aabb.max_ - aabb.min_;

  double diagonal = size.norm();

  logInform("    DF: sz=(%7.3f %7.3f %7.3f) cnt=(%d %d %d) diag=%f",
                              size.x(),
                              size.y(),
                              size.z(),
                              int(size.x()/resolution),
                              int(size.y()/resolution),
                              int(size.z()/resolution),
                              diagonal);


  distance_field::PropagationDistanceField df(
                              size.x(),
                              size.y(),
                              size.z(),
                              resolution,
                              aabb.min_.x(),
                              aabb.min_.y(),
                              aabb.min_.z(),
                              diagonal * 2.0,
                              true);
  df.addPointsToField(points);

  DistPosEntry default_entry;
  default_entry.distance_ = diagonal * 2.0;
  default_entry.cell_id_ = -1;

  resize(size.x(),
         size.y(),
         size.z(),
         resolution,
         aabb.min_.x(),
         aabb.min_.y(),
         aabb.min_.z(),
         default_entry);

  logInform("    copy %d points.",
    getNumCells(distance_field::DIM_X) *
    getNumCells(distance_field::DIM_Y) *
    getNumCells(distance_field::DIM_Z));

  int pdf_x,pdf_y,pdf_z;
  int sdf_x,sdf_y,sdf_z;
  Eigen::Vector3d pdf_p, sdf_p;
  df.worldToGrid(aabb.min_.x(), aabb.min_.y(), aabb.min_.z(), pdf_x,pdf_y,pdf_z);
  worldToGrid(aabb.min_.x(), aabb.min_.y(), aabb.min_.z(), sdf_x,sdf_y,sdf_z);
  df.gridToWorld(pdf_x,pdf_y,pdf_z, pdf_p.x(), pdf_p.y(), pdf_p.z());
  gridToWorld(sdf_x,sdf_y,sdf_z, sdf_p.x(), sdf_p.y(), sdf_p.z());

  logInform("    DF: min=(%10.6f %10.6f %10.6f)  quant->%3d %3d %3d  (pdf)",
                              aabb.min_.x(),
                              aabb.min_.y(),
                              aabb.min_.z(),
                              pdf_x,
                              pdf_y,
                              pdf_z);
  logInform("    DF: min=(%10.6f %10.6f %10.6f)  quant<-%3d %3d %3d  (pdf)",
                              pdf_p.x(),
                              pdf_p.y(),
                              pdf_p.z(),
                              pdf_x,
                              pdf_y,
                              pdf_z);
  logInform("    DF: min=(%10.6f %10.6f %10.6f)  quant<-%3d %3d %3d  (sdf)",
                              sdf_p.x(),
                              sdf_p.y(),
                              sdf_p.z(),
                              sdf_x,
                              sdf_y,
                              sdf_z);


  df.worldToGrid(0,0,0, pdf_x,pdf_y,pdf_z);
  worldToGrid(0,0,0, sdf_x,sdf_y,sdf_z);
  df.gridToWorld(pdf_x,pdf_y,pdf_z, pdf_p.x(), pdf_p.y(), pdf_p.z());
  gridToWorld(sdf_x,sdf_y,sdf_z, sdf_p.x(), sdf_p.y(), sdf_p.z());

  logInform("    DF: org=(%10.6f %10.6f %10.6f)  quant->%3d %3d %3d  (pdf)",
                              0.0,
                              0.0,
                              0.0,
                              pdf_x,
                              pdf_y,
                              pdf_z);
  logInform("    DF: org=(%10.6f %10.6f %10.6f)  quant<-%3d %3d %3d  (pdf)",
                              pdf_p.x(),
                              pdf_p.y(),
                              pdf_p.z(),
                              pdf_x,
                              pdf_y,
                              pdf_z);
  logInform("    DF: org=(%10.6f %10.6f %10.6f)  quant<-%3d %3d %3d  (sdf)",
                              sdf_p.x(),
                              sdf_p.y(),
                              sdf_p.z(),
                              sdf_x,
                              sdf_y,
                              sdf_z);


  df.worldToGrid(points[0].x(), points[0].y(), points[0].z(), pdf_x,pdf_y,pdf_z);
  worldToGrid(points[0].x(), points[0].y(), points[0].z(), sdf_x,sdf_y,sdf_z);
  df.gridToWorld(pdf_x,pdf_y,pdf_z, pdf_p.x(), pdf_p.y(), pdf_p.z());
  gridToWorld(sdf_x,sdf_y,sdf_z, sdf_p.x(), sdf_p.y(), sdf_p.z());

  logInform("    DF: p0 =(%10.6f %10.6f %10.6f)  quant->%3d %3d %3d  (pdf)",
                              points[0].x(),
                              points[0].y(),
                              points[0].z(),
                              pdf_x,
                              pdf_y,
                              pdf_z);
  logInform("    DF: p0 =(%10.6f %10.6f %10.6f)  quant<-%3d %3d %3d  (pdf)",
                              pdf_p.x(),
                              pdf_p.y(),
                              pdf_p.z(),
                              pdf_x,
                              pdf_y,
                              pdf_z);
  logInform("    DF: p0 =(%10.6f %10.6f %10.6f)  quant<-%3d %3d %3d  (sdf)",
                              sdf_p.x(),
                              sdf_p.y(),
                              sdf_p.z(),
                              sdf_x,
                              sdf_y,
                              sdf_z);


  for (int z = 0 ; z < df.getZNumCells() ; ++z)
  {
    for (int y = 0 ; y < df.getYNumCells() ; ++y)
    {
      for (int x = 0 ; x < df.getXNumCells() ; ++x)
      {
        DistPosEntry entry;
        double dist = df.getDistance(x, y, z);
        const distance_field::PropDistanceFieldVoxel& voxel = df.getCell(x,y,z);

        if (dist < 0)
        {

          // propogation distance field has a bias of -1*resolution on points inside the object
          if (dist <= -resolution)
          {
            dist += resolution;
          }
          else
          {
            logError("PropagationDistanceField returned distance=%f between 0 and -resolution=%f."
                     "  Did someone fix it?"
                     "  Need to remove workaround from static_distance_field.cpp",
                     dist,-resolution);
            dist = 0.0;
          }
          entry.distance_ = dist;
          entry.cell_id_ = getCellId(
                              voxel.closest_negative_point_.x(),
                              voxel.closest_negative_point_.y(),
                              voxel.closest_negative_point_.z());
        }
        else
        {
          entry.distance_ = dist;
          entry.cell_id_ = getCellId(
                              voxel.closest_point_.x(),
                              voxel.closest_point_.y(),
                              voxel.closest_point_.z());
        }
        setCell(x, y, z, entry);
      }
    }
  }

  if (save_points)
    std::swap(points, points_);
}
ompl::base::StateStoragePtr ompl_interface::ConstraintsLibrary::constructConstraintApproximation(const ModelBasedPlanningContextPtr &pcontext,
                                                                                                 const moveit_msgs::Constraints &constr_sampling,
                                                                                                 const moveit_msgs::Constraints &constr_hard,
                                                                                                 const ConstraintStateStorageOrderFn &order,
                                                                                                 unsigned int samples, unsigned int edges_per_sample,
                                                                                                 ConstraintApproximationConstructionResults &result)
{
  // state storage structure
  ConstraintApproximationStateStorage *cass = new ConstraintApproximationStateStorage(pcontext->getOMPLStateSpace());
  ob::StateStoragePtr sstor(cass);
  
  // construct a sampler for the sampling constraints
  kinematic_constraints::KinematicConstraintSet kset(pcontext->getRobotModel(), robot_state::TransformsConstPtr(new robot_state::Transforms(pcontext->getRobotModel()->getModelFrame())));
  kset.add(constr_hard);

  const robot_state::RobotState &default_state = pcontext->getCompleteInitialRobotState();
  
  int nthreads = 0;
  unsigned int attempts = 0;
  
  double bounds_val = std::numeric_limits<double>::max() / 2.0 - 1.0;
  pcontext->getOMPLStateSpace()->setPlanningVolume(-bounds_val, bounds_val, -bounds_val, bounds_val, -bounds_val, bounds_val);
  pcontext->getOMPLStateSpace()->setup();
  
  // construct the constrained states
#pragma omp parallel
  { 
#pragma omp master
    {
	nthreads = omp_get_num_threads();    
    }
    
    robot_state::RobotState kstate(default_state);
    const constraint_samplers::ConstraintSamplerManagerPtr &csmng = pcontext->getConstraintSamplerManager();
    ConstrainedSampler *csmp = NULL;
    if (csmng)
    {
      constraint_samplers::ConstraintSamplerPtr cs = csmng->selectSampler(pcontext->getPlanningScene(), pcontext->getJointModelGroup()->getName(), constr_sampling);
      if (cs)
        csmp = new ConstrainedSampler(pcontext.get(), cs);
    }
    
    ob::StateSamplerPtr ss(csmp ? ob::StateSamplerPtr(csmp) : pcontext->getOMPLStateSpace()->allocDefaultStateSampler());
    
    ompl::base::ScopedState<> temp(pcontext->getOMPLStateSpace());
    int done = -1;
    bool slow_warn = false;
    ompl::time::point start = ompl::time::now();
    while (sstor->size() < samples)
    {
      ++attempts;
#pragma omp master
      {      
	int done_now = 100 * sstor->size() / samples;
	if (done != done_now)
	{
	  done = done_now;
	  logInform("%d%% complete (kept %0.1lf%% sampled states)", done, 100.0 * (double)sstor->size() / (double)attempts);
	}

	if (!slow_warn && attempts > 10 && attempts > sstor->size() * 100)
	{
	  slow_warn = true;
	  logWarn("Computation of valid state database is very slow...");
	}
      }

      if (attempts > samples && sstor->size() == 0)
      {
	logError("Unable to generate any samples");
	break;
      }
      
      ss->sampleUniform(temp.get());
      pcontext->getOMPLStateSpace()->copyToRobotState(kstate, temp.get());
      if (kset.decide(kstate).satisfied)
      {
#pragma omp critical
	{
	  if (sstor->size() < samples)
	  {
	    temp->as<ModelBasedStateSpace::StateType>()->tag = sstor->size();
	    sstor->addState(temp.get());
	  }
	}
      }
    }
#pragma omp master
    {
      result.state_sampling_time = ompl::time::seconds(ompl::time::now() - start);
      logInform("Generated %u states in %lf seconds", (unsigned int)sstor->size(), result.state_sampling_time); 
      if (csmp)
      {
        result.sampling_success_rate = csmp->getConstrainedSamplingRate();
        logInform("Constrained sampling rate: %lf", result.sampling_success_rate);
      }
    }
  }
  if (order)
  {
    logInform("Sorting states...");
    sstor->sort(order);
  }
  
  if (edges_per_sample > 0)
  {
    logInform("Computing graph connections (max %u edges per sample) ...", edges_per_sample);
    
    ompl::tools::SelfConfig sc(pcontext->getOMPLSimpleSetup().getSpaceInformation());
    double range = 0.0;
    sc.configurePlannerRange(range);
    
    // construct connexions
    const ob::StateSpacePtr &space = pcontext->getOMPLSimpleSetup().getStateSpace();
    std::vector<robot_state::RobotState> kstates(nthreads, default_state);
    const std::vector<const ompl::base::State*> &states = sstor->getStates();
    std::vector<ompl::base::ScopedState<> > temps(nthreads, ompl::base::ScopedState<>(space));
    
    ompl::time::point start = ompl::time::now();
    int good = 0;
    int done = -1;
    
#pragma omp parallel for schedule(dynamic) 
    for (std::size_t j = 0 ; j < sstor->size() ; ++j)
    {
      int threadid = omp_get_thread_num();
      robot_state::RobotState &kstate = kstates[threadid];
      robot_state::JointStateGroup *jsg = kstate.getJointStateGroup(pcontext->getJointModelGroup()->getName());
      ompl::base::State *temp = temps[threadid].get();
      int done_now = 100 * j / sstor->size();
      if (done != done_now)
      {
	done = done_now;
        logInform("%d%% complete", done);
      }
      
      for (std::size_t i = j + 1 ; i < sstor->size() ; ++i)
      {
	double d = space->distance(states[j], states[i]);

        if (d > range * 3.0 || d < range / 100.0)
          continue;
        
        space->interpolate(states[j], states[i], 0.5, temp);
        pcontext->getOMPLStateSpace()->copyToRobotState(kstate, temp);
        if (kset.decide(kstate).satisfied)
        {
	  space->interpolate(states[j], states[i], 0.25, temp);
	  pcontext->getOMPLStateSpace()->copyToRobotState(kstate, temp);
	  if (kset.decide(kstate).satisfied)
	  {
            space->interpolate(states[j], states[i], 0.75, temp);
            pcontext->getOMPLStateSpace()->copyToRobotState(kstate, temp);
            if (kset.decide(kstate).satisfied)
            {
#pragma omp critical
              {
                cass->getMetadata(i).push_back(j);
                cass->getMetadata(j).push_back(i);
                good++;
              }
              if (cass->getMetadata(j).size() >= edges_per_sample)
                break;
            }
	  }
        }
      }
    }
    result.state_connection_time = ompl::time::seconds(ompl::time::now() - start);
    logInform("Computed possible connexions in %lf seconds. Added %d connexions", result.state_connection_time, good);
  }
  
  return sstor;
}
Ejemplo n.º 18
0
void collision_detection::CollisionRobotAllValid::checkSelfCollision(const CollisionRequest &req, CollisionResult &res, const robot_state::RobotState &state1, const robot_state::RobotState &state2, const AllowedCollisionMatrix &acm) const
{
  res.collision = false;
  if (req.verbose)
    logInform("Using AllValid collision detection. No collision checking is performed.");}
Ejemplo n.º 19
0
bool parseJoint(Joint &joint, TiXmlElement* config)
{
  joint.clear();

  // Get Joint Name
  const char *name = config->Attribute("name");
  if (!name)
  {
    logError("unnamed joint found");
    return false;
  }
  joint.name = name;

  // Get transform from Parent Link to Joint Frame
  TiXmlElement *origin_xml = config->FirstChildElement("origin");
  if (!origin_xml)
  {
    logDebug("urdfdom: Joint [%s] missing origin tag under parent describing transform from Parent Link to Joint Frame, (using Identity transform).", joint.name.c_str());
    joint.parent_to_joint_origin_transform.clear();
  }
  else
  {
    if (!parsePose(joint.parent_to_joint_origin_transform, origin_xml))
    {
      joint.parent_to_joint_origin_transform.clear();
      logError("Malformed parent origin element for joint [%s]", joint.name.c_str());
      return false;
    }
  }

  // Get Parent Link
  TiXmlElement *parent_xml = config->FirstChildElement("parent");
  if (parent_xml)
  {
    const char *pname = parent_xml->Attribute("link");
    if (!pname)
    {
      logInform("no parent link name specified for Joint link [%s]. this might be the root?", joint.name.c_str());
    }
    else
    {
      joint.parent_link_name = std::string(pname);
    }
  }

  // Get Child Link
  TiXmlElement *child_xml = config->FirstChildElement("child");
  if (child_xml)
  {
    const char *pname = child_xml->Attribute("link");
    if (!pname)
    {
      logInform("no child link name specified for Joint link [%s].", joint.name.c_str());
    }
    else
    {
      joint.child_link_name = std::string(pname);
    }
  }

  // Get Joint type
  const char* type_char = config->Attribute("type");
  if (!type_char)
  {
    logError("joint [%s] has no type, check to see if it's a reference.", joint.name.c_str());
    return false;
  }

  std::string type_str = type_char;
  if (type_str == "planar")
    joint.type = Joint::PLANAR;
  else if (type_str == "floating")
    joint.type = Joint::FLOATING;
  else if (type_str == "revolute")
    joint.type = Joint::REVOLUTE;
  else if (type_str == "continuous")
    joint.type = Joint::CONTINUOUS;
  else if (type_str == "prismatic")
    joint.type = Joint::PRISMATIC;
  else if (type_str == "fixed")
    joint.type = Joint::FIXED;
  else
  {
    logError("Joint [%s] has no known type [%s]", joint.name.c_str(), type_str.c_str());
    return false;
  }

  // Get Joint Axis
  if (joint.type != Joint::FLOATING && joint.type != Joint::FIXED)
  {
    // axis
    TiXmlElement *axis_xml = config->FirstChildElement("axis");
    if (!axis_xml){
      logDebug("urdfdom: no axis elemement for Joint link [%s], defaulting to (1,0,0) axis", joint.name.c_str());
      joint.axis = Vector3(1.0, 0.0, 0.0);
    }
    else{
      if (axis_xml->Attribute("xyz")){
        try {
          joint.axis.init(axis_xml->Attribute("xyz"));
        }
        catch (ParseError &e) {
          joint.axis.clear();
          logError("Malformed axis element for joint [%s]: %s", joint.name.c_str(), e.what());
          return false;
        }
      }
    }
  }

  // Get limit
  TiXmlElement *limit_xml = config->FirstChildElement("limit");
  if (limit_xml)
  {
    joint.limits.reset(new JointLimits());
    if (!parseJointLimits(*joint.limits, limit_xml))
    {
      logError("Could not parse limit element for joint [%s]", joint.name.c_str());
      joint.limits.reset();
      return false;
    }
  }
  else if (joint.type == Joint::REVOLUTE)
  {
    logError("Joint [%s] is of type REVOLUTE but it does not specify limits", joint.name.c_str());
    return false;
  }
  else if (joint.type == Joint::PRISMATIC)
  {
    logError("Joint [%s] is of type PRISMATIC without limits", joint.name.c_str());
    return false;
  }

  // Get safety
  TiXmlElement *safety_xml = config->FirstChildElement("safety_controller");
  if (safety_xml)
  {
    joint.safety.reset(new JointSafety());
    if (!parseJointSafety(*joint.safety, safety_xml))
    {
      logError("Could not parse safety element for joint [%s]", joint.name.c_str());
      joint.safety.reset();
      return false;
    }
  }

  // Get calibration
  TiXmlElement *calibration_xml = config->FirstChildElement("calibration");
  if (calibration_xml)
  {
    joint.calibration.reset(new JointCalibration());
    if (!parseJointCalibration(*joint.calibration, calibration_xml))
    {
      logError("Could not parse calibration element for joint  [%s]", joint.name.c_str());
      joint.calibration.reset();
      return false;
    }
  }

  // Get Joint Mimic
  TiXmlElement *mimic_xml = config->FirstChildElement("mimic");
  if (mimic_xml)
  {
    joint.mimic.reset(new JointMimic());
    if (!parseJointMimic(*joint.mimic, mimic_xml))
    {
      logError("Could not parse mimic element for joint  [%s]", joint.name.c_str());
      joint.mimic.reset();
      return false;
    }
  }

  // Get Dynamics
  TiXmlElement *prop_xml = config->FirstChildElement("dynamics");
  if (prop_xml)
  {
    joint.dynamics.reset(new JointDynamics());
    if (!parseJointDynamics(*joint.dynamics, prop_xml))
    {
      logError("Could not parse joint_dynamics element for joint [%s]", joint.name.c_str());
      joint.dynamics.reset();
      return false;
    }
  }

  return true;
}
kinematic_constraints::ConstraintEvaluationResult kinematic_constraints::VisibilityConstraint::decide(const robot_state::RobotState &state, bool verbose) const
{
  if (target_radius_ <= std::numeric_limits<double>::epsilon())
    return ConstraintEvaluationResult(true, 0.0);

  if (max_view_angle_ > 0.0 || max_range_angle_ > 0.0)
  {
    const Eigen::Affine3d &sp = mobile_sensor_frame_ ? tf_->getTransform(state, sensor_frame_id_) * sensor_pose_ : sensor_pose_;
    const Eigen::Affine3d &tp = mobile_target_frame_ ? tf_->getTransform(state, target_frame_id_) * target_pose_ : target_pose_;
    //necessary to do subtraction as SENSOR_Z is 0 and SENSOR_X is 2
    const Eigen::Vector3d &normal2 = sp.rotation().col(2-sensor_view_direction_);

    if (max_view_angle_ > 0.0)
    {
      const Eigen::Vector3d &normal1 = tp.rotation().col(2)*-1.0; // along Z axis and inverted
      double dp = normal2.dot(normal1);
      double ang = acos(dp);
      if (dp < 0.0)
      {
        if (verbose)
          logInform("Visibility constraint is violated because the sensor is looking at the wrong side");
        return ConstraintEvaluationResult(false, 0.0);
      }
      if (max_view_angle_ < ang)
      {
        if (verbose)
          logInform("Visibility constraint is violated because the view angle is %lf (above the maximum allowed of %lf)", ang, max_view_angle_);
        return ConstraintEvaluationResult(false, 0.0);
      }
    }
    if (max_range_angle_ > 0.0)
    {
      const Eigen::Vector3d &dir = (tp.translation() - sp.translation()).normalized();
      double dp = normal2.dot(dir);
      if (dp < 0.0)
      {
        if (verbose)
          logInform("Visibility constraint is violated because the sensor is looking at the wrong side");
        return ConstraintEvaluationResult(false, 0.0);
      }

      double ang = acos(dp);
      if (max_range_angle_ < ang)
      {
        if (verbose)
          logInform("Visibility constraint is violated because the range angle is %lf (above the maximum allowed of %lf)", ang, max_range_angle_);
        return ConstraintEvaluationResult(false, 0.0);
      }
    }
  }

  shapes::Mesh *m = getVisibilityCone(state);
  if (!m)
    return ConstraintEvaluationResult(false, 0.0);

  // add the visibility cone as an object
  collision_detection::CollisionWorldFCL collision_world;
  collision_world.getWorld()->addToObject("cone", shapes::ShapeConstPtr(m), Eigen::Affine3d::Identity());

  // check for collisions between the robot and the cone
  collision_detection::CollisionRequest req;
  collision_detection::CollisionResult res;
  collision_detection::AllowedCollisionMatrix acm;
  acm.setDefaultEntry("cone", boost::bind(&VisibilityConstraint::decideContact, this, _1));
  req.contacts = true;
  req.verbose = verbose;
  req.max_contacts = 1;
  collision_world.checkRobotCollision(req, res, *collision_robot_, state, acm);

  if (verbose)
  {
    std::stringstream ss;
    m->print(ss);
    logInform("Visibility constraint %ssatisfied. Visibility cone approximation:\n %s", res.collision ? "not " : "", ss.str().c_str());
  }

  return ConstraintEvaluationResult(!res.collision, res.collision ? res.contacts.begin()->second.front().depth : 0.0);
}
Ejemplo n.º 21
0
bool mesh_core::LineSegment2D::intersect(
      const LineSegment2D& other,
      Eigen::Vector2d& intersection,
      bool& parallel) const
{
  const LineSegment2D& a = *this;
  const LineSegment2D& b = other;

  if (acorn_debug_ear_state)
  {
    logInform("Intersect");
    logInform("     a=%s",a.str().c_str());
    logInform("     b=%s",b.str().c_str());
  }

  if (a.vertical_)
  {
    if (b.vertical_)
    {
      parallel = true;
      intersection = a.pt_[0];
      if (a.pt_[0].x() != b.pt_[0].x())
        return false;

      double aymin = std::min(a.pt_[0].y(), a.pt_[1].y());
      double aymax = std::max(a.pt_[0].y(), a.pt_[1].y());
      double bymin = std::min(b.pt_[0].y(), b.pt_[1].y());
      double bymax = std::max(b.pt_[0].y(), b.pt_[1].y());

      if (acorn_debug_ear_state)
      {
        logInform("     both vertical aymin=%f aymax=%f bymin=%f bymax\%f",
          aymin, aymax, bymin, bymax);
      }

      if (bymax < aymin)
        return false;
      if (bymin > aymax)
        return false;

      if (bymax <= aymax)
        intersection.y() = bymax;
      else if (bymin >= aymin)
        intersection.y() = bymin;
      else
        intersection.y() = aymin;

      if (acorn_debug_ear_state)
      {
        logInform("     INTERSECTS");
      }
      return true;
    }
    parallel = false;
    intersection.x() = a.pt_[0].x();
    intersection.y() = b.slope_ * intersection.x() + b.y_intercept_;

    double tb = (intersection.x() - b.pt_[0].x()) * b.inv_dx_;
    if (acorn_debug_ear_state)
    {
      logInform("     a vertical pt=(%8.4f, %8.4f) tb=%f",
        intersection.x(),
        intersection.y(),
        tb);
    }
    if (tb > 1.0 || tb < 0.0)
      return false;

    if (b.inv_dx_ == 0.0)
    {
      if (intersection.y() != a.pt_[0].y())
        return false;
    }
    else
    {
      double ta = (intersection.y() - a.pt_[0].y()) * a.inv_dx_;
      if (acorn_debug_ear_state)
      {
        logInform("       ta=%f", ta);
      }
      if (ta > 1.0 || ta < 0.0)
        return false;
    }

    if (acorn_debug_ear_state)
    {
      logInform("     INTERSECTS");
    }
    return true;
  }
  else if (b.vertical_)
  {
    return b.intersect(a, intersection, parallel);
  }
  else
  {
    double bottom = a.slope_ - b.slope_;
    if (std::abs(bottom) < std::numeric_limits<double>::epsilon())
    {
      parallel = true;
      intersection.setZero();
      return false;
    }

    parallel = false;
    intersection.x() = (b.y_intercept_ - a.y_intercept_) / bottom;
    intersection.y() = a.slope_ * intersection.x() + a.y_intercept_;

    double ta = (intersection.x() - a.pt_[0].x()) * a.inv_dx_;
    if (acorn_debug_ear_state)
    {
      logInform("     not vertical pt=(%8.4f, %8.4f) ta=%f",
        intersection.x(),
        intersection.y(),
        ta);
    }
    if (ta > 1.0 || ta < 0.0)
      return false;

    double tb = (intersection.x() - b.pt_[0].x()) * b.inv_dx_;
    if (acorn_debug_ear_state)
    {
      logInform("       tb=%f", tb);
    }
    if (tb > 1.0 || tb < 0.0)
      return false;

    if (acorn_debug_ear_state)
    {
      logInform("     INTERSECTS");
    }
    return true;
  }
}
// find the tightest bounding sphere.
// Recursive.
// The first nbound points in list_ are known to be on the boundary.  The rest need to be checked.
void SphereInfo::findSphere(
      int nbound,
      int npoints)
{
  // increase radius by this much to avoid flipping between points that are
  // equal distance from center.
  static const double radius_expand =
                            std::numeric_limits<float>::epsilon() * 1000.0;

  if (g_verbose)
  {
    logInform(" findSphere(%d,%3d) ENTER",
      nbound,npoints);
  }

  switch(nbound)
  {
  case 0:
    center_ = Eigen::Vector3d::Zero();
    radius_ = 0;
    break;
  case 1:
    center_ = *list_[0];
    radius_ = radius_expand;
    break;
  case 2:
    mesh_core::findSphereTouching2Points(
            center_,
            radius_,
            *list_[0],
            *list_[1]);
    radius_ += radius_expand;
    break;
  case 3:
    mesh_core::findSphereTouching3Points(
            center_,
            radius_,
            *list_[0],
            *list_[1],
            *list_[2]);
    radius_ += radius_expand;
    break;
  default:
    logError("Bad nbound=%d for findSphere",nbound);
  case 4:
    mesh_core::findSphereTouching4Points(
            center_,
            radius_,
            *list_[0],
            *list_[1],
            *list_[2],
            *list_[3]);
    radius_ += radius_expand;
    radius_sq_ = radius_ * radius_;
    if (g_verbose)
    {
      logInform(" findSphere(%d,%4d) begin check   s = (%7.3f %7.3f %7.3f) r=%10.6f   rsq=%10.6f    ",
        nbound,
        npoints,
        center_.x(),
        center_.y(),
        center_.z(),
        radius_,
        radius_sq_);
      for (int i=0; i<nbound; ++i)
      {
        double d = (*list_[i] - center_).norm();
        logInform("    BOUND: list_[%4d] = %4d         (%7.3f %7.3f %7.3f) d=%10.6f (%10.6f)    (BOUND)    ",
          i,
          int(list_[i] - &points_[0]),
          list_[i]->x(),
          list_[i]->y(),
          list_[i]->z(),
          d,
          radius_ - d);
      }
    }
    return;
  }
  radius_sq_ = radius_ * radius_;

  if (g_verbose)
  {
    logInform(" findSphere(%d,%4d) begin check   s = (%7.3f %7.3f %7.3f) r=%10.6f   rsq=%10.6f    ",
      nbound,
      npoints,
      center_.x(),
      center_.y(),
      center_.z(),
      radius_,
      radius_sq_);
    for (int i=0; i<nbound; ++i)
    {
      double d = (*list_[i] - center_).norm();
      logInform("    BOUND: list_[%4d] = %4d         (%7.3f %7.3f %7.3f) d=%10.6f (%10.6f)    (BOUND)    ",
        i,
        int(list_[i] - &points_[0]),
        list_[i]->x(),
        list_[i]->y(),
        list_[i]->z(),
        d,
        radius_ - d);
    }
  }

  for (int i = nbound ; i < npoints ; ++i)
  {

    if (g_verbose)
    {
      double d = (*list_[i] - center_).norm();
      logInform("    check  list_[%4d] = %4d         (%7.3f %7.3f %7.3f) d=%10.6f (%10.6f)    (%s)    ",
        i,
        int(list_[i] - &points_[0]),
        list_[i]->x(),
        list_[i]->y(),
        list_[i]->z(),
        d,
        radius_ - d,
        ((*list_[i] - center_).squaredNorm() > radius_sq_) ? "OUTSIDE" : "ok");
    }

    if ((*list_[i] - center_).squaredNorm() > radius_sq_)
    {
      // entry i is a troublemaker, so move it to head of list (i.e. to
      // list_[nbound])
      const Eigen::Vector3d *p = list_[i];

      if (g_verbose)
      {
        logInform("        Point %4d outside -- move to list_[%4d]    ",
          int(list_[i] - &points_[0]),
          nbound);
      }

      memmove(&list_[nbound+1],
              &list_[nbound],
              sizeof(const Eigen::Vector3d*) * (i - nbound));
      list_[nbound] = p;

      // find a sphere that has the new boundary point and contains all points that have already been checked so far.
      findSphere(nbound + 1, i + 1);

      if (g_verbose)
      {
        logInform(" findSphere(%d,%4d) cont          s = (%7.3f %7.3f %7.3f) r=%10.6f   rsq=%10.6f    ",
          nbound,
          npoints,
          center_.x(),
          center_.y(),
          center_.z(),
          radius_,
          radius_sq_);
      }
    }
  }

  if (g_verbose)
  {
    logInform(" findSphere(%d,%4d) RETURN        s = (%7.3f %7.3f %7.3f) r=%10.6f   rsq=%10.6f    ",
      nbound,
      npoints,
      center_.x(),
      center_.y(),
      center_.z(),
      radius_,
      radius_sq_);
  }
}
TEST_F(LoadPlanningModelsPr2, SubgroupPoseConstraintsSampler)
{
  moveit_msgs::Constraints c;

  moveit_msgs::PositionConstraint pcm;
  pcm.link_name = "l_wrist_roll_link";
  pcm.target_point_offset.x = 0;
  pcm.target_point_offset.y = 0;
  pcm.target_point_offset.z = 0;

  pcm.constraint_region.primitives.resize(1);
  pcm.constraint_region.primitives[0].type = shape_msgs::SolidPrimitive::SPHERE;
  pcm.constraint_region.primitives[0].dimensions.resize(1);
  pcm.constraint_region.primitives[0].dimensions[0] = 0.001;

  pcm.header.frame_id = kmodel->getModelFrame();

  pcm.constraint_region.primitive_poses.resize(1);
  pcm.constraint_region.primitive_poses[0].position.x = 0.55;
  pcm.constraint_region.primitive_poses[0].position.y = 0.2;
  pcm.constraint_region.primitive_poses[0].position.z = 1.25;
  pcm.constraint_region.primitive_poses[0].orientation.x = 0.0;
  pcm.constraint_region.primitive_poses[0].orientation.y = 0.0;
  pcm.constraint_region.primitive_poses[0].orientation.z = 0.0;
  pcm.constraint_region.primitive_poses[0].orientation.w = 1.0;
  pcm.weight = 1.0;
  c.position_constraints.push_back(pcm);

  moveit_msgs::OrientationConstraint ocm;
  ocm.link_name = "l_wrist_roll_link";
  ocm.header.frame_id = kmodel->getModelFrame();
  ocm.orientation.x = 0.0;
  ocm.orientation.y = 0.0;
  ocm.orientation.z = 0.0;
  ocm.orientation.w = 1.0;
  ocm.absolute_x_axis_tolerance = 0.2;
  ocm.absolute_y_axis_tolerance = 0.1;
  ocm.absolute_z_axis_tolerance = 0.4;
  ocm.weight = 1.0;
  c.orientation_constraints.push_back(ocm);

  ocm.link_name = "r_wrist_roll_link";
  ocm.header.frame_id = kmodel->getModelFrame();
  ocm.orientation.x = 0.0;
  ocm.orientation.y = 0.0;
  ocm.orientation.z = 0.0;
  ocm.orientation.w = 1.0;
  ocm.absolute_x_axis_tolerance = 0.01;
  ocm.absolute_y_axis_tolerance = 0.01;
  ocm.absolute_z_axis_tolerance = 0.01;
  ocm.weight = 1.0;
  c.orientation_constraints.push_back(ocm);

  robot_state::Transforms &tf = ps->getTransformsNonConst();
  constraint_samplers::ConstraintSamplerPtr s = constraint_samplers::ConstraintSamplerManager::selectDefaultSampler(ps, "arms", c);
  EXPECT_TRUE(s);
  constraint_samplers::UnionConstraintSampler* ucs = dynamic_cast<constraint_samplers::UnionConstraintSampler*>(s.get());
  EXPECT_TRUE(ucs);

  kinematic_constraints::KinematicConstraintSet kset(kmodel);
  kset.add(c, tf);

  robot_state::RobotState ks(kmodel);
  ks.setToDefaultValues();
  ks.update();
  robot_state::RobotState ks_const(kmodel);
  ks_const.setToDefaultValues();
  ks_const.update();

  static const int NT = 100;
  int succ = 0;
  for (int t = 0 ; t < NT ; ++t)
  {
    EXPECT_TRUE(s->sample(ks, ks_const, 1000));
    EXPECT_TRUE(kset.decide(ks).satisfied);
    if (s->sample(ks, ks_const, 1))
      succ++;
  }
  logInform("Success rate for IK Constraint Sampler with position & orientation constraints for both arms: %lf", (double)succ / (double)NT);
}
void mesh_core::findSphereTouching4Points(
      Eigen::Vector3d& center,
      double& radius,
      const Eigen::Vector3d& a,
      const Eigen::Vector3d& b,
      const Eigen::Vector3d& c,
      const Eigen::Vector3d& d)
{
  Eigen::Matrix3d m;
  m.col(0) = b - a;
  m.col(1) = c - a;
  m.col(2) = d - a;

  double det = m.determinant();

  // points are coplanar?
  if (std::abs(det) <= std::numeric_limits<double>::epsilon())
  {
    findSphereTouching4PointsCoplanar(center, radius, a,b,c,d);
    if (g_verbose)
    {
      logInform("findSphereTouching4Points() COPLANAR  QQQQ");
      logInform("           a = (%7.3f %7.3f %7.3f)",
        a.x(),
        a.y(),
        a.z());
      logInform("           b = (%7.3f %7.3f %7.3f)",
        b.x(),
        b.y(),
        b.z());
      logInform("           c = (%7.3f %7.3f %7.3f)",
        c.x(),
        c.y(),
        c.z());
      logInform("           d = (%7.3f %7.3f %7.3f)",
        d.x(),
        d.y(),
        d.z());
      logInform("           s = (%7.3f %7.3f %7.3f) r=%7.3f",
        center.x(),
        center.y(),
        center.z(),
        radius);
    }
    return;
  }

  double ab_lensq = m.col(0).squaredNorm();
  double ac_lensq = m.col(1).squaredNorm();
  double ad_lensq = m.col(2).squaredNorm();
  Eigen::Vector3d rel_center = ((ad_lensq * m.col(0).cross(m.col(1))) +
                                (ac_lensq * m.col(2).cross(m.col(0))) +
                                (ab_lensq * m.col(1).cross(m.col(2)))) /
                               (2.0 * det);

  radius = rel_center.norm();
  center = rel_center + a;

  if (g_verbose)
  {
    logInform("findSphereTouching4Points()");
    logInform("           a = (%7.3f %7.3f %7.3f)",
      a.x(),
      a.y(),
      a.z());
    logInform("           b = (%7.3f %7.3f %7.3f)",
      b.x(),
      b.y(),
      b.z());
    logInform("           c = (%7.3f %7.3f %7.3f)",
      c.x(),
      c.y(),
      c.z());
    logInform("           d = (%7.3f %7.3f %7.3f)",
      d.x(),
      d.y(),
      d.z());
    logInform("           s = (%7.3f %7.3f %7.3f) r=%7.3f",
      center.x(),
      center.y(),
      center.z(),
      radius);
  }
}
Ejemplo n.º 25
0
// return closest point on triangle to the given point, and the distance
// betweeen them.
// If distance is greater than max_dist then skip the calculations and just return the approximate distance (anything greater than max_dist).
double mesh_core::closestPointOnTriangle(
      const Eigen::Vector3d& tri_a,
      const Eigen::Vector3d& tri_b,
      const Eigen::Vector3d& tri_c,
      const Eigen::Vector3d& point,
      Eigen::Vector3d& closest_point,
      double max_dist)
{
  Eigen::Vector3d ab = tri_b - tri_a;
  Eigen::Vector3d ac = tri_c - tri_a;
  Eigen::Vector3d n = ab.cross(ac);
  Eigen::Vector3d norm = n.normalized();

  Eigen::Vector3d ap = point - tri_a;
  double dist = norm.dot(ap);
  double abs_dist = std::abs(dist);

  if (abs_dist >= max_dist)
    return abs_dist;

  closest_point = point - dist * norm;

  if (acorn_closest_debug)
  {
    logInform(" CDB: tri_a     (%8.4f %8.4f %8.4f)",
      tri_a.x(),
      tri_a.y(),
      tri_a.z());
    logInform(" CDB: tri_b     (%8.4f %8.4f %8.4f)",
      tri_b.x(),
      tri_b.y(),
      tri_b.z());
    logInform(" CDB: tri_c     (%8.4f %8.4f %8.4f)",
      tri_c.x(),
      tri_c.y(),
      tri_c.z());
    logInform(" CDB: point     (%8.4f %8.4f %8.4f)",
      point.x(),
      point.y(),
      point.z());
    logInform(" CDB: intersect (%8.4f %8.4f %8.4f)",
      closest_point.x(),
      closest_point.y(),
      closest_point.z());
  }

  Eigen::Vector3d ab_norm = ab.cross(norm);
  if (acorn_closest_debug)
  {
    logInform(" CDB: ab_norm   (%8.4f %8.4f %8.4f) dp=%8.4f >? da=%8.4f",
      ab_norm.x(),
      ab_norm.y(),
      ab_norm.z(),
        ab_norm.dot(point),
        ab_norm.dot(tri_a));
  }
  if (ab_norm.dot(point) > ab_norm.dot(tri_a))
  {
    if (acorn_closest_debug)
    {
      logInform(" CDB: beyond ab");
    }
    return closestPointOnLine(tri_a, tri_b, point, closest_point);
  }

  Eigen::Vector3d ac_norm = ac.cross(norm);
  if (acorn_closest_debug)
  {
    logInform(" CDB: ac_norm   (%8.4f %8.4f %8.4f) dp=%8.4f <? da=%8.4f",
      ac_norm.x(),
      ac_norm.y(),
      ac_norm.z(),
        ac_norm.dot(point),
        ac_norm.dot(tri_a));
  }
  if (ac_norm.dot(point) < ac_norm.dot(tri_a))
  {
    if (acorn_closest_debug)
    {
      logInform(" CDB: beyond ac");
    }
    return closestPointOnLine(tri_a, tri_c, point, closest_point);
  }

  Eigen::Vector3d bc = tri_c - tri_b;
  Eigen::Vector3d bc_norm = bc.cross(norm);
  if (acorn_closest_debug)
  {
    logInform(" CDB: ab_norm   (%8.4f %8.4f %8.4f) dp=%8.4f >? db=%8.4f",
      bc_norm.x(),
      bc_norm.y(),
      bc_norm.z(),
        bc_norm.dot(point),
        bc_norm.dot(tri_b));
  }
  if (bc_norm.dot(point) > bc_norm.dot(tri_b))
  {
    if (acorn_closest_debug)
    {
      logInform(" CDB: beyond bc");
    }
    return closestPointOnLine(tri_b, tri_c, point, closest_point);
  }

  return abs_dist;
}
static void findSphereTouching4PointsCoplanar(
      Eigen::Vector3d& center,
      double& radius,
      const Eigen::Vector3d& a,
      const Eigen::Vector3d& b,
      const Eigen::Vector3d& c,
      const Eigen::Vector3d& d)
{
  mesh_core::findSphereTouching3Points(center,
                                                         radius,
                                                         a,
                                                         b,
                                                         c);
  if (g_verbose)
  {
    double dist = (center - d).norm();
    logInform("    findSphereTouching4PointsCoplanar abc center=(%7.3f %7.3f %7.3f) r=%10.6f d.dist=%10.6f (%10.6f)   (%s)",
      center.x(),
      center.y(),
      center.z(),
      radius,
      dist,
      radius - dist,
      radius - dist < 0 ? "OUTSIDE" : "ok");
  }
  if ((center - d).squaredNorm() <= radius*radius)
    return;
  mesh_core::findSphereTouching3Points(center,
                                                         radius,
                                                         a,
                                                         b,
                                                         d);
  if (g_verbose)
  {
    double dist = (center - c).norm();
    logInform("    findSphereTouching4PointsCoplanar abd center=(%7.3f %7.3f %7.3f) r=%10.6f c.dist=%10.6f (%10.6f)   (%s)",
      center.x(),
      center.y(),
      center.z(),
      radius,
      dist,
      radius - dist,
      radius - dist < 0 ? "OUTSIDE" : "ok");
  }
  if ((center - c).squaredNorm() <= radius*radius)
    return;
  mesh_core::findSphereTouching3Points(center,
                                                         radius,
                                                         a,
                                                         c,
                                                         d);
  if (g_verbose)
  {
    double dist = (center - b).norm();
    logInform("    findSphereTouching4PointsCoplanar acd center=(%7.3f %7.3f %7.3f) r=%10.6f b.dist=%10.6f (%10.6f)   (%s)",
      center.x(),
      center.y(),
      center.z(),
      radius,
      dist,
      radius - dist,
      radius - dist < 0 ? "OUTSIDE" : "ok");
  }
  if ((center - b).squaredNorm() <= radius*radius)
    return;
  mesh_core::findSphereTouching3Points(center,
                                                         radius,
                                                         b,
                                                         c,
                                                         d);
  if (g_verbose)
  {
    double dist = (center - a).norm();
    logInform("    findSphereTouching4PointsCoplanar bcd center=(%7.3f %7.3f %7.3f) r=%10.6f a.dist=%10.6f (%10.6f)   (%s)",
      center.x(),
      center.y(),
      center.z(),
      radius,
      dist,
      radius - dist,
      radius - dist < 0 ? "OUTSIDE" : "ok");
  }
}
Ejemplo n.º 27
0
ompl::base::PlannerStatus ompl::geometric::RRTConnect::solve(const base::PlannerTerminationCondition &ptc)
{
    checkValidity();
    base::GoalSampleableRegion *goal = dynamic_cast<base::GoalSampleableRegion*>(pdef_->getGoal().get());

    if (!goal)
    {
        logError("Unknown type of goal (or goal undefined)");
        return base::PlannerStatus::UNRECOGNIZED_GOAL_TYPE;
    }

    while (const base::State *st = pis_.nextStart())
    {
        Motion *motion = new Motion(si_);
        si_->copyState(motion->state, st);
        motion->root = motion->state;
        tStart_->add(motion);
    }

    if (tStart_->size() == 0)
    {
        logError("Motion planning start tree could not be initialized!");
        return base::PlannerStatus::INVALID_START;
    }

    if (!goal->couldSample())
    {
        logError("Insufficient states in sampleable goal region");
        return base::PlannerStatus::INVALID_GOAL;
    }

    if (!sampler_)
        sampler_ = si_->allocStateSampler();

    logInform("Starting with %d states", (int)(tStart_->size() + tGoal_->size()));

    TreeGrowingInfo tgi;
    tgi.xstate = si_->allocState();

    Motion   *rmotion   = new Motion(si_);
    base::State *rstate = rmotion->state;
    bool startTree      = true;
    bool solved         = false;

    while (ptc() == false)
    {
        TreeData &tree      = startTree ? tStart_ : tGoal_;
        tgi.start = startTree;
        startTree = !startTree;
        TreeData &otherTree = startTree ? tStart_ : tGoal_;

        if (tGoal_->size() == 0 || pis_.getSampledGoalsCount() < tGoal_->size() / 2)
        {
            const base::State *st = tGoal_->size() == 0 ? pis_.nextGoal(ptc) : pis_.nextGoal();
            if (st)
            {
                Motion* motion = new Motion(si_);
                si_->copyState(motion->state, st);
                motion->root = motion->state;
                tGoal_->add(motion);
            }

            if (tGoal_->size() == 0)
            {
                logError("Unable to sample any valid states for goal tree");
                break;
            }
        }

        /* sample random state */
        sampler_->sampleUniform(rstate);

        GrowState gs = growTree(tree, tgi, rmotion);

        if (gs != TRAPPED)
        {
            /* remember which motion was just added */
            Motion *addedMotion = tgi.xmotion;

            /* attempt to connect trees */

            /* if reached, it means we used rstate directly, no need top copy again */
            if (gs != REACHED)
                si_->copyState(rstate, tgi.xstate);

            GrowState gsc = ADVANCED;
            tgi.start = startTree;
            while (gsc == ADVANCED)
                gsc = growTree(otherTree, tgi, rmotion);

            Motion *startMotion = startTree ? tgi.xmotion : addedMotion;
            Motion *goalMotion  = startTree ? addedMotion : tgi.xmotion;

            /* if we connected the trees in a valid way (start and goal pair is valid)*/
            if (gsc == REACHED && goal->isStartGoalPairValid(startMotion->root, goalMotion->root))
            {
                // it must be the case that either the start tree or the goal tree has made some progress
                // so one of the parents is not NULL. We go one step 'back' to avoid having a duplicate state
                // on the solution path
                if (startMotion->parent)
                    startMotion = startMotion->parent;
                else
                    goalMotion = goalMotion->parent;

                connectionPoint_ = std::make_pair<base::State*, base::State*>(startMotion->state, goalMotion->state);

                /* construct the solution path */
                Motion *solution = startMotion;
                std::vector<Motion*> mpath1;
                while (solution != NULL)
                {
                    mpath1.push_back(solution);
                    solution = solution->parent;
                }

                solution = goalMotion;
                std::vector<Motion*> mpath2;
                while (solution != NULL)
                {
                    mpath2.push_back(solution);
                    solution = solution->parent;
                }

                PathGeometric *path = new PathGeometric(si_);
                path->getStates().reserve(mpath1.size() + mpath2.size());
                for (int i = mpath1.size() - 1 ; i >= 0 ; --i)
                    path->append(mpath1[i]->state);
                for (unsigned int i = 0 ; i < mpath2.size() ; ++i)
                    path->append(mpath2[i]->state);

                pdef_->addSolutionPath(base::PathPtr(path), false, 0.0);
                solved = true;
                break;
            }
        }
    }

    si_->freeState(tgi.xstate);
    si_->freeState(rstate);
    delete rmotion;

    logInform("Created %u states (%u start + %u goal)", tStart_->size() + tGoal_->size(), tStart_->size(), tGoal_->size());

    return solved ? base::PlannerStatus::EXACT_SOLUTION : base::PlannerStatus::TIMEOUT;
}
void mesh_core::findSphereTouching3Points(
      Eigen::Vector3d& center,
      double& radius,
      const Eigen::Vector3d& a,
      const Eigen::Vector3d& b,
      const Eigen::Vector3d& c)
{
  Eigen::Vector3d ab = b - a;
  Eigen::Vector3d ac = c - a;
  Eigen::Vector3d n = ab.cross(ac);

  double ab_lensq = ab.squaredNorm();
  double ac_lensq = ac.squaredNorm();
  double n_lensq = n.squaredNorm();

  // points are colinear?
  if (n_lensq <= std::numeric_limits<double>::epsilon())
  {
    findSphereTouching3PointsColinear(
          center,
          radius,
          a,
          b,
          c,
          ab_lensq,
          (c - b).squaredNorm(),
          ac_lensq);
    if (g_verbose)
    {
      logInform("findSphereTouching3Points() COLINEAR QQQQ");
      logInform("           a = (%7.3f %7.3f %7.3f)",
        a.x(),
        a.y(),
        a.z());
      logInform("           b = (%7.3f %7.3f %7.3f)",
        b.x(),
        b.y(),
        b.z());
      logInform("           c = (%7.3f %7.3f %7.3f)",
        c.x(),
        c.y(),
        c.z());
      logInform("           s = (%7.3f %7.3f %7.3f) r=%7.3f",
        center.x(),
        center.y(),
        center.z(),
        radius);
    }
    return;
  }

  Eigen::Vector3d rel_center = (ac_lensq * n.cross(ab) +
                                ab_lensq * ac.cross(n)) /
                               (2.0 * n_lensq);
  radius = rel_center.norm();
  center = rel_center + a;

  if (g_verbose)
  {
    logInform("findSphereTouching3Points()");
    logInform("           a = (%7.3f %7.3f %7.3f)",
      a.x(),
      a.y(),
      a.z());
    logInform("           b = (%7.3f %7.3f %7.3f)",
      b.x(),
      b.y(),
      b.z());
    logInform("           c = (%7.3f %7.3f %7.3f)",
      c.x(),
      c.y(),
      c.z());
    logInform("           s = (%7.3f %7.3f %7.3f) r=%7.3f",
      center.x(),
      center.y(),
      center.z(),
      radius);
  }
}