Skip to content

Commit 48aa18a

Browse files
fix integrateDepth with pointcloud in mapper (#117)
Co-authored-by: Remo Steiner <remos@nvidia.com>
1 parent 9413b5d commit 48aa18a

File tree

4 files changed

+121
-2
lines changed

4 files changed

+121
-2
lines changed

nvblox/include/nvblox/mapper/internal/impl/mapper_impl.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ limitations under the License.
1515
*/
1616
#pragma once
1717

18+
#include "nvblox/sensors/pointcloud_to_depth_conversion.h"
19+
1820
namespace nvblox {
1921
template <typename SensorType>
2022
void Mapper::integrateDepth(const DepthImage& depth_frame,
@@ -96,8 +98,7 @@ void Mapper::integrateDepth(const Pointcloud& pointcloud,
9698
*cuda_stream_);
9799

98100
// Integrate the depth image.
99-
integrateDepth(depth_frame_from_pointcloud_, T_L_S_scanStart, lidar_sensor,
100-
T_L_S_scanEnd, scan_duration_ms);
101+
integrateDepth(depth_frame_from_pointcloud_, T_L_S_scanStart, lidar_sensor);
101102
}
102103

103104
template <typename SensorType>

nvblox/include/nvblox/mapper/internal/impl/multi_mapper_impl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
16+
#pragma once
1617

1718
#include "nvblox/sensors/pointcloud_to_depth_conversion.h"
1819

nvblox/tests/test_mapper.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ limitations under the License.
2626
#include "nvblox/mapper/mapper.h"
2727
#include "nvblox/mesh/mesh.h"
2828
#include "nvblox/primitives/scene.h"
29+
#include "nvblox/sensors/lidar.h"
2930
#include "nvblox/tests/utils.h"
3031

3132
using namespace nvblox;
@@ -403,6 +404,64 @@ TEST(MapperTest, SaveAndLoad) {
403404
mapper2.freespace_layer().numBlocks());
404405
}
405406

407+
TEST(MapperTest, IntegratePointcloud) {
408+
// Create a simple pointcloud
409+
Pointcloud pointcloud(MemoryType::kUnified);
410+
std::vector<Vector3f> points_host = {
411+
Vector3f(1.0f, 0.0f, 0.0f), Vector3f(2.0f, 0.0f, 0.0f),
412+
Vector3f(3.0f, 0.0f, 0.0f), Vector3f(1.5f, 0.5f, 0.0f),
413+
Vector3f(2.5f, -0.5f, 0.0f), Vector3f(2.0f, 1.0f, 0.0f),
414+
Vector3f(2.0f, -1.0f, 0.0f), Vector3f(3.0f, 0.5f, 0.5f)};
415+
pointcloud.copyPointsFromAsync(points_host, CudaStreamOwning());
416+
417+
// Create a Lidar sensor with valid dimensions
418+
const int num_azimuth_divisions = 1024;
419+
const int num_elevation_divisions = 16;
420+
const float min_valid_range_m = 0.1f;
421+
const float vertical_fov_rad = 30.0f * M_PI / 180.0f;
422+
Lidar lidar(num_azimuth_divisions, num_elevation_divisions, min_valid_range_m,
423+
vertical_fov_rad);
424+
425+
// Create Mapper
426+
const float voxel_size_m = 0.1f;
427+
Mapper mapper(voxel_size_m, MemoryType::kDevice, ProjectiveLayerType::kTsdf);
428+
429+
// Integrate pointcloud without motion compensation
430+
Transform T_L_S = Transform::Identity();
431+
bool use_lidar_motion_compensation = false;
432+
mapper.integrateDepth(pointcloud, T_L_S, lidar,
433+
use_lidar_motion_compensation);
434+
435+
// Verify integration worked - should have allocated some blocks
436+
const int num_blocks_after_first = mapper.tsdf_layer().numBlocks();
437+
EXPECT_GT(num_blocks_after_first, 0);
438+
439+
// Integrate pointcloud again with motion compensation from a different
440+
// location Motion compensation requires timestamps for each point
441+
const int64_t scan_duration_ms_value = 100;
442+
Time scan_duration_ms(scan_duration_ms_value);
443+
std::vector<Time> timestamps_ms(points_host.size());
444+
for (size_t i = 0; i < points_host.size(); i++) {
445+
// Spread timestamps evenly across scan duration
446+
timestamps_ms[i] = Time(i * scan_duration_ms_value / points_host.size());
447+
}
448+
pointcloud.copyTimestampsFromAsync(timestamps_ms, CudaStreamOwning());
449+
450+
// Start from a different position to cover new space
451+
Transform T_L_S_scanStart2 = Transform::Identity();
452+
T_L_S_scanStart2.translate(Vector3f(0.0f, 3.0f, 0.0f)); // Start 3m away in y
453+
Transform T_L_S_scanEnd2 = Transform::Identity();
454+
T_L_S_scanEnd2.translate(Vector3f(0.0f, 4.0f, 0.0f)); // End 4m away in y
455+
use_lidar_motion_compensation = true;
456+
mapper.integrateDepth(pointcloud, T_L_S_scanStart2, lidar,
457+
use_lidar_motion_compensation, T_L_S_scanEnd2,
458+
scan_duration_ms);
459+
460+
// Verify more blocks were allocated after second integration
461+
const int num_blocks_after_second = mapper.tsdf_layer().numBlocks();
462+
EXPECT_GT(num_blocks_after_second, num_blocks_after_first);
463+
}
464+
406465
int main(int argc, char** argv) {
407466
FLAGS_alsologtostderr = true;
408467
google::InitGoogleLogging(argv[0]);

nvblox/tests/test_multi_mapper.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ limitations under the License.
1919

2020
#include "nvblox/datasets/3dmatch.h"
2121
#include "nvblox/mapper/multi_mapper.h"
22+
#include "nvblox/sensors/lidar.h"
2223

2324
using namespace nvblox;
2425

@@ -191,6 +192,63 @@ TEST_F(MultiMapperTest, MaskOnAndOff) {
191192
LOG(INFO) << "num_non_zero_weight_voxels: ";
192193
}
193194

195+
TEST_F(MultiMapperTest, IntegratePointcloud) {
196+
// Create a simple pointcloud
197+
Pointcloud pointcloud(MemoryType::kUnified);
198+
std::vector<Vector3f> points_host = {
199+
Vector3f(1.0f, 0.0f, 0.0f), Vector3f(2.0f, 0.0f, 0.0f),
200+
Vector3f(3.0f, 0.0f, 0.0f), Vector3f(1.5f, 0.5f, 0.0f),
201+
Vector3f(2.5f, -0.5f, 0.0f), Vector3f(2.0f, 1.0f, 0.0f),
202+
Vector3f(2.0f, -1.0f, 0.0f), Vector3f(3.0f, 0.5f, 0.5f)};
203+
pointcloud.copyPointsFromAsync(points_host, CudaStreamOwning());
204+
205+
// Create a Lidar sensor with valid dimensions
206+
const int num_azimuth_divisions = 1024;
207+
const int num_elevation_divisions = 16;
208+
const float min_valid_range_m = 0.1f;
209+
const float vertical_fov_rad = 30.0f * M_PI / 180.0f;
210+
Lidar lidar(num_azimuth_divisions, num_elevation_divisions, min_valid_range_m,
211+
vertical_fov_rad);
212+
213+
// Integrate pointcloud using MultiMapper without motion compensation
214+
Transform T_L_S = Transform::Identity();
215+
bool use_lidar_motion_compensation = false;
216+
multi_mapper_.integrateDepth(pointcloud, T_L_S, lidar,
217+
use_lidar_motion_compensation);
218+
219+
// Verify integration worked - should have allocated some blocks
220+
// MultiMapper integrates into the background mapper by default
221+
const int num_blocks_after_first =
222+
multi_mapper_.background_mapper()->tsdf_layer().numBlocks();
223+
EXPECT_GT(num_blocks_after_first, 0);
224+
225+
// Integrate pointcloud again with motion compensation from a different
226+
// location Motion compensation requires timestamps for each point
227+
const int64_t scan_duration_ms_value = 100;
228+
Time scan_duration_ms(scan_duration_ms_value);
229+
std::vector<Time> timestamps_ms(points_host.size());
230+
for (size_t i = 0; i < points_host.size(); i++) {
231+
// Spread timestamps evenly across scan duration
232+
timestamps_ms[i] = Time(i * scan_duration_ms_value / points_host.size());
233+
}
234+
pointcloud.copyTimestampsFromAsync(timestamps_ms, CudaStreamOwning());
235+
236+
// Start from a different position to cover new space
237+
Transform T_L_S_scanStart2 = Transform::Identity();
238+
T_L_S_scanStart2.translate(Vector3f(0.0f, 3.0f, 0.0f)); // Start 3m away in y
239+
Transform T_L_S_scanEnd2 = Transform::Identity();
240+
T_L_S_scanEnd2.translate(Vector3f(0.0f, 4.0f, 0.0f)); // End 4m away in y
241+
use_lidar_motion_compensation = true;
242+
multi_mapper_.integrateDepth(pointcloud, T_L_S_scanStart2, lidar,
243+
use_lidar_motion_compensation, T_L_S_scanEnd2,
244+
scan_duration_ms);
245+
246+
// Verify more blocks were allocated after second integration
247+
const int num_blocks_after_second =
248+
multi_mapper_.background_mapper()->tsdf_layer().numBlocks();
249+
EXPECT_GT(num_blocks_after_second, num_blocks_after_first);
250+
}
251+
194252
int main(int argc, char** argv) {
195253
FLAGS_alsologtostderr = true;
196254
google::InitGoogleLogging(argv[0]);

0 commit comments

Comments
 (0)