25 #include "nav2_amcl/sensors/laser/laser.hpp"
30 LikelihoodFieldModel::LikelihoodFieldModel(
31 double z_hit,
double z_rand,
double sigma_hit,
32 double max_occ_dist,
size_t max_beams,
map_t * map)
33 : Laser(max_beams, map)
37 sigma_hit_ = sigma_hit;
44 if (map->max_occ_dist != max_occ_dist) {
45 map_update_cspace(map, max_occ_dist);
50 LikelihoodFieldModel::sensorFunction(LaserData * data,
pf_sample_set_t * set)
52 LikelihoodFieldModel *
self;
56 double obs_range, obs_bearing;
62 self =
reinterpret_cast<LikelihoodFieldModel *
>(data->laser);
65 double z_hit_denom = 2 *
self->sigma_hit_ *
self->sigma_hit_;
66 double z_rand_mult = 1.0 / data->range_max;
68 step = (data->range_count - 1) / (self->max_beams_ - 1);
78 for (j = 0; j < set->sample_count; j++) {
79 sample = set->samples + j;
83 pose = pf_vector_coord_add(self->laser_pose_, pose);
87 for (i = 0; i < data->range_count; i += step) {
88 obs_range = data->ranges[i][0];
89 obs_bearing = data->ranges[i][1];
92 if (obs_range >= data->range_max) {
97 if (obs_range != obs_range) {
104 hit.v[0] = pose.v[0] + obs_range * cos(pose.v[2] + obs_bearing);
105 hit.v[1] = pose.v[1] + obs_range * sin(pose.v[2] + obs_bearing);
109 mi = MAP_GXWX(self->map_, hit.v[0]);
110 mj = MAP_GYWY(self->map_, hit.v[1]);
114 if (!MAP_VALID(self->map_, mi, mj)) {
115 z =
self->map_->max_occ_dist;
117 z =
self->map_->cells[MAP_INDEX(self->map_, mi, mj)].occ_dist;
121 pz +=
self->z_hit_ * exp(-(z * z) / z_hit_denom);
123 pz +=
self->z_rand_ * z_rand_mult;
136 total_weight += sample->weight;
144 LikelihoodFieldModel::sensorUpdate(
pf_t * pf, LaserData * data)
146 if (max_beams_ < 2) {
149 pf_update_sensor(pf, (pf_sensor_model_fn_t) sensorFunction, data);