示例#1
0
文件: common.hpp 项目: jgarstka/pcl
inline double
pcl::getAngle3D (const Eigen::Vector3f &v1, const Eigen::Vector3f &v2, const bool in_degree)
{
    // Compute the actual angle
    double rad = v1.normalized ().dot (v2.normalized ());
    if (rad < -1.0)
        rad = -1.0;
    else if (rad >  1.0)
        rad = 1.0;
    return (in_degree ? acos (rad) * 180.0 / M_PI : acos (rad));
}
void
pd_solver_advance(struct PdSolver *solver, uint32_t const n_iterations)
{
        /* set external force */
        Eigen::VectorXf ext_accel = Eigen::VectorXf::Zero(solver->positions.size());
#pragma omp parallel for
        for (uint32_t i = 0; i < solver->positions.size()/3; ++i)
                for (int j = 0; j < 3; ++j)
                        ext_accel[3*i + j] = solver->ext_force[j];
        Eigen::VectorXf const ext_force = solver->mass_mat*ext_accel;
        Eigen::VectorXf const mass_y = solver->mass_mat*(2.0f*solver->positions - solver->positions_last);

        solver->positions_last = solver->positions;

        for (uint32_t iter = 0; iter < n_iterations; ++iter) {
                /* LOCAL STEP */
                /* LOCAL STEP (we account everything except the global solve */
                struct timespec local_start;
                clock_gettime(CLOCK_MONOTONIC, &local_start);
                uint32_t const n_constraints = solver->n_attachments + solver->n_springs;
                Eigen::VectorXf d(3*n_constraints);
                for (uint32_t i = 0; i < solver->n_attachments; ++i) {
                        struct PdConstraintAttachment c = solver->attachments[i];
                        d.block<3, 1>(3*i, 0) = Eigen::Map<Eigen::Vector3f>(c.position);
                }

                uint32_t const offset = solver->n_attachments;
                for (uint32_t i = 0; i < solver->n_springs; ++i) {
                        struct PdConstraintSpring c = solver->springs[i];
                        Eigen::Vector3f const v = solver->positions.block<3, 1>(3*c.i[1], 0)
                                - solver->positions.block<3, 1>(3*c.i[0], 0);
                        d.block<3, 1>(3*(offset + i), 0) = v.normalized()*c.rest_length;
                }

                Eigen::VectorXf const b = mass_y + solver->t2*(solver->j_mat*d + ext_force);
                struct timespec local_end;
                clock_gettime(CLOCK_MONOTONIC, &local_end);

                /* GLOBAL STEP */
                struct timespec global_start;
                clock_gettime(CLOCK_MONOTONIC, &global_start);
                solve(solver, b);
                struct timespec global_end;
                clock_gettime(CLOCK_MONOTONIC, &global_end);

                solver->global_time = pd_time_diff_ms(&global_start, &global_end);
                solver->local_time = pd_time_diff_ms(&local_start, &local_end);

                solver->global_cma = (solver->global_time + solver->n_iters*solver->global_cma)/(solver->n_iters + 1);
                solver->local_cma = (solver->local_time + solver->n_iters*solver->local_cma)/(solver->n_iters + 1);

                if (!(solver->n_iters % 1000)) {
                        printf("Local CMA: %f ms\n", solver->local_cma);
                        printf("Global CMA: %f ms\n\n", solver->global_cma);
                }

                ++solver->n_iters;
        }
}
示例#3
0
void stateCallback(const nav_msgs::Odometry::ConstPtr& state)
{
  
	
		vel[0] = state->twist.twist.linear.x;
		vel[1] = state->twist.twist.linear.y;
		vel[2] = state->twist.twist.linear.z;
		pos[2] = state->pose.pose.position.z;
    
		//q.x() = state->pose.pose.orientation.x;
		//q.y() = state->pose.pose.orientation.y;
		//q.z() = state->pose.pose.orientation.z;
		//q.w() = state->pose.pose.orientation.w; 
    float q_x = state->pose.pose.orientation.x;
		float q_y = state->pose.pose.orientation.y;
		float q_z = state->pose.pose.orientation.z;
		float q_w = state->pose.pose.orientation.w;

float  yaw = atan2(2*(q_w*q_z+q_x*q_y),1-2*(q_y*q_y+q_z*q_z));
//Eigen::Matrix3d R(q);
	force(0) = offset_x+k_vxy*(vel_des(0)-vel(0))+m*acc_des(0);
	if(pd_control==0)
  force(1) = offset_y+k_vxy*(vel_des(1)-vel(1))+m*acc_des(1);
  else if(pd_control==1)
  {
    pos[1]=state->pose.pose.position.y;
    force(1) = offset_y+k_vxy*(vel_des(1)-vel(1))+k_xy*(0-pos[1])+m*acc_des(1);
  }
	force(2) = (k_z*(pos_des(2)-pos(2))+k_vz*(vel_des(2)-vel(2))+m*g(2)+m*acc_des(2));


  b3 = force.normalized();
  b2 = b3.cross(b1w);
  b1 = b2.cross(b3);
  R_des<<b1[0],b2[0],b3[0],
    b1[1],b2[1],b3[1],
    b1[2],b2[2],b3[2];
  Eigen::Quaternionf q_des(R_des);
  	
  quadrotor_msgs::SO3Command command;
	command.force.x = force[0];
  command.force.y = force[1];
  command.force.z = force[2];
  command.orientation.x = q_des.x();
  command.orientation.y = q_des.y();
  command.orientation.z = q_des.z();
  command.orientation.w = q_des.w();
  command.kR[0] = k_R;
  command.kR[1] = k_R;
  command.kR[2] = k_R;
  command.kOm[0] = k_omg;
  command.kOm[1] = k_omg;
  command.kOm[2] = k_omg;
	command.aux.current_yaw = yaw;
	command.aux.enable_motors = true;
	command.aux.use_external_yaw = true;
  control_pub.publish(command);
}
示例#4
0
 Point ModelView::make_exocentric_focus__(
     Eigen::Vector3f const & view_direction,
     Point const & view_origin)
 {
     Eigen::Vector3f unit_viewdir = view_direction.normalized();
     return Point(view_origin.x() + unit_viewdir.x(),
                  view_origin.y() + unit_viewdir.y(),
                  view_origin.z() + unit_viewdir.z());
 }
示例#5
0
	Eigen::Matrix4f MatrixFactory::createLookAt
	(
		const Eigen::Vector3f& position,
		const Eigen::Vector3f& direction,
		const Eigen::Vector3f& world_up,
		Handedness handedness
	) const
	{
		if (handedness == Handedness::RightHanded)
		{
			Eigen::Vector3f right, up, dir;
			dir = -direction.normalized();
			right = world_up.normalized().cross(dir).normalized();
			up = dir.cross(right);

			Eigen::Matrix4f matrix;
			matrix << right.x(), right.y(), right.z(), -right.dot(position),
				      up.x(),    up.y(),    up.z(),    -up.dot(position),
				      dir.x(),   dir.y(),   dir.z(),   -dir.dot(position),
				      0.0f, 0.0f, 0.0f, 1.0f;

			return matrix;
		}
		else if (handedness == Handedness::LeftHanded)
		{
			Eigen::Vector3f right, up, dir;
			dir = direction.normalized();
			right = world_up.normalized().cross(dir).normalized();
			up = dir.cross(right);

			Eigen::Matrix4f matrix;
			matrix << right.x(), right.y(), right.z(), -right.dot(position),
				      up.x(),    up.y(),    up.z(),    -up.dot(position),
				      dir.x(),   dir.y(),   dir.z(),   -dir.dot(position),
				      0.0f, 0.0f, 0.0f, 1.0f;

			return matrix;
		}
		else
		{
			DebugError("Not implemented.");
			return Eigen::Matrix4f::Zero();
		}
	}
void computeTransformationFromYZVectorsAndOrigin(const Eigen::Vector3f& y_direction, const Eigen::Vector3f& z_axis,
  const Eigen::Vector3f& origin, Eigen::Affine3f& transformation){

 Eigen::Vector3f x = (y_direction.cross(z_axis)).normalized();
 Eigen::Vector3f y = y_direction.normalized();
 Eigen::Vector3f z = z_axis.normalized();

 Eigen::Affine3f sub = Eigen::Affine3f::Identity();
 sub(0,3) = -origin[0];
 sub(1,3) = -origin[1];
 sub(2,3) = -origin[2];


 transformation = Eigen::Affine3f::Identity();
 transformation(0,0)=x[0]; transformation(0,1)=x[1]; transformation(0,2)=x[2]; // x^t
 transformation(1,0)=y[0]; transformation(1,1)=y[1]; transformation(1,2)=y[2]; // y^t
 transformation(2,0)=z[0]; transformation(2,1)=z[1]; transformation(2,2)=z[2]; // z^t

 transformation = transformation*sub;
}
  void
  Cylinder::updateAttributes(const Eigen::Vector3f& sym_axis, const Eigen::Vector3f& origin, const Eigen::Vector3f& z_axis)
  {
    //origin_= new_origin;
    sym_axis_ = sym_axis;
    if (sym_axis_[2] < 0 )
    {
      sym_axis_ = sym_axis_ * -1;
    }
    computePose(origin, z_axis.normalized());
    //d_ = fabs(pose_.translation().dot(normal_));
    //normal_ = new_normal;

    /*Eigen::Affine3f transform_from_plane_to_world;
  getTransformationFromPlaneToWorld(sym_axis,normal,origin_,transform_from_plane_to_world);
  transform_from_world_to_plane=transform_from_plane_to_world.inverse();*/
  }
示例#8
0
bool Camera::collides(const Entity &e) {
//    return false;
    float cam_rad = collisionRadius();

    if (e.useBoundingBox()) {
        //      return true;
        BoundingBox bb = e.getBoundingBox();
        bb.box.min += e.getPosition();
        bb.box.max += e.getPosition();
        Eigen::Vector3f our_pos = -translations;
        if (bb.contains(our_pos)) {
            return true;
        }

        Eigen::Vector3f displacement = (bb.box.center() - our_pos);
        float distance = displacement.norm();
        Eigen::Vector3f direction = displacement.normalized();

        if (bb.contains(direction * cam_rad + our_pos)) {
            return true;
        }

        return false;
        
    }
    else {
        Eigen::Vector3f their_pos = e.getCenterWorld();
        Eigen::Vector3f our_pos = translations;
        their_pos(1) = 0;
        our_pos(1) = 0;
        Eigen::Vector3f delta = -their_pos - our_pos;
        return std::abs(delta.norm()) < cam_rad + e.getRadius();
    }
    
    
    /*
    std::cout << "object pos" << std::endl;
    std::cout << their_pos << std::endl;
    std::cout << "cam pos" << std::endl;
    std::cout << our_pos << std::endl;
    std::cout << " dist = " << std::abs(delta.norm()) << std::endl;
    */

    
}
  void
  Cylinder::getMergeCandidates(const std::vector<Polygon::Ptr>& cylinder_array,
                               std::vector<int>& intersections)
  {

    for (size_t i = 0; i < cylinder_array.size(); i++)
    {
      Cylinder::Ptr c(boost::dynamic_pointer_cast<Cylinder>(cylinder_array[i]));
      BOOST_ASSERT(c);
      Cylinder& c_map = *c;
      Eigen::Vector3f connection = c_map.pose_.translation() - pose_.translation();
      //connection.normalize();
      //Eigen::Vector3f d= c_map.origin_  - this->origin_   ;

      // Test for geometrical attributes of cylinders
      if(fabs(c_map.sym_axis_.dot(sym_axis_)) > merge_settings_.angle_thresh && (fabs(c_map.r_ - r_) < (0.1 ))) //TODO: add param
      {
        // Test for spatial attributes of cylinders
        if( connection.norm() < (c_map.r_ + 0.1) || fabs(c_map.sym_axis_.dot(connection.normalized())) > merge_settings_.angle_thresh )
        {
          /*Cylinder::Ptr c1(new Cylinder);
        Cylinder::Ptr c2(new Cylinder);
           *c1 = *this;
           *c2 = c_map;
        c2->pose_ = c1->pose_;
        //c2->transform_from_world_to_plane = c1->transform_from_world_to_plane;
        c1->makeCyl2D();
        c2->makeCyl2D();*/
          if(isIntersectedWith(cylinder_array[i]))
            //if (c1->isIntersectedWith(c2))
          {
            intersections.push_back(i);
          }
        }
      }
    }
  }
示例#10
0
 Plane::Plane(Eigen::Vector3f normal, double d) :
   normal_(normal.normalized()), d_(d / normal.norm())
 {
   initializeCoordinates();
 }
示例#11
0
template<typename PointT> void
pcl::BoxClipper3D<PointT>::setTransformation (const Eigen::Vector3f& rodrigues, const Eigen::Vector3f& translation, const Eigen::Vector3f& box_size)
{
  transformation_ = Eigen::Translation3f (translation) * Eigen::AngleAxisf(rodrigues.norm (), rodrigues.normalized ()) * Eigen::Scaling (box_size);
  //inverse_transformation_ = transformation_.inverse ();
}
示例#12
0
文件: combo.cpp 项目: sikang/nanoplus
void stateCallback(const nav_msgs::Odometry::ConstPtr& state)
{

	if(mode==1){
		vel_des[0]=rc_vx;
		vel_des[1]=rc_vy;
		vel_des[2]=0;
		pos_des[1]=0;
		pos_des[2]=rc_z;
	}
	else if(mode==2)
	{
		double cur_t = ros::Time::now().toSec();
		double t = cur_t-init_t;
    
		vel_des[2]=0;
    
		if(t<t1){
			vel_des[0]=ax*t;
			vel_des[1]=ay*t;
      acc_des[0]=ax;
      acc_des[1]=ay;
      acc_des[2]=0;
		}
		else if(t<des_t-t1&&t>=t1){
			vel_des[0]=des_vx;
			vel_des[1]=des_vy;
			acc_des = Eigen::Vector3f::Zero();
	}
		else if(t>=des_t-t1&&t<des_t){
			vel_des[0] = des_vx-ax*(t+t1-des_t);
			vel_des[1] = des_vy-ay*(t+t1-des_t);
      acc_des[0] = -ax;
      acc_des[1] = -ay;
      acc_des[2] = 0;
		}
		else if(t>=des_t){
			vel_des = Eigen::Vector3f::Zero();
			acc_des = Eigen::Vector3f::Zero();
		}
		vel_des[0] = vel_des[0]+rc_vx/2;
		vel_des[1] = vel_des[1]+rc_vy/2;
	}

else if(mode==3)
	{
		double cur_t = ros::Time::now().toSec();
		double t = cur_t-init_t;
    
		vel_des[2]=0;
    
		if(t<t1){
			vel_des[0]=ax*t;
			vel_des[1]=ay*t;
      acc_des[0]=ax;
      acc_des[1]=ay;
      acc_des[2]=0;
		}
		else if(t<des_t-t3&&t>=t1){
			vel_des[0]=des_vx;
			vel_des[1]=des_vy;
			acc_des = Eigen::Vector3f::Zero();
		}
		else if(t>=des_t-t3&&t<des_t){
			vel_des[0] = 0;
			vel_des[1] = 0;
      acc_des[0] = -ax3;
      acc_des[1] = -ay3;
      acc_des[2] = 0;
      stop = 1;
		}
		else if(t>=des_t){
      stop = 0;
			vel_des = Eigen::Vector3f::Zero();
			acc_des = Eigen::Vector3f::Zero();
		}
		vel_des[0] = vel_des[0]+rc_vx/2;
		vel_des[1] = vel_des[1]+rc_vy/2;
	}

	vel(0) = state->twist.twist.linear.x;
	vel(1) = state->twist.twist.linear.y;
	vel(2) = state->twist.twist.linear.z;
	pos(2) = state->pose.pose.position.z;

	//q.x() = state->pose.pose.orientation.x;
	//q.y() = state->pose.pose.orientation.y;
	//q.z() = state->pose.pose.orientation.z;
	//q.w() = state->pose.pose.orientation.w; 
	float q_x = state->pose.pose.orientation.x;
	float q_y = state->pose.pose.orientation.y;
	float q_z = state->pose.pose.orientation.z;
	float q_w = state->pose.pose.orientation.w;

	float  yaw = atan2(2*(q_w*q_z+q_x*q_y),1-2*(q_y*q_y+q_z*q_z));
	if(stop==0){
		force(0) = offset_x+k_vxy*(vel_des(0)-vel(0))+m*acc_des(0);
		if(pd_control==0)
			force(1) = offset_y+k_vxy*(vel_des(1)-vel(1))+m*acc_des(1);
		else if(pd_control==1)
		{
			pos(1)=state->pose.pose.position.y;
			force(1) = offset_y+k_vxy*(vel_des(1)-vel(1))+k_xy*(0-pos(1))+m*acc_des(1);
		}
		force(2) = (k_z*(pos_des(2)-pos(2))+k_vz*(vel_des(2)-vel(2))+m*g(2)+m*acc_des(2));
	}
	else if(stop==1)
	{
		force(0) = offset_x+m*acc_des(0);
		force(1) = offset_y+m*acc_des(1);
  }


	b3 = force.normalized();
	b2 = b3.cross(b1w);
	b1 = b2.cross(b3);
	R_des<<b1[0],b2[0],b3[0],
    b1[1],b2[1],b3[1],
    b1[2],b2[2],b3[2];
  Eigen::Quaternionf q_des(R_des);
  	
  
  quadrotor_msgs::SO3Command command;
	command.force.x = force[0];
  command.force.y = force[1];
  command.force.z = force[2];
  command.orientation.x = q_des.x();
  command.orientation.y = q_des.y();
  command.orientation.z = q_des.z();
  command.orientation.w = q_des.w();
  command.kR[0] = k_R;
  command.kR[1] = k_R;
  command.kR[2] = k_R;
  command.kOm[0] = k_omg;
  command.kOm[1] = k_omg;
  command.kOm[2] = k_omg;
	command.aux.current_yaw = yaw;
	command.aux.enable_motors = true;
	command.aux.use_external_yaw = true;
  control_pub.publish(command);

opticalflow_msgs::Traj traj;

	traj.x = pos_des[0];
	traj.y = pos_des[1];
	traj.z = pos_des[2];
	traj.vx = vel_des[0];
	traj.vy = vel_des[1];
	traj.vz = vel_des[2];
	traj.acc_x = acc_des[0];
	traj.acc_y = acc_des[1];
	traj.acc_z = acc_des[2];
	traj.stop = 0;
	traj.mode = mode;
	traj.use_sensor = true;
	traj_pub.publish(traj);

}
示例#13
0
void SilhouetteExtractor::computeVisibleFrontFacingStatus()
{
    int terrain_width = terrain_->width();
    int terrain_height = terrain_->height();

    delete front_facing_;
    front_facing_ = new FacingMode [(terrain_width-1)*(terrain_height-1)];

    bool use_intersections = true ;

    if (!use_intersections)
    {
        setupPixelBuffer();
        pixelbuffer_->makeCurrent();
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_LIGHT0);
        glEnable(GL_LIGHTING);
        GLfloat lightpos[] = {.5, 1., 1., 0.};
        glLightfv(GL_LIGHT0, GL_POSITION, lightpos);

        glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        drawTerrain();
        updateMatrices();

        saveBuffer("test_dpth.png");
        pixelbuffer_->makeCurrent();
    }

    double begin = omp_get_wtime();

    int i = 0;
#pragma omp parallel for private(i)
    for (int j = 0; j < terrain_->height()-1; ++j)
        for (i = 0; i < terrain_->width()-1; ++i)
        {
            front_facing_[j*(terrain_width-1)+i] = kInvisible;

            Eigen::Vector3f center = getFaceCentroid(i, j);
            Eigen::Vector3f projector = center - camera_info_.position;
            //projector = camera_info_.direction;

            float theta = acos(camera_info_.direction.normalized().dot(projector.normalized()));
            if (theta > camera_info_.fov_in_rads/2)
                continue;

            front_facing_[j*(terrain_width-1)+i] = kBackFacing;

            if (terrain_->getGridNormal(i, j).dot(projector) <= -FLT_EPSILON)
            {
                if (use_intersections)
                {
                    if (checkVisibility(center))
                        front_facing_[j*(terrain_width-1)+i] = kFrontFacing;
                } else
                {
                    Eigen::Vector3d window_coords;
                    gluProject(center[0], center[1], center[2],
                               modelview_matrix_, projection_matrix_, viewport_,
                               &window_coords[0], &window_coords[1], &window_coords[2]);

                    if (window_coords[0] < 0 || window_coords[1] < 0 || window_coords[0] >= width() || window_coords[1] >= height())
                        continue;
                    float depth = 0.0;
                    glReadPixels(window_coords[0], window_coords[1], 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);

                    if (std::abs(depth-window_coords[2]) < 1e-3)
                        front_facing_[j*(terrain_width-1)+i] = kFrontFacing;
                }
            }
        }

    double end = omp_get_wtime();
    double elapsed_secs = double(end - begin);
    fprintf(stdout, "Elapsed time for checking front/back facing: %.2f secs\n", elapsed_secs);
    fprintf(stdout, "Num of threads: %d threads\n", omp_get_thread_num());
    fflush(stdout);

    if (pixelbuffer_)
    {
        pixelbuffer_->doneCurrent();
        cleanupPixelBuffer();
    }
}
std::vector<Vector3f> ShapeEstimation::gradientField(ImageReader mask, std::vector<float> &pixelLuminances, std::vector<float> &gradientX, std::vector<float> &gradientY){
    int rows = mask.getImageHeight();
    int cols = mask.getImageWidth();

    float gxNormalize = 0.0f;
    float gyNormalize = 0.0f;

    for(int row = 0; row < rows; row++){
        for(int col = 0; col < cols; col++){
           int index = mask.indexAt(row, col);
           if(row + 1 < rows){
               int indexUp = mask.indexAt(row + 1, col);
               float dY = pixelLuminances[indexUp] - pixelLuminances[index];
               gradientY.push_back(dY);
               if(fabs(dY) > gyNormalize){
                   gyNormalize = fabs(dY);
               }

           } else {
               gradientY.push_back(0.0f);
           }

           if(col + 1 < cols){
               int indexRight = mask.indexAt(row, col+1);
               float dX = pixelLuminances[indexRight] - pixelLuminances[index];
               gradientX.push_back(dX);
               if(fabs(dX) > gxNormalize){
                   gxNormalize = fabs(dX);
               }
           } else {
               gradientX.push_back(0.0f);
           }

        }
    }
    assert(gradientX.size() == gradientY.size());

    for(int i = 0; i < gradientX.size(); i++){
        gradientX[i] = gradientReshapeRecursive(gradientX[i]/gxNormalize, m_curvature) * gxNormalize;

    }
    for(int i = 0; i < gradientY.size(); i++){
        gradientY[i] = gradientReshapeRecursive(gradientY[i]/gyNormalize, m_curvature) * gyNormalize;
    }

    std::vector<Vector3f> normals;
    for(int i = 0; i < rows; i++){
        for(int j = 0; j < cols; j++){
            QColor maskColor = QColor(mask.pixelAt(i,j));
            if(maskColor.red() > 150){
                Eigen::Vector3f gx = Vector3f(1.0f, 0.0f, gradientX[mask.indexAt(i,j)]);
                Eigen::Vector3f gy = Vector3f(0.0f, 1.0f, gradientY[mask.indexAt(i,j)]);


                Eigen::Vector3f normal = (gx.cross(gy));

                normal = normal.normalized();
                normals.push_back(normal);
            } else {
                normals.push_back(Vector3f(0.0,0.0,0.0));
            }
        }
    }
    //pixelLuminances = gradientX;
    return normals;
}
示例#15
0
NORI_NAMESPACE_BEGIN

NoriObject *loadFromXML(const std::string &filename) {
    /* Load the XML file using 'pugi' (a tiny self-contained XML parser implemented in C++) */
    pugi::xml_document doc;
    pugi::xml_parse_result result = doc.load_file(filename.c_str());

    /* Helper function: map a position offset in bytes to a more readable row/column value */
    auto offset = [&](ptrdiff_t pos) -> std::string {
        std::fstream is(filename);
        char buffer[1024];
        int line = 0, linestart = 0, offset = 0;
        while (is.good()) {
            is.read(buffer, sizeof(buffer));
            for (int i = 0; i < is.gcount(); ++i) {
                if (buffer[i] == '\n') {
                    if (offset + i >= pos)
                        return tfm::format("row %i, col %i", line + 1, pos - linestart);
                    ++line;
                    linestart = offset + i;
                }
            }
            offset += (int) is.gcount();
        }
        return "byte offset " + std::to_string(pos);
    };

    if (!result) /* There was a parser / file IO error */
        throw NoriException("Error while parsing \"%s\": %s (at %s)", filename, result.description(), offset(result.offset));

    /* Set of supported XML tags */
    enum ETag {
        /* Object classes */
        EScene                = NoriObject::EScene,
        EMesh                 = NoriObject::EMesh,
        EBSDF                 = NoriObject::EBSDF,
        ETEXTURE              = NoriObject::ETEXTURE,
        EPERLIN               = NoriObject::EPERLIN,
        EMIXTEXTURE           = NoriObject::EMIXTEXTURE,
        EMIXBUMPMAP           = NoriObject::EMIXBUMPMAP,
        EBUMPMAP              = NoriObject::EBUMPMAP,
        EPhaseFunction        = NoriObject::EPhaseFunction,
        EEmitter              = NoriObject::EEmitter,
        EMedium               = NoriObject::EMedium,
        EVolume               = NoriObject::EVolume,
        ECamera               = NoriObject::ECamera,
        EIntegrator           = NoriObject::EIntegrator,
        ESampler              = NoriObject::ESampler,
        ETest                 = NoriObject::ETest,
        EReconstructionFilter = NoriObject::EReconstructionFilter,

        /* Properties */
        EBoolean = NoriObject::EClassTypeCount,
        EInteger,
        EFloat,
        EString,
        EPoint,
        EVector,
        EColor,
        ETransform,
        ETranslate,
        EMatrix,
        ERotate,
        EScale,
        ELookAt,

        EInvalid
    };

    /* Create a mapping from tag names to tag IDs */
    std::map<std::string, ETag> tags;
    tags["scene"]      = EScene;
    tags["mesh"]       = EMesh;
    tags["bsdf"]       = EBSDF;
    tags["texture"]    = ETEXTURE;
    tags["bumpmap"]    = EBUMPMAP;
    tags["perlin"]     = EPERLIN;
    tags["mixTexture"] = EMIXTEXTURE;
    tags["mixBumpmap"] = EMIXBUMPMAP;
    tags["bumpmap"]    = EBUMPMAP;
    tags["emitter"]    = EEmitter;
    tags["camera"]     = ECamera;
    tags["medium"]     = EMedium;
    tags["volume"]     = EVolume;
    tags["phase"]      = EPhaseFunction;
    tags["integrator"] = EIntegrator;
    tags["sampler"]    = ESampler;
    tags["rfilter"]    = EReconstructionFilter;
    tags["test"]       = ETest;
    tags["boolean"]    = EBoolean;
    tags["integer"]    = EInteger;
    tags["float"]      = EFloat;
    tags["string"]     = EString;
    tags["point"]      = EPoint;
    tags["vector"]     = EVector;
    tags["color"]      = EColor;
    tags["transform"]  = ETransform;
    tags["translate"]  = ETranslate;
    tags["matrix"]     = EMatrix;
    tags["rotate"]     = ERotate;
    tags["scale"]      = EScale;
    tags["lookat"]     = ELookAt;

    /* Helper function to check if attributes are fully specified */
    auto check_attributes = [&](const pugi::xml_node &node, std::set<std::string> attrs) {
        for (auto attr : node.attributes()) {
            auto it = attrs.find(attr.name());
            if (it == attrs.end())
                throw NoriException("Error while parsing \"%s\": unexpected attribute \"%s\" in \"%s\" at %s",
                                    filename, attr.name(), node.name(), offset(node.offset_debug()));
            attrs.erase(it);
        }
        if (!attrs.empty())
            throw NoriException("Error while parsing \"%s\": missing attribute \"%s\" in \"%s\" at %s",
                                filename, *attrs.begin(), node.name(), offset(node.offset_debug()));
    };

    Eigen::Affine3f transform;

    /* Helper function to parse a Nori XML node (recursive) */
    std::function<NoriObject *(pugi::xml_node &, PropertyList &, int)> parseTag = [&](
    pugi::xml_node &node, PropertyList &list, int parentTag) -> NoriObject * {
        /* Skip over comments */
        if (node.type() == pugi::node_comment || node.type() == pugi::node_declaration)
            return nullptr;

        if (node.type() != pugi::node_element)
            throw NoriException(
                "Error while parsing \"%s\": unexpected content at %s",
                filename, offset(node.offset_debug()));

        /* Look up the name of the current element */
        auto it = tags.find(node.name());
        if (it == tags.end())
            throw NoriException("Error while parsing \"%s\": unexpected tag \"%s\" at %s",
            filename, node.name(), offset(node.offset_debug()));
        int tag = it->second;

        /* Perform some safety checks to make sure that the XML tree really makes sense */
        bool hasParent            = parentTag != EInvalid;
        bool parentIsObject       = hasParent && parentTag < NoriObject::EClassTypeCount;
        bool currentIsObject      = tag < NoriObject::EClassTypeCount;
        bool parentIsTransform    = parentTag == ETransform;
        bool currentIsTransformOp = tag == ETranslate || tag == ERotate || tag == EScale || tag == ELookAt || tag == EMatrix;

        if (!hasParent && !currentIsObject)
            throw NoriException("Error while parsing \"%s\": root element \"%s\" must be a Nori object (at %s)",
            filename, node.name(), offset(node.offset_debug()));

        if (parentIsTransform != currentIsTransformOp)
            throw NoriException("Error while parsing \"%s\": transform nodes "
            "can only contain transform operations (at %s)",
            filename,  offset(node.offset_debug()));

        if (hasParent && !parentIsObject && !(parentIsTransform && currentIsTransformOp))
            throw NoriException("Error while parsing \"%s\": node \"%s\" requires a Nori object as parent (at %s)",
            filename, node.name(), offset(node.offset_debug()));

        if (tag == EScene)
            node.append_attribute("type") = "scene";
        else if (tag == ETransform)
            transform.setIdentity();

        PropertyList propList;
        std::vector<NoriObject *> children;
        for (pugi::xml_node &ch: node.children()) {
            NoriObject *child = parseTag(ch, propList, tag);
            if (child)
                children.push_back(child);
        }

        NoriObject *result = nullptr;
        try {
            if (currentIsObject) {
                check_attributes(node, { "type" });

                /* This is an object, first instantiate it */
                result = NoriObjectFactory::createInstance(
                             node.attribute("type").value(),
                             propList
                         );

                if (result->getClassType() != (int) tag) {
                    throw NoriException(
                        "Unexpectedly constructed an object "
                        "of type <%s> (expected type <%s>): %s",
                        NoriObject::classTypeName(result->getClassType()),
                        NoriObject::classTypeName((NoriObject::EClassType) tag),
                        result->toString());
                }

                /* Add all children */
                for (auto ch: children) {
                    result->addChild(ch);
                    ch->setParent(result);
                }

                /* Activate / configure the object */
                result->activate();
            } else {
                /* This is a property */
                switch (tag) {
                case EString: {
                    check_attributes(node, { "name", "value" });
                    list.setString(node.attribute("name").value(), node.attribute("value").value());
                }
                break;
                case EFloat: {
                    check_attributes(node, { "name", "value" });
                    list.setFloat(node.attribute("name").value(), toFloat(node.attribute("value").value()));
                }
                break;
                case EInteger: {
                    check_attributes(node, { "name", "value" });
                    list.setInteger(node.attribute("name").value(), toInt(node.attribute("value").value()));
                }
                break;
                case EBoolean: {
                    check_attributes(node, { "name", "value" });
                    list.setBoolean(node.attribute("name").value(), toBool(node.attribute("value").value()));
                }
                break;
                case EPoint: {
                    check_attributes(node, { "name", "value" });
                    list.setPoint(node.attribute("name").value(), Point3f(toVector3f(node.attribute("value").value())));
                }
                break;
                case EVector: {
                    check_attributes(node, { "name", "value" });
                    list.setVector(node.attribute("name").value(), Vector3f(toVector3f(node.attribute("value").value())));
                }
                break;
                case EColor: {
                    check_attributes(node, { "name", "value" });
                    list.setColor(node.attribute("name").value(), Color3f(toVector3f(node.attribute("value").value()).array()));
                }
                break;
                case ETransform: {
                    check_attributes(node, { "name" });
                    list.setTransform(node.attribute("name").value(), transform.matrix());
                }
                break;
                case ETranslate: {
                    check_attributes(node, { "value" });
                    Eigen::Vector3f v = toVector3f(node.attribute("value").value());
                    transform = Eigen::Translation<float, 3>(v.x(), v.y(), v.z()) * transform;
                }
                break;
                case EMatrix: {
                    check_attributes(node, { "value" });
                    std::vector<std::string> tokens = tokenize(node.attribute("value").value());
                    if (tokens.size() != 16)
                        throw NoriException("Expected 16 values");
                    Eigen::Matrix4f matrix;
                    for (int i=0; i<4; ++i)
                        for (int j=0; j<4; ++j)
                            matrix(i, j) = toFloat(tokens[i*4+j]);
                    transform = Eigen::Affine3f(matrix) * transform;
                }
                break;
                case EScale: {
                    check_attributes(node, { "value" });
                    Eigen::Vector3f v = toVector3f(node.attribute("value").value());
                    transform = Eigen::DiagonalMatrix<float, 3>(v) * transform;
                }
                break;
                case ERotate: {
                    check_attributes(node, { "angle", "axis" });
                    float angle = degToRad(toFloat(node.attribute("angle").value()));
                    Eigen::Vector3f axis = toVector3f(node.attribute("axis").value());
                    transform = Eigen::AngleAxis<float>(angle, axis) * transform;
                }
                break;
                case ELookAt: {
                    check_attributes(node, { "origin", "target", "up" });
                    Eigen::Vector3f origin = toVector3f(node.attribute("origin").value());
                    Eigen::Vector3f target = toVector3f(node.attribute("target").value());
                    Eigen::Vector3f up = toVector3f(node.attribute("up").value());

                    Vector3f dir = (target - origin).normalized();
                    Vector3f left = up.normalized().cross(dir);
                    Vector3f newUp = dir.cross(left);

                    Eigen::Matrix4f trafo;
                    trafo << left, newUp, dir, origin,
                          0, 0, 0, 1;

                    transform = Eigen::Affine3f(trafo) * transform;
                }
                break;

                default:
                    throw NoriException("Unhandled element \"%s\"", node.name());
                };
            }
        } catch (const NoriException &e) {
            throw NoriException("Error while parsing \"%s\": %s (at %s)", filename,
                                e.what(), offset(node.offset_debug()));
        }

        return result;
    };

    PropertyList list;
    return parseTag(*doc.begin(), list, EInvalid);
}
template<typename Point> void
TableObjectCluster<Point>::calculateBoundingBox(
  const PointCloudPtr& cloud,
  const pcl::PointIndices& indices,
  const Eigen::Vector3f& plane_normal,
  const Eigen::Vector3f& plane_point,
  Eigen::Vector3f& position,
  Eigen::Quaternion<float>& orientation,
  Eigen::Vector3f& size)
{
  // transform to table coordinate frame and project points on X-Y, save max height
  Eigen::Affine3f tf;
  pcl::getTransformationFromTwoUnitVectorsAndOrigin(plane_normal.unitOrthogonal(), plane_normal, plane_point, tf);
  pcl::PointCloud<pcl::PointXYZ>::Ptr pc2d(new pcl::PointCloud<pcl::PointXYZ>);
  float height = 0.0;
  for(std::vector<int>::const_iterator it=indices.indices.begin(); it != indices.indices.end(); ++it)
  {
    Eigen::Vector3f tmp = tf * (*cloud)[*it].getVector3fMap();
    height = std::max<float>(height, fabs(tmp(2)));
    pc2d->push_back(pcl::PointXYZ(tmp(0),tmp(1),0.0));
  }

  // create convex hull of projected points
  #ifdef PCL_MINOR_VERSION >= 6
  pcl::PointCloud<pcl::PointXYZ>::Ptr conv_hull(new pcl::PointCloud<pcl::PointXYZ>);
  pcl::ConvexHull<pcl::PointXYZ> chull;
  chull.setDimension(2);
  chull.setInputCloud(pc2d);
  chull.reconstruct(*conv_hull);
  #endif

  /*for(int i=0; i<conv_hull->size(); ++i)
    std::cout << (*conv_hull)[i].x << "," << (*conv_hull)[i].y << std::endl;*/

  // find the minimal bounding rectangle in 2D and table coordinates
  Eigen::Vector2f p1, p2, p3;
  cob_3d_mapping::MinimalRectangle2D mr2d;
  mr2d.setConvexHull(conv_hull->points);
  mr2d.rotatingCalipers(p2, p1, p3);
  /*std::cout << "BB: \n" << p1[0] << "," << p1[1] <<"\n"
            << p2[0] << "," << p2[1] <<"\n"
            << p3[0] << "," << p3[1] <<"\n ---" << std::endl;*/

  // compute center of rectangle
  position[0] = 0.5f*(p1[0] + p3[0]);
  position[1] = 0.5f*(p1[1] + p3[1]);
  position[2] = 0.0f;
  // transform back
  Eigen::Affine3f inv_tf = tf.inverse();
  position = inv_tf * position;
  // set size of bounding box
  float norm_1 = (p3-p2).norm();
  float norm_2 = (p1-p2).norm();
  // BoundingBox coordinates: X:= main direction, Z:= table normal
  Eigen::Vector3f direction; // y direction
  if (norm_1 < norm_2)
  {
    direction = Eigen::Vector3f(p3[0]-p2[0], p3[1]-p2[1], 0) / (norm_1);
    size[0] = norm_2 * 0.5f;
    size[1] = norm_1 * 0.5f;
  }
  else
  {
    direction = Eigen::Vector3f(p1[0]-p2[0], p1[1]-p2[1], 0) / (norm_2);
    size[0] = norm_1 * 0.5f;
    size[1] = norm_2 * 0.5f;
  }
  size[2] = -height;


  direction = inv_tf.rotation() * direction;
  orientation = pcl::getTransformationFromTwoUnitVectors(direction, plane_normal).rotation(); // (y, z-direction)

  return;
  Eigen::Matrix3f M = Eigen::Matrix3f::Identity() - plane_normal * plane_normal.transpose();
  Eigen::Vector3f xn = M * Eigen::Vector3f::UnitX(); // X-axis project on normal
  Eigen::Vector3f xxn = M * direction;
  float cos_phi = acos(xn.normalized().dot(xxn.normalized())); // angle between xn and main direction
  cos_phi = cos(0.5f * cos_phi);
  float sin_phi = sqrt(1.0f-cos_phi*cos_phi);
  //orientation.w() = cos_phi;
  //orientation.x() = sin_phi * plane_normal(0);
  //orientation.y() = sin_phi * plane_normal(1);
  //orientation.z() = sin_phi * plane_normal(2);
}
示例#17
0
 Plane::Plane(Eigen::Vector3f normal, Eigen::Vector3f p) :
   normal_(normal.normalized()), d_(- normal.dot(p) / normal.norm())
 {
   initializeCoordinates();
 }
示例#18
0
BlockFitter::Result BlockFitter::
go() {
  Result result;
  result.mSuccess = false;

  if (mCloud->size() < 100) return result;

  // voxelize
  LabeledCloud::Ptr cloud(new LabeledCloud());
  pcl::VoxelGrid<pcl::PointXYZL> voxelGrid;
  voxelGrid.setInputCloud(mCloud);
  voxelGrid.setLeafSize(mDownsampleResolution, mDownsampleResolution,
                        mDownsampleResolution);
  voxelGrid.filter(*cloud);
  for (int i = 0; i < (int)cloud->size(); ++i) cloud->points[i].label = i;

  if (mDebug) {
    std::cout << "Original cloud size " << mCloud->size() << std::endl;
    std::cout << "Voxelized cloud size " << cloud->size() << std::endl;
    pcl::io::savePCDFileBinary("cloud_full.pcd", *cloud);
  }

  if (cloud->size() < 100) return result;

  // pose
  cloud->sensor_origin_.head<3>() = mOrigin;
  cloud->sensor_origin_[3] = 1;
  Eigen::Vector3f rz = mLookDir;
  Eigen::Vector3f rx = rz.cross(Eigen::Vector3f::UnitZ());
  Eigen::Vector3f ry = rz.cross(rx);
  Eigen::Matrix3f rotation;
  rotation.col(0) = rx.normalized();
  rotation.col(1) = ry.normalized();
  rotation.col(2) = rz.normalized();
  Eigen::Isometry3f pose = Eigen::Isometry3f::Identity();
  pose.linear() = rotation;
  pose.translation() = mOrigin;

  // ground removal
  if (mRemoveGround) {
    Eigen::Vector4f groundPlane;

    // filter points
    float minZ = mMinGroundZ;
    float maxZ = mMaxGroundZ;
    if ((minZ > 10000) && (maxZ > 10000)) {
      std::vector<float> zVals(cloud->size());
      for (int i = 0; i < (int)cloud->size(); ++i) {
        zVals[i] = cloud->points[i].z;
      }
      std::sort(zVals.begin(), zVals.end());
      minZ = zVals[0]-0.1;
      maxZ = minZ + 0.5;
    }
    LabeledCloud::Ptr tempCloud(new LabeledCloud());
    for (int i = 0; i < (int)cloud->size(); ++i) {
      const Eigen::Vector3f& p = cloud->points[i].getVector3fMap();
      if ((p[2] < minZ) || (p[2] > maxZ)) continue;
      tempCloud->push_back(cloud->points[i]);
    }

    // downsample
    voxelGrid.setInputCloud(tempCloud);
    voxelGrid.setLeafSize(0.1, 0.1, 0.1);
    voxelGrid.filter(*tempCloud);

    if (tempCloud->size() < 100) return result;

    // find ground plane
    std::vector<Eigen::Vector3f> pts(tempCloud->size());
    for (int i = 0; i < (int)tempCloud->size(); ++i) {
      pts[i] = tempCloud->points[i].getVector3fMap();
    }
    const float kGroundPlaneDistanceThresh = 0.01; // TODO: param
    PlaneFitter planeFitter;
    planeFitter.setMaxDistance(kGroundPlaneDistanceThresh);
    planeFitter.setRefineUsingInliers(true);
    auto res = planeFitter.go(pts);
    groundPlane = res.mPlane;
    if (groundPlane[2] < 0) groundPlane = -groundPlane;
    if (mDebug) {
      std::cout << "dominant plane: " << groundPlane.transpose() << std::endl;
      std::cout << "  inliers: " << res.mInliers.size() << std::endl;
    }

    if (std::acos(groundPlane[2]) > 30*M_PI/180) {
      std::cout << "error: ground plane not found!" << std::endl;
      std::cout << "proceeding with full segmentation (may take a while)..." <<
        std::endl;
    }

    else {
      // compute convex hull
      result.mGroundPlane = groundPlane;
      {
        tempCloud.reset(new LabeledCloud());
        for (int i = 0; i < (int)cloud->size(); ++i) {
          Eigen::Vector3f p = cloud->points[i].getVector3fMap();
          float dist = groundPlane.head<3>().dot(p) + groundPlane[3];
          if (std::abs(dist) > kGroundPlaneDistanceThresh) continue;
          p -= (groundPlane.head<3>()*dist);
          pcl::PointXYZL cloudPt;
          cloudPt.getVector3fMap() = p;
          tempCloud->push_back(cloudPt);
        }
        pcl::ConvexHull<pcl::PointXYZL> chull;
        pcl::PointCloud<pcl::PointXYZL> hull;
        chull.setInputCloud(tempCloud);
        chull.reconstruct(hull);
        result.mGroundPolygon.resize(hull.size());
        for (int i = 0; i < (int)hull.size(); ++i) {
          result.mGroundPolygon[i] = hull[i].getVector3fMap();
        }
      }

      // remove points below or near ground
      tempCloud.reset(new LabeledCloud());
      for (int i = 0; i < (int)cloud->size(); ++i) {
        Eigen::Vector3f p = cloud->points[i].getVector3fMap();
        float dist = p.dot(groundPlane.head<3>()) + groundPlane[3];
        if ((dist < mMinHeightAboveGround) ||
            (dist > mMaxHeightAboveGround)) continue;
        float range = (p-mOrigin).norm();
        if (range > mMaxRange) continue;
        tempCloud->push_back(cloud->points[i]);
      }
      std::swap(tempCloud, cloud);
      if (mDebug) {
        std::cout << "Filtered cloud size " << cloud->size() << std::endl;
      }
    }
  }

  // normal estimation
  auto t0 = std::chrono::high_resolution_clock::now();
  if (mDebug) {
    std::cout << "computing normals..." << std::flush;
  }
  RobustNormalEstimator normalEstimator;
  normalEstimator.setMaxEstimationError(0.01);
  normalEstimator.setRadius(0.1);
  normalEstimator.setMaxCenterError(0.02);
  normalEstimator.setMaxIterations(100);
  NormalCloud::Ptr normals(new NormalCloud());
  normalEstimator.go(cloud, *normals);
  if (mDebug) {
    auto t1 = std::chrono::high_resolution_clock::now();
    auto dt = std::chrono::duration_cast<std::chrono::milliseconds>(t1-t0);
    std::cout << "finished in " << dt.count()/1e3 << " sec" << std::endl;
  }

  // filter non-horizontal points
  const float maxNormalAngle = mMaxAngleFromHorizontal*M_PI/180;
  LabeledCloud::Ptr tempCloud(new LabeledCloud());
  NormalCloud::Ptr tempNormals(new NormalCloud());
  for (int i = 0; i < (int)normals->size(); ++i) {
    const auto& norm = normals->points[i];
    Eigen::Vector3f normal(norm.normal_x, norm.normal_y, norm.normal_z);
    float angle = std::acos(normal[2]);
    if (angle > maxNormalAngle) continue;
    tempCloud->push_back(cloud->points[i]);
    tempNormals->push_back(normals->points[i]);
  }
  std::swap(tempCloud, cloud);
  std::swap(tempNormals, normals);

  if (mDebug) {
    std::cout << "Horizontal points remaining " << cloud->size() << std::endl;
    pcl::io::savePCDFileBinary("cloud.pcd", *cloud);
    pcl::io::savePCDFileBinary("robust_normals.pcd", *normals);
  }

  // plane segmentation
  t0 = std::chrono::high_resolution_clock::now();
  if (mDebug) {
    std::cout << "segmenting planes..." << std::flush;
  }
  PlaneSegmenter segmenter;
  segmenter.setData(cloud, normals);
  segmenter.setMaxError(0.05);
  segmenter.setMaxAngle(5);
  segmenter.setMinPoints(100);
  PlaneSegmenter::Result segmenterResult = segmenter.go();
  if (mDebug) {
    auto t1 = std::chrono::high_resolution_clock::now();
    auto dt = std::chrono::duration_cast<std::chrono::milliseconds>(t1-t0);
    std::cout << "finished in " << dt.count()/1e3 << " sec" << std::endl;

    std::ofstream ofs("labels.txt");
    for (const int lab : segmenterResult.mLabels) {
      ofs << lab << std::endl;
    }
    ofs.close();

    ofs.open("planes.txt");
    for (auto it : segmenterResult.mPlanes) {
      auto& plane = it.second;
      ofs << it.first << " " << plane.transpose() << std::endl;
    }
    ofs.close();
  }

  // create point clouds
  std::unordered_map<int,std::vector<Eigen::Vector3f>> cloudMap;
  for (int i = 0; i < (int)segmenterResult.mLabels.size(); ++i) {
    int label = segmenterResult.mLabels[i];
    if (label <= 0) continue;
    cloudMap[label].push_back(cloud->points[i].getVector3fMap());
  }
  struct Plane {
    MatrixX3f mPoints;
    Eigen::Vector4f mPlane;
  };
  std::vector<Plane> planes;
  planes.reserve(cloudMap.size());
  for (auto it : cloudMap) {
    int n = it.second.size();
    Plane plane;
    plane.mPoints.resize(n,3);
    for (int i = 0; i < n; ++i) plane.mPoints.row(i) = it.second[i];
    plane.mPlane = segmenterResult.mPlanes[it.first];
    planes.push_back(plane);
  }

  std::vector<RectangleFitter::Result> results;
  for (auto& plane : planes) {
    RectangleFitter fitter;
    fitter.setDimensions(mBlockDimensions.head<2>());
    fitter.setAlgorithm((RectangleFitter::Algorithm)mRectangleFitAlgorithm);
    fitter.setData(plane.mPoints, plane.mPlane);
    auto result = fitter.go();
    results.push_back(result);
  }

  if (mDebug) {
    std::ofstream ofs("boxes.txt");
    for (int i = 0; i < (int)results.size(); ++i) {
      auto& res = results[i];
      for (auto& p : res.mPolygon) {
        ofs << i << " " << p.transpose() << std::endl;
      }
    }
    ofs.close();

    ofs.open("hulls.txt");
    for (int i = 0; i < (int)results.size(); ++i) {
      auto& res = results[i];
      for (auto& p : res.mConvexHull) {
        ofs << i << " " << p.transpose() << std::endl;
      }
    }
    ofs.close();

    ofs.open("poses.txt");
    for (int i = 0; i < (int)results.size(); ++i) {
      auto& res = results[i];
      auto transform = res.mPose;
      ofs << transform.matrix() << std::endl;
    }
    ofs.close();
  }

  for (int i = 0; i < (int)results.size(); ++i) {
    const auto& res = results[i];
    if (mBlockDimensions.head<2>().norm() > 1e-5) {
      float areaRatio = mBlockDimensions.head<2>().prod()/res.mConvexArea;
      if ((areaRatio < mAreaThreshMin) ||
          (areaRatio > mAreaThreshMax)) continue;
    }

    Block block;
    block.mSize << res.mSize[0], res.mSize[1], mBlockDimensions[2];
    block.mPose = res.mPose;
    block.mPose.translation() -=
      block.mPose.rotation().col(2)*mBlockDimensions[2]/2;
    block.mHull = res.mConvexHull;
    result.mBlocks.push_back(block);
  }
  if (mDebug) {
    std::cout << "Surviving blocks: " << result.mBlocks.size() << std::endl;
  }

  result.mSuccess = true;
  return result;
}
示例#19
0
文件: cPlane.cpp 项目: winkie/cg
cPlane::cPlane(const Eigen::Vector3f& n, float d): mNormal(n.normalized()), mD(d)
{
}
示例#20
0
文件: cPlane.cpp 项目: winkie/cg
cPlane::cPlane(const Eigen::Vector3f& n, float d, const sMaterial& mat): mNormal(n.normalized()), mD(d), aWorldObject(mat)
{
}