Closed Nasrudin78 closed 4 months ago
Hi, I do not understand why you are converting the internal points of an Open3D
point cloud to a std::vector<Eigen::Vector3d>
. You can just access the attribute .points_
and get what you want. have you try that?
Same:
Full code:
#include <iostream>
#include <vector>
#include <string>
#include <filesystem>
#include <open3d/Open3D.h>
#include <kiss_icp/pipeline/KissICP.hpp>
namespace fs = std::filesystem;
using namespace open3d;
std::vector<std::shared_ptr<geometry::PointCloud>> point_clouds;
std::vector<Eigen::Matrix4d> transformations;
// Function to load a point cloud from a file
std::shared_ptr<geometry::PointCloud> LoadPointCloud(const std::string& filename) {
auto pcd = std::make_shared<geometry::PointCloud>();
if (io::ReadPointCloud(filename, *pcd)) {
std::cout << "Successfully read " << filename << std::endl;
} else {
std::cerr << "Failed to read " << filename << std::endl;
return nullptr;
}
return pcd;
}
// Function to compute odometry using KISS-ICP
Eigen::Matrix4d ComputeOdometryKISSICP(std::shared_ptr<kiss_icp::pipeline::KissICP>& kiss_icp_pipeline,
const std::shared_ptr<geometry::PointCloud>& source) {
const std::vector<Eigen::Vector3d> source_pc = source->points_;
std::cout << "Calling RegisterFrame\n";
auto [deskew_source, registered_source] = kiss_icp_pipeline->RegisterFrame(source_pc);
std::cout << "RegisterFrame returned\n";
return kiss_icp_pipeline->poses()[0].matrix();
}
int main(int argc, char** argv) {
if (argc < 2) {
std::cerr << "Usage: " << argv[0] << " <directory_path>" << std::endl;
return 1;
}
std::string directory_path = argv[1];
// Iterate through the directory and load PLY files
for (const auto& entry : fs::directory_iterator(directory_path)) {
if (entry.path().extension() == ".ply") {
auto pcd = LoadPointCloud(entry.path().string());
if (pcd != nullptr) {
point_clouds.push_back(pcd);
transformations.push_back(Eigen::Matrix4d::Identity());
}
}
}
if (point_clouds.size() < 2) {
std::cerr << "At least two point clouds are required." << std::endl;
return 1;
}
// Initialize KISS-ICP pipeline
kiss_icp::pipeline::KISSConfig config;
auto kiss_icp_pipeline = std::make_shared<kiss_icp::pipeline::KissICP>(config);
for (size_t i = 1; i < point_clouds.size(); ++i) {
auto transformation = ComputeOdometryKISSICP(kiss_icp_pipeline, point_clouds[i]);
transformations[i] = transformations[i - 1] * transformation;
}
return 0;
}
And output:
Successfully read ../data2/point_cloud_stitched_0500.ply Successfully read ../data2/point_cloud_stitched_0501.ply Successfully read ../data2/point_cloud_stitched_0502.ply Successfully read ../data2/point_cloud_stitched_0503.ply Successfully read ../data2/point_cloud_stitched_0504.ply Successfully read ../data2/point_cloud_stitched_0505.ply Successfully read ../data2/point_cloud_stitched_0506.ply Successfully read ../data2/point_cloud_stitched_0507.ply Successfully read ../data2/point_cloud_stitched_0508.ply Successfully read ../data2/point_cloud_stitched_0509.ply Calling RegisterFrame Segmentation fault (core dumped) `
I found the error: I linked kiss_cip_core and pipeline with my main program:
target_link_libraries(odometry_kiss_icp ${Open3D_LIBRARIES} Sophus::Sophus TBB::tbb kiss_icp_core kiss_icp_pipeline)
Since kiss_icp_pipeline already comes linked with kiss_icp_core , is not necessary to link it again
So I removed:
target_link_libraries(odometry_kiss_icp
kiss_icp_pipeline
${Open3D_LIBRARIES}
)
Hi all, I have the following simplified main code that reads a collection of .ply files resulting from a custom scene: point_clouds is std::vector<std::shared_ptr>
where :
With the parent CMakelists.txt adding the kiss_icp project:
The problem is when I execute the binary it yields a "segmentation fault error" and std::cout << "RegisterFrame returned." << std::endl; is never displayed
Gdb code:
Any idea? Thank you very much