cyclical_buffer.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Point Cloud Library (PCL) - www.pointclouds.org
5  * Copyright (c) 2010-2011, Willow Garage, Inc.
6  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * * Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following
17  * disclaimer in the documentation and/or other materials provided
18  * with the distribution.
19  * * Neither the name of Willow Garage, Inc. nor the names of its
20  * contributors may be used to endorse or promote products derived
21  * from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  *
36  */
37 
38 
40 #include <kfusion/precomp.hpp>
41 
42 bool
43 kfusion::cuda::CyclicalBuffer::checkForShift (cv::Ptr<cuda::TsdfVolume> volume, const Affine3f &cam_pose, const double distance_camera_target, const bool perform_shift, const bool last_shift, const bool record_mode)
44 {
45  bool result = false;
46  //mcwrap_.setCameraDist(distance_camera_target);
47  cv::Vec3f targetPoint(0,0, distance_camera_target);
48  targetPoint = cam_pose * targetPoint;
49  targetPoint[1] = cam_pose.translation()[1];
50  cv::Vec3f center_cube;
51  center_cube[0] = buffer_.origin_metric.x + buffer_.volume_size.x/2.0f;
52  center_cube[1] = buffer_.origin_metric.y + buffer_.volume_size.y/2.0f;
53  center_cube[2] = buffer_.origin_metric.z + buffer_.volume_size.z/2.0f;
54  double dist = norm(targetPoint, center_cube, cv::NORM_L2);
55  //printf(" dist: %f \n", dist);
56  if (dist > distance_threshold_)
57  result = true;
58 
59  // perform shifting operations
60  if (result || last_shift || perform_shift)
61  {
62  performShift (volume, targetPoint, cam_pose, last_shift, record_mode);
63  return true;
64  }
65 
66  return (result);
67 }
68 
69 
70 void
71 kfusion::cuda::CyclicalBuffer::performShift (cv::Ptr<cuda::TsdfVolume> volume, const cv::Vec3f& target_point, const Affine3f &cam_pose, const bool last_shift, const bool record_mode)
72 {
73  //ScopeTime* time = new ScopeTime("Whole Cube shift");
74  // compute new origin and offsets
75  Vec3i offset;
76  Vec3i minBounds;
77  Vec3i maxBounds;
78  if(!last_shift)
79  computeAndSetNewCubeMetricOrigin (volume, target_point, offset);
80  //ScopeTime* slice_time = new ScopeTime("Slice download");
81  // extract current slice from the TSDF volume (coordinates are in indices! (see fetchSliceAsCloud() )
82  if(!no_reconstruct_)
83  {
84  DeviceArray<Point> cloud;
85 
86  // calculate mininum and maximum slice bounds
87  if(last_shift)
88  {
89  minBounds[0] = minBounds[1] = minBounds[2] = 0;
90  maxBounds[0] = maxBounds[1] = maxBounds[2] = 512;
91  }
92  else
93  {
94  calcBounds(offset, minBounds, maxBounds);
95  }
96 
97  cloud = volume->fetchSliceAsCloud(cloud_buffer_device_, &buffer_, minBounds, maxBounds, global_shift_ );
98 
99  cloud_slice_ = cv::Mat(1, (int)cloud.size(), CV_32FC4);
100  cloud.download(cloud_slice_.ptr<Point>());
101 
102  //delete slice_time;
103 
104  Point* tsdf_ptr = cloud_slice_.ptr<Point>();
105  if(cloud.size() > 0)
106  {
107  std::cout << "#### Performing slice number: " << slice_count_ << " with " << cloud.size() << " TSDF values ####" << std::endl;
108  Vec3i fusionShift = global_shift_;
109  Vec3i fusionBackShift = global_shift_;
110  for(int i = 0; i < 3; i++)
111  {
112  if(minBounds[i] == 1 && !last_shift)
113  {
114  fusionShift[i] += maxBounds[i];
115  fusionBackShift[i] += minBounds[i];
116  }
117  else if(last_shift)
118  {
119  fusionShift[i] -= 1000000000;
120  fusionBackShift[i] += maxBounds[i];
121  }
122  else
123  {
124  fusionShift[i] += minBounds[i];
125  fusionBackShift[i] += maxBounds[i];
126  }
127  }
128  TSDFSlice slice;
129  slice.tsdf_values_ = cloud_slice_;
130  slice.offset_ = fusionShift;
131  slice.back_offset_ = fusionBackShift;
132  slice.imgposes_ = imgPoses_;
133  pl_.addTSDFSlice(slice, last_shift);
134  slice_count_++;
135  }
136  }
137  if(!last_shift)
138  {
139  // clear buffer slice and update the world model
140  volume->clearSlice(&buffer_, offset);
141 
142  // shift buffer addresses
143  shiftOrigin (volume, offset);
144  }
145 
146 
147 }
148 
149 void
150 kfusion::cuda::CyclicalBuffer::computeAndSetNewCubeMetricOrigin (cv::Ptr<cuda::TsdfVolume> volume, const cv::Vec3f& target_point, Vec3i& offset)
151 {
152  // compute new origin for the cube, based on the target point
153  float3 new_cube_origin_meters;
154  new_cube_origin_meters.x = target_point[0] - buffer_.volume_size.x/2.0f;
155  new_cube_origin_meters.y = target_point[1] - buffer_.volume_size.y/2.0f;
156  new_cube_origin_meters.z = target_point[2] - buffer_.volume_size.z/2.0f;
157  //printf("The old cube's metric origin was (%f, %f, %f).\n", buffer_.origin_metric.x, buffer_.origin_metric.y, buffer_.origin_metric.z);
158  //printf("The new cube's metric origin is now (%f, %f, %f).\n", new_cube_origin_meters.x, new_cube_origin_meters.y, new_cube_origin_meters.z);
159 
160  // deduce each shift in indices
161  offset[0] = calcIndex((new_cube_origin_meters.x - buffer_.origin_metric.x) * ( buffer_.voxels_size.x / (float) (buffer_.volume_size.x) ));
162  offset[1] = calcIndex((new_cube_origin_meters.y - buffer_.origin_metric.y) * ( buffer_.voxels_size.y / (float) (buffer_.volume_size.y) ));
163  offset[2] = calcIndex((new_cube_origin_meters.z - buffer_.origin_metric.z) * ( buffer_.voxels_size.z / (float) (buffer_.volume_size.z) ));
164 
165  //printf("The shift indices are (X:%d, Y:%d, Z:%d).\n", offset[0], offset[1], offset[2]);
166  // update the cube's metric origin
167  buffer_.origin_metric = new_cube_origin_meters;
168  volume->setPose(Affine3f().translate(Vec3f(new_cube_origin_meters.x, new_cube_origin_meters.y, new_cube_origin_meters.z)));
169 }
170 
171 void kfusion::cuda::CyclicalBuffer::calcBounds(Vec3i& offset, Vec3i& minBounds, Vec3i& maxBounds)
172 {
173 
174  //Compute slice bounds
175  int newX = buffer_.origin_GRID.x + offset[0];
176  int newY = buffer_.origin_GRID.y + offset[1];
177  int newZ = buffer_.origin_GRID.z + offset[2];
178 
179  //X
180  if (newX >= 0)
181  {
182  minBounds[0] = buffer_.origin_GRID.x;
183  maxBounds[0] = newX;
184  }
185  else
186  {
187  minBounds[0] = newX + buffer_.voxels_size.x;
188  maxBounds[0] = buffer_.origin_GRID.x + buffer_.voxels_size.x;
189  }
190 
191  if (minBounds[0] > maxBounds[0])
192  std::swap (minBounds[0], maxBounds[0]);
193 
194  //Y
195  if (newY >= 0)
196  {
197  minBounds[1] = buffer_.origin_GRID.y;
198  maxBounds[1] = newY;
199  }
200  else
201  {
202  minBounds[1] = newY + buffer_.voxels_size.y;
203  maxBounds[1] = buffer_.origin_GRID.y + buffer_.voxels_size.y;
204  }
205 
206  if(minBounds[1] > maxBounds[1])
207  std::swap (minBounds[1], maxBounds[1]);
208 
209  //Z
210  if (newZ >= 0)
211  {
212  minBounds[2] = buffer_.origin_GRID.z;
213  maxBounds[2] = newZ;
214  }
215  else
216  {
217  minBounds[2] = newZ + buffer_.voxels_size.z;
218  maxBounds[2] = buffer_.origin_GRID.z + buffer_.voxels_size.z;
219  }
220 
221  if (minBounds[2] > maxBounds[2])
222  std::swap(minBounds[2], maxBounds[2]);
223 
224  minBounds[0] -= buffer_.origin_GRID.x;
225  maxBounds[0] -= buffer_.origin_GRID.x;
226 
227  minBounds[1] -= buffer_.origin_GRID.y;
228  maxBounds[1] -= buffer_.origin_GRID.y;
229 
230  minBounds[2] -= buffer_.origin_GRID.z;
231  maxBounds[2] -= buffer_.origin_GRID.z;
232 
233  if (minBounds[0] < 0) // We are shifting Left
234  {
235  minBounds[0] += buffer_.voxels_size.x;
236  maxBounds[0] += buffer_.voxels_size.x;
237  }
238 
239 
240  if (minBounds[1] < 0) // We are shifting up
241  {
242  minBounds[1] += buffer_.voxels_size.y;
243  maxBounds[1] += buffer_.voxels_size.y;
244  }
245 
246  if (minBounds[2] < 0) // We are shifting forward
247  {
248  minBounds[2] += buffer_.voxels_size.z;
249  maxBounds[2] += buffer_.voxels_size.z;
250  }
251  for(int i = 0; i < 3; i++)
252  {
253  if(maxBounds[i] > 0)
254  {
255  if(minBounds[i] == 0)
256  {
257  maxBounds[i] += 1;
258  minBounds[i] += 1;
259 
260  }
261  if(maxBounds[i] == 512)
262  {
263  minBounds[i] -= 1;
264  maxBounds[i] -= 1;
265  //offset[i] -=1;
266  }
267  }
268  }
269 
270 
271  //cout << "minBounds: " << minBounds[0] << ", " << minBounds[1] << ", " << minBounds[2] << endl;
272  //cout << "maxBounds: " << maxBounds[0] << ", " << maxBounds[1] << ", " << maxBounds[2] << endl;
273 }
kfusion::TSDFSlice::imgposes_
std::vector< ImgPose * > imgposes_
Definition: types.hpp:42
kfusion::TSDFSlice::offset_
Vec3i offset_
Definition: types.hpp:40
kfusion::cuda::DeviceArray::size
size_t size() const
Returns size in elements.
Definition: device_array.hpp:257
cyclical_buffer.h
kfusion::Vec3f
cv::Vec3f Vec3f
Definition: types.hpp:16
kfusion::TSDFSlice
Definition: types.hpp:37
kfusion::cuda::DeviceArray::download
void download(T *host_ptr) const
Downloads data from internal buffer to CPU memory.
Definition: device_array.hpp:250
kfusion::TSDFSlice::back_offset_
Vec3i back_offset_
Definition: types.hpp:41
precomp.hpp
kfusion::cuda::CyclicalBuffer::calcBounds
void calcBounds(Vec3i &offset, Vec3i &minBounds, Vec3i &maxBounds)
Definition: cyclical_buffer.cpp:171
kfusion::cuda::CyclicalBuffer::buffer_
tsdf_buffer buffer_
structure that contains all TSDF buffer's addresses
Definition: cyclical_buffer.h:254
kfusion::Affine3f
cv::Affine3f Affine3f
Definition: types.hpp:18
kfusion::TSDFSlice::tsdf_values_
cv::Mat tsdf_values_
Definition: types.hpp:39
kfusion::device::Vec3f
float3 Vec3f
Definition: internal.hpp:26
kfusion::Vec3i
cv::Vec3i Vec3i
Definition: types.hpp:17
kfusion::tsdf_buffer::volume_size
float3 volume_size
Size of the volume, in meters.
Definition: tsdf_buffer.h:64
kfusion::cuda::CyclicalBuffer::distance_threshold_
double distance_threshold_
distance threshold (cube's center to target point) to trigger shift
Definition: cyclical_buffer.h:245
kfusion::tsdf_buffer::origin_metric
float3 origin_metric
Current metric origin of the cube, in world coordinates.
Definition: tsdf_buffer.h:62
kfusion::cuda::DeviceArray< Point >
kfusion::cuda::CyclicalBuffer::checkForShift
bool checkForShift(cv::Ptr< cuda::TsdfVolume > volume, const Affine3f &cam_pose, const double distance_camera_target, const bool perform_shift=true, const bool last_shift=false, const bool record_mode=false)
Check if shifting needs to be performed, returns true if so. Shifting is considered needed if the tar...
Definition: cyclical_buffer.cpp:43
kfusion::cuda::CyclicalBuffer::performShift
void performShift(cv::Ptr< cuda::TsdfVolume > volume, const cv::Vec3f &target_point, const Affine3f &cam_pose, const bool last_shift=false, const bool record_mode=false)
Perform shifting operations: Compute offsets. Extract current slice from TSDF buffer....
Definition: cyclical_buffer.cpp:71
kfusion::device::swap
__kf_hdevice__ void swap(T &a, T &b)
Definition: temp_utils.hpp:10
kfusion::Point
Definition: types.hpp:47
kfusion::device::norm
__kf_device__ float norm(const float3 &v)
Definition: temp_utils.hpp:87
kfusion::cuda::CyclicalBuffer::computeAndSetNewCubeMetricOrigin
void computeAndSetNewCubeMetricOrigin(cv::Ptr< cuda::TsdfVolume > volume, const cv::Vec3f &target_point, Vec3i &offset)
Computes and set the origin of the new cube (relative to the world), centered around a the target poi...
Definition: cyclical_buffer.cpp:150


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:23