// // Created by zx on 2021/8/27. // #include "rotate_center_caliber.h" #include #include // extern pcl::visualization::PCLVisualizer viewer; // extern std::mutex mut; void rotate_center_caliber::rotate_center_caliber_init() { } void rotate_center_caliber::rotate_center_caliber_uninit() { delete mp_matcher; mp_matcher = nullptr; } void rotate_center_caliber::set_first_frame(pcl::PointCloud::Ptr cloud_model) { m_model_cloud=cloud_model; Eigen::Vector4f centroid; pcl::compute3DCentroid(*cloud_model, centroid); m_center.x=centroid[0]; m_center.y=centroid[1]; m_center.z=centroid[2]; //平移点云 Eigen::Affine3f transform_2 = Eigen::Affine3f::Identity(); pcl::PointCloud::Ptr transformed_cloud(new pcl::PointCloud()); transform_2.translation() << -centroid[0],-centroid[1],-centroid[2]; pcl::transformPointCloud(*cloud_model, *transformed_cloud, transform_2); printf("model center: %.5f,%.5f,%.5f\n",centroid[0],centroid[1],centroid[2]); mp_matcher=new detect_ceres3d(transformed_cloud); } bool rotate_center_caliber::push_cloud(pcl::PointCloud::Ptr cloud) { //平移点云 Eigen::Affine3f transform_2 = Eigen::Affine3f::Identity(); pcl::PointCloud::Ptr offset_cloud(new pcl::PointCloud()); transform_2.translation() << -m_center.x,-m_center.y,-m_center.z; pcl::transformPointCloud(*cloud, *offset_cloud, transform_2); // mut.lock(); // pcl::visualization::PointCloudColorHandlerCustom single_color(cloud, 0, 255, 0); // green // viewer.removePointCloud("cloud_rotation"); // viewer.addPointCloud(cloud, single_color,"cloud_rotation"); // mut.unlock(); if(mp_matcher== nullptr) return false; static detect_ceres3d::Detect_result last_result; std::string error; pcl::PointCloud::Ptr transform_cloud(new pcl::PointCloud()); detect_ceres3d::Detect_result result=last_result; if(mp_matcher->detect(offset_cloud,result,transform_cloud,error)) { if(fabs(result.theta-last_result.theta)>1.0/180.*M_PI) { printf(" detect success r : %.3f t:%.5f,%.5f\n", result.theta * 180. / M_PI, result.cx, result.cy); Eigen::Affine3f transform_affine = Eigen::Affine3f::Identity(); pcl::PointCloud::Ptr new_cloud(new pcl::PointCloud()); transform_affine.translation() << m_center.x, m_center.y, m_center.z; pcl::transformPointCloud(*transform_cloud, *new_cloud, transform_affine); // mut.lock(); // pcl::visualization::PointCloudColorHandlerCustom single_color(cloud, 255, 0, 0); // green // viewer.removePointCloud("ndt_cloud"); // viewer.addPointCloud(new_cloud, single_color, "ndt_cloud"); // mut.unlock(); match_transform solve_data; solve_data.theta = result.theta; solve_data.dx = result.cx; solve_data.dy = result.cy; m_match_datas.push_back(solve_data); last_result = result; } else { // std::cout << " small dtheta: " << (result.theta - last_result.theta) * 180.0 / M_PI << std::endl; } }else{ std::cout << "?????" << std::endl; } /*Eigen::Matrix temp; temp.setZero(); static Eigen::Matrix last_transform=temp; printf("init r:%.3f,%.3f,%.3f, t :%.5f,%.5f,%.5f\n", last_transform(2,0)*180.0/M_PI,last_transform(1,0)*180.0/M_PI,last_transform(0,0)*180.0/M_PI, last_transform(3,0),last_transform(4,0),last_transform(5,0)); Eigen::Matrix4f matrix=match(m_model_cloud,cloud,last_transform); //std::cout<<" match :"<::Ptr cloud_center, pcl::PointCloud::Ptr cloud,Eigen::Matrix init_transform) { //初始化正态分布变换(NDT) pcl::NormalDistributionsTransform ndt; //设置依赖尺度NDT参数 //为终止条件设置最小转换差异 ndt.setTransformationEpsilon(0.0001); //为More-Thuente线搜索设置最大步长 ndt.setStepSize(0.1); //设置NDT网格结构的分辨率(VoxelGridCovariance) ndt.setResolution(0.3); //设置匹配迭代的最大次数 ndt.setMaximumIterations(100); // 设置要配准的点云 ndt.setInputSource(cloud); //设置点云配准目标 ndt.setInputTarget(cloud_center); //设置使用机器人测距法得到的初始对准估计结果 Eigen::AngleAxisf rollAngle(Eigen::AngleAxisf(init_transform(0), Eigen::Vector3f::UnitX())); Eigen::AngleAxisf pitchAngle(Eigen::AngleAxisf(init_transform(1), Eigen::Vector3f::UnitY())); Eigen::AngleAxisf yawAngle(Eigen::AngleAxisf(init_transform(2), Eigen::Vector3f::UnitZ())); Eigen::AngleAxisf rotation ; rotation = yawAngle*pitchAngle*rollAngle; Eigen::Affine3f transform_2 = Eigen::Affine3f::Identity(); transform_2.translation() << init_transform(3),init_transform(4),init_transform(5); // 三个数分别对应X轴、Y轴、Z轴方向上的平移 transform_2.rotate(rotation); //同理,UnitX(),绕X轴;UnitY( Eigen::Matrix4f init_guess = transform_2.matrix(); //计算需要的刚体变换以便将输入的点云匹配到目标点云 pcl::PointCloud::Ptr output_cloud(new pcl::PointCloud); ndt.align(*output_cloud, init_guess); std::cout << "Normal Distributions Transform has converged:" << ndt.hasConverged() << " score: " << ndt.getFitnessScore() << std::endl; //使用创建的变换对未过滤的输入点云进行变换 return ndt.getFinalTransformation(); } bool rotate_center_caliber::solve() { int size=m_match_datas.size(); if(size<=1) { LOG(INFO) <<"match_data size:"<< m_match_datas.size(); return false; } Eigen::MatrixXf A; A.resize(2*size,2); Eigen::MatrixXf B; B.resize(2*size,1); for(int i=0;imax_d) max_d=distance; } id = m_match_datas.size(); if((max_d-min_d)>0.01) { LOG(ERROR)<<" distances verify failed "; return ; } LOG(INFO)<<" distances verify :"<