15 #ifndef BELUGA_SENSOR_LANDMARK_SENSOR_MODEL_HPP
16 #define BELUGA_SENSOR_LANDMARK_SENSOR_MODEL_HPP
19 #include <range/v3/range/conversion.hpp>
20 #include <range/v3/view/all.hpp>
21 #include <range/v3/view/transform.hpp>
62 template <
class LandmarkMap,
class StateType>
95 if constexpr (std::is_same_v<state_type, Sophus::SE3d>) {
97 robot_pose_in_world =
state;
105 Eigen::Vector3d{
state.translation().x(),
state.translation().y(), 0.0}};
108 const auto detection_weight = [
this, &robot_pose_in_world](
const auto& detection) {
111 const auto& detection_category = detection.category;
112 const auto& detection_position_in_robot = detection.detection_position_in_robot;
114 const auto detection_range_in_robot = detection_position_in_robot.norm();
115 const auto detection_bearing_in_robot = detection_position_in_robot.normalized();
118 const auto detection_position_in_world = robot_pose_in_world * detection_position_in_robot;
121 const auto opt_landmark_position_in_world =
125 if (!opt_landmark_position_in_world) {
131 const auto& landmark_position_in_world = *opt_landmark_position_in_world;
132 const auto landmark_in_robot_position = robot_pose_in_world.inverse() * landmark_position_in_world;
134 const auto landmark_range_in_robot = landmark_in_robot_position.norm();
135 const auto landmark_bearing_in_robot = landmark_in_robot_position.normalized();
138 const auto cos_aperture = landmark_bearing_in_robot.dot(detection_bearing_in_robot);
139 const auto sin_aperture = landmark_bearing_in_robot.cross(detection_bearing_in_robot).norm();
140 const auto bearing_error = std::atan2(sin_aperture, cos_aperture);
142 const auto range_error = detection_range_in_robot - landmark_range_in_robot;
145 const auto range_error_prob =
147 const auto bearing_error_prob =
151 return range_error_prob * bearing_error_prob;
154 return std::transform_reduce(detections.cbegin(), detections.cend(), 1.0, std::multiplies{}, detection_weight);
167 template <
class LandmarkMap>
171 template <
class LandmarkMap>