Robotics StackExchange | Archived questions

Correct tf-order for odom frame in cartographer

Hi,

I am currently trying to improve the accuracy of the cartographerros by adding an odometry. However, the first result was not very satisfying as the cartographer automatically places the origin of the odom frame directly into the origin of the baselink frame. My first attempt was to create the odom-frame in the robot model and link it to the base_link with the correct frame offset:

image description image description

<robot name="broetje_Prototype_AGV">

  <material name="gray">
    <color rgba="0.7 0.7 0.7 0.5" />
  </material>
  <material name="red">
    <color rgba="1.0 0.0 0.0 1.0" />
  </material>
  <material name="yellow">
    <color rgba="1.0 0.73 0.0 0.5" />
  </material>

  <!--LINK: Map-->
  <!--link name="map">
    <visual>
      <origin rpy="0 0 0" xyz="0 0 0"/>
    </visual>
  </link-->
  <!--JOINT: Odometry-->
  <!--joint name="map_to_odom" type="fixed">
    <parent link="map" />
    <child link="odom" />
    <origin rpy="0 0 0" xyz="0.5 -0.3 0"/>
  </joint-->

  <!--LINK: Odometry-->
  <!--link name="odom">
    <visual>
      <origin rpy="0 0 0" xyz="0 0 0"/>
    </visual>
  </link-->
  <!--JOINT: Base-->
  <!--joint name="odom_to_base" type="fixed">
    <parent link="odom" />
    <child link="base_link" />
    <origin rpy="0 0 0" xyz="-0.5 0.3 0"/>
  </joint-->

  <!--LINK: Base-->
  <link name="base_link">
    <visual>
      <geometry>
        <mesh filename="package://cartographer_ros/meshes/Cobot2019_origin.dae"/>
        <!--box size="1 0.6 0.45"/-->
      </geometry>
      <origin rpy="0 0 0" xyz="0.5 -0.3 0"/>
      <material name="red"/>
    </visual>
  </link>
  <!--JOINT: Safety Scanner 1-->
  <joint name="base_to_scan_1" type="fixed">
    <parent link="base_link" />
    <child link="scan_1" />
    <origin rpy="3.1416 0 2.3561925" xyz="0.055 -0.055 0.18"/>
  </joint>
  <!--JOINT: Safety Scanner 2-->
  <joint name="base_to_scan_2" type="fixed">
    <parent link="base_link" />
    <child link="scan_2" />
    <origin rpy="3.1416 0 -0.7853975" xyz="0.956 -0.556 0.18"/>
  </joint>
  <!--JOINT: Odometry-->
  <joint name="base_to_odom" type="fixed">
    <parent link="base_link" />
    <child link="odom" />
    <origin rpy="0 0 0" xyz="0.5 -0.3 0"/>
  </joint>

  <!--LINK: Safety Scanner 1-->
  <link name="scan_1">
    <visual>
      <geometry>
        <mesh filename="package://cartographer_ros/meshes/sick_scanner_origin.dae"/>
      </geometry>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <material name="yellow"/>
    </visual>
  </link>

  <!--LINK: Safety Scanner 2-->
  <link name="scan_2">
    <visual>
      <geometry>  
        <mesh filename="package://cartographer_ros/meshes/sick_scanner_origin.dae"/>
      </geometry>
      <origin rpy="0 0 0" xyz="0 0 0"/>
      <material name="yellow"/>
    </visual>
  </link>

    <!--LINK: Odometry-->
  <link name="odom">
    <visual>
      <origin rpy="0 0 0" xyz="0.5 -0.3 0"/>
    </visual>
  </link>

</robot>

If I proceed as displayed above, baselink or odom starts jumping around while rotating the AGV. The jumping is not due to the odometry itself. It works with low latency and is quite accurate. Outside the cartographer there are no problems. Also it is sometimes indicated that odom causes a closed-loop, because it seems to be parent of baselink as well. This might be the course of the problem.

I tried to move the odom-frame between the map and the baselink as the cartographer does when the publishodometrie=true option is selected. This of course leads to the odom-frame not moving anymore, because then it has a fixed connection to the map-frame.

At this point, I don't really know how to proceed. Maybe one of you can tell me where the odom frame has to be linked. If there is any information missing, please let me know.

Thanks a lot Tillman

Asked by BATillmanOtt on 2019-12-16 11:30:37 UTC

Comments

I'm not into mobile bases (or navigation), but I do know that odom is not a frame that you put in your robot's model (ie: urdf), but it something produced by localisation packages.

You may want to take a look at REP 105: Coordinate Frames for Mobile Platforms for a general overview.

Perhaps another visitor of this forum can provide a more helpful answer.

Asked by gvdhoorn on 2019-12-16 12:01:16 UTC

Its OK for odom to start the center of the robot on startup. The odom frame is pretty arbitrary and doesn't matter where it is specifically. The point of the odom -> robot transform is to give you a completely smooth, non-cusping, non-jumping relative motion estimation. This is useful if you want instanteous ground speed or acceleration or to compute distance travelled in a local time horizon.

The reason SLAM / localization makes the map->odom is to correct the fact that the odom->robot transform will naturally drift if you don't correct it to be able to be smooth.

Asked by stevemacenski on 2019-12-16 13:18:08 UTC

I calculate the odometry for the middle of the vehicle, because the vehicle rotates around this point. If the odometry frame is at the coordinate origin of the vehicle, the representation of the vehicle rotates around this point and not around the centre of the vehicle. So I assume that i have to define the correct position for the odometry in my urdf file.

Asked by BATillmanOtt on 2019-12-17 03:39:56 UTC

No, that's not how this works.

The odom frame is just a TF frame you publish/broadcast. It doesn't (and shouldn't) be part of the URDF and shouldn't be part of your robot model. It's a frame external to your robot. See also REP 105.

I calculate the odometry for the middle of the vehicle, because the vehicle rotates around this point.

I've often seen base_link placed at the centre of rotation for mobile robots.

Also:

  <link name="odom">
    <visual>
      <origin rpy="0 0 0" xyz="0.5 -0.3 0"/>
    </visual>
  </link>

This doesn't really do what I believe you think it does.

The origin there changes the origin of the visual element, not of the link with the name odom. That is probably not what you wanted to do.

Asked by gvdhoorn on 2019-12-17 03:43:14 UTC

Thank you very much for your explanation, it really helped. If odometry behaves the way you describe it, I would have to place my base_link in the center of rotation of the vehicle. Currently it is always in the middle of the vehicle, but I plan to make it variable. That would be hard to achieve. There must be a possibility to specify a point for the odometry (similar to an IMU or the laser scanners)...

Asked by BATillmanOtt on 2019-12-17 05:28:43 UTC

That shouldn’t be difficult, rigid body transformations and all...

Asked by stevemacenski on 2019-12-17 12:01:24 UTC

Answers