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;
38 map_update_cspace(map, max_occ_dist);
42 LikelihoodFieldModel::sensorFunction(LaserData * data,
pf_sample_set_t * set)
44 LikelihoodFieldModel *
self;
48 double obs_range, obs_bearing;
54 self =
reinterpret_cast<LikelihoodFieldModel *
>(data->laser);
57 double z_hit_denom = 2 *
self->sigma_hit_ *
self->sigma_hit_;
58 double z_rand_mult = 1.0 / data->range_max;
60 step = (data->range_count - 1) / (self->max_beams_ - 1);
70 for (j = 0; j < set->sample_count; j++) {
71 sample = set->samples + j;
75 pose = pf_vector_coord_add(self->laser_pose_, pose);
79 for (i = 0; i < data->range_count; i += step) {
80 obs_range = data->ranges[i][0];
81 obs_bearing = data->ranges[i][1];
84 if (obs_range >= data->range_max) {
89 if (obs_range != obs_range) {
96 hit.v[0] = pose.v[0] + obs_range * cos(pose.v[2] + obs_bearing);
97 hit.v[1] = pose.v[1] + obs_range * sin(pose.v[2] + obs_bearing);
101 mi = MAP_GXWX(self->map_, hit.v[0]);
102 mj = MAP_GYWY(self->map_, hit.v[1]);
106 if (!MAP_VALID(self->map_, mi, mj)) {
107 z =
self->map_->max_occ_dist;
109 z =
self->map_->cells[MAP_INDEX(self->map_, mi, mj)].occ_dist;
113 pz +=
self->z_hit_ * exp(-(z * z) / z_hit_denom);
115 pz +=
self->z_rand_ * z_rand_mult;
128 total_weight += sample->weight;
136 LikelihoodFieldModel::sensorUpdate(
pf_t * pf, LaserData * data)
138 if (max_beams_ < 2) {
141 pf_update_sensor(pf, (pf_sensor_model_fn_t) sensorFunction, data);