/** * @project Project * @brief TODO: add a brief * @author lz * @data 2023/6/24 **/ #include #include #include #include #include #include #include #include #include #include #include "rslidar_mqtt_async.h" using namespace std; typedef pcl::PointXYZ PointT; typedef pcl::PointCloud PointCloudT; bool next_iteration = false; void print4x4Matrix(const Eigen::Matrix4d &matrix) { printf("Rotation matrix :\n"); printf(" | %6.6f %6.6f %6.6f | \n", matrix(0, 0), matrix(0, 1), matrix(0, 2)); printf("R = | %6.6f %6.6f %6.6f | \n", matrix(1, 0), matrix(1, 1), matrix(1, 2)); printf(" | %6.6f %6.6f %6.6f | \n", matrix(2, 0), matrix(2, 1), matrix(2, 2)); printf("Translation vector :\n"); printf("t = < %6.6f, %6.6f, %6.6f >\n\n", matrix(0, 3), matrix(1, 3), matrix(2, 3)); } void keyboardEventOccurred(const pcl::visualization::KeyboardEvent &event, void *nothing) { if (event.getKeySym() == "space" && event.keyDown()) next_iteration = true; } void findcorrespondences(pcl::PointCloud::Ptr &source, pcl::PointCloud::Ptr &target, pcl::PointCloud::Ptr &P, pcl::PointCloud::Ptr &Q) { P->clear(); Q->clear(); pcl::KdTreeFLANN kdtree; kdtree.setInputCloud(target); //#pragma omp parallel for num_threads(200) for (int i = 0; i < source->points.size(); i++) { vector indx; vector dists; kdtree.nearestKSearch(source->points[i], 1, indx, dists); if (dists[0] < 0.02) { P->push_back(source->points[i]); Q->push_back(target->points[indx[0]]); } } } Eigen::Matrix findRT(pcl::PointCloud::Ptr &P, pcl::PointCloud::Ptr &Q) { int n = P->points.size(); Eigen::Matrix matrixP(3, n), matrixQ(3, n); for (int i = 0; i < n; i++) { matrixP(0, i) = P->points[i].x; matrixP(1, i) = P->points[i].y; matrixP(2, i) = P->points[i].z; matrixQ(0, i) = Q->points[i].x; matrixQ(1, i) = Q->points[i].y; matrixQ(2, i) = Q->points[i].z; } Eigen::Matrix4d RT = Eigen::umeyama(matrixP, matrixQ); print4x4Matrix(RT); return RT; } void myICP(pcl::PointCloud::Ptr &source, pcl::PointCloud::Ptr &target, Eigen::Matrix &RT) { pcl::PointCloud::Ptr P(new pcl::PointCloud); pcl::PointCloud::Ptr Q(new pcl::PointCloud); pcl::visualization::PCLVisualizer viewer("viewer"); pcl::visualization::PointCloudColorHandlerCustom cloud_source(source, 255, 0, 0), cloud_target(target, 255, 255, 255); viewer.addPointCloud(source, cloud_source, "source"); viewer.addPointCloud(target, cloud_target, "target"); viewer.registerKeyboardCallback(&keyboardEventOccurred, (void *) nullptr); while (!viewer.wasStopped()) { viewer.spinOnce(); if (next_iteration) { findcorrespondences(source, target, P, Q); RT = findRT(P, Q); pcl::transformPointCloud(*source, *source, RT); viewer.updatePointCloud(source, cloud_source, "source"); } next_iteration = false; } } int main() { CloudDataMqttAsync mqtt_client; mqtt_client.init(); std::map::Ptr> cloud_map; cloud_map.insert(std::pair::Ptr>("rslidar/6311", new pcl::PointCloud)); cloud_map.insert(std::pair::Ptr>("rslidar/6312", new pcl::PointCloud)); cloud_map.insert(std::pair::Ptr>("rslidar/6313", new pcl::PointCloud)); cloud_map.insert(std::pair::Ptr>("rslidar/6314", new pcl::PointCloud)); cloud_map.insert(std::pair::Ptr>("rslidar/6315", new pcl::PointCloud)); cloud_map.insert(std::pair::Ptr>("rslidar/6316", new pcl::PointCloud)); std::map> rt_map; rt_map.insert(std::pair>("rslidar/6311", Eigen::Matrix())); rt_map.insert(std::pair>("rslidar/6312", Eigen::Matrix())); rt_map.insert(std::pair>("rslidar/6313", Eigen::Matrix())); rt_map.insert(std::pair>("rslidar/6314", Eigen::Matrix())); rt_map.insert(std::pair>("rslidar/6315", Eigen::Matrix())); rt_map.insert(std::pair>("rslidar/6316", Eigen::Matrix())); bool run = true; while (run) { for (auto &iter: cloud_map) { mqtt_client.getCloudData(iter.first, iter.second); } if (cloud_map.find("rslidar/6314")->second->empty()) { continue; } if (!cloud_map.find("rslidar/6311")->second->empty()) { myICP(cloud_map.find("rslidar/6314")->second, cloud_map.find("rslidar/6311")->second, rt_map.find("rslidar/6311")->second); } break; if (!cloud_map.find("rslidar/6312")->second->empty()) { myICP(cloud_map.find("rslidar/6314")->second, cloud_map.find("rslidar/6312")->second, rt_map.find("rslidar/6312")->second); } if (!cloud_map.find("rslidar/6313")->second->empty()) { myICP(cloud_map.find("rslidar/6314")->second, cloud_map.find("rslidar/6313")->second, rt_map.find("rslidar/6313")->second); } if (!cloud_map.find("rslidar/6314")->second->empty()) { myICP(cloud_map.find("rslidar/6314")->second, cloud_map.find("rslidar/6314")->second, rt_map.find("rslidar/6314")->second); } if (!cloud_map.find("rslidar/6315")->second->empty()) { myICP(cloud_map.find("rslidar/6314")->second, cloud_map.find("rslidar/6315")->second, rt_map.find("rslidar/6315")->second); } if (!cloud_map.find("rslidar/6316")->second->empty()) { myICP(cloud_map.find("rslidar/6314")->second, cloud_map.find("rslidar/6316")->second, rt_map.find("rslidar/6316")->second); } run = false; } }