32 msg.poses.resize(
p_.size());
34 for (uint32_t i = 0; i <
p_.size(); ++i)
36 msg.poses[i].position.x =
static_cast<double>(
p_[i].x) + offset.x;
37 msg.poses[i].position.y = static_cast<double>(
p_[i].y) + offset.y;
38 msg.poses[i].position.z =
static_cast<double>(
p_[i].z) + offset.z;
39 msg.poses[i].orientation.x = 0.;
40 msg.poses[i].orientation.y = 0.;
41 msg.poses[i].orientation.z = sin(static_cast<double>(
p_[i].a * 0.5
f));
42 msg.poses[i].orientation.w = cos(static_cast<double>(
p_[i].a * 0.5f));
46 void ParticleFilter::init(
const int num_particles,
const float x_init,
const float y_init,
const float z_init,
47 const float a_init,
const float x_dev,
const float y_dev,
const float z_dev,
51 p_.resize(abs(num_particles));
54 const float dev = std::max(std::max(x_dev, y_dev), z_dev);
55 const float gauss_const_1 = 1. / (dev * sqrt(2 *
M_PI));
56 const float gauss_const_2 = 1. / (2 * dev * dev);
62 p_[0].w = gauss_const_1;
67 for (uint32_t i = 1; i <
p_.size(); ++i)
74 dist = sqrt((
p_[i].
x -
p_[0].
x) * (
p_[i].x -
p_[0].x) + (
p_[i].
y -
p_[0].
y) * (
p_[i].y -
p_[0].y) +
77 p_[i].w = gauss_const_1 * exp(-dist * dist * gauss_const_2);
83 for (uint32_t i = 0; i <
p_.size(); ++i)
87 mean_p.
x +=
p_[i].w *
p_[i].x;
88 mean_p.
y +=
p_[i].w *
p_[i].y;
89 mean_p.
z +=
p_[i].w *
p_[i].z;
90 mean_p.
a +=
p_[i].w *
p_[i].a;
98 const double odom_a_mod,
const double delta_x,
const double delta_y,
const double delta_z,
101 const double x_dev = fabs(delta_x * odom_x_mod);
102 const double y_dev = fabs(delta_y * odom_y_mod);
103 const double z_dev = fabs(delta_z * odom_z_mod);
104 const double a_dev = fabs(delta_a * odom_a_mod);
107 float sa, ca, rand_x, rand_y;
108 for (uint32_t i = 0; i <
p_.size(); ++i)
114 p_[i].x += ca * rand_x - sa * rand_y;
115 p_[i].y += sa * rand_x + ca * rand_y;
122 const std::vector<Range>& range_data,
const double alpha,
const double sigma)
125 float wtp = 0, wtr = 0;
127 clock_t begin_for1 = clock();
128 for (uint32_t i = 0; i <
p_.size(); ++i)
153 clock_t end_for1 = clock();
154 double elapsed_secs = double(end_for1 - begin_for1) / CLOCKS_PER_SEC;
155 ROS_INFO(
"Update time 1: [%lf] sec", elapsed_secs);
159 for (uint32_t i = 0; i <
p_.size(); ++i)
171 p_[i].w =
p_[i].wp * alpha +
p_[i].wr * (1 - alpha);
176 for (uint32_t i = 0; i <
p_.size(); ++i)
183 mean_p.
x +=
p_[i].w *
p_[i].x;
184 mean_p.
y +=
p_[i].w *
p_[i].y;
185 mean_p.
z +=
p_[i].w *
p_[i].z;
186 mean_p.
a +=
p_[i].w *
p_[i].a;
193 std::vector<Particle> new_p(
p_.size());
194 const float factor = 1.f /
p_.size();
200 for (uint32_t m = 0, i = 0; m <
p_.size(); ++m)
205 if (++i >=
p_.size())
218 const std::vector<Range>& range_data,
const double sigma)
220 if (range_data.empty())
224 const float k1 = 1.f / (sigma * sqrt(2 *
M_PI));
225 const float k2 = 0.5f / (sigma * sigma);
227 for (uint32_t i = 0; i < range_data.size(); ++i)
229 ax = range_data[i].ax;
230 ay = range_data[i].ay;
231 az = range_data[i].az;
232 r = sqrt((x - ax) * (x - ax) + (y - ay) * (y - ay) + (z - az) * (z - az));
233 w *= k1 * exp(-k2 * (r - range_data[i].r) * (r - range_data[i].r));
241 std::normal_distribution<float> distribution(mean, sigma);
247 std::uniform_real_distribution<float> distribution(range_from, range_to);
bool isIntoMap(const float x, const float y, const float z) const
float rngUniform(const float range_from, const float range_to)
float ranGaussian(const double mean, const double sigma)
TFSIMD_FORCE_INLINE const tfScalar & y() const
void update(const Grid3d &grid3d, const std::vector< pcl::PointXYZ > &points, const std::vector< Range > &range_data, const double alpha, const double sigma)
Update Particles with a pointcloud update.
virtual ~ParticleFilter()
std::vector< Particle > p_
Particles.
Struct that contains the data concerning one particle.
float computeCloudWeight(const std::vector< pcl::PointXYZ > &points, const float tx, const float ty, const float tz, const float a) const
void buildParticlesPoseMsg(const geometry_msgs::Point32 &offset, geometry_msgs::PoseArray &msg) const
TFSIMD_FORCE_INLINE const tfScalar & x() const
void predict(const double odom_x_mod, const double odom_y_mod, const double odom_z_mod, const double odom_a_mod, const double delta_x, const double delta_y, const double delta_z, const double delta_a)
TFSIMD_FORCE_INLINE const tfScalar & z() const
bool initialized_
Indicates if the filter was initialized.
TFSIMD_FORCE_INLINE const tfScalar & w() const
float computeRangeWeight(const float x, const float y, const float z, const std::vector< Range > &range_data, const double sigma)
void init(const int num_particles, const float x_init, const float y_init, const float z_init, const float a_init, const float x_dev, const float y_dev, const float z_dev, const float a_dev)
Set the initial pose of the particle filter.
void resample()
Resample the set of particles using low-variance sampling.