How to convert gmapping datas into a new frame with a different resolution ?

asked 2018-08-16 08:51:23 -0500

Delb gravatar image

updated 2018-08-17 03:27:35 -0500

Hi all,

I want to create a new map according to the data from the map generated by the gmapping but according to the robot position and orientation and other specifications, I'm going to explain exactly what I want. So here's the initial situation : image description

This new map must respect those rules :

  • It has to encompass the gmapping map.
  • It has a much bigger resolution (lets say 3meters) and the current position of the robot must be the coordinate of one a the new cells (meaning the robot has to be aligned on the bottom right of a cell because the new map is generated according to its position). I draw a little example where the grid you see represents all the cells of the new map :

image description

  • I set the values in NewOccupancyGrid.data according to the ones from the gmapping map : With a for loop I check all the cells value (from gmapping map) and increment different counters (one counter for each of the corresponding cell of my new map) whenever a cell equal -1 (UNKNOWN) or 100 (OBSTACLE) and if a counter exceeds a value I consider that my new cell is occupied.

Here is the code for this part it might help you see what I'm doing :

std::vector<double> unknown_counter(tile_map_size);
std::vector<double> obstacle_counter(tile_map_size);
std::vector<double> free_counter(tile_map_size);
std::vector<double> number_cells(tile_map_size);

float x_from_map_origin = 0.0;
float y_from_map_origin = 0.0;
int tile_index = 0;
for (int map_row = 0; map_row < map_metadata.width; map_row++)
   {
    for (int map_column = 0; map_column < map_metadata.height; map_column++)
    {
          number_cells[tile_index] += 1;
          x_from_map_origin = map_metadata.origin.position.x + map_row * map_metadata.resolution;
          y_from_map_origin = map_metadata.origin.position.y + map_column * map_metadata.resolution;
          tile_index = floor((x_from_map_origin - tile_map_metadata.origin.position.x)/tile_length_) + floor((y_from_map_origin - tile_map_metadata.origin.position.y)/tile_length_) * tile_map_metadata.width;

          if (occupancy_grid_temp.data[map_row + map_column*map_metadata.width] == OCCUPIED_CELL)
          {       
                obstacle_counter[tile_index] += 1;
          }
          else if (occupancy_grid_temp.data[map_row + map_column*map_metadata.width] == UNKNOWN_CELL)
          {
               unknown_counter[tile_index] += 1;
           }
           else 
           {
                free_counter[tile_index] += 1;
           }
       }
}
std::vector<int8_t> vect(tile_map_size);
tile_map_occupancy_grid.data = vect;
tile_map_occupancy_grid.info = tile_map_metadata;
for (int tile_map_index = 0; tile_map_index < tile_map_size; tile_map_index++)
{
       //If there is more than 80% of obstacles
       if (100*obstacle_counter[tile_map_index]/number_cells[tile_map_index] > 80)
       {
            tile_map_occupancy_grid.data[tile_map_index] = 100;
       }
       //if there's at least 20% of space
       else if (100*free_counter[tile_map_index]/number_cells[tile_map_index] > 20)
       {
            tile_map_occupancy_grid.data[tile_map_index] = 0;
       }
       else
       {
            tile_map_occupancy_grid.data[tile_map_index] = 50;
       }
}

I'm currently able to get to this result because I'm launching my node before the robot moves so the odom and map frames are aligned. My problem is now to get to this result : image description

If I move the robot before creating the new map (and that will happen), since the orientation has changed it makes all the situation a lot more complex. So I have these questions :

  • Is it possible when I'm launching my node to change the gmapping orientation (I don't care about position it's only an offset) to have the value of the occupancy grid aligned with my new occupancy grid so that I can use the same algorithm ...
(more)
edit retag flag offensive close merge delete