From d852c92f62d59d6d8c1cddb3a3205d76a0449c5e Mon Sep 17 00:00:00 2001
From: joanvallve <jvallve@iri.upc.edu>
Date: Wed, 26 Jun 2024 13:07:06 +0200
Subject: [PATCH] improved icp test

---
 test/gtest_icp.cpp | 187 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 149 insertions(+), 38 deletions(-)

diff --git a/test/gtest_icp.cpp b/test/gtest_icp.cpp
index b79c7a0..a633fdc 100644
--- a/test/gtest_icp.cpp
+++ b/test/gtest_icp.cpp
@@ -25,6 +25,9 @@
 
 using namespace laserscanutils;
 
+int N = 50;
+int n_attempts = 5;
+
 const Eigen::Vector2d A = Eigen::Vector2d::Zero();
 const Eigen::Vector2d B = (Eigen::Vector2d() << 0, 40).finished();
 const Eigen::Vector2d C = (Eigen::Vector2d() << 30, 0).finished();
@@ -243,7 +246,7 @@ TEST(TestIcp, TestGenerateRandomPose)
   LaserScanParams scan_params = generateLaserScanParams(-180, 1);
 
   // 100 random poses and scans
-  for (auto i = 0; i < 100; i++)
+  for (auto i = 0; i < N; i++)
   {
     auto laser_pose = generateRandomPoseInsideTriangle();
     ASSERT_TRUE(insideTriangle(laser_pose));
@@ -256,8 +259,9 @@ TEST(TestIcp, TestIcpSame1)
 {
   // -180,180 (1 degrees step)
   LaserScanParams scan_params = generateLaserScanParams(-180, 1);
+  double pert = 0.0;
 
-  for (auto i = 0; i < 10; i++)
+  for (auto i = 0; i < N; i++)
   {
     auto pose = generateRandomPoseInsideTriangle();
     auto scan = simulateScan(pose, scan_params);
@@ -266,34 +270,54 @@ TEST(TestIcp, TestIcpSame1)
     auto icp_params = icp_params_default;
 
     // no perturbation
-    std::cout << "//////////// TestIcpSame1: random problem " << i << " pose: " << pose.transpose() << std::endl;
-    std::cout << "//////////// NO perturbation" << std::endl;
+    std::cout << "\n//////////// TestIcpSame1: random problem " << i << " pose: " << pose.transpose() << std::endl;
+    std::cout << "------ NO perturbation" << std::endl;
     auto icp_output = ICP::align(scan,
                                  scan,
                                  scan_params,
                                  icp_params,
                                  Eigen::Vector3d::Zero());
 
+    std::cout << "  icp_output:   " << icp_output.res_transf.transpose() << std::endl;
+    std::cout << "  icp error:    " << icp_output.error << std::endl;
+    std::cout << "  icp valid:    " << icp_output.valid << std::endl;
+
     ASSERT_TRUE(icp_output.valid);
     EXPECT_MATRIX_APPROX(icp_output.res_transf, Eigen::Vector3d::Zero(), 1e-1);
 
     // perturbation
-    std::cout << "//////////// WITH perturbation" << std::endl;
+    std::cout << "------ WITH perturbation: " << pert << std::endl;
+    Eigen::Vector3d initial_guess = Eigen::Vector3d::Random() * pert;
+    int n = 1;
     icp_output = ICP::align(scan,
                             scan,
                             scan_params,
                             icp_params,
-                            Eigen::Vector3d::Random() * 0.1);
+                            initial_guess);
 
-    if (not icp_output.valid)
+    while (not icp_output.valid or icp_output.error > 1e-1)
+    {
+      n++;
+      initial_guess = Eigen::Vector3d::Random() * pert;
       icp_output = ICP::align(scan,
                               scan,
                               scan_params,
                               icp_params,
-                              Eigen::Vector3d::Random() * 0.1);
+                              initial_guess);
+      if (n == n_attempts)
+        break;
+    }
+
+    std::cout << "  initial_guess: " << initial_guess.transpose() << std::endl;
+    std::cout << "  icp_output:    " << icp_output.res_transf.transpose() << std::endl;
+    std::cout << "  icp error:     " << icp_output.error << std::endl;
+    std::cout << "  icp valid:     " << icp_output.valid << std::endl;
+    std::cout << "  icp attempts:  " << n << std::endl;
 
     ASSERT_TRUE(icp_output.valid);
     EXPECT_MATRIX_APPROX(icp_output.res_transf, Eigen::Vector3d::Zero(), 1e-1);
+
+    pert += 0.5 / N;
   }
 }
 
@@ -301,44 +325,96 @@ TEST(TestIcp, TestIcpSame2)
 {
   // 0,360 (1 degrees step)
   LaserScanParams scan_params = generateLaserScanParams(0, 1);
+  double pert = 0.0;
 
-  for (auto i = 0; i < 10; i++)
+  for (auto i = 0; i < N; i++)
   {
     auto pose = generateRandomPoseInsideTriangle();
     auto scan = simulateScan(pose, scan_params);
 
     // icp
     auto icp_params = icp_params_default;
+    icp_params.verbose = false;                    //    false, // bool verbose (prints debug messages)
+    icp_params.use_point_to_line_distance = false; //    true,  // bool use_point_to_line_distance
+    //    5.0,   // double max_angular_correction_deg
+    //    1,     // double max_linear_correction
+    //    0.5,   // double max_correspondence_dist
+    icp_params.use_corr_tricks = false;     //    false, // bool use_corr_tricks
+    icp_params.debug_verify_tricks = false; //    false, // bool debug_verify_tricks
+    //    50,    // int max_iterations
+    //    1e-4,  // double epsilon_xy
+    //    1e-3,  // double epsilon_theta
+    icp_params.restart = true;                     //    false, // bool restart
+    icp_params.restart_threshold_mean_error = 0.1; //    0,     // double restart_threshold_mean_error
+    //    0,     // double restart_dt
+    //    0,     // double restart_dtheta
+    //    0.023, // double min_reading
+    //    60,    // max_reading
+    //    1,     // double outliers_maxPerc
+    //    0.8,   // double outliers_adaptive_order
+    //    2,     // double outliers_adaptive_mult
+    //    false, // bool outliers_remove_doubles
+    //    false, // bool do_visibility_test
+    //    false, // bool do_alpha_test
+    //    10,    // double do_alpha_test_thresholdDeg
+    //    0.5,   // double clustering_threshold
+    //    4,     // int orientation_neighbourhood
+    //    false, // bool use_ml_weights
+    //    false, // bool use_sigma_weights
+    //    0.2,   // double sigma
+    //    true,  // bool do_compute_covariance
+    //    5,     // double cov_factor
+    //    2      // double cov_max_eigv_factor
 
     // no perturbation
-    std::cout << "//////////// TestIcpSame1: random problem " << i << " pose: " << pose.transpose() << std::endl;
-    std::cout << "//////////// NO perturbation" << std::endl;
+    std::cout << "\n//////////// TestIcpSame2: random problem " << i << " pose: " << pose.transpose() << std::endl;
+    std::cout << "------ NO perturbation" << std::endl;
     auto icp_output = ICP::align(scan,
                                  scan,
                                  scan_params,
                                  icp_params,
                                  Eigen::Vector3d::Zero());
 
+    std::cout << "  icp_output:   " << icp_output.res_transf.transpose() << std::endl;
+    std::cout << "  icp error:    " << icp_output.error << std::endl;
+    std::cout << "  icp valid:    " << icp_output.valid << std::endl;
+
     ASSERT_TRUE(icp_output.valid);
     EXPECT_MATRIX_APPROX(icp_output.res_transf, Eigen::Vector3d::Zero(), 1e-1);
 
     // perturbation
-    std::cout << "//////////// WITH perturbation" << std::endl;
+    std::cout << "------ WITH perturbation: " << pert << std::endl;
+    Eigen::Vector3d initial_guess = Eigen::Vector3d::Random() * pert;
+    int n = 1;
     icp_output = ICP::align(scan,
                             scan,
                             scan_params,
                             icp_params,
-                            Eigen::Vector3d::Random() * 0.1);
+                            initial_guess);
 
-    if (not icp_output.valid)
+    while (not icp_output.valid or icp_output.error > 1e-1)
+    {
+      n++;
+      initial_guess = Eigen::Vector3d::Random() * pert;
       icp_output = ICP::align(scan,
                               scan,
                               scan_params,
                               icp_params,
-                              Eigen::Vector3d::Random() * 0.1);
+                              initial_guess);
+      if (n == n_attempts)
+        break;
+    }
+
+    std::cout << "  initial_guess: " << initial_guess.transpose() << std::endl;
+    std::cout << "  icp_output:    " << icp_output.res_transf.transpose() << std::endl;
+    std::cout << "  icp error:     " << icp_output.error << std::endl;
+    std::cout << "  icp valid:     " << icp_output.valid << std::endl;
+    std::cout << "  icp attempts:  " << n << std::endl;
 
     ASSERT_TRUE(icp_output.valid);
     EXPECT_MATRIX_APPROX(icp_output.res_transf, Eigen::Vector3d::Zero(), 1e-1);
+
+    pert += 0.5 / N;
   }
 }
 
@@ -350,15 +426,15 @@ TEST(TestIcp, TestIcp1)
   Eigen::Vector3d pose_ref, pose_tar, pose_d, initial_guess;
   LaserScan scan_ref, scan_tar;
 
-  for (auto i = 0; i < 10; i++)
+  double pert = 0.0;
+  for (auto i = 0; i < N; i++)
   {
     // Random problem
     generateRandomProblem(pose_ref, pose_tar, pose_d, scan_params, scan_ref, scan_tar);
 
-    initial_guess = pose_d + 0.2 * Eigen::Vector3d::Random();
-
     // icp
     auto icp_params = icp_params_default;
+    int n = 1;
 
     auto icp_output = ICP::align(scan_tar,
                                  scan_ref,
@@ -366,17 +442,34 @@ TEST(TestIcp, TestIcp1)
                                  icp_params,
                                  initial_guess);
 
-    std::cout << "\n//////////// TestIcp1: random problem " << i << std::endl;
-    std::cout << "   pose_ref:      " << pose_ref.transpose() << std::endl;
-    std::cout << "   pose_tar:      " << pose_tar.transpose() << std::endl;
-    std::cout << "   groundtruth:   " << pose_d.transpose() << std::endl;
-    std::cout << "   initial_guess: " << initial_guess.transpose() << std::endl;
-    std::cout << "   icp_output:    " << icp_output.res_transf.transpose() << std::endl;
-    std::cout << "   icp error:     " << icp_output.error << std::endl;
-    std::cout << "   d error:       " << (pose_d - icp_output.res_transf).transpose() << std::endl;
-    
+    while (not icp_output.valid or icp_output.error > 1e-1)
+    {
+      n++;
+      initial_guess = pose_d + pert * Eigen::Vector3d::Random();
+      icp_output = ICP::align(scan_tar,
+                              scan_ref,
+                              scan_params,
+                              icp_params,
+                              initial_guess);
+      if (n == n_attempts)
+        break;
+    }
+
+    std::cout << "\n//////////// TestIcp1: random problem " << i << " - perturbation: " << pert << std::endl;
+    std::cout << "  pose_ref:       " << pose_ref.transpose() << std::endl;
+    std::cout << "  pose_tar:       " << pose_tar.transpose() << std::endl;
+    std::cout << "  groundtruth:    " << pose_d.transpose() << std::endl;
+    std::cout << "  initial_guess:  " << initial_guess.transpose() << std::endl;
+    std::cout << "  icp_output:     " << icp_output.res_transf.transpose() << std::endl;
+    std::cout << "  icp error:      " << icp_output.error << std::endl;
+    std::cout << "  icp valid:      " << icp_output.valid << std::endl;
+    std::cout << "  icp attempts:   " << n << std::endl;
+    std::cout << "  d error:        " << (pose_d - icp_output.res_transf).transpose() << std::endl;
+
     ASSERT_TRUE(icp_output.valid);
     EXPECT_MATRIX_APPROX(icp_output.res_transf, pose_d, 1e-1);
+
+    pert += 0.5 / N;
   }
 }
 
@@ -388,33 +481,51 @@ TEST(TestIcp, TestIcp10)
   Eigen::Vector3d pose_ref, pose_tar, pose_d, initial_guess;
   LaserScan scan_ref, scan_tar;
 
-  for (auto i = 0; i < 10; i++)
+  double pert = 0.0;
+  for (auto i = 0; i < N; i++)
   {
     // Random problem
     generateRandomProblem(pose_ref, pose_tar, pose_d, scan_params, scan_ref, scan_tar, 10);
 
-    initial_guess = pose_d + 0.2 * Eigen::Vector3d::Random();
+    initial_guess = pose_d + pert * Eigen::Vector3d::Random();
 
     // icp
     auto icp_params = icp_params_default;
+    int n = 1;
 
     auto icp_output = ICP::align(scan_tar,
                                  scan_ref,
                                  scan_params,
                                  icp_params,
                                  initial_guess);
+    while (not icp_output.valid or icp_output.error > 1e-1)
+    {
+      n++;
+      initial_guess = pose_d + pert * Eigen::Vector3d::Random();
+      icp_output = ICP::align(scan_tar,
+                              scan_ref,
+                              scan_params,
+                              icp_params,
+                              initial_guess);
+      if (n == n_attempts)
+        break;
+    }
+
+    std::cout << "\n//////////// TestIcp10: random problem " << i << " - perturbation: " << pert << std::endl;
+    std::cout << "  pose_ref:       " << pose_ref.transpose() << std::endl;
+    std::cout << "  pose_tar:       " << pose_tar.transpose() << std::endl;
+    std::cout << "  groundtruth:    " << pose_d.transpose() << std::endl;
+    std::cout << "  initial_guess:  " << initial_guess.transpose() << std::endl;
+    std::cout << "  icp_output:     " << icp_output.res_transf.transpose() << std::endl;
+    std::cout << "  icp error:      " << icp_output.error << std::endl;
+    std::cout << "  icp valid:      " << icp_output.valid << std::endl;
+    std::cout << "  icp attempts:   " << n << std::endl;
+    std::cout << "  d error:        " << (pose_d - icp_output.res_transf).transpose() << std::endl;
 
-    std::cout << "\n//////////// TestIcp1: random problem " << i << std::endl;
-    std::cout << "   pose_ref:      " << pose_ref.transpose() << std::endl;
-    std::cout << "   pose_tar:      " << pose_tar.transpose() << std::endl;
-    std::cout << "   groundtruth:   " << pose_d.transpose() << std::endl;
-    std::cout << "   initial_guess: " << initial_guess.transpose() << std::endl;
-    std::cout << "   icp_output:    " << icp_output.res_transf.transpose() << std::endl;
-    std::cout << "   icp error:     " << icp_output.error << std::endl;
-    std::cout << "   d error:       " << (pose_d - icp_output.res_transf).transpose() << std::endl;
-    
     ASSERT_TRUE(icp_output.valid);
     EXPECT_MATRIX_APPROX(icp_output.res_transf, pose_d, 1e-1);
+
+    pert += 0.5 / N;
   }
 } //*/
 
-- 
GitLab