bearing_sensor_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_SENSOR_BEARING_SENSOR_MODEL_HPP
16 #define BELUGA_SENSOR_BEARING_SENSOR_MODEL_HPP
17 
18 // external
19 #include <range/v3/range/conversion.hpp>
20 #include <range/v3/view/all.hpp>
21 #include <range/v3/view/transform.hpp>
22 #include <sophus/se2.hpp>
23 #include <sophus/se3.hpp>
24 
25 // standard library
26 #include <cmath>
27 #include <random>
28 #include <utility>
29 #include <vector>
30 
31 // project
33 
39 namespace beluga {
40 
43  double sigma_bearing{1.0};
45 };
46 
48 
59 template <class LandmarkMap, class StateType>
61  public:
63  using state_type = StateType;
65  using weight_type = double;
67  using measurement_type = std::vector<LandmarkBearingDetection>;
72 
74 
79  template <class... Args>
80  explicit BearingSensorModel(param_type params, LandmarkMap landmark_map)
81  : params_{std::move(params)}, landmark_map_{std::move(landmark_map)} {}
82 
84 
89  [[nodiscard]] auto operator()(measurement_type&& detections) const {
90  return [this, detections = std::move(detections)](const state_type& state) -> weight_type {
91  Sophus::SE3d robot_pose_in_world;
92 
93  if constexpr (std::is_same_v<state_type, Sophus::SE3d>) {
94  // The robot pose state is already given in 3D,
95  robot_pose_in_world = state;
96  } else {
97  // The robot pose state is given in 2D. Notice that in this case
98  // the 2D pose of the robot is assumed to be that of the robot footprint (projection of the robot
99  // on the z=0 plane of the 3D world frame). This is so that we can tie the sensor reference frame
100  // to the world frame where the landmarks are given without additional structural information.
101  robot_pose_in_world = Sophus::SE3d{
102  Sophus::SO3d::rotZ(state.so2().log()),
103  Eigen::Vector3d{state.translation().x(), state.translation().y(), 0.0}};
104  }
105 
106  // precalculate the sensor pose in the world frame
107  const auto sensor_pose_in_world = robot_pose_in_world * params_.sensor_pose_in_robot;
108 
109  const auto detection_weight = [this, &sensor_pose_in_world](const auto& detection) {
110  // find the landmark the most closely matches the sample bearing vector
111  const auto opt_landmark_bearing_in_sensor = landmark_map_.find_closest_bearing_landmark(
112  detection.detection_bearing_in_sensor, detection.category, sensor_pose_in_world);
113 
114  // if we did not find a matching landmark, return 0.0
115  if (!opt_landmark_bearing_in_sensor) {
116  return 0.0;
117  }
118 
119  // recover sample bearing vector
120  const auto detection_bearing_in_sensor = detection.detection_bearing_in_sensor.normalized();
121 
122  // recover landmark bearing vector
123  const auto& landmark_bearing_in_sensor = *opt_landmark_bearing_in_sensor;
124 
125  // calculate the aperture angle between the detection and the landmark
126  const auto cos_aperture = detection_bearing_in_sensor.dot(landmark_bearing_in_sensor);
127  const auto sin_aperture = detection_bearing_in_sensor.cross(landmark_bearing_in_sensor).norm();
128 
129  // calculate the angle between the sample and the landmark
130  const auto bearing_error = std::atan2(sin_aperture, cos_aperture);
131 
132  // model the probability of the landmark being detected as depending on the bearing error
133  const auto bearing_error_prob =
134  std::exp(-bearing_error * bearing_error / (2. * params_.sigma_bearing * params_.sigma_bearing));
135 
136  return bearing_error_prob;
137  };
138 
139  return std::transform_reduce(detections.cbegin(), detections.cend(), 1.0, std::multiplies{}, detection_weight);
140  };
141  }
142 
144  void update_map(map_type&& map) { landmark_map_ = std::move(map); }
145 
146  private:
149 };
150 
152 template <class LandmarkMap>
154 
156 template <class LandmarkMap>
158 
159 } // namespace beluga
160 
161 #endif
beluga::LandmarkMap::find_closest_bearing_landmark
std::optional< LandmarkBearing3 > find_closest_bearing_landmark(const LandmarkBearing3 &detection_bearing_in_sensor, const LandmarkCategory &detection_category, const world_pose_type &sensor_pose_in_world) const
Finds the landmark that minimizes the bearing error to a given detection and returns its data.
Definition: landmark_map.hpp:96
beluga::state
constexpr state_detail::state_fn state
Customization point object for accessing the state of a particle.
Definition: primitives.hpp:163
landmark_detection_types.hpp
Auxiliar types for landmark models.
beluga::BearingSensorModel::state_type
StateType state_type
State type of a particle.
Definition: bearing_sensor_model.hpp:63
beluga::BearingModelParam
Parameters used to construct a BearingSensorModel instance.
Definition: bearing_sensor_model.hpp:42
se2.hpp
beluga::BearingSensorModel::update_map
void update_map(map_type &&map)
Update the sensor model with a new landmark map.
Definition: bearing_sensor_model.hpp:144
beluga::BearingSensorModel::measurement_type
std::vector< LandmarkBearingDetection > measurement_type
Measurement type of the sensor: vector of landmark detections.
Definition: bearing_sensor_model.hpp:67
beluga::BearingSensorModel::params_
param_type params_
Definition: bearing_sensor_model.hpp:147
beluga::BearingModelParam::sigma_bearing
double sigma_bearing
Standard deviation of the bearing error.
Definition: bearing_sensor_model.hpp:43
beluga::BearingSensorModel::BearingSensorModel
BearingSensorModel(param_type params, LandmarkMap landmark_map)
Constructs a BearingSensorModel instance.
Definition: bearing_sensor_model.hpp:80
Sophus::SE3
beluga::LandmarkMap
Basic 3D landmark map datatype.
Definition: landmark_map.hpp:39
beluga::BearingSensorModel::landmark_map_
LandmarkMap landmark_map_
Definition: bearing_sensor_model.hpp:148
beluga::BearingSensorModel::weight_type
double weight_type
Weight type of the particle.
Definition: bearing_sensor_model.hpp:65
Sophus::SO3::rotZ
static SOPHUS_FUNC SO3 rotZ(Scalar const &z)
beluga::BearingModelParam::sensor_pose_in_robot
Sophus::SE3d sensor_pose_in_robot
Pose of the sensor in the robot reference frame.
Definition: bearing_sensor_model.hpp:44
beluga::BearingSensorModel
Generic bearing sensor model, for both 2D and 3D state types.
Definition: bearing_sensor_model.hpp:60
beluga
The main Beluga namespace.
Definition: 3d_embedding.hpp:21
beluga::BearingSensorModel::operator()
auto operator()(measurement_type &&detections) const
Returns a state weighting function conditioned on landmark bearing detections.
Definition: bearing_sensor_model.hpp:89
se3.hpp


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