amcl_laser 似然域--概率计算
1、蒙特卡罗定位主要流程:amcl_laser.cpp
1、蒙特卡罗定位主要流程:
1)评分的基础方法是机器人感知模型----测距仪似然域模型。这里的模型采用四类测量误差,小的测量噪声hit、意外对象引起的误差short,以及由于未检测到对象引起的误差max和随机意外噪声rand。 2)通过按照不同权重进行组合上面四类重点测量误差,得到一个混合分布模型 3)通过该方法计算每个粒子,将平面栅格地图转化为似然地图 4)伪代码 伪代码程序用似然域计算测量概率的算法。外循环将各个p (z|x, m) 的值相乘,并假定不同传感器波束的噪声是相互独立的。 第 4 行检查传感器读数是否为最大距离读数,如果是则被舍弃。第 5-8 行处理有趣的情况:会计算x-y 空间中与最近障碍物的距离(第 7 行)。在第 8 行通过将一个正态分布和一个均匀分布混合得到似然结果。(附代码和解析)
amcl_laser.cpp
double AMCLLaser
::LikelihoodFieldModel(AMCLLaserData
*data
, pf_sample_set_t
* set)
{
AMCLLaser
*self
;
int i
, j
, step
;
double z
, pz
;
double 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;
for (j
= 0; j
< set->sample_count
; j
++)
{
sample
= set->samples
+ j
;
pose
= sample
->pose
;
pose
= pf_vector_coord_add(self
->laser_pose
, pose
);
p
= 1.0;
double z_hit_denom
= 2 * self
->sigma_hit
* self
->sigma_hit
;
double z_rand_mult
= 1.0/data
->range_max
;
step
= (data
->range_count
- 1) / (self
->max_beams
- 1);
if(step
< 1)
step
= 1;
for (i
= 0; i
< data
->range_count
; i
+= step
)
{
obs_range
= data
->ranges
[i
][0];
obs_bearing
= data
->ranges
[i
][1];
if(obs_range
>= data
->range_max
)
continue;
if(obs_range
!= obs_range
)
continue;
pz
= 0.0;
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
);
int mi
, mj
;
mi
= MAP_GXWX(self
->map
, hit
.v
[0]);
mj
= MAP_GYWY(self
->map
, hit
.v
[1]);
if(!MAP_VALID(self
->map
, mi
, mj
))
z
= self
->map
->max_occ_dist
;
else
z
= self
->map
->cells
[MAP_INDEX(self
->map
,mi
,mj
)].occ_dist
;
pz
+= self
->z_hit
* exp(-(z
* z
) / z_hit_denom
);
pz
+= self
->z_rand
* z_rand_mult
;
assert(pz
<= 1.0);
assert(pz
>= 0.0);
p
+= pz
*pz
*pz
;
}
sample
->weight
*= p
;
total_weight
+= sample
->weight
;
}
return(total_weight
);
}