# Refresh map on navigation

Hello

I'm using the navigation_stack for make a robot move autonomously. So far I've managed to make the robot move and avoid obstacles, but only if I use a reference map. With this reference map, the robot uses the AMCL package and then gets its localization on the map.

What I get now is that the robot go from one point to another without a known map. To fix this, I thought of using a laser to generate a map periodically, and transfer this map to AMCL package.

The problem is that I don't know how to pass the map built to AMCL. I tried to post on the topic /map the information of the constructed map, but then when I visualize it with Rviz see only gray. Besides the move_base package tells me:

Request for map failed, trying again ...

So there's something I'm missing.

Maybe sending the map with the map_server would be easier, but I haven't found documentation of how to use it from the code.

Can anyone tell me how I can transfer this map constructed to navigation_stack? Or if there is an easier way to get what you want.

edit retag close merge delete

Sort by » oldest newest most voted

I found the answer looking into the gmapping code: https://code.ros.org/svn/ros-pkg/stacks/slam_gmapping/tags/slam_gmapping-1.2.5/gmapping/src/slam_gmapping.cpp

    map_.map.info.width = smap.getMapSizeX();
map_.map.info.height = smap.getMapSizeY();
map_.map.info.origin.position.x = xmin_;
map_.map.info.origin.position.y = ymin_;
map_.map.data.resize(map_.map.info.width * map_.map.info.height);

}

for(int x=0; x < smap.getMapSizeX(); x++)
{
for(int y=0; y < smap.getMapSizeY(); y++)
{
/// @todo Sort out the unknown vs. free vs. obstacle thresholding
GMapping::IntPoint p(x, y);
double occ=smap.cell(p);
assert(occ <= 1.0);
if(occ < 0)
map_.map.data[MAP_IDX(map_.map.info.width, x, y)] = -1;
else if(occ > occ_thresh_)
{
//map_.map.data[MAP_IDX(map_.map.info.width, x, y)] = (int)round(occ*100.0);
map_.map.data[MAP_IDX(map_.map.info.width, x, y)] = 100;
}
else
map_.map.data[MAP_IDX(map_.map.info.width, x, y)] = 0;
}
}

//make sure to set the header information on the map

sst_.publish(map_.map);
sstm_.publish(map_.map.info);


I didn't index correctly the data

(MAP_IDX(map_.map.info.width, x, y))

And also I wasn't publishing the metadata info in a separated topic. Thanks Lorenz for the idea ;)

more

Use gmapping or another node for SLAM instead of amcl. gmapping generates a map from laser and odometry data and publishes it on the /map topic so that it can be used by the nav stack.

more

Well, I'm using MRPT for doing the SLAM. The reasons why I use MRPT insted a node of ROS are: 1) The laser I have is a kinect fake laser, and thus the range is only 7 meters. With this reduced range gmapping gives me problems. 2) In the future I want to make a 3D SLAM, and MRPT gives me more tools

( 2012-10-29 21:30:20 -0500 )edit

(continue) How can I publish the data without using gmapping or other node of ROS? I mean, what's the way I should publish the map info for making the navigation stack get the map?

( 2012-10-29 21:36:06 -0500 )edit
1

You basically do the same as gmapping does, i.e. publish a map on the /map topic and publish the /map -> /odom transform for the robot position. (You might have /map -> /base_link internally and need to transform that). Do not start AMCL in that case.

( 2012-10-30 00:36:41 -0500 )edit