ScanMatcher.h
Go to the documentation of this file.
1 //=================================================================================================
2 // Copyright (c) 2011, Stefan Kohlbrecher, TU Darmstadt
3 // All rights reserved.
4 
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above copyright
10 // notice, this list of conditions and the following disclaimer in the
11 // documentation and/or other materials provided with the distribution.
12 // * Neither the name of the Simulation, Systems Optimization and Robotics
13 // group, TU Darmstadt nor the names of its contributors may be used to
14 // endorse or promote products derived from this software without
15 // specific prior written permission.
16 
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //=================================================================================================
28 
29 #ifndef _scanmatcher_h__
30 #define _scanmatcher_h__
31 
32 #include <Eigen/Geometry>
33 #include "../scan/DataPointContainer.h"
34 #include "../util/UtilFunctions.h"
35 
36 #include "../util/DrawInterface.h"
37 #include "../util/HectorDebugInfoInterface.h"
38 
39 namespace hectorslam{
40 
41 template<typename ConcreteOccGridMapUtil>
43 {
44 public:
45 
46  ScanMatcher(DrawInterface* drawInterfaceIn = 0, HectorDebugInfoInterface* debugInterfaceIn = 0)
47  : drawInterface(drawInterfaceIn)
48  , debugInterface(debugInterfaceIn)
49  {}
50 
52  {}
53 
54  Eigen::Vector3f matchData(const Eigen::Vector3f& beginEstimateWorld, ConcreteOccGridMapUtil& gridMapUtil, const DataContainer& dataContainer, Eigen::Matrix3f& covMatrix, int maxIterations)
55  {
56  if (drawInterface){
57  drawInterface->setScale(0.05f);
58  drawInterface->setColor(0.0f,1.0f, 0.0f);
59  drawInterface->drawArrow(beginEstimateWorld);
60 
61  Eigen::Vector3f beginEstimateMap(gridMapUtil.getMapCoordsPose(beginEstimateWorld));
62 
63  drawScan(beginEstimateMap, gridMapUtil, dataContainer);
64 
65  drawInterface->setColor(1.0,0.0,0.0);
66  }
67 
68  if (dataContainer.getSize() != 0) {
69 
70  Eigen::Vector3f beginEstimateMap(gridMapUtil.getMapCoordsPose(beginEstimateWorld));
71 
72  Eigen::Vector3f estimate(beginEstimateMap);
73 
74  estimateTransformationLogLh(estimate, gridMapUtil, dataContainer);
75  //bool notConverged = estimateTransformationLogLh(estimate, gridMapUtil, dataContainer);
76 
77  /*
78  const Eigen::Matrix2f& hessian (H.block<2,2>(0,0));
79 
80 
81  Eigen::SelfAdjointEigenSolver<Eigen::Matrix2f> eig(hessian);
82 
83  const Eigen::Vector2f& eigValues (eig.eigenvalues());
84 
85  float cond = eigValues[1] / eigValues[0];
86  float determinant = (hessian.determinant());
87  */
88  //std::cout << "\n cond: " << cond << " det: " << determinant << "\n";
89 
90 
91  int numIter = maxIterations;
92 
93 
94  for (int i = 0; i < numIter; ++i) {
95  //std::cout << "\nest:\n" << estimate;
96 
97  estimateTransformationLogLh(estimate, gridMapUtil, dataContainer);
98  //notConverged = estimateTransformationLogLh(estimate, gridMapUtil, dataContainer);
99 
100  if(drawInterface){
101  float invNumIterf = 1.0f/static_cast<float> (numIter);
102  drawInterface->setColor(static_cast<float>(i)*invNumIterf,0.0f, 0.0f);
103  drawInterface->drawArrow(gridMapUtil.getWorldCoordsPose(estimate));
104  //drawInterface->drawArrow(Eigen::Vector3f(0.0f, static_cast<float>(i)*0.05, 0.0f));
105  }
106 
107  if(debugInterface){
109  }
110  }
111 
112  if (drawInterface){
113  drawInterface->setColor(0.0,0.0,1.0);
114  drawScan(estimate, gridMapUtil, dataContainer);
115  }
116  /*
117  Eigen::Matrix2f testMat(Eigen::Matrix2f::Identity());
118  testMat(0,0) = 2.0f;
119 
120  float angleWorldCoords = util::toRad(30.0f);
121  float sinAngle = sin(angleWorldCoords);
122  float cosAngle = cos(angleWorldCoords);
123 
124  Eigen::Matrix2f rotMat;
125  rotMat << cosAngle, -sinAngle, sinAngle, cosAngle;
126  Eigen::Matrix2f covarianceRotated (rotMat * testMat * rotMat.transpose());
127 
128  drawInterface->setColor(0.0,0.0,1.0,0.5);
129  drawInterface->drawCovariance(gridMapUtil.getWorldCoordsPoint(estimate.start<2>()), covarianceRotated);
130  */
131 
132 
133 
134  /*
135  Eigen::Matrix3f covMatMap (gridMapUtil.getCovarianceForPose(estimate, dataContainer));
136  std::cout << "\nestim:" << estimate;
137  std::cout << "\ncovMap\n" << covMatMap;
138  drawInterface->setColor(0.0,0.0,1.0,0.5);
139 
140 
141  Eigen::Matrix3f covMatWorld(gridMapUtil.getCovMatrixWorldCoords(covMatMap));
142  std::cout << "\ncovWorld\n" << covMatWorld;
143 
144  drawInterface->drawCovariance(gridMapUtil.getWorldCoordsPoint(estimate.start<2>()), covMatMap.block<2,2>(0,0));
145 
146  drawInterface->setColor(1.0,0.0,0.0,0.5);
147  drawInterface->drawCovariance(gridMapUtil.getWorldCoordsPoint(estimate.start<2>()), covMatWorld.block<2,2>(0,0));
148 
149  std::cout << "\nH:\n" << H;
150 
151  float determinant = H.determinant();
152  std::cout << "\nH_det: " << determinant;
153  */
154 
155  /*
156  Eigen::Matrix2f covFromHessian(H.block<2,2>(0,0) * 1.0f);
157  //std::cout << "\nCovFromHess:\n" << covFromHessian;
158 
159  drawInterface->setColor(0.0, 1.0, 0.0, 0.5);
160  drawInterface->drawCovariance(gridMapUtil.getWorldCoordsPoint(estimate.start<2>()),covFromHessian.inverse());
161 
162  Eigen::Matrix3f covFromHessian3d(H * 1.0f);
163  //std::cout << "\nCovFromHess:\n" << covFromHessian;
164 
165  drawInterface->setColor(1.0, 0.0, 0.0, 0.8);
166  drawInterface->drawCovariance(gridMapUtil.getWorldCoordsPoint(estimate.start<2>()),(covFromHessian3d.inverse()).block<2,2>(0,0));
167  */
168 
169 
170  estimate[2] = util::normalize_angle(estimate[2]);
171 
172  covMatrix = Eigen::Matrix3f::Zero();
173  //covMatrix.block<2,2>(0,0) = (H.block<2,2>(0,0).inverse());
174  //covMatrix.block<2,2>(0,0) = (H.block<2,2>(0,0));
175 
176 
177  /*
178  covMatrix(0,0) = 1.0/(0.1*0.1);
179  covMatrix(1,1) = 1.0/(0.1*0.1);
180  covMatrix(2,2) = 1.0/((M_PI / 18.0f) * (M_PI / 18.0f));
181  */
182 
183 
184  covMatrix = H;
185 
186  return gridMapUtil.getWorldCoordsPose(estimate);
187  }
188 
189  return beginEstimateWorld;
190  }
191 
192 protected:
193 
194  bool estimateTransformationLogLh(Eigen::Vector3f& estimate, ConcreteOccGridMapUtil& gridMapUtil, const DataContainer& dataPoints)
195  {
196  gridMapUtil.getCompleteHessianDerivs(estimate, dataPoints, H, dTr);
197  //std::cout << "\nH\n" << H << "\n";
198  //std::cout << "\ndTr\n" << dTr << "\n";
199 
200 
201  if ((H(0, 0) != 0.0f) && (H(1, 1) != 0.0f)) {
202 
203 
204  //H += Eigen::Matrix3f::Identity() * 1.0f;
205  Eigen::Vector3f searchDir (H.inverse() * dTr);
206 
207  //std::cout << "\nsearchdir\n" << searchDir << "\n";
208 
209  if (searchDir[2] > 0.2f) {
210  searchDir[2] = 0.2f;
211  std::cout << "SearchDir angle change too large\n";
212  } else if (searchDir[2] < -0.2f) {
213  searchDir[2] = -0.2f;
214  std::cout << "SearchDir angle change too large\n";
215  }
216 
217  updateEstimatedPose(estimate, searchDir);
218  return true;
219  }
220  return false;
221  }
222 
223  void updateEstimatedPose(Eigen::Vector3f& estimate, const Eigen::Vector3f& change)
224  {
225  estimate += change;
226  }
227 
228  void drawScan(const Eigen::Vector3f& pose, const ConcreteOccGridMapUtil& gridMapUtil, const DataContainer& dataContainer)
229  {
230  drawInterface->setScale(0.02);
231 
232  Eigen::Affine2f transform(gridMapUtil.getTransformForState(pose));
233 
234  int size = dataContainer.getSize();
235  for (int i = 0; i < size; ++i) {
236  const Eigen::Vector2f& currPoint (dataContainer.getVecEntry(i));
237  drawInterface->drawPoint(gridMapUtil.getWorldCoordsPoint(transform * currPoint));
238  }
239  }
240 
241 protected:
242  Eigen::Vector3f dTr;
243  Eigen::Matrix3f H;
244 
247 };
248 
249 }
250 
251 
252 #endif
void drawScan(const Eigen::Vector3f &pose, const ConcreteOccGridMapUtil &gridMapUtil, const DataContainer &dataContainer)
Definition: ScanMatcher.h:228
void updateEstimatedPose(Eigen::Vector3f &estimate, const Eigen::Vector3f &change)
Definition: ScanMatcher.h:223
f
virtual void setColor(double r, double g, double b, double a=1.0)=0
ScanMatcher(DrawInterface *drawInterfaceIn=0, HectorDebugInfoInterface *debugInterfaceIn=0)
Definition: ScanMatcher.h:46
virtual void drawPoint(const Eigen::Vector2f &pointWorldFrame)=0
Eigen::Vector3f dTr
Definition: ScanMatcher.h:242
virtual void setScale(double scale)=0
const DataPointType & getVecEntry(int index) const
static float normalize_angle(float angle)
Definition: UtilFunctions.h:41
virtual void drawArrow(const Eigen::Vector3f &poseWorld)=0
bool estimateTransformationLogLh(Eigen::Vector3f &estimate, ConcreteOccGridMapUtil &gridMapUtil, const DataContainer &dataPoints)
Definition: ScanMatcher.h:194
virtual void addHessianMatrix(const Eigen::Matrix3f &hessian)=0
Eigen::Vector3f matchData(const Eigen::Vector3f &beginEstimateWorld, ConcreteOccGridMapUtil &gridMapUtil, const DataContainer &dataContainer, Eigen::Matrix3f &covMatrix, int maxIterations)
Definition: ScanMatcher.h:54
HectorDebugInfoInterface * debugInterface
Definition: ScanMatcher.h:246
DrawInterface * drawInterface
Definition: ScanMatcher.h:245
Eigen::Matrix3f H
Definition: ScanMatcher.h:243


hector_mapping
Author(s): Stefan Kohlbrecher
autogenerated on Sun Nov 3 2019 03:18:33