Skip to content

range_sensor_layer don’t use clear_threshold to clear master grid #51

Open
@PSotiriadis

Description

@PSotiriadis

I use ROS kinetic in order to be able to drive my differential drive robot and I also use range_sensor_layer package (Branch Indigo V0.4.0) in order to be able to use SRF sensors. Recently I noticed that range_sensor_layer, in function RangeSensorLayer::updateCosts() in lines 434-437, updates master grid cells for clearing, only if old_cost is NO_INFORMATION (if current=FREE_SPACE=0 then old_cost can never be smaller than current, because old_cost is an unsighned char and cannot be negative)

void RangeSensorLayer::updateCosts(costmap_2d::Costmap2D& master_grid, int min_i, int min_j, int max_i, int max_j)
{
  if (!enabled_)
    return;

  unsigned char* master_array = master_grid.getCharMap();
  unsigned int span = master_grid.getSizeInCellsX();
  unsigned char clear = to_cost(clear_threshold_), mark = to_cost(mark_threshold_);

  for (int j = min_j; j < max_j; j++)
  {
    unsigned int it = j * span + min_i;
    for (int i = min_i; i < max_i; i++)
    {
      unsigned char prob = costmap_[it];
      unsigned char current;
      if(prob==costmap_2d::NO_INFORMATION){
        it++;
        continue;
      }
      else if(prob>mark)
        current = costmap_2d::LETHAL_OBSTACLE;
      else if(prob<clear)
        current = costmap_2d::FREE_SPACE;
      else{
        it++;
        continue;
      }

      unsigned char old_cost = master_array[it];

      if (old_cost == NO_INFORMATION || old_cost < current)
        master_array[it] = current;
      it++;
    }
  }

  buffered_readings_ = 0;
  current_ = true;
}

But what happened if master grid old_cost is not NO_INFORMATION(255) and current=FREE_SPACE (0)?? Is that not possible?? Because if it’s possible, we ignore completely this case and that may cause errors. In this case maybe a possible solution is something like this (but it is not tested):

void RangeSensorLayer::updateCosts(costmap_2d::Costmap2D& master_grid, int min_i, int min_j, int max_i, int max_j)
{
  if (!enabled_)
    return;

  unsigned char* master_array = master_grid.getCharMap();
  unsigned int span = master_grid.getSizeInCellsX();
  unsigned char clear = to_cost(clear_threshold_), mark = to_cost(mark_threshold_);

  for (int j = min_j; j < max_j; j++)
  {
    unsigned int it = j * span + min_i;
    for (int i = min_i; i < max_i; i++)
    {
      unsigned char prob = costmap_[it];
	  unsigned char old_cost = master_array[it];
      unsigned char current;
      if(prob==costmap_2d::NO_INFORMATION){
        it++;
        continue;
      }
      else if(prob>mark){
        current = costmap_2d::LETHAL_OBSTACLE;
	if (old_cost == NO_INFORMATION || old_cost < current){
		master_array[it] = current;
	}
	it++;
      }
      else if(prob<clear){
        current = costmap_2d::FREE_SPACE;
	if (old_cost > current){
		master_array[it] = current;
	}
	it++;
      }
      else{
        it++;
        continue;
      }
    }
  }

  buffered_readings_ = 0;
  current_ = true;
}

In addition, I want to highlight another two points of range_sensor_layer source code.
First, in function RangeSensorLayer::processVariableRangeMsg() in line 231, it is critical programming to compare if two float values are equal.

  if (range_message.range == range_message.max_range && clear_on_max_reading_)
    clear_sensor_cone = true;

A better way to do that (considering float A and float B) is:

if ( fabs( A - B ) < limit_value )

where limit_value indicates the desired decimal position, in which we want if-statement to compare A and B equality .

And second, I want to ask if it is possible to define a parameter, in order to be able to configure how long we want to wait for transform in line 245 (now is used a fix value of 0.1(100msec))

  if(!tf_->waitForTransform(global_frame_, in.header.frame_id, in.header.stamp, ros::Duration(0.1)) )
  {
    ROS_ERROR_THROTTLE(1.0, "Range sensor layer can't transform from %s to %s at %f",
        global_frame_.c_str(), in.header.frame_id.c_str(),
        in.header.stamp.toSec());
    return;
  }

Thanks in advance

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions