amcl 似然域概率模型

1.首先定义一些变量

  AMCLLaser *self;
  int i, j, step;
  double z, pz;
  double log_p;
  double obs_range, obs_bearing;
  double total_weight;
  pf_sample_t *sample;
  pf_vector_t pose;
  pf_vector_t hit;

  self = (AMCLLaser*) data->sensor;

  total_weight = 0.0;

2.确定步长,根据激光的总个数与最大波束计算

  step = ceil((data->range_count) / static_cast<double>(self->max_beams));   // 总角度/间隔大小
  
  // Step size must be at least 1
  if(step < 1)
    step = 1;

3.高斯误差  、随机偶然误差   还有最远点的概率

  // Pre-compute a couple of things
  double z_hit_denom = 2 * self->sigma_hit * self->sigma_hit;        // 高斯分布测量,sigma为标准偏差
  double z_rand_mult = 1.0/data->range_max;    // 随机测量相关,1/雷达最大距离

  double max_dist_prob = exp(-(self->map->max_occ_dist * self->map->max_occ_dist) / z_hit_denom);  //高斯指数部分

4.光束跳跃参数,

  bool do_beamskip = self->do_beamskip;
  double beam_skip_distance = self->beam_skip_distance;
  double beam_skip_threshold = self->beam_skip_threshold;
  
  //we only do beam skipping if the filter has converged    //收敛
  if(do_beamskip && !set->converged){
    do_beamskip = false;
  }

5.与地图相符的点的数量,并进行整合计算

  //我们需要计算光束与地图一致的粒子数
  int *obs_count = new int[self->max_beams]();

   //选择哪些激光点进行所有粒子的计算
  bool *obs_mask = new bool[self->max_beams]();

6.光束进行跳变的判断

  //判断是否进行光束跳跃
  bool realloc = false; 

7.当有临时跳变时,创建临时数据

 if(do_beamskip){
    if(self->max_obs < self->max_beams){            //? 有不正常激光点
      realloc = true;
    }

    if(self->max_samples < set->sample_count){     //?粒子数目条件
      realloc = true;
    }

    if(realloc){
      self->reallocTempData(set->sample_count, self->max_beams);        //建立临时数据
      fprintf(stderr, "Reallocing temp weights %d - %d\n", self->max_samples, self->max_obs);
    }
  }

8.开始处理每一个粒子

9.对于每个粒子,遍历其激光点数,根据间隔点选取,

    for (i = 0; i < data->range_count; i += step, beam_ind++)    //遍历激光点数,间隔选点,因为计算时间原因
    {
      obs_range = data->ranges[i][0];                       //距离
      obs_bearing = data->ranges[i][1];                     //角度

      // This model ignores max range readings               丢掉最大距离,无意义,因为看不到障碍物
      if(obs_range >= data->range_max){
        continue;
      }

      // Check for NaN
      if(obs_range != obs_range){
        continue;
      }

      pz = 0.0;

10.将激光点映射到地图中

      // Compute the endpoint of the beam                         //
      hit.v[0] = pose.v[0] + obs_range * cos(pose.v[2] + obs_bearing);
      hit.v[1] = pose.v[1] + obs_range * sin(pose.v[2] + obs_bearing);

      // Convert to map grid coords.
      int mi, mj;
      mi = MAP_GXWX(self->map, hit.v[0]);       //将点编入格栅地图中
      mj = MAP_GYWY(self->map, hit.v[1]);

11.当该点位于边界时,看做最大障碍物距离,否则取最小障碍物距离,当最小距离小于设定的波束跳跃距离时,可用点+1,同时确定高斯噪声。

      if(!MAP_VALID(self->map, mi, mj)){      //地图外看作最大障碍物距离
        pz += self->z_hit * max_dist_prob;
      }
      else{
        z = self->map->cells[MAP_INDEX(self->map,mi,mj)].occ_dist;  //最小障碍物距离
        if(z < beam_skip_distance){
           obs_count[beam_ind] += 1;
      }
        pz += self->z_hit * exp(-(z * z) / z_hit_denom);      //高斯模型
      }

12.在加上随机模型,检测概率

      // Gaussian model
      // NOTE: this should have a normalization of 1/(sqrt(2pi)*sigma)
      
      // Part 2: random measurements
      pz += self->z_rand * z_rand_mult;               //随机测量模型

      assert(pz <= 1.0); 
      assert(pz >= 0.0);

13.做不做跳变进行独立处理,不做跳变时权重正常相加

      if(!do_beamskip){
        log_p += log(pz);
      }
      else{
        self->temp_obs[j][beam_ind] = pz;         //短读数处理
      }

   if(!do_beamskip){
      sample->weight *= exp(log_p);
      total_weight += sample->weight;
    }

14.做跳变时,如果跳变的个数占总个数一定权重时,设定障碍物遮挡

   int skipped_beam_count = 0; 
    for (beam_ind = 0; beam_ind < self->max_beams; beam_ind++){
      if((obs_count[beam_ind] / static_cast<double>(set->sample_count)) > beam_skip_threshold){
          obs_mask[beam_ind] = true;
      }
      else{
          obs_mask[beam_ind] = false;
          skipped_beam_count++;
      }
    }

15.如果跳过光束大于跳过错误的阈值时,erraor = true

  if(skipped_beam_count >= (beam_ind * self->beam_skip_error_threshold)){
      fprintf(stderr, "Over %f%% of the observations were not in the map - pf may have converged to wrong pose - integrating all observations\n", (100 * self->beam_skip_error_threshold));
      error = true; 
    }

16.

    for (j = 0; j < set->sample_count; j++)
    {
        sample = set->samples + j;
        pose = sample->pose;

        log_p = 0;

        for (beam_ind = 0; beam_ind < self->max_beams; beam_ind++){
           if(error || obs_mask[beam_ind]){
              log_p += log(self->temp_obs[j][beam_ind]);
          }
        }

      sample->weight *= exp(log_p);

      total_weight += sample->weight;
    }

 

 

 

 

 

 

 

 

 

 

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值