15 #ifndef BELUGA_MOTION_DIFFERENTIAL_DRIVE_MODEL_HPP
16 #define BELUGA_MOTION_DIFFERENTIAL_DRIVE_MODEL_HPP
27 #include <type_traits>
79 template <
class StateType = Sophus::SE2d>
82 std::is_same_v<StateType, Sophus::SE2d> or std::is_same_v<StateType, Sophus::SE3d>,
83 "Differential model only supports SE2 and SE3 state types.");
108 template <
class Control,
typename = common_tuple_type_t<Control, control_type>>
110 const auto& [pose, previous_pose] = action;
111 if constexpr (std::is_same_v<state_type, Sophus::SE2d>) {
123 const auto current_pose_2d =
To2d(pose);
124 const auto previous_pose_pose_2d =
To2d(previous_pose);
125 const auto two_d_sampling_fn =
sampling_fn_2d(current_pose_2d, previous_pose_pose_2d);
131 const double distance = translation.norm();
132 const double distance_variance = distance * distance;
134 const auto& previous_orientation = previous_pose.
so2();
135 const auto& current_orientation = pose.
so2();
136 const auto heading_rotation =
Sophus::SO2d{std::atan2(translation.y(), translation.x())};
137 const auto first_rotation =
139 const auto second_rotation = current_orientation * previous_orientation.inverse() * first_rotation.inverse();
141 using DistributionParam =
typename std::normal_distribution<double>::param_type;
142 const auto first_rotation_params = DistributionParam{
143 first_rotation.log(), std::sqrt(
146 const auto translation_params = DistributionParam{
151 const auto second_rotation_params = DistributionParam{
152 second_rotation.log(), std::sqrt(
156 return [=](
const auto&
state,
auto& gen) {
157 static thread_local
auto distribution = std::normal_distribution<double>{};
158 const auto first_rotation =
Sophus::SO2d{distribution(gen, first_rotation_params)};
159 const auto translation = Eigen::Vector2d{distribution(gen, translation_params), 0.0};
160 const auto second_rotation =
Sophus::SO2d{distribution(gen, second_rotation_params)};
170 const auto flipped_rotation = rotation * kFlippingRotation;
171 const auto delta = std::min(std::abs(rotation.log()), std::abs(flipped_rotation.log()));
172 return delta * delta;