MegviiRobot / CamLaserCalibraTool

Extrinsic Calibration of a Camera and 2d Laser
BSD 3-Clause "New" or "Revised" License
661 stars 200 forks source link

One D laser calibration #10

Open JadTawil-theonly opened 4 years ago

JadTawil-theonly commented 4 years ago

What do you think would happen if this calibration method was used on a 1D laser range finder and camera?

So that each observation contains the pose of the calibration pattern, as well as a single vector (0, 0, d) from the single range finder.

The PointInPlaneFactor still applies to this case.

JadTawil-theonly commented 4 years ago

Its a different problem, because the rotation of the laser scanner on its own axis does not matter at all, so its an optimization over 3 translation parameters, and 2 rotation parameters (not 3).

HeYijia commented 4 years ago

Yes, you are right. In addition, you can use the simulation code I provided to verify your conclusion. You will find a nullspace base that shows the system has an unobservable angle.

JadTawil-theonly commented 4 years ago

Hey HeY,

I replaced the following code:


    for (size_t j = 0; j < 180; j++)
    {
      double theta = -M_PI_2 + j * M_PI/180;
      Eigen::Vector3d ray(cos(theta), sin(theta), 0);
      double depth = -d/(ray.dot(n));

      if( std::isnan(depth) || depth < 0)
        continue;

      Eigen::Vector3d p = depth * ray;

      // valid laser points
      if( std::fabs(p.x()) < 5 && std::fabs(p.y()) < 5)
      {
          points.push_back(p);
      }
      // std::cout << p.transpose() << std::endl;
    }

With

double theta = 0.0;

    //Eigen::Vector3d ray(cos(theta), sin(theta), 0);
    Eigen::Vector3d ray(cos(theta), sin(theta), 0);
    double depth = -d/(ray.dot(n));
    if( std::isnan(depth) || depth < 0)
      continue;

    Eigen::Vector3d p = depth * ray;

    // valid laser points
    if( std::fabs(p.x()) < 5 && std::fabs(p.y()) < 5)
    {
        points.push_back(p);
    }

So that for each camera pose, there is 1 ray, at 0 theta (simulating the 1D laser case).

The following is the result:


============= Ground Truth of Rotation and translation =============== 
 0  0  1
-1  0  0
 0 -1  0
0.1
0.2
0.3
   roll(rad): -1.5708 pitch(rad): 0 yaw(rad): -1.5708
or roll(deg): -90 pitch(deg): 0 yaw(deg): -90
       tx(m): 0.1  ty(m): 0.2   tz(m): 0.3
============= End =============== 
obs size: 1329
----- H singular values--------:
1230.97
1121.64
1034.39
15.7625
13.9415
      0
====== null space basis, it's means the unobservable direction for Tcl ======
       please note the unobservable direction is for Tcl, not for Tlc        
0
0
0
1
0
0

recover chi2: 5.39867e-22

----- Transform from Camera to Laser Tlc is: -----

-5.14566e-13 -5.31309e-13            1          0.1
  -0.0596479     0.998219  4.99664e-13    -0.287536
   -0.998219   -0.0596479 -5.45475e-13     0.217538
           0            0           -0            1

----- Transform from Camera to Laser, euler angles and translations are: -----

   roll(rad): -1.5708 pitch(rad): 1.51111 yaw(rad): -1.5708
or roll(deg): -90 pitch(deg): 86.5804 yaw(deg): -90
       tx(m): 0.1  ty(m): -0.287536   tz(m): 0.217538

Notice that while 1 degree is not observable, the estimated parameters are unfortunately not accurate. What do you think?

JadTawil-theonly commented 4 years ago

I have managed to solve the problem. The optimization was formulated differently. I have created a branch. If you would like, i can certainly make it available to you!