omnidirectional_drive_model.hpp
Go to the documentation of this file.
1 // Copyright 2023 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_MOTION_OMNIDIRECTIONAL_DRIVE_MODEL_HPP
16 #define BELUGA_MOTION_OMNIDIRECTIONAL_DRIVE_MODEL_HPP
17 
18 #include <optional>
19 #include <random>
20 #include <tuple>
21 #include <type_traits>
22 
24 
25 #include <sophus/se2.hpp>
26 #include <sophus/so2.hpp>
27 
33 namespace beluga {
34 
38 
44 
50 
57 
63 
69 
71  double distance_threshold = 0.01;
72 };
73 
75 
79  public:
81  using control_type = std::tuple<Sophus::SE2d, Sophus::SE2d>;
84 
87 
89 
93  explicit OmnidirectionalDriveModel(const param_type& params) : params_{params} {}
94 
96 
101  template <class Control, typename = common_tuple_type_t<Control, control_type>>
102  [[nodiscard]] auto operator()(Control&& action) const {
103  const auto& [pose, previous_pose] = action;
104 
105  const auto translation = pose.translation() - previous_pose.translation();
106  const double distance = translation.norm();
107  const double distance_variance = distance * distance;
108 
109  const auto& previous_orientation = previous_pose.so2();
110  const auto& current_orientation = pose.so2();
111  const auto rotation = current_orientation * previous_orientation.inverse();
112 
113  const auto heading_rotation = Sophus::SO2d{std::atan2(translation.y(), translation.x())};
114  const auto first_rotation =
115  distance > params_.distance_threshold ? heading_rotation * previous_orientation.inverse() : Sophus::SO2d{};
116 
117  using DistributionParam = typename std::normal_distribution<double>::param_type;
118  const auto rotation_params = DistributionParam{
119  rotation.log(), std::sqrt(
121  params_.rotation_noise_from_translation * distance_variance)};
122 
123  const auto translation_params = DistributionParam{
124  distance, std::sqrt(
125  params_.translation_noise_from_translation * distance_variance +
127 
128  const auto strafe_params = DistributionParam{
129  0.0, std::sqrt(
130  params_.strafe_noise_from_translation * distance_variance +
132 
133  return [=](const state_type& state, auto& gen) {
134  static thread_local auto distribution = std::normal_distribution<double>{};
135  // This is an implementation based on the same set of parameters that is used in
136  // nav2's omni_motion_model. To simplify the implementation, the following
137  // variable substitutions were performed:
138  // - first_rotation = delta_bearing - previous_orientation
139  // - second_rotation = delta_rot_hat - first_rotation
140  const auto second_rotation = Sophus::SO2d{distribution(gen, rotation_params)} * first_rotation.inverse();
141  const auto translation =
142  Eigen::Vector2d{distribution(gen, translation_params), -distribution(gen, strafe_params)};
143  return state * Sophus::SE2d{first_rotation, Eigen::Vector2d{0.0, 0.0}} *
144  Sophus::SE2d{second_rotation, translation};
145  };
146  }
147 
148  private:
150 
151  static double rotation_variance(const Sophus::SO2d& rotation) {
152  // Treat backward and forward motion symmetrically for the noise models.
153  const auto flipped_rotation = rotation * Sophus::SO2d{Sophus::Constants<double>::pi()};
154  const auto delta = std::min(std::abs(rotation.log()), std::abs(flipped_rotation.log()));
155  return delta * delta;
156  }
157 };
158 
159 } // namespace beluga
160 
161 #endif
beluga::OmnidirectionalDriveModelParam::strafe_noise_from_translation
double strafe_noise_from_translation
Translational strafe noise from translation.
Definition: omnidirectional_drive_model.hpp:68
Sophus::SO2
beluga::OmnidirectionalDriveModelParam::distance_threshold
double distance_threshold
Distance threshold to detect in-place rotation.
Definition: omnidirectional_drive_model.hpp:71
beluga::OmnidirectionalDriveModel::operator()
auto operator()(Control &&action) const
Computes a state sampling function conditioned on a given control action.
Definition: omnidirectional_drive_model.hpp:102
beluga::OmnidirectionalDriveModelParam::translation_noise_from_translation
double translation_noise_from_translation
Translational noise from translation.
Definition: omnidirectional_drive_model.hpp:55
beluga::state
constexpr state_detail::state_fn state
Customization point object for accessing the state of a particle.
Definition: primitives.hpp:163
beluga::OmnidirectionalDriveModel::rotation_variance
static double rotation_variance(const Sophus::SO2d &rotation)
Definition: omnidirectional_drive_model.hpp:151
beluga::OmnidirectionalDriveModel::params_
param_type params_
Definition: omnidirectional_drive_model.hpp:149
se2.hpp
beluga::OmnidirectionalDriveModelParam
Parameters to construct an OmnidirectionalDriveModel instance.
Definition: omnidirectional_drive_model.hpp:36
Sophus::SE2
so2.hpp
beluga::OmnidirectionalDriveModel::control_type
std::tuple< Sophus::SE2d, Sophus::SE2d > control_type
Current and previous odometry estimates as motion model control action.
Definition: omnidirectional_drive_model.hpp:81
beluga::OmnidirectionalDriveModel
Sampled odometry model for an omnidirectional drive.
Definition: omnidirectional_drive_model.hpp:78
tuple_traits.hpp
Implementation of traits for tuple-like types.
Sophus::Constants::pi
static SOPHUS_FUNC Scalar pi()
Sophus::SE2d
SE2< double > SE2d
beluga::OmnidirectionalDriveModelParam::rotation_noise_from_translation
double rotation_noise_from_translation
Rotational noise from translation.
Definition: omnidirectional_drive_model.hpp:48
beluga::OmnidirectionalDriveModelParam::rotation_noise_from_rotation
double rotation_noise_from_rotation
Rotational noise from rotation.
Definition: omnidirectional_drive_model.hpp:42
beluga::OmnidirectionalDriveModel::OmnidirectionalDriveModel
OmnidirectionalDriveModel(const param_type &params)
Constructs an OmnidirectionalDriveModel instance.
Definition: omnidirectional_drive_model.hpp:93
beluga
The main Beluga namespace.
Definition: 3d_embedding.hpp:21
beluga::OmnidirectionalDriveModelParam::translation_noise_from_rotation
double translation_noise_from_rotation
Translational noise from rotation.
Definition: omnidirectional_drive_model.hpp:61


beluga
Author(s):
autogenerated on Tue Jul 16 2024 02:59:53