ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
3

robot_localization Map, Odom, and drift.

asked 2016-10-05 15:39:45 -0600

Nocare gravatar image

updated 2016-10-19 14:06:58 -0600

So we have a robot that uses the Odom frame to navigate using an IMU and 4 encoders. We have a Map frame that also receives gps input on top of the filtered output from the first localization node. As expected the position of the robot relative to 0,0 drifts over time in the Odom frame makeing it eventually useless if I wanted to drive back to say 0,0 and be in the same real world location that the robot started. As I understand it the purpose of the Map frame is to provide location data that can be used to correct for this drift however beacuse of its noisy nature for very short movements its unsuitable for navigation thus the existence of Odom.

My problem is I don't know how to correct the robots location in Odom using date from the Map frame. My expectation based on what knowledge I do have is that there would be a method to input date from Map whenever the positions varies by more than a certain amount thus preventing the drift from growing larger without bound but also allowing for the continuous nature of Odom. This wouldn't prevent drift just bound it by the noise level of your Maps accuracy. Thus also allowing the fine small movement that Odom is used for such as driving forward 1 meter without jumping all round the point as you try to do so.

Can someone tell me how to do this or if I am completely off base how this problem should be approached.

EDIT: To get clarification the amcl package can use a map generated by robot_localization and an odom_frame generated by robot localization devoid of any laser based data whatsoever? I ask beacuse the code and wiki info on amcl make it sound like it only works if the map was generated using laser data rather then just being a map_frame that is nothing more than the robots current location in either frame and needing a transform between the two frames positions.

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
5

answered 2016-10-05 22:24:15 -0600

Shay gravatar image

For ROS navigation, there is a tf tree map->odom->base_link. The odom pose is the base_link frame pose relative to odom frame. The absolute/global pose is the base_link frame pose relative to map frame.

IMU and encoders provide the odom pose which drifts over time and thus only right for a short time.

GPS, amcl and indoor position system provide the absolute/global pose.

You got odom pose means you got the tf odom->base_link, and you got absolute/global pose means you got base_link pose relative to map. To correct the robot location, you have to provide the tf map->odom, which can be calculated from odom->base_link and base_link pose relative to map.

For details about how to get map->odom, you can refer to amcl wiki and amcl source.

The amcl code about map->odom(only the key part):

  // subtracting base to odom from map to base and send map to odom instead
  tf::Stamped<tf::Pose> odom_to_map;
  try
  {
    tf::Transform tmp_tf(tf::createQuaternionFromYaw(hyps[max_weight_hyp].pf_pose_mean.v[2]),
                         tf::Vector3(hyps[max_weight_hyp].pf_pose_mean.v[0],
                                     hyps[max_weight_hyp].pf_pose_mean.v[1],
                                     0.0));
    tf::Stamped<tf::Pose> tmp_tf_stamped (tmp_tf.inverse(),
                                          laser_scan->header.stamp,
                                          base_frame_id_);
    this->tf_->transformPose(odom_frame_id_,
                             tmp_tf_stamped,
                             odom_to_map);
  }
  catch(tf::TransformException)
  {
    ROS_DEBUG("Failed to subtract base to odom transform");
    return;
  }

  latest_tf_ = tf::Transform(tf::Quaternion(odom_to_map.getRotation()),
                             tf::Point(odom_to_map.getOrigin()));
  latest_tf_valid_ = true;

  if (tf_broadcast_ == true)
  {
    // We want to send a transform that is good up until a
    // tolerance time so that odom can be used
    ros::Time transform_expiration = (laser_scan->header.stamp +
                                      transform_tolerance_);
    tf::StampedTransform tmp_tf_stamped(latest_tf_.inverse(),
                                        transform_expiration,
                                        global_frame_id_, odom_frame_id_);
    this->tfb_->sendTransform(tmp_tf_stamped);
    sent_first_transform_ = true;
  }
edit flag offensive delete link more

Comments

So ive been reading up on amcl, I had seen it in a lot of other posts before I even made this one. However I have to verify it is able to do the calculation for the robot_localization package''s EKF output rather than using its own map and odom systems? Its difficult to tell from the wiki pages.

Nocare gravatar image Nocare  ( 2016-10-08 08:28:07 -0600 )edit

It also states that its only setup to work with a laser map and laser scans which is why I ignored it first time through.

Nocare gravatar image Nocare  ( 2016-10-08 08:32:04 -0600 )edit

Question Tools

Stats

Asked: 2016-10-05 15:39:45 -0600

Seen: 4,704 times

Last updated: Oct 19 '16