understanding tf transform

asked 2021-04-20 16:50:48 -0500

Eman.m gravatar image


I am running simulated Rosbot2 in Gazebo. I have a static map for the world.

I understand that I must provide transformation: map to odom, odom to base_link, base_link to laser

I have the following lines in my navigation launch file:

    <arg name="use_rosbot" default="false"/>
    <arg name="use_gazebo" default="true"/>
    <param if="$(arg use_gazebo)" name="use_sim_time" value="true"/>
<!-- Bring the ROSbot model and show it in Gazebo and in Rviz  -->
    <include file="$(find rosbot_description)/launch/rosbot_rviz.launch"/>
<!-- Map server -->
    <arg name="map_file" default="$(find rosbot_navigation)/maps/willowgarage-refined.yaml"/>
    <node name="map_server" pkg="map_server" type="map_server" args="$(arg map_file)" />
<!--- tf -->
    <node unless="$(arg use_rosbot)" pkg="tf" type="static_transform_publisher" name="map_odom_tf" args="0 0 0 0 0 0 map odom 100" /> 
    <node if="$(arg use_rosbot)" pkg="tf" type="static_transform_publisher" name="base_link_to_laser" args="0 0 0 3.14 0 0 base_link laser 100" />

    <node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher">
    <param name="publish_frequency" type="double" value="30.0" />
<!--- Localization: Run AMCL -->
  <node pkg="amcl" type="amcl" name="amcl" output="screen">
        <remap from="scan" to="/scan"/>
        <param name="odom_frame_id" value="odom"/>
        <!-- <param name="odom_model_type" value="diff-corrected"/> --> 
        <param name="odom_model_type" value="diff"/>
        <param name="base_frame_id" value="base_link"/>
        <param name="update_min_d" value="0.05"/>
        <param name="update_min_a" value="0.1"/>
        <param name="min_particles" value="500"/>
        <param name="max_particles" value="10000"/>
        <param name="initial_pose_x" value="0"/>
        <param name="initial_pose_y" value="0"/>
<!-- Move base -->
    <node pkg="move_base" type="move_base" name="move_base" output="screen">
        <param name="base_global_planner" value="navfn/NavfnROS"/>
        <param name="base_local_planner" value="base_local_planner/TrajectoryPlannerROS"/>
        <param name="controller_frequency" value="10.0"/>
        <rosparam file="$(find rosbot_navigation)/config/costmap_common_params.yaml" command="load" ns="global_costmap" />
        <rosparam file="$(find rosbot_navigation)/config/costmap_common_params.yaml" command="load" ns="local_costmap" />
        <rosparam file="$(find rosbot_navigation)/config/local_costmap_params.yaml" command="load" />
        <rosparam file="$(find rosbot_navigation)/config/global_costmap_params.yaml" command="load" />
        <rosparam file="$(find rosbot_navigation)/config/trajectory_planner.yaml" command="load" />

what I need to understand is:

1- there are (map to odom) and (base_link to laser) in the lanuch file, but how can I set (odom to base_link)?

2- should I include all these 3 transforms in "simulated robot" and in "real robot"?

Thanks ,,,

edit retag flag offensive close merge delete


This feels like a duplicate of Question # 104111 so I would start by referring there. I would suggest updating your question if you feel this previous answer doesn't help you.

shonigmann gravatar image shonigmann  ( 2021-04-20 18:43:24 -0500 )edit

The answer clarifies some points. The answer means that odom to base_link is always fixed and no need for transform? correct me please if I am mistaken.

Is it the case for both simulated and real robot?

Eman.m gravatar image Eman.m  ( 2021-04-22 15:36:33 -0500 )edit

Not quite. odom -> base_link is only fixed if the robot itself is fixed (e.g. think of an industrial robot arm that is bolted down to the ground). In the case of mobile robots, the odom -> base_link transform represents the robot's best guess at where it currently is in its own idea of the environment. This will change as the robot moves around the environment.

shonigmann gravatar image shonigmann  ( 2021-04-22 16:39:12 -0500 )edit

I like to think of the transforms as follows:

map -> base_link : where the robot actually is. If you had a magic sensor that gave you perfect measurements of where your robot is in the world, this would be that transformation

odom -> base_link : where your robot thinks it is. odometry is imperfect. you may tell the robot to go forward 1 m and maybe it only goes 0.9m. Your odom -> base_link transform will say 1 m because that is what your robot thinks it did, until you take other measurements into account to correct that bad guess.

map -> odom : this is where the magic happens when you use a localization algorithm like amcl. It takes sensor data and estimates the difference between the map ('real world coordinates') and the odometry ('robot's best guess') and adjusts the map->odom transformation accordingly.

shonigmann gravatar image shonigmann  ( 2021-04-22 16:41:26 -0500 )edit

Thanks shonigmann . so we can say odom -> base_link is not exact, it is the robot's best guess,

"Odom -> base link transform is updated from continuously sampled data and describes where you are relative to where you started (within that odom frame)." from https://www.reddit.com/r/ROS/comments... so what do they mean by "continuously sampled data"

Eman.m gravatar image Eman.m  ( 2021-04-22 17:41:50 -0500 )edit

It really depends on the specific implementation. In the simplest case (think a simple differential drive robot) it could be that wheel encoders are continuously read and used to identify how the robot's position changed from its initial position.

shonigmann gravatar image shonigmann  ( 2021-04-22 17:46:17 -0500 )edit