difference between calibration parameters and ros2 tf

Hi,

I have a zed2i camera and tested it with both sdk and ros2 wrapper.

I found one issue regarding zed.get_camera_information().camera_configuration.calibration_parameters.stereo_transform is different from ros2 tf messages.

When I check the stereo_transform with zed sdk, it returns (0.11982602626085281, 0.0, 0.0). But, when I check it with lookup_transform in ros2, I got geometry_msgs.msg.Transform(translation=geometry_msgs.msg.Vector3(x=0.12, y=-3.469446951953614e-17, z=-6.245004513516506e-17), rotation=geometry_msgs.msg.Quaternion(x=0.0, y=0.0, z=0.0, w=1.0)). I know the difference is very small but I would like to know why there is a difference and what value I can trust.

Here, I attached my scripts.

with zed sdk

import pyzed.sl as sl

def main():
    zed = sl.Camera()

    init_params = sl.InitParameters()
    init_params.camera_resolution = sl.RESOLUTION.HD2K 
    init_params.camera_fps = 30 
    init_params.coordinate_units = sl.UNIT.METER

    # Open the camera
    err = zed.open(init_params)
    if err != sl.ERROR_CODE.SUCCESS:
        print("Camera Open : " + repr(err) + ". Exit program.")
        exit()

    calibration_params = zed.get_camera_information().camera_configuration.calibration_parameters

    # left to right camera translation
    print(calibration_params.stereo_transform.get_translation().get()[0])
    print(calibration_params.stereo_transform.get_translation().get()[1])
    print(calibration_params.stereo_transform.get_translation().get()[2])

    zed.close()

if __name__ == "__main__":
    main()

with ros2

import rclpy
from rclpy.node import Node
from tf2_ros import Buffer, TransformListener


class TFInspector(Node):
    def __init__(self):
        super().__init__('tf_inspector')
        self.tf_buffer = Buffer()
        self.tf_listener = TransformListener(self.tf_buffer, self)
        self.timer = self.create_timer(1.0, self.lookup)

    def lookup(self):
        try:
            tf = self.tf_buffer.lookup_transform(
                'zed_left_camera_optical_frame',
                'zed_right_camera_optical_frame',
                rclpy.time.Time()
            )
            self.get_logger().info(f"Transform: {tf.transform}")
        except Exception as e:
            self.get_logger().warn(f"TF lookup failed: {e}")


def main(args=None):
    rclpy.init()
    node = TFInspector()
    rclpy.spin(node)

Hi @jaysong,

Welcome to the forums :waving_hand:

The transform provided by the ZED SDK is the value measured by our factory calibration process, this value should indeed be trusted. The TF value in the ROS2 wrapper appears to be theoretical.

You can make a PR on the zed-ros2-wrapper repository with a fix for this in order to apply to ZED SDK’s calibration extrinsics to the left/right cam TF. I’ll be logging this internally so we can have someone looking into this soon.

Hi @mattrouss

Thank you for the answer. Since I am not familiar with the source code of zed-ros2-wrapper, please update this when you release a next version. I have one further question. The ros2 TF is composed of camera center to left cam and right cam. Then, should the camera center to left cam be still 0.6 or half of the translation provided by ZED SDK?

In this case this would be half the translation provided by the ZED SDK