supereight
tracker.hpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2014 University of Edinburgh, Imperial College, University of Manchester
3  * SPDX-FileCopyrightText: 2016-2019 Emanuele Vespa
4  * SPDX-FileCopyrightText: 2022 Smart Robotics Lab, Imperial College London, Technical University of Munich
5  * SPDX-FileCopyrightText: 2022 Nils Funk
6  * SPDX-FileCopyrightText: 2022 Sotiris Papatheodorou
7  * SPDX-License-Identifier: MIT
8  */
9 
10 #ifndef SE_TRACKER_HPP
11 #define SE_TRACKER_HPP
12 
13 #include "se/map/preprocessor.hpp"
14 #include "se/map/raycaster.hpp"
15 #include "se/sensor/sensor.hpp"
16 
17 namespace se {
18 
19 constexpr float e_delta = 0.1f;
20 
21 struct TrackerConfig {
22  std::vector<int> iterations{10, 5, 4};
23  float dist_threshold = 0.1f;
24  float normal_threshold = 0.8f;
25  float track_threshold = 0.15f;
26  float icp_threshold = 0.00001f;
27 
31  void readYaml(const std::string& filename);
32 };
33 
34 std::ostream& operator<<(std::ostream& os, const TrackerConfig& c);
35 
36 
37 
38 struct TrackData {
39  int result;
40  float error;
41  float J[6];
42 
43  TrackData() : result(0), error(0.0f), J{0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}
44  {
45  }
46 };
47 
48 
49 
50 static inline Eigen::Matrix<float, 6, 6> makeJTJ(const Eigen::Matrix<float, 1, 21>& v)
51 {
52  Eigen::Matrix<float, 6, 6> C = Eigen::Matrix<float, 6, 6>::Zero();
53  C.row(0) = v.segment(0, 6);
54  C.row(1).segment(1, 5) = v.segment(6, 5);
55  C.row(2).segment(2, 4) = v.segment(11, 4);
56  C.row(3).segment(3, 3) = v.segment(15, 3);
57  C.row(4).segment(4, 2) = v.segment(18, 2);
58  C(5, 5) = v(20);
59 
60  for (int r = 1; r < 6; ++r)
61  for (int c = 0; c < r; ++c)
62  C(r, c) = C(c, r);
63  return C;
64 }
65 
66 
67 
68 static inline Eigen::Matrix<float, 6, 1> solve(const Eigen::Matrix<float, 1, 27>& vals)
69 {
70  const Eigen::Matrix<float, 6, 1> b = vals.segment(0, 6);
71  const Eigen::Matrix<float, 6, 6> C = makeJTJ(vals.segment(6, 21));
72  Eigen::LLT<Eigen::Matrix<float, 6, 6>> llt;
73  llt.compute(C);
74  Eigen::Matrix<float, 6, 1> res = llt.solve(b);
75  return llt.info() == Eigen::Success ? res : Eigen::Matrix<float, 6, 1>::Zero();
76 }
77 
78 
79 
80 template<typename MapT, typename SensorT>
81 class Tracker {
82  public:
83  Tracker(MapT& map, const SensorT& sensor, const TrackerConfig config = TrackerConfig()) :
84  map_(map),
85  sensor_(sensor),
86  config_(config),
87  tracking_result(sensor_.model.imageWidth() * sensor_.model.imageHeight(), TrackData())
88  {
89  }
90 
99  bool track(const se::Image<float>& depth_img, Eigen::Matrix4f& T_WS);
100 
111  bool track(const se::Image<float>& depth_img,
112  Eigen::Matrix4f& T_WS,
113  se::Image<Eigen::Vector3f>& surface_point_cloud_W,
114  se::Image<Eigen::Vector3f>& surface_normals_W);
115 
116  void renderTrackingResult(uint32_t* tracking_img_data);
117 
118  private:
119  void newReduce(const int block_idx,
120  float* output_data,
121  const Eigen::Vector2i& output_res,
122  TrackData* J_data,
123  const Eigen::Vector2i& J_res);
124 
125  void reduceKernel(float* output_data,
126  const Eigen::Vector2i& output_res,
127  TrackData* J_data,
128  const Eigen::Vector2i& J_res);
129 
130  void trackKernel(TrackData* output_data,
131  const se::Image<Eigen::Vector3f>& input_point_cloud_S,
132  const se::Image<Eigen::Vector3f>& input_normals_S,
133  const se::Image<Eigen::Vector3f>& surface_point_cloud_M_ref,
134  const se::Image<Eigen::Vector3f>& surface_normals_M_ref,
135  const Eigen::Matrix4f& T_WS,
136  const Eigen::Matrix4f& T_WS_ref,
137  const float dist_threshold,
138  const float normal_threshold);
139 
140  bool updatePoseKernel(Eigen::Matrix4f& T_WS,
141  const float* reduction_output_data,
142  const float icp_threshold);
143 
144  bool checkPoseKernel(Eigen::Matrix4f& T_WS,
145  Eigen::Matrix4f& previous_T_WS,
146  const float* reduction_output_data,
147  const Eigen::Vector2i& reduction_output_res,
148  const float track_threshold);
149 
150  MapT& map_;
151  const SensorT& sensor_;
152  const TrackerConfig config_;
153  std::vector<TrackData> tracking_result;
154 };
155 
156 } // namespace se
157 
158 #include "impl/tracker_impl.hpp"
159 
160 #endif // SE_TRACKER_HPP
Definition: tracker.hpp:21
float normal_threshold
Definition: tracker.hpp:24
std::ostream & operator<<(std::ostream &os, const FieldDataConfig< se::Field::Occupancy > &c)
float error
Definition: tracker.hpp:40
static Eigen::Matrix< float, 6, 6 > makeJTJ(const Eigen::Matrix< float, 1, 21 > &v)
Definition: tracker.hpp:50
Definition: tracker.hpp:38
Tracker(MapT &map, const SensorT &sensor, const TrackerConfig config=TrackerConfig())
Definition: tracker.hpp:83
Definition: tracker.hpp:81
TrackData()
Definition: tracker.hpp:43
static Eigen::Matrix< float, 6, 1 > solve(const Eigen::Matrix< float, 1, 27 > &vals)
Definition: tracker.hpp:68
float icp_threshold
Definition: tracker.hpp:26
constexpr float e_delta
Definition: tracker.hpp:19
float dist_threshold
Definition: tracker.hpp:23
int result
Definition: tracker.hpp:39
void readYaml(const std::string &filename)
Reads the struct members from the "tracker" node of a YAML file.
float track_threshold
Definition: tracker.hpp:25
std::vector< int > iterations
Definition: tracker.hpp:22
Helper wrapper to allocate and de-allocate octants in the octree.
Definition: colour_utils.hpp:17