RegistrationPipeline.cpp
Go to the documentation of this file.
1 
31 
32 #include "vector"
33 #include <math.h>
34 
43 using namespace lvr2;
44 
46 {
47  Rotationd rotateA = a.block<3, 3>(0, 0);
48  Rotationd rotateB = b.block<3, 3>(0, 0);
49  Vector4d translateA = a.col(3);
50  Vector4d translateB = b.col(3);
51  assert(translateA[3] == 1.0);
52  assert(translateB[3] == 1.0);
53 
54  // calculate translation distance
55  double dist = (translateB - translateA).norm();
56 
57  // calculate angle difference
58  Rotationd bTransposed = rotateB.transpose();
59  Rotationd r = rotateA * bTransposed;
60 
61  double tmp = (r.trace() / 2.0) - 0.5;
62 
63  // fix so there will be no rounding errors, otherwise acos can be nan !!!
64  if (tmp < -1.0)
65  {
66  tmp = -1.0;
67  }
68  else if (tmp > 1.0)
69  {
70  tmp = 1.0;
71  }
72 
73  double angle = std::acos(tmp);
74 
75  if(m_options->verbose)
76  {
77  std::cout << "PoseDiff: " << dist << " ; AngleDiff: " << angle << std::endl;
78  }
79 
80  return (angle < m_options->diffAngle && dist < m_options->diffPosition);
81 }
82 
83 void RegistrationPipeline::rotateAroundYAxis(Transformd *inputMatrix4x4, double angle)
84 {
85  // rotate only the upper left part of inputMatrix4x4
86  Eigen::Matrix<double, 3, 3> tmp_mat(inputMatrix4x4->block<3,3>(0,0));
87  // create y-vector (in scan coordinates) which can be transformed to world coordinates
88  Eigen::Vector3d v(0, 1, 0);
89  v = tmp_mat * v;
90 
91  double cosA = cos(angle);
92  double sinA = sin(angle);
93 
94  // create rotation matrix
95  Eigen::Matrix<double, 3, 3> mult_mat;
96  mult_mat << v(0)*v(0)*(1.0-cosA)+cosA, v(0)*v(1)*(1.0-cosA)-v(2)*sinA, v(0)*v(2)*(1.0-cosA)+v(1)*sinA,
97  v(1)*v(0)*(1.0-cosA)+v(2)*sinA, v(1)*v(1)*(1.0-cosA)+cosA, v(1)*v(2)*(1.0-cosA)-v(0)*sinA,
98  v(2)*v(0)*(1.0-cosA)-v(1)*sinA, v(2)*v(1)*(1.0-cosA)+v(0)*sinA, v(2)*v(2)*(1.0-cosA)+cosA;
99  tmp_mat = tmp_mat * mult_mat;
100 
101  // save result in original Matrix
102  inputMatrix4x4[0](0,0) = tmp_mat(0,0);
103  inputMatrix4x4[0](0,1) = tmp_mat(0,1);
104  inputMatrix4x4[0](0,2) = tmp_mat(0,2);
105  inputMatrix4x4[0](1,0) = tmp_mat(1,0);
106  inputMatrix4x4[0](1,1) = tmp_mat(1,1);
107  inputMatrix4x4[0](1,2) = tmp_mat(1,2);
108  inputMatrix4x4[0](2,0) = tmp_mat(2,0);
109  inputMatrix4x4[0](2,1) = tmp_mat(2,1);
110  inputMatrix4x4[0](2,2) = tmp_mat(2,2);
111 }
112 
114 {
115  m_options = options;
116  m_scans = scans;
117 }
118 
119 
121 {
122  // Create SLAMAlign object and add separate scans. The scans are not transferred via the constructor, because then they will not reduced.
123  SLAMAlign align(*m_options);
124  for (size_t i = 0; i < m_scans->project->positions.size(); i++)
125  {
126  if(m_scans->project->positions.at(i)->scans.size())
127  {
128  // if m_options->rotate_angle is not 0 -> all scans will be rotate around y axis
129  rotateAroundYAxis(&(m_scans->project->positions[i]->scans[0]->poseEstimation), m_options->rotate_angle * M_PI / 180);
130 
131  // the SLAMAlign object needs a scan pointer
132  ScanPtr scptr = std::make_shared<Scan>(*(m_scans->project->positions[i]->scans[0]));
133  align.addScan(scptr);
134  }
135  }
136 
137  if (m_options->verbose)
138  {
139  cout << "start SLAMAlign registration" << endl;
140  }
141 
142  // start the registration (with params from m_options)
143  align.finish();
144 
145  if (m_options->verbose)
146  {
147  cout << "end SLAMAlign registration" << endl;
148  }
149 
150  // if all values are new, the second registration is not needed
151  bool all_values_new = true;
152  for (int i = 0; i < m_scans->project->positions.size(); i++)
153  {
154  // check if the new pos different to old pos
155  ScanPositionPtr posPtr = m_scans->project->positions.at(i);
156 
157  if (( !m_scans->changed.at(i)) &&
158  !isToleratedDifference(
159  m_scans->project->positions.at(i)->scans[0]->registration,
160  align.scan(i)->pose()))
161  {
162  m_scans->changed.at(i) = true;
163  cout << "New Values"<< endl;
164  }
165  // new pose of the first scan is same as the old pose
166  else if (i != 0)
167  {
168  all_values_new = false;
169  }
170  }
171  cout << "First registration done" << endl;
172 
173  // new align with fix old values only when not all poses new
174  if (all_values_new)
175  {
176  cout << "no new registration" << endl;
177  }
178  else
179  {
180  cout << "start new registration with some fix poses" << endl;
181 
182  // do the same as above only with the m_scans->changed array wich says which scan is fix
183  align = SLAMAlign(*m_options, m_scans->changed);
184 
185  for (size_t i = 0; i < m_scans->project->positions.size(); i++)
186  {
187  if(m_scans->project->positions.at(i)->scans.size())
188  {
189  ScanPtr scptr = std::make_shared<Scan>(*(m_scans->project->positions[i]->scans[0]));
190 
191  align.addScan(scptr);
192  }
193  }
194 
195  align.finish();
196  }
197 
198  // transfer the calculated poses into the original data
199  for (int i = 0; i < m_scans->project->positions.size(); i++)
200  {
201  ScanPositionPtr posPtr = m_scans->project->positions.at(i);
202 
203  if (m_scans->changed.at(i) || all_values_new)
204  {
205  posPtr->scans[0]->registration = align.scan(i)->pose();
206  posPtr->registration = align.scan(i)->pose();
207  cout << "Pose Scan Nummer " << i << endl << posPtr->scans[0]->registration << endl;
208  }
209  }
210 }
RegistrationPipeline::RegistrationPipeline
RegistrationPipeline(const SLAMOptions *options, ScanProjectEditMarkPtr scans)
Construct a new RegistrationPipeline object.
Definition: RegistrationPipeline.cpp:113
lvr2::ScanProjectEditMarkPtr
std::shared_ptr< ScanProjectEditMark > ScanProjectEditMarkPtr
Definition: ScanTypes.hpp:357
SLAMAlign.hpp
lvr2::Transformd
Transform< double > Transformd
4x4 double precision transformation matrix
Definition: MatrixTypes.hpp:71
SLAMScanWrapper.hpp
M_PI
#define M_PI
Definition: Matrix4.hpp:52
RegistrationPipeline.hpp
options
const kaboom::Options * options
Definition: src/tools/lvr2_kaboom/Main.cpp:45
lvr2::SLAMAlign::scan
SLAMScanPtr scan(size_t index) const
Returns a shared_ptr to a Scan.
Definition: SLAMAlign.cpp:93
lvr2::ScanPositionPtr
std::shared_ptr< ScanPosition > ScanPositionPtr
Definition: ScanTypes.hpp:311
RegistrationPipeline::isToleratedDifference
bool isToleratedDifference(Transformd a, Transformd b)
Metric to determine wether the given matrices are too different from each other.
Definition: RegistrationPipeline.cpp:45
RegistrationPipeline::rotateAroundYAxis
void rotateAroundYAxis(Transformd *inputMatrix4x4, double angle)
Rotates the given 4x4 matrix around the y-axis.
Definition: RegistrationPipeline.cpp:83
RegistrationPipeline::doRegistration
void doRegistration()
Starts the registration.
Definition: RegistrationPipeline.cpp:120
lvr2::Vector3d
Eigen::Vector3d Vector3d
Eigen 3D vector, double precision.
Definition: MatrixTypes.hpp:121
lvr2::SLAMAlign
A class to run SLAM on Scans.
Definition: SLAMAlign.hpp:48
lvr2
Definition: BaseBufferManipulators.hpp:39
lvr2::Vector4d
Eigen::Vector4d Vector4d
Eigen 4D vector, double precision.
Definition: MatrixTypes.hpp:134
kfusion::device::norm
__kf_device__ float norm(const float3 &v)
Definition: temp_utils.hpp:87
lvr2::SLAMAlign::finish
void finish()
Indicates that no new Scans will be added.
Definition: SLAMAlign.cpp:369
lvr2::SLAMOptions
A struct to configure SLAMAlign.
Definition: SLAMOptions.hpp:45
lvr2::SLAMAlign::addScan
void addScan(const SLAMScanPtr &scan, bool match=false)
Adds a new Scan to the SLAM instance.
Definition: SLAMAlign.cpp:77
lvr2::Rotationd
Rotation< double > Rotationd
Double precision 3x3 rotation matrix.
Definition: MatrixTypes.hpp:81
lvr2::ScanPtr
std::shared_ptr< Scan > ScanPtr
Shared pointer to scans.
Definition: ScanTypes.hpp:98


lvr2
Author(s): Thomas Wiemann , Sebastian Pütz , Alexander Mock , Lars Kiesow , Lukas Kalbertodt , Tristan Igelbrink , Johan M. von Behren , Dominik Feldschnieders , Alexander Löhr
autogenerated on Wed Mar 2 2022 00:37:24