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

tf_prefix in fake_localization and move_base

asked 2014-01-29 10:56:10 -0500

Constantin S gravatar image

updated 2014-01-29 18:28:40 -0500

ahendrix gravatar image

I've been examining a strange issue with multiple robots in stage and move_base. Move_base and costmap2D use tf::resolve with tf_prefix to resolve global frames. However fake_localization does not - this leads to the message:

Waiting on transform from robot_0/base_link to robot_0/map to become available before running costmap, tf error:

A few people have had trouble with this. I have examined fake_localization and I believe the following lines (as done in costmap_2d_ros.cpp) need to be added:

// get our tf prefix
ros::NodeHandle prefix_nh;
std::string tf_prefix = tf::getPrefixParam(prefix_nh);
global_frame_id_ = tf::resolve(tf_prefix, global_frame_id_);
base_frame_id_ = tf::resolve(tf_prefix, base_frame_id_);
odom_frame_id_ = tf::resolve(tf_prefix, odom_frame_id_);

Furthermore I had another problem in move_base. tf_prefix is resolved too many times in the Costmap2D and NavFN. Here is the exact situation in navfn_ros.cpp::makePlan()

ros::NodeHandle n;
costmap_2d::Costmap2D* costmap = costmap_ros_->getCostmap();
std::string global_frame = costmap_ros_->getGlobalFrameID();

//until tf can handle transforming things that are way in the past... we'll require the goal to be in our global frame
if(tf::resolve(tf_prefix_, goal.header.frame_id) != tf::resolve(tf_prefix_, global_frame)){
  ROS_ERROR("The goal pose passed to this planner must be in the %s frame.  It is instead in the %s frame.", tf::resolve(tf_prefix_, global_frame).c_str(), tf::resolve(tf_prefix_, goal.header.frame_id).c_str());
  return false;

if(tf::resolve(tf_prefix_, start.header.frame_id) != tf::resolve(tf_prefix_, global_frame)){
  ROS_ERROR("The start pose passed to this planner must be in the %s frame.  It is instead in the %s frame.", tf::resolve(tf_prefix_, global_frame).c_str(), tf::resolve(tf_prefix_, start.header.frame_id).c_str());
  return false;

What happens is that global_frame has already been resolved (removed preceding slash) inside the Costmap2D class. Now we resolve again, and since the slash is gone it appends the prefix. Thus we get /robot_0/robot_0/map I do not have a solution for this as I expect that this might be done on purpose?

Are there any thoughts on the problems presented here and a possible solution to the over resolving? Thanks!

Here's an example launch file for one robot of a multi robot stage sim. Note that under fake_localization I can adjust the global_frame_id via parameter. However, this is a hacky fix.

  <!-- BEGIN ROBOT 0 -->
  <group ns="robot_0">
    <param name="tf_prefix" value="robot_0"></param>

    <arg default="$(find some_path)/launch/move_base_config/cost_map.yaml" name="map_file">
    <node args="$(arg map_file)" name="map_server" pkg="map_server" type="map_server">
        <param name="frame_id" value="map"></param>

    <node name="fake_localization" output="screen" pkg="fake_localization" respawn="false" type="fake_localization">
        Uncomment here for success - without making above changes
      <!--param name="global_frame_id" value="/robot_0/map"/-->
       <param name="global_frame_id" value="map"></param> Need this to be in a relative frame

    <node name="move_base_node" output="screen" pkg="move_base" respawn="false" type="move_base">
      <param name="controller_frequency" value="10.0"></param>
      <param name="recovery_behavior_enabled" value="true"></param>
      <param name="oscillation_timeout" value="5.0"></param>
      <param name="oscillation_distance" value="1.0"></param>
      <rosparam command="load" file="$(find some_path)/launch/move_base_config/costmap_common_params.yaml" ns="global_costmap">
      <rosparam command ...
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2014-01-29 18:28:21 -0500

ahendrix gravatar image

As far as I'm aware, tf_prefix isn't supported any more, and has been removed or deprecated in tf2.

From what I understand, most packages (something like 80-90%) didn't use it, and of the packages that did try to use it, most of the didn't use it correctly, so it was dropped.

edit flag offensive delete link more


Well that's good to know - is this documented anywhere? Also what's the new approach for having multiple robots in stage with move_base? Also while deprecated, it still seems to be used in the navigation_stack.

Constantin S gravatar image Constantin S  ( 2014-01-30 05:13:54 -0500 )edit

For the change in tf2, it's documented in the migration doc.

130s gravatar image 130s  ( 2015-06-29 19:48:47 -0500 )edit

Question Tools

1 follower


Asked: 2014-01-29 10:56:10 -0500

Seen: 2,280 times

Last updated: Jan 29 '14