# Compute tranformation matrix for odom to base_link depending on tracking camera attached relative to base_link

To complete my tf tree, I must broadcast transformation from odom to base_link. I am receiving position from the tracking camera, which is attached to the camera mount relative to base_link. So, I have a pose from the tracking_camera_frame and I know static transform between base_link and tracking_camera_frame

map
|
|
odom
|
| ?
+------base_link
|
|
+----camera_mount
|
+----tracking_camera_frame


I don't know how to express the transformation odom to base_link if I have two mentioned transformations.

When I read about it on the internet, there is always only an example that with multiplication, you can express a point from one coordinate system relative to another.

However, I probably found a solution in the ZED wrapper for ROS, but I don't understand it.

tf2::Transform deltaOdomTf_base = mSensor2BaseTransf.inverse() * deltaOdomTf * mSensor2BaseTransf;


According to this, my example should be

odom_to_base_link = base_link_to_tracking_camera_frame.inverse() * pose * base_link_to_tracking_camera_frame


I would like to understand the background of this calculation. Why is it so, or what is the correct form?

Update:

I asked chatGPT, and it told me that for equation resultTF = deltaTF^-1 * pose * deltaTF, the deltaTF will be effectively cancelled, and the result will be directly related to parent TF. It is what I want. However, what is the mathematical background of this? I want to understand it step by step. It looks like resultTF == pose, but this is not true. So why must these matrices be applied in this order?

## 1 Answer

One way is with a utility node I made called 'old_tf_to_new_tf' which is configured with four frames: lookup_parent lookup_child, broadcast_parent, and broadcast_child- the first 3 need to exist in your system already, there needs to be an existing chain of transforms between the two lookup frames (they can be parents/childs/distant cousins in either position as long as there is a connection), then broadcast_child is published by the old_tf_to_new_tf node.

For your case you would want a second tracking_camera_frame, call it tracking_camera_frame_zed or something else distinct from the one that probably came out of your urdf or similar, and configure the zed node to publish 'odom -> tracking_camera_frame_zed' when it does visual odometry (or whatever, just assuming that based on your reference to zed cameras). Then the old to new tf node would have:

lookup_parent:=tracking_camera_frame
lookup_child:=base_link
broadcast_parent:=tracking_camera_frame_zed
broadcast_child:=base_link


It does a lookup transform with the two lookup frames, then re-publishes the returned transform out but with the provided broadcast parent and child frames replacing the looked-up ones, mirroring the transform from one part of a tree to another part.

https://github.com/lucasw/tf_demo/blob/old_tf_to_new_tf/src/old_tf_to_new_tf.cpp

There's an example launch file in the package too, trying that out and looking at the tf tree in rviz may help it more clear.

It's possible to call it directly inside your C++ node (it sounds like you have one) instead of having a separate node, make your own CopyTransform instance like in the cpp source linked to above.