VotingSpace.cpp
Go to the documentation of this file.
1 
18 #include "VotingSpace.hpp"
19 
20 //Global includes
21 #include <iostream>
22 #include <stdexcept>
23 #include <stdlib.h>
24 #include <math.h>
25 #include <map>
26 #include <algorithm>
27 
28 //Pkg includes
29 #include <boost/make_shared.hpp>
30 #include <boost/range/irange.hpp>
31 
32 //Local includes
35 #include "VotingResult.hpp"
37 
38 namespace ISM {
39 
41 {
42  //Flush voxelgrid from votes of e.g. last sub-ISM that used the grid to process its VotedPoses.
43  voteGrid.clear();
44  VotingSpacePtr votingSpaceInEval = shared_from_this();
45  std::vector<VotingResultCalculatorPtr> calculatorPerThread;
46  std::vector<boost::shared_ptr<boost::thread>> threads;
47  for (int i : boost::irange(0, nThreads)) {
48  votingBinsPerThread[i].clear();
49  resultsPerThread[i].clear();
50  calculatorPerThread.push_back(VotingResultCalculatorPtr(new VotingResultCalculator(votingSpaceInEval, enabledSelfVoteCheck, mRaterType)));
51  }
52 
53  std::sort(votes.begin(), votes.end(), [](const VotedPosePtr& v1, const VotedPosePtr& v2)
54  {
55  return v1->weight > v2->weight;
56  });
57 
58  curThread = 0;
59  //Insert all voted poses into voxelgrid (votingspace).
60  for (const VotedPosePtr& vote : votes)
61  {
62  PointPtr point = vote->pose->point;
63  VotingBinPtr bin = getBin(point->eigen.x(), point->eigen.y(), point->eigen.z());
64  bin->insert(vote);
65  }
66 
67  VotingResultPtrs results;
68  for (int i : boost::irange(0, nThreads)) {
69  //This little guy searches for scene instances in each voxel grid element.
70  threads.push_back(boost::make_shared<boost::thread>(&VotingSpace::calcResult, this, i, calculatorPerThread[i]));
71  }
72 
73  // join all threads and collect results
74  for (int i : boost::irange(0, nThreads)) {
75  threads[i]->join();
76  if (!resultsPerThread[i].empty())
77  results.insert(results.end(), resultsPerThread[i].begin(), resultsPerThread[i].end());
78  }
79 
80  return results;
81 }
82 
84  if (votingBinsPerThread[i].empty())
85  return;
86  for (VotingBinPtr& votingBin : votingBinsPerThread[i]) {
87  VotingResultPtr result;
88  if (calculator->computeVotingResult(result, votingBin->votes))
89  {
90  resultsPerThread[i].push_back(result);
91  }
92  }
93 }
94 
95 VotingBinPtr VotingSpace::getBin(double x, double y, double z)
96 {
97  int binx = discretizeToBins(x);
98  int biny = discretizeToBins(y);
99  int binz = discretizeToBins(z);
100 
101  if (voteGrid.find(binx) == voteGrid.end())
102  {
103  voteGrid.insert(std::make_pair(binx, YIndexToZIndex()));
104  }
105 
106  if (voteGrid[binx].find(biny) == voteGrid[binx].end())
107  {
108  voteGrid[binx].insert(std::make_pair(biny, ZIndexToVotingBinPtr()));
109  }
110 
111  if (voteGrid[binx][biny].find(binz) == voteGrid[binx][biny].end())
112  {
113  voteGrid[binx][biny].insert(std::make_pair(binz, VotingBinPtr(new VotingBin(binx, biny, binz))));
114  // add bins to thread
115  votingBinsPerThread[curThread].push_back(voteGrid[binx][biny][binz]);
116  curThread = (curThread + 1) % nThreads;
117  }
118 
119  return voteGrid[binx][biny][binz];
120 }
121 
122 TypeToInnerMap VotingSpace::collectVotesInSphere(PointPtr &sphereCenter, bool& voteFromReferenceObjectExists)
123 {
124  voteFromReferenceObjectExists = false;
125 
126  const int binXIdx = discretizeToBins(sphereCenter->eigen.x());
127  const int binYIdx = discretizeToBins(sphereCenter->eigen.y());
128  const int binZIdx = discretizeToBins(sphereCenter->eigen.z());
129 
130  //We need the cartisian position of the center of the current bin to compare it to originForFitting.
131  PointPtr binCenter = PointPtr(new Point(binXIdx * binSize, binYIdx * binSize, binZIdx * binSize));
132 
133  // 3 bins per axis
134  int minXIdx = binXIdx - 1;
135  int minYIdx = binYIdx - 1;
136  int minZIdx = binZIdx - 1;
137  int maxXIdx = binXIdx + 1;
138  int maxYIdx = binYIdx + 1;
139  int maxZIdx = binZIdx + 1;
140 
141  // if sphere center is properly positioned, we don't have to consider all bins
142  if (sphereCenter->eigen.x() - binCenter->eigen.x() > offsetOfSphere) {
143  minXIdx ++;
144  } else if (sphereCenter->eigen.x() - binCenter->eigen.x() < -offsetOfSphere) {
145  maxXIdx --;
146  }
147  if (sphereCenter->eigen.y() - binCenter->eigen.y() > offsetOfSphere) {
148  minYIdx ++;
149  } else if (sphereCenter->eigen.y() - binCenter->eigen.y() < -offsetOfSphere) {
150  maxYIdx --;
151  }
152  if (sphereCenter->eigen.z() - binCenter->eigen.z() > offsetOfSphere) {
153  minZIdx ++;
154  } else if (sphereCenter->eigen.z() - binCenter->eigen.z() < -offsetOfSphere) {
155  maxZIdx --;
156  }
157 
158  // NOTE: At most 3 * 3 * 3 = 27 bins must be checked
159  TypeToInnerMap currentVoteMap;
160 
161  //Parts of this code are executed millions of times, so this code is perfomance optimized, not beautiful.
162  for (int xIdx = minXIdx; xIdx <= maxXIdx; xIdx++)
163  {
164  XIndexToYIndex::iterator yzGridIt = voteGrid.find(xIdx);
165  if (yzGridIt == voteGrid.end()) {
166  continue;
167  }
168  YIndexToZIndex yzGrid = yzGridIt->second;
169 
170  for (int yIdx = minYIdx; yIdx <= maxYIdx; yIdx++)
171  {
172  YIndexToZIndex::iterator zGridIt = yzGrid.find(yIdx);
173  if (zGridIt == yzGrid.end()) {
174  continue;
175  }
176  ZIndexToVotingBinPtr zGrid = zGridIt->second;
177 
178  for (int zIdx = minZIdx; zIdx <= maxZIdx; zIdx++)
179  {
180  ZIndexToVotingBinPtr::iterator votingBinIt = zGrid.find(zIdx);
181  if (votingBinIt == zGrid.end()) {
182  continue;
183  }
184  VotingBinPtr votingBinPtr = votingBinIt->second;
185 
186  VotedPosePtr votedPosePtr;
187  double squaredDistance;
188 
189  //Check all type and id combinations in that voxel element.
190  for (TypeToInnerMap::iterator typeIt = votingBinPtr->votes.begin();
191  typeIt != votingBinPtr->votes.end(); typeIt++)
192  {
193 
194  for (IdToVoteMap::iterator idIt = typeIt->second.begin();
195  idIt != typeIt->second.end(); idIt++)
196  {
197  //Categorizing votedPoses per type and id is required for reducing optimization of votedPose combination to optimization of votedPoses per type and id combination.
198  VotedPosePtrs& mapForCurrentTypeAndId = currentVoteMap[typeIt->first][idIt->first];
199 
200  //Self vote needs only to be checked once per type and id combination since all votes of the reference object are selfvotes.
201  if (GeometryHelper::isSelfVote(idIt->second.front()->vote))
202  voteFromReferenceObjectExists = true;
203 
204  for (VotedPosePtrs::iterator votedPosePtrsIt = idIt->second.begin();
205  votedPosePtrsIt != idIt->second.end(); votedPosePtrsIt++)
206  {
207  votedPosePtr = (*votedPosePtrsIt);
208  squaredDistance = GeometryHelper::getSquaredDistanceBetweenPoints(sphereCenter,
209  votedPosePtr->pose->point);
210  //Does votedPose lie within sphere?
211  if (squaredDistance < squaredRadius)
212  mapForCurrentTypeAndId.push_back(votedPosePtr);
213  }
214  }
215  }
216  }
217  }
218  }
219  return currentVoteMap;
220 }
221 
223 {
224  int result = 0;
225 
226  if(x >= -halfBinSize)
227  {
228  double temp = ((x + halfBinSize) / binSize);
229  if(fabs(temp - round(temp)) < VotingSpace::epsilon)
230  result = (int)round(temp);
231  else
232  result = (int) temp;
233  }
234  else
235  {
236  // 0.7071067811865475 double should have precision 15
237  double temp = (x - halfBinSize) / binSize;
238  if(fabs(temp - round(temp)) < VotingSpace::epsilon)
239  result = ((int)round(temp)) + 1;
240  else
241  result = (int) temp;
242  }
243  return result;
244 }
245 
246 }
VotingBinPtr getBin(double x, double y, double z)
Definition: VotingSpace.cpp:95
std::vector< std::vector< VotingResultPtr > > resultsPerThread
Definition: VotingSpace.hpp:88
boost::shared_ptr< VotingBin > VotingBinPtr
Definition: typedef.hpp:43
static bool isSelfVote(const VoteSpecifierPtr &vote)
void calcResult(int i, VotingResultCalculatorPtr &calculator)
Definition: VotingSpace.cpp:83
SOCI_EMPTY_DECL empty_backend_factory const empty
VotingResultPtrs fillAndEvalVotingSpace(VotedPosePtrs &votes, bool enabledSelfVoteCheck)
Definition: VotingSpace.cpp:40
boost::shared_ptr< Point > PointPtr
Definition: Point.hpp:45
int discretizeToBins(double x)
const double squaredRadius
Definition: VotingSpace.hpp:80
boost::shared_ptr< VotingResult > VotingResultPtr
Definition: typedef.hpp:37
const double halfBinSize
Definition: VotingSpace.hpp:75
std::vector< VotedPosePtr > VotedPosePtrs
Definition: typedef.hpp:59
const int mRaterType
Definition: VotingSpace.hpp:72
boost::shared_ptr< VotedPose > VotedPosePtr
Definition: typedef.hpp:31
std::map< std::string, IdToVoteMap > TypeToInnerMap
Definition: typedef.hpp:71
static double getSquaredDistanceBetweenPoints(const PointPtr &p1, const PointPtr &p2)
std::vector< boost::shared_ptr< boost::thread > > threads
Definition: VotingSpace.hpp:86
std::map< int, ZIndexToVotingBinPtr > YIndexToZIndex
Definition: typedef.hpp:78
const double offsetOfSphere
Definition: VotingSpace.hpp:82
std::map< int, VotingBinPtr > ZIndexToVotingBinPtr
Definition: typedef.hpp:77
boost::shared_ptr< VotingResultCalculator > VotingResultCalculatorPtr
std::vector< std::vector< VotingBinPtr > > votingBinsPerThread
Definition: VotingSpace.hpp:87
std::vector< VotingResultPtr > VotingResultPtrs
Definition: typedef.hpp:60
static constexpr double epsilon
Definition: VotingSpace.hpp:76
boost::shared_ptr< VotingSpace > VotingSpacePtr
Definition: typedef.hpp:34
this namespace contains all generally usable classes.
XIndexToYIndex voteGrid
Definition: VotingSpace.hpp:65
TypeToInnerMap collectVotesInSphere(PointPtr &centerPtr, bool &voteFromReferenceObjectExists)


asr_lib_ism
Author(s): Hanselmann Fabian, Heller Florian, Heizmann Heinrich, Kübler Marcel, Mehlhaus Jonas, Meißner Pascal, Qattan Mohamad, Reckling Reno, Stroh Daniel
autogenerated on Wed Jan 8 2020 04:02:41