Calculation of Hand-Eye Calibration Residual and PoseError

General Information

  • Product: N36-604-16 BL
  • Ensenso SDK Version: 3.6.1617
  • Operating System: Windows

Problem / Question

I have two questions regarding the Result of the Hand-Eye Calibration.

  1. In the documentation, the Residual is explained as “The residual of the final solution.”.

- → How is the residual calculated and what unit does it have?

  1. In the documentation, the PoseError is explained as “… the difference between the pattern’s position estimated through the camera and the pattern pose estimated by the calibration over the robot position.”

- → Can you clarify that? I understand, that the PatternPose (which is also a parameter of the Result) is estimated globally (how? maybe by averaging all camera pattern poses?), and then for each image, the pattern pose is estimated from the image and the PoseError is the difference between the two. Is that correct?

Hi @SvenJoe ,

this is indeed a bit vague in the manual:

  • Residual is simply the norm of the optimizer; in ancient SDK releases this used to be the reprojection error of all pattern points, in current major sdk releases (at least since 3.x) we switched to optimizing the euclidean distance between the fitted calibration object and each observed calibration object long time ago. The coordinates are in millimeters internally, but I’m not sure if this output is correctly normalized though, maybe you shouldn’t rely on this.
  • PoseError is an array of transformations between the fitted, final pose of the calibration object, and each observed calibration object pose (by chaining each of the robot poses with the (single) estimated camera/hand transformation, and each camera-to-“observed calibration plate” transformation)

All calibration target poses are anchored in the middle of the dot grid, so the poses in ‘PoseError’ also relate to the center of the calibration plate.

Hope that shed some light on the outputs… otherwise let me know if that still unclear.

best regards, Rainer

Hi Rainer,

thank you for the explanation!

So from the PatternPose and the Poses within the Results it should be possible to recalculate all those values and check, if the Residual is properly normalized. I will try that to be sure about the Residual.

Hi Sven,

if I’m not mistaken and interpret the code correctly, you should be able to reproduce the ‘Residual’ by stacking all n translation residuals from the ‘PoseError’ array into a 3 n long vector v, and then ‘Residual’ should be \frac{1}{\sqrt{ 3 n}} \lvert v \rvert ^2 .

Let me know if that works, otherwise we’ll have to dig a little deeper.

Hi Rainer,

I tried your formula and for my data, if I use the translation vectors from PoseError, I get 0.330776, but the residual from the SDK is 0.356763. So something is a little off. Can you dig deeper?

Cheers

Sven