/home/runner/work/beluga/beluga/beluga_ros/include/beluga_ros/amcl.hpp Source File

/home/runner/work/beluga/beluga/beluga_ros/include/beluga_ros/amcl.hpp Source File#

Beluga ROS: /home/runner/work/beluga/beluga/beluga_ros/include/beluga_ros/amcl.hpp Source File
Beluga ROS
amcl.hpp
Go to the documentation of this file.
1 // Copyright 2024 Ekumen, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef BELUGA_ROS_AMCL_HPP
16 #define BELUGA_ROS_AMCL_HPP
17 
18 #include <optional>
19 #include <utility>
20 #include <variant>
21 
22 #include <range/v3/range/conversion.hpp>
23 #include <range/v3/view/take_exactly.hpp>
24 
25 #include <sophus/se2.hpp>
26 
28 #include <beluga/algorithm/thrun_recovery_probability_estimator.hpp>
29 #include <beluga/containers.hpp>
30 #include <beluga/motion.hpp>
31 #include <beluga/policies.hpp>
32 #include <beluga/random.hpp>
33 #include <beluga/sensor.hpp>
35 #include <beluga/sensor/primitives.hpp>
36 #include <beluga/views/sample.hpp>
37 
41 
47 namespace beluga_ros {
48 
50 struct AmclParams {
52  double update_min_d = 0.25;
53 
55  double update_min_a = 0.2;
56 
58  std::size_t resample_interval = 1UL;
59 
65  bool selective_resampling = false;
66 
68  std::size_t min_particles = 500UL;
69 
71  std::size_t max_particles = 2000UL;
72 
75  double alpha_slow = 0.001;
76 
79  double alpha_fast = 0.1;
80 
84  double kld_epsilon = 0.05;
85 
88  double kld_z = 3.0;
89 
91  double spatial_resolution_x = 0.5;
92 
94  double spatial_resolution_y = 0.5;
95 
97  double spatial_resolution_theta = 10 * Sophus::Constants<double>::pi() / 180;
98 };
99 
102 class Amcl {
103  public:
105  using particle_type = std::tuple<Sophus::SE2d, beluga::Weight>;
106 
108  using motion_model_variant = std::variant<
112 
114  using sensor_model_variant = std::variant<
118 
120  using execution_policy_variant = std::variant<std::execution::sequenced_policy, std::execution::parallel_policy>;
121 
123 
132  motion_model_variant motion_model,
133  sensor_model_variant sensor_model,
134  const AmclParams& params,
135  execution_policy_variant execution_policy);
136 
138  [[nodiscard]] const auto& particles() const { return particles_; }
139 
141  [[nodiscard]] const auto& likelihood_field() const {
142  std::optional<std::reference_wrapper<const beluga::ValueGrid2<float>>> result;
143 
144  std::visit(
145  [&result](const auto& sensor_model) {
146  using T = std::decay_t<decltype(sensor_model)>;
147  if constexpr (beluga::has_likelihood_field_v<T>) {
148  result = std::cref(sensor_model.likelihood_field());
149  }
150  },
151  sensor_model_);
152 
153  if (!result) {
154  throw std::runtime_error("The current sensor model does not support likelihood field");
155  }
156 
157  return result->get();
158  }
159 
161  [[nodiscard]] auto likelihood_field_origin() const {
162  std::optional<Sophus::SE2<double>> result;
163 
164  std::visit(
165  [&result](const auto& sensor_model) {
166  using T = std::decay_t<decltype(sensor_model)>;
167  if constexpr (beluga::has_likelihood_field_v<T>) {
168  result = sensor_model.likelihood_field_origin();
169  }
170  },
171  sensor_model_);
172 
173  if (!result) {
174  throw std::runtime_error("The current sensor model does not support likelihood field");
175  }
176 
177  return *result; // return by value
178  }
179 
181  [[nodiscard]] bool has_likelihood_field() const {
182  return std::visit(
183  [](const auto& sensor_model) {
184  using T = std::decay_t<decltype(sensor_model)>;
185  return beluga::has_likelihood_field_v<T>;
186  },
187  sensor_model_);
188  }
189 
191  template <class Distribution>
192  void initialize(Distribution distribution) {
193  particles_ = beluga::views::sample(std::move(distribution)) | //
194  ranges::views::transform(beluga::make_from_state<particle_type>) | //
195  ranges::views::take_exactly(params_.max_particles) | //
196  ranges::to<beluga::TupleVector>;
197  force_update_ = true;
198  }
199 
201 
204  void initialize(Sophus::SE2d pose, Sophus::Matrix3d covariance) {
206  }
207 
209  void initialize_from_map() { initialize(std::ref(map_distribution_)); }
210 
213 
215 
227  auto update(Sophus::SE2d base_pose_in_odom, beluga_ros::LaserScan laser_scan)
228  -> std::optional<std::pair<Sophus::SE2d, Sophus::Matrix3d>>;
229 
231 
243  auto update(Sophus::SE2d base_pose_in_odom, beluga_ros::SparsePointCloud3f point_cloud)
244  -> std::optional<std::pair<Sophus::SE2d, Sophus::Matrix3d>>;
245 
247 
259  auto update(Sophus::SE2d base_pose_in_odom, std::vector<std::pair<double, double>>&& measurement)
260  -> std::optional<std::pair<Sophus::SE2d, Sophus::Matrix3d>>;
261 
263  void force_update() { force_update_ = true; }
264 
265  private:
267 
268  AmclParams params_;
270  motion_model_variant motion_model_;
271  sensor_model_variant sensor_model_;
272  execution_policy_variant execution_policy_;
273 
274  beluga::spatial_hash<Sophus::SE2d> spatial_hasher_;
275  beluga::ThrunRecoveryProbabilityEstimator random_probability_estimator_;
276  beluga::any_policy<Sophus::SE2d> update_policy_;
277  beluga::any_policy<decltype(particles_)> resample_policy_;
278 
279  beluga::RollingWindow<Sophus::SE2d, 2> control_action_window_;
280 
281  bool force_update_{true};
282 };
283 
284 } // namespace beluga_ros
285 
286 #endif // BELUGA_ROS_AMCL_HPP
Definition: amcl.hpp:102
auto update(Sophus::SE2d base_pose_in_odom, std::vector< std::pair< double, double >> &&measurement) -> std::optional< std::pair< Sophus::SE2d, Sophus::Matrix3d >>
Update particles based on motion and sensor information.
const auto & likelihood_field() const
Returns a reference to the current likelihood field.
Definition: amcl.hpp:141
void initialize_from_map()
Initialize particles using the default map distribution.
Definition: amcl.hpp:209
std::variant< beluga::DifferentialDriveModel2d, beluga::OmnidirectionalDriveModel, beluga::StationaryModel > motion_model_variant
Motion model variant type for runtime selection support.
Definition: amcl.hpp:111
std::variant< std::execution::sequenced_policy, std::execution::parallel_policy > execution_policy_variant
Execution policy variant type for runtime selection support.
Definition: amcl.hpp:120
void update_map(beluga_ros::OccupancyGrid map)
Update the map used for localization.
bool has_likelihood_field() const
Check if the sensor model bears a likelihood field.
Definition: amcl.hpp:181
auto likelihood_field_origin() const
Returns the current likelihood field origin transform.
Definition: amcl.hpp:161
const auto & particles() const
Returns a reference to the current set of particles.
Definition: amcl.hpp:138
std::tuple< Sophus::SE2d, beluga::Weight > particle_type
Weighted SE(2) state particle type.
Definition: amcl.hpp:105
void initialize(Sophus::SE2d pose, Sophus::Matrix3d covariance)
Initialize particles with a given pose and covariance.
Definition: amcl.hpp:204
auto update(Sophus::SE2d base_pose_in_odom, beluga_ros::SparsePointCloud3f point_cloud) -> std::optional< std::pair< Sophus::SE2d, Sophus::Matrix3d >>
Update particles using point cloud data.
void initialize(Distribution distribution)
Initialize particles using a custom distribution.
Definition: amcl.hpp:192
std::variant< beluga::LikelihoodFieldModel< beluga_ros::OccupancyGrid >, beluga::LikelihoodFieldProbModel< beluga_ros::OccupancyGrid >, beluga::BeamSensorModel< beluga_ros::OccupancyGrid > > sensor_model_variant
Sensor model variant type for runtime selection support.
Definition: amcl.hpp:117
auto update(Sophus::SE2d base_pose_in_odom, beluga_ros::LaserScan laser_scan) -> std::optional< std::pair< Sophus::SE2d, Sophus::Matrix3d >>
Update particles using laser scan data.
Amcl(beluga_ros::OccupancyGrid map, motion_model_variant motion_model, sensor_model_variant sensor_model, const AmclParams &params, execution_policy_variant execution_policy)
Constructor.
void force_update()
Force a manual update of the particles on the next iteration of the filter.
Definition: amcl.hpp:263
Thin wrapper type for 2D sensor_msgs/LaserScan messages.
Definition: laser_scan.hpp:36
Thin wrapper type for 2D nav_msgs/OccupancyGrid messages.
Definition: occupancy_grid.hpp:42
Thin wrapper for 3D sensor_msgs/PointCloud2 messages with potentially sparse layouts.
Definition: sparse_point_cloud.hpp:53
Implementation of sensor_msgs/LaserScan wrapper type.
The main Beluga ROS namespace.
Definition: amcl.hpp:47
constexpr detail::covariance_fn covariance
DifferentialDriveModel< Sophus::SE2d > DifferentialDriveModel2d
Implementation of nav_msgs/OccupancyGrid wrapper type.
Implementation of sensor_msgs/PointCloud2 wrapper type for messages without alignment constraints on ...
Struct containing parameters for the Adaptive Monte Carlo Localization (AMCL) implementation.
Definition: amcl.hpp:50
std::size_t max_particles
Maximum allowed number of particles.
Definition: amcl.hpp:71
std::size_t resample_interval
Number of filter updates required before resampling.
Definition: amcl.hpp:58
double kld_epsilon
Maximum particle filter population error between the true distribution and the estimated distribution...
Definition: amcl.hpp:84
double kld_z
Upper standard normal quantile for , where is the probability that the error in the estimated distri...
Definition: amcl.hpp:88
double alpha_fast
Exponential decay rate for the fast average weight filter, used in deciding when to recover from a ba...
Definition: amcl.hpp:79
double update_min_a
Rotational movement required from last resample for resampling to happen again.
Definition: amcl.hpp:55
double alpha_slow
Exponential decay rate for the slow average weight filter, used in deciding when to recover from a ba...
Definition: amcl.hpp:75
double spatial_resolution_theta
Spatial resolution around the z-axis to create buckets for KLD resampling.
Definition: amcl.hpp:97
double spatial_resolution_x
Spatial resolution along the x-axis to create buckets for KLD resampling.
Definition: amcl.hpp:91
std::size_t min_particles
Minimum allowed number of particles.
Definition: amcl.hpp:68
double spatial_resolution_y
Spatial resolution along the y-axis to create buckets for KLD resampling.
Definition: amcl.hpp:94
bool selective_resampling
Whether to enable selective resampling to help avoid loss of diversity in the particle population....
Definition: amcl.hpp:65
double update_min_d
Translational movement required from last resample for resampling to happen again.
Definition: amcl.hpp:52