5
5
6
6
#include " RGLFields.hpp"
7
7
#include " math/Mat3x4f.hpp"
8
+ #include " gpu/MultiReturn.hpp"
9
+
10
+ #include < cmath>
8
11
9
12
using namespace std ::chrono_literals;
10
13
@@ -17,8 +20,10 @@ class GraphMultiReturn : public RGLTest
17
20
protected:
18
21
// VLP16 data
19
22
const float vlp16LidarObjectDistance = 100 .0f ;
20
- const float vlp16LidarHBeamDivergence = 0 .003f ; // Velodyne VLP16 horizontal beam divergence in rads
21
- const float vlp16LidarHBeamDiameter = 0 .2868f ; // Velodyne VLP16 beam horizontal diameter at 100m
23
+ const float vlp16LidarHBeamDivergence = 0 .003f ; // Velodyne VLP16 horizontal beam divergence in rads
24
+ const float vlp16LidarVBeamDivergence = 0 .0015f ; // Velodyne VLP16 vertical beam divergence in rads
25
+ const float vlp16LidarHBeamDiameter = 0 .2868f ; // Velodyne VLP16 beam horizontal diameter at 100m
26
+ const float vlp16LidarVBeamDiameter = 0 .1596f ; // Velodyne VLP16 beam vertical diameter at 100m
22
27
23
28
std::vector<Mat3x4f> vlp16Channels{Mat3x4f::TRS ({0 .0f , 0 .0f , mmToMeters (11 .2f )}, {0 .0f , -15 .0f , 0 .0f }),
24
29
Mat3x4f::TRS ({0 .0f , 0 .0f , mmToMeters (0 .7f )}, {0 .0f , +1 .0f , 0 .0f }),
@@ -45,13 +50,13 @@ class GraphMultiReturn : public RGLTest
45
50
publish = nullptr , cameraPublish = nullptr , mrPublishFirst = nullptr , mrPublishLast = nullptr ,
46
51
compactFirst = nullptr , compactLast = nullptr ;
47
52
48
- void constructMRGraph (const std::vector<rgl_mat3x4f>& raysTf, const rgl_mat3x4f& lidarPose, const float beamDivAngle ,
49
- bool withPublish = false )
53
+ void constructMRGraph (const std::vector<rgl_mat3x4f>& raysTf, const rgl_mat3x4f& lidarPose, const float hBeamDivAngle ,
54
+ const float vBeamDivAngle, bool withPublish = false )
50
55
{
51
56
EXPECT_RGL_SUCCESS (rgl_node_rays_from_mat3x4f (&mrRays, raysTf.data (), raysTf.size ()));
52
57
EXPECT_RGL_SUCCESS (rgl_node_rays_transform (&mrTransform, &lidarPose));
53
58
EXPECT_RGL_SUCCESS (rgl_node_raytrace (&mrRaytrace, nullptr ));
54
- EXPECT_RGL_SUCCESS (rgl_node_raytrace_configure_beam_divergence (mrRaytrace, beamDivAngle ));
59
+ EXPECT_RGL_SUCCESS (rgl_node_raytrace_configure_beam_divergence (mrRaytrace, hBeamDivAngle, vBeamDivAngle ));
55
60
EXPECT_RGL_SUCCESS (rgl_node_multi_return_switch (&mrFirst, RGL_RETURN_TYPE_FIRST));
56
61
EXPECT_RGL_SUCCESS (rgl_node_multi_return_switch (&mrLast, RGL_RETURN_TYPE_LAST));
57
62
EXPECT_RGL_SUCCESS (rgl_node_points_compact_by_field (&compactFirst, RGL_FIELD_IS_HIT_I32));
@@ -134,9 +139,7 @@ TEST_F(GraphMultiReturn, vlp16_data_compare)
134
139
// Scene
135
140
spawnCubeOnScene (Mat3x4f::identity ());
136
141
137
- // VLP16 horizontal beam divergence in rads
138
- const float beamDivAngle = vlp16LidarHBeamDivergence;
139
- constructMRGraph (raysTf, lidarPose, beamDivAngle);
142
+ constructMRGraph (raysTf, lidarPose, vlp16LidarHBeamDivergence, vlp16LidarVBeamDivergence);
140
143
141
144
EXPECT_RGL_SUCCESS (rgl_graph_run (mrRays));
142
145
@@ -159,7 +162,7 @@ TEST_F(GraphMultiReturn, vlp16_data_compare)
159
162
const auto mrLastIsHits = mrLastOutPointcloud.getFieldValues <IS_HIT_I32>();
160
163
const auto mrLastPoints = mrLastOutPointcloud.getFieldValues <XYZ_VEC3_F32>();
161
164
const auto mrLastDistances = mrLastOutPointcloud.getFieldValues <DISTANCE_F32>();
162
- const float expectedDiameter = vlp16LidarHBeamDiameter;
165
+ const float expectedDiameter = std::max ( vlp16LidarHBeamDiameter, vlp16LidarVBeamDiameter) ;
163
166
const auto expectedLastDistance = static_cast <float >(sqrt (pow (lidarCubeFaceDist, 2 ) + pow (expectedDiameter / 2 , 2 )));
164
167
// Substract because the ray is pointing as is the negative X axis
165
168
const auto expectedLastPoint = lidarTransl - Vec3f{expectedLastDistance, 0 .0f , 0 .0f };
@@ -177,7 +180,7 @@ TEST_F(GraphMultiReturn, vlp16_data_compare)
177
180
* with two cubes placed one behind the other, one cube cyclically moving sideways.
178
181
* LiDAR fires the beam in such a way that in some frames the beam partially overlaps the edge of the moving cube.
179
182
*/
180
- TEST_F (GraphMultiReturn, pairs_of_cubes_in_motion )
183
+ TEST_F (GraphMultiReturn, cube_in_motion )
181
184
{
182
185
/*
183
186
* gap
@@ -208,8 +211,7 @@ TEST_F(GraphMultiReturn, pairs_of_cubes_in_motion)
208
211
spawnCubeOnScene (entitiesTransforms.at (1 ))};
209
212
210
213
// Lidar with MR
211
- const float beamDivAngle = 0 .003f ;
212
- constructMRGraph (raysTf, lidarPose, beamDivAngle, true );
214
+ constructMRGraph (raysTf, lidarPose, vlp16LidarHBeamDivergence, vlp16LidarVBeamDivergence, true );
213
215
214
216
// Lidar without MR
215
217
EXPECT_RGL_SUCCESS (rgl_node_rays_from_mat3x4f (&rays, raysTf.data (), raysTf.size ()));
@@ -264,7 +266,7 @@ TEST_F(GraphMultiReturn, stairs)
264
266
// Scene
265
267
const float stairsBaseHeight = 0 .0f ;
266
268
const float stepWidth = 1 .0f ;
267
- const float stepHeight = vlp16LidarHBeamDiameter + 0 .1f ;
269
+ const float stepHeight = vlp16LidarVBeamDiameter + 0 .1f ;
268
270
const float stepDepth = 0 .8f ;
269
271
const Vec3f stairsTranslation{2 .0f , 0 .0f , 0 .0f };
270
272
@@ -279,8 +281,7 @@ TEST_F(GraphMultiReturn, stairs)
279
281
const rgl_mat3x4f lidarPose{(Mat3x4f::translation (lidarTransl + stairsTranslation)).toRGL ()};
280
282
281
283
// Lidar with MR
282
- const float beamDivAngle = vlp16LidarHBeamDivergence;
283
- constructMRGraph (raysTf, lidarPose, beamDivAngle, true );
284
+ constructMRGraph (raysTf, lidarPose, vlp16LidarHBeamDivergence, vlp16LidarVBeamDivergence, true );
284
285
285
286
// Camera
286
287
rgl_mat3x4f cameraPose = Mat3x4f::translation ({0 .0f , -1 .5f , stepHeight * 3 + 1 .0f }).toRGL ();
@@ -289,8 +290,9 @@ TEST_F(GraphMultiReturn, stairs)
289
290
290
291
int frameId = 0 ;
291
292
while (true ) {
292
- const float newBeamDivAngle = beamDivAngle + std::sin (frameId * 0 .1f ) * beamDivAngle;
293
- ASSERT_RGL_SUCCESS (rgl_node_raytrace_configure_beam_divergence (mrRaytrace, newBeamDivAngle));
293
+ const float newVBeamDivAngle = vlp16LidarVBeamDivergence + std::sin (frameId * 0 .1f ) * vlp16LidarVBeamDivergence;
294
+ ASSERT_RGL_SUCCESS (
295
+ rgl_node_raytrace_configure_beam_divergence (mrRaytrace, vlp16LidarHBeamDivergence, newVBeamDivAngle));
294
296
295
297
ASSERT_RGL_SUCCESS (rgl_graph_run (mrRaytrace));
296
298
@@ -330,4 +332,63 @@ TEST_F(GraphMultiReturn, multiple_ray_beams)
330
332
ASSERT_RGL_SUCCESS (rgl_graph_run (cameraRays));
331
333
ASSERT_RGL_SUCCESS (rgl_graph_run (mrRays));
332
334
}
335
+
336
+ /* *
337
+ * In the MR implementation, the beam is modeled using beam samples, from which the first and last hits are calculated.
338
+ * This test uses the code that generates these beam samples and fires them inside the cube.
339
+ * It verifies the accuracy of beam sample generation with different horizontal and vertical divergence angles.
340
+ */
341
+ TEST_F (GraphMultiReturn, horizontal_vertical_beam_divergence)
342
+ {
343
+ GTEST_SKIP (); // Comment to run the test
344
+
345
+ const float hHalfDivergenceAngleRad = M_PI / 4 ;
346
+ const float vHalfDivergenceAngleRad = M_PI / 8 ;
347
+
348
+ // Lidar
349
+ const auto lidarTransl = Vec3f{0 .0f , 0 .0f , 0 .0f };
350
+ const rgl_mat3x4f lidarPose = Mat3x4f::TRS (lidarTransl).toRGL ();
351
+ std::vector<rgl_mat3x4f> raysTf;
352
+ raysTf.reserve (MULTI_RETURN_BEAM_SAMPLES);
353
+
354
+ raysTf.emplace_back (Mat3x4f::identity ().toRGL ());
355
+
356
+ // Code that generates beam samples in the makeBeamSampleRayTransform function (gpu/optixPrograms.cu)
357
+ for (int layerIdx = 0 ; layerIdx < MULTI_RETURN_BEAM_LAYERS; ++layerIdx) {
358
+ for (int vertexIdx = 0 ; vertexIdx < MULTI_RETURN_BEAM_VERTICES; ++vertexIdx) {
359
+ const float hCurrentDivergence = hHalfDivergenceAngleRad *
360
+ (1 .0f - static_cast <float >(layerIdx) / MULTI_RETURN_BEAM_LAYERS);
361
+ const float vCurrentDivergence = vHalfDivergenceAngleRad *
362
+ (1 .0f - static_cast <float >(layerIdx) / MULTI_RETURN_BEAM_LAYERS);
363
+
364
+ const float angleStep = 2 .0f * static_cast <float >(M_PI) / MULTI_RETURN_BEAM_VERTICES;
365
+
366
+ const float hAngle = hCurrentDivergence * std::cos (static_cast <float >(vertexIdx) * angleStep);
367
+ const float vAngle = vCurrentDivergence * std::sin (static_cast <float >(vertexIdx) * angleStep);
368
+
369
+ const auto rotation = Mat3x4f::rotationRad (vAngle, 0 .0f , 0 .0f ) * Mat3x4f::rotationRad (0 .0f , hAngle, 0 .0f );
370
+ raysTf.emplace_back (rotation.toRGL ());
371
+ }
372
+ }
373
+
374
+ // Scene
375
+ spawnCubeOnScene (Mat3x4f::TRS ({0 .0f , 0 .0f , 0 .0f }, {0 .0f , 0 .0f , 0 .0f }, {6 .0f , 6 .0f , 6 .0f }));
376
+
377
+ // Camera
378
+ constructCameraGraph (Mat3x4f::identity ().toRGL ());
379
+
380
+ // Graph without MR
381
+ EXPECT_RGL_SUCCESS (rgl_node_rays_from_mat3x4f (&rays, raysTf.data (), raysTf.size ()));
382
+ EXPECT_RGL_SUCCESS (rgl_node_rays_transform (&transform, &lidarPose));
383
+ EXPECT_RGL_SUCCESS (rgl_node_raytrace (&raytrace, nullptr ));
384
+ EXPECT_RGL_SUCCESS (rgl_node_points_format (&format, fields.data (), fields.size ()));
385
+ EXPECT_RGL_SUCCESS (rgl_node_points_ros2_publish (&publish, " MRTest_Lidar_Without_MR" , " world" ));
386
+ EXPECT_RGL_SUCCESS (rgl_graph_node_add_child (rays, transform));
387
+ EXPECT_RGL_SUCCESS (rgl_graph_node_add_child (transform, raytrace));
388
+ EXPECT_RGL_SUCCESS (rgl_graph_node_add_child (raytrace, format));
389
+ EXPECT_RGL_SUCCESS (rgl_graph_node_add_child (format, publish));
390
+
391
+ ASSERT_RGL_SUCCESS (rgl_graph_run (cameraRays));
392
+ ASSERT_RGL_SUCCESS (rgl_graph_run (rays));
393
+ }
333
394
#endif
0 commit comments