Skip to content

Commit d7094d1

Browse files
nebraszkamsz-rai
authored andcommitted
Update MR beam model - distinct vertical/horizontal divergence (#297)
1 parent d8763a3 commit d7094d1

File tree

9 files changed

+123
-48
lines changed

9 files changed

+123
-48
lines changed

include/rgl/api/core.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -736,9 +736,10 @@ RGL_API rgl_status_t rgl_node_raytrace_configure_mask(rgl_node_t node, const int
736736
* Setting beam divergence > 0.0f is required to use query for multi-return results.
737737
* Setting beam divergence == 0.0f disables multi-return.
738738
* @param node RaytraceNode to modify.
739-
* @param beamDivergence Beam divergence in radians.
739+
* @param horizontal_beam_divergence Horizontal beam divergence in radians.
740+
* @param vertical_beam_divergence Vertical beam divergence in radians.
740741
*/
741-
RGL_API rgl_status_t rgl_node_raytrace_configure_beam_divergence(rgl_node_t node, float beam_divergence);
742+
RGL_API rgl_status_t rgl_node_raytrace_configure_beam_divergence(rgl_node_t node, float horizontal_beam_divergence, float vertical_beam_divergence);
742743

743744
/**
744745
* Creates or modifies FormatPointsNode.

src/api/apiCore.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -958,24 +958,27 @@ void TapeCore::tape_node_raytrace_configure_mask(const YAML::Node& yamlNode, Pla
958958
rgl_node_raytrace_configure_mask(node, state.getPtr<const int8_t>(yamlNode[1]), yamlNode[2].as<int32_t>());
959959
}
960960

961-
RGL_API rgl_status_t rgl_node_raytrace_configure_beam_divergence(rgl_node_t node, float beam_divergence)
961+
RGL_API rgl_status_t rgl_node_raytrace_configure_beam_divergence(rgl_node_t node, float horizontal_beam_divergence,
962+
float vertical_beam_divergence)
962963
{
963964
auto status = rglSafeCall([&]() {
964-
RGL_API_LOG("rgl_node_raytrace_configure_beam_divergence(node={}, divergence={})", repr(node), beam_divergence);
965+
RGL_API_LOG("rgl_node_raytrace_configure_beam_divergence(node={}, horizontal_divergence={}, vertical_divergence={})", repr(node),
966+
horizontal_beam_divergence, vertical_beam_divergence);
965967
CHECK_ARG(node != nullptr);
966-
CHECK_ARG(beam_divergence >= 0.0f);
968+
CHECK_ARG((horizontal_beam_divergence > 0.0f && vertical_beam_divergence > 0.0f) ||
969+
(horizontal_beam_divergence == 0.0f && vertical_beam_divergence == 0.0f));
967970
RaytraceNode::Ptr raytraceNode = Node::validatePtr<RaytraceNode>(node);
968-
raytraceNode->setBeamDivergence(beam_divergence);
971+
raytraceNode->setBeamDivergence(horizontal_beam_divergence, vertical_beam_divergence);
969972
});
970-
TAPE_HOOK(node, beam_divergence);
973+
TAPE_HOOK(node, horizontal_beam_divergence, vertical_beam_divergence);
971974
return status;
972975
}
973976

974977
void TapeCore::tape_node_raytrace_configure_beam_divergence(const YAML::Node& yamlNode, PlaybackState& state)
975978
{
976979
auto nodeId = yamlNode[0].as<TapeAPIObjectID>();
977980
rgl_node_t node = state.nodes.at(nodeId);
978-
rgl_node_raytrace_configure_beam_divergence(node, yamlNode[1].as<float>());
981+
rgl_node_raytrace_configure_beam_divergence(node, yamlNode[1].as<float>(), yamlNode[2].as<float>());
979982
}
980983

981984
RGL_API rgl_status_t rgl_node_points_format(rgl_node_t* node, const rgl_field_t* fields, int32_t field_count)

src/gpu/MultiReturn.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
#include <RGLFields.hpp>
1818

1919
#define MULTI_RETURN_BEAM_VERTICES 8
20-
#define MULTI_RETURN_BEAM_CIRCLES 2
21-
#define MULTI_RETURN_BEAM_SAMPLES (1 + (MULTI_RETURN_BEAM_VERTICES * MULTI_RETURN_BEAM_CIRCLES))
20+
#define MULTI_RETURN_BEAM_LAYERS 2
21+
#define MULTI_RETURN_BEAM_SAMPLES (1 + (MULTI_RETURN_BEAM_VERTICES * MULTI_RETURN_BEAM_LAYERS))
2222

2323
struct MultiReturnPointers
2424
{

src/gpu/RaytraceRequestContext.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ struct RaytraceRequestContext
6767
Field<INCIDENT_ANGLE_F32>::type* incidentAngle;
6868

6969
// Multi-Return
70-
float beamHalfDivergence;
70+
float hBeamHalfDivergenceRad;
71+
float vBeamHalfDivergenceRad;
7172
MultiReturnPointers mrSamples;
7273
};
7374
static_assert(std::is_trivially_copyable<RaytraceRequestContext>::value);

src/gpu/optixPrograms.cu

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ __device__ void saveRayResult(const Vec3f& xyz, float distance, float intensity,
3939
float laserRetro);
4040
__device__ void saveNonHitRayResult(float nonHitDistance);
4141
__device__ void shootSamplingRay(const Mat3x4f& ray, float maxRange, unsigned sampleBeamIdx);
42-
__device__ Mat3x4f makeBeamSampleRayTransform(float halfDivergenceAngleRad, unsigned circleIdx, unsigned vertexIdx);
42+
__device__ Mat3x4f makeBeamSampleRayTransform(float hHalfDivergenceRad, float vHalfDivergenceRad, unsigned layerIdx, unsigned vertexIdx);
4343

4444
extern "C" __global__ void __raygen__()
4545
{
@@ -86,13 +86,13 @@ extern "C" __global__ void __raygen__()
8686
float maxRange = ctx.rayRangesCount == 1 ? ctx.rayRanges[0].y() : ctx.rayRanges[rayIdx].y();
8787

8888
shootSamplingRay(ray, maxRange, 0); // Shoot primary ray
89-
if (ctx.beamHalfDivergence > 0.0f) {
89+
if (ctx.hBeamHalfDivergenceRad > 0.0f && ctx.vBeamHalfDivergenceRad > 0.0f) {
9090
// Shoot multi-return sampling rays
91-
for (int circleIdx = 0; circleIdx < MULTI_RETURN_BEAM_CIRCLES; ++circleIdx) {
91+
for (int layerIdx = 0; layerIdx < MULTI_RETURN_BEAM_LAYERS; ++layerIdx) {
9292
for (int vertexIdx = 0; vertexIdx < MULTI_RETURN_BEAM_VERTICES; vertexIdx++) {
93-
Mat3x4f sampleRay = ray * makeBeamSampleRayTransform(ctx.beamHalfDivergence, circleIdx, vertexIdx);
93+
Mat3x4f sampleRay = ray * makeBeamSampleRayTransform(ctx.hBeamHalfDivergenceRad, ctx.vBeamHalfDivergenceRad, layerIdx, vertexIdx);
9494
// Sampling rays indexes start from 1, 0 is reserved for the primary ray
95-
const unsigned beamSampleRayIdx = 1 + circleIdx * MULTI_RETURN_BEAM_VERTICES + vertexIdx;
95+
const unsigned beamSampleRayIdx = 1 + layerIdx * MULTI_RETURN_BEAM_VERTICES + vertexIdx;
9696
shootSamplingRay(sampleRay, maxRange, beamSampleRayIdx);
9797
}
9898
}
@@ -147,7 +147,7 @@ extern "C" __global__ void __closesthit__()
147147
return hitWorldRaytraced;
148148
}
149149
Mat3x4f sampleRayTf = beamSampleRayIdx == 0 ? Mat3x4f::identity() :
150-
makeBeamSampleRayTransform(ctx.beamHalfDivergence, circleIdx, vertexIdx);
150+
makeBeamSampleRayTransform(ctx.hBeamHalfDivergenceRad, ctx.vBeamHalfDivergenceRad, circleIdx, vertexIdx);
151151
Mat3x4f undistortedRay = ctx.raysWorld[beamIdx] * sampleRayTf;
152152
Vec3f undistortedOrigin = undistortedRay * Vec3f{0, 0, 0};
153153
Vec3f undistortedDir = undistortedRay * Vec3f{0, 0, 1} - undistortedOrigin;
@@ -257,17 +257,21 @@ __device__ void shootSamplingRay(const Mat3x4f& ray, float maxRange, unsigned in
257257
optixTrace(ctx.scene, origin, dir, 0.0f, maxRange, 0.0f, OptixVisibilityMask(255), flags, 0, 1, 0, beamSampleRayIdx);
258258
}
259259

260-
__device__ Mat3x4f makeBeamSampleRayTransform(float halfDivergenceAngleRad, unsigned int circleIdx, unsigned int vertexIdx)
260+
__device__ Mat3x4f makeBeamSampleRayTransform(float hHalfDivergenceRad, float vHalfDivergenceRad, unsigned int layerIdx, unsigned int vertexIdx)
261261
{
262-
if (ctx.beamHalfDivergence == 0.0f) {
262+
if (ctx.hBeamHalfDivergenceRad == 0.0f && ctx.vBeamHalfDivergenceRad == 0.0f) {
263263
return Mat3x4f::identity();
264264
}
265-
const auto circleDivergence = halfDivergenceAngleRad * (1.0f - static_cast<float>(circleIdx) / MULTI_RETURN_BEAM_CIRCLES);
266-
auto vertexAngleStep = 2.0f * static_cast<float>(M_PI) / MULTI_RETURN_BEAM_VERTICES;
267-
// First, rotate around X to move the ray vector (initially {0,0,1}) to diverge from the Z axis by circleDivergence.
268-
// Then rotate around Z to move the ray vector on the circle.
269-
return Mat3x4f::rotationRad(0, 0, static_cast<float>(vertexIdx) * vertexAngleStep) * // Second
270-
Mat3x4f::rotationRad(circleDivergence, 0, 0);
265+
266+
const float hCurrentHalfDivergenceRad = hHalfDivergenceRad * (1.0f - static_cast<float>(layerIdx) / MULTI_RETURN_BEAM_LAYERS);
267+
const float vCurrentHalfDivergenceRad = vHalfDivergenceRad * (1.0f - static_cast<float>(layerIdx) / MULTI_RETURN_BEAM_LAYERS);
268+
269+
const float angleStep = 2.0f * static_cast<float>(M_PI) / MULTI_RETURN_BEAM_VERTICES;
270+
271+
const float hAngle = hCurrentHalfDivergenceRad * cos(static_cast<float>(vertexIdx) * angleStep);
272+
const float vAngle = vCurrentHalfDivergenceRad * sin(static_cast<float>(vertexIdx) * angleStep);
273+
274+
return Mat3x4f::rotationRad(vAngle, 0.0f, 0.0f) * Mat3x4f::rotationRad(0.0f, hAngle, 0.0f);
271275
}
272276

273277
__device__ void saveNonHitRayResult(float nonHitDistance)

src/graph/NodesCore.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,9 @@ struct RaytraceNode : IPointsNode
135135
void enableRayDistortion(bool enabled) { doApplyDistortion = enabled; }
136136
void setNonHitDistanceValues(float nearDistance, float farDistance);
137137
void setNonHitsMask(const int8_t* maskRaw, size_t maskPointCount);
138-
void setBeamDivergence(float divergence) { beamHalfDivergence = divergence / 2.0f; }
138+
void setBeamDivergence(float hDivergenceRad, float vDivergenceRad) {
139+
hBeamHalfDivergenceRad = hDivergenceRad / 2.0f;
140+
vBeamHalfDivergenceRad = vDivergenceRad / 2.0f;}
139141

140142
private:
141143
IRaysNode::Ptr raysNode;
@@ -147,7 +149,8 @@ struct RaytraceNode : IPointsNode
147149

148150
float nearNonHitDistance{std::numeric_limits<float>::infinity()};
149151
float farNonHitDistance{std::numeric_limits<float>::infinity()};
150-
float beamHalfDivergence = 0.0f;
152+
float hBeamHalfDivergenceRad = 0.0f;
153+
float vBeamHalfDivergenceRad = 0.0f;
151154

152155
DeviceAsyncArray<int8_t>::Ptr rayMask;
153156

src/graph/RaytraceNode.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ void RaytraceNode::enqueueExecImpl()
124124
.elevation = getPtrTo<ELEVATION_F32>(),
125125
.normal = getPtrTo<NORMAL_VEC3_F32>(),
126126
.incidentAngle = getPtrTo<INCIDENT_ANGLE_F32>(),
127-
.beamHalfDivergence = beamHalfDivergence,
127+
.hBeamHalfDivergenceRad = hBeamHalfDivergenceRad,
128+
.vBeamHalfDivergenceRad = vBeamHalfDivergenceRad,
128129
.mrSamples = mrSamples.getPointers(),
129130
};
130131

@@ -134,7 +135,7 @@ void RaytraceNode::enqueueExecImpl()
134135
CHECK_OPTIX(optixLaunch(Optix::getOrCreate().pipeline, getStreamHandle(), pipelineArgsPtr, pipelineArgsSize, &sceneSBT,
135136
launchDims.x, launchDims.y, launchDims.y));
136137

137-
if (beamHalfDivergence > 0.0f) {
138+
if (hBeamHalfDivergenceRad > 0.0f && vBeamHalfDivergenceRad > 0.0f) {
138139
gpuProcessBeamSamplesFirstLast(getStreamHandle(), raysNode->getRayCount(), MULTI_RETURN_BEAM_SAMPLES,
139140
mrSamples.getPointers(), mrFirst.getPointers(), mrLast.getPointers(), raysPtr);
140141
}

test/src/TapeTest.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,9 @@ TEST_F(TapeTest, RecordPlayAllCalls)
235235
float farNonHitDistance = 2.0f;
236236
EXPECT_RGL_SUCCESS(rgl_node_raytrace_configure_non_hits(raytrace, nearNonHitDistance, farNonHitDistance));
237237

238-
float beamDivergence = 0.1f;
239-
EXPECT_RGL_SUCCESS(rgl_node_raytrace_configure_beam_divergence(raytrace, beamDivergence));
238+
float hBeamDivergence = 0.1f;
239+
float vBeamDivergence = 0.1f;
240+
EXPECT_RGL_SUCCESS(rgl_node_raytrace_configure_beam_divergence(raytrace, hBeamDivergence, vBeamDivergence));
240241

241242
rgl_node_t format = nullptr;
242243
std::vector<rgl_field_t> fields = {RGL_FIELD_XYZ_VEC3_F32, RGL_FIELD_DISTANCE_F32};

test/src/graph/multiReturnTest.cpp

Lines changed: 78 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55

66
#include "RGLFields.hpp"
77
#include "math/Mat3x4f.hpp"
8+
#include "gpu/MultiReturn.hpp"
9+
10+
#include <cmath>
811

912
using namespace std::chrono_literals;
1013

@@ -17,8 +20,10 @@ class GraphMultiReturn : public RGLTest
1720
protected:
1821
// VLP16 data
1922
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
2227

2328
std::vector<Mat3x4f> vlp16Channels{Mat3x4f::TRS({0.0f, 0.0f, mmToMeters(11.2f)}, {0.0f, -15.0f, 0.0f}),
2429
Mat3x4f::TRS({0.0f, 0.0f, mmToMeters(0.7f)}, {0.0f, +1.0f, 0.0f}),
@@ -45,13 +50,13 @@ class GraphMultiReturn : public RGLTest
4550
publish = nullptr, cameraPublish = nullptr, mrPublishFirst = nullptr, mrPublishLast = nullptr,
4651
compactFirst = nullptr, compactLast = nullptr;
4752

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)
5055
{
5156
EXPECT_RGL_SUCCESS(rgl_node_rays_from_mat3x4f(&mrRays, raysTf.data(), raysTf.size()));
5257
EXPECT_RGL_SUCCESS(rgl_node_rays_transform(&mrTransform, &lidarPose));
5358
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));
5560
EXPECT_RGL_SUCCESS(rgl_node_multi_return_switch(&mrFirst, RGL_RETURN_TYPE_FIRST));
5661
EXPECT_RGL_SUCCESS(rgl_node_multi_return_switch(&mrLast, RGL_RETURN_TYPE_LAST));
5762
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)
134139
// Scene
135140
spawnCubeOnScene(Mat3x4f::identity());
136141

137-
// VLP16 horizontal beam divergence in rads
138-
const float beamDivAngle = vlp16LidarHBeamDivergence;
139-
constructMRGraph(raysTf, lidarPose, beamDivAngle);
142+
constructMRGraph(raysTf, lidarPose, vlp16LidarHBeamDivergence, vlp16LidarVBeamDivergence);
140143

141144
EXPECT_RGL_SUCCESS(rgl_graph_run(mrRays));
142145

@@ -159,7 +162,7 @@ TEST_F(GraphMultiReturn, vlp16_data_compare)
159162
const auto mrLastIsHits = mrLastOutPointcloud.getFieldValues<IS_HIT_I32>();
160163
const auto mrLastPoints = mrLastOutPointcloud.getFieldValues<XYZ_VEC3_F32>();
161164
const auto mrLastDistances = mrLastOutPointcloud.getFieldValues<DISTANCE_F32>();
162-
const float expectedDiameter = vlp16LidarHBeamDiameter;
165+
const float expectedDiameter = std::max(vlp16LidarHBeamDiameter, vlp16LidarVBeamDiameter);
163166
const auto expectedLastDistance = static_cast<float>(sqrt(pow(lidarCubeFaceDist, 2) + pow(expectedDiameter / 2, 2)));
164167
// Substract because the ray is pointing as is the negative X axis
165168
const auto expectedLastPoint = lidarTransl - Vec3f{expectedLastDistance, 0.0f, 0.0f};
@@ -177,7 +180,7 @@ TEST_F(GraphMultiReturn, vlp16_data_compare)
177180
* with two cubes placed one behind the other, one cube cyclically moving sideways.
178181
* LiDAR fires the beam in such a way that in some frames the beam partially overlaps the edge of the moving cube.
179182
*/
180-
TEST_F(GraphMultiReturn, pairs_of_cubes_in_motion)
183+
TEST_F(GraphMultiReturn, cube_in_motion)
181184
{
182185
/*
183186
* gap
@@ -208,8 +211,7 @@ TEST_F(GraphMultiReturn, pairs_of_cubes_in_motion)
208211
spawnCubeOnScene(entitiesTransforms.at(1))};
209212

210213
// Lidar with MR
211-
const float beamDivAngle = 0.003f;
212-
constructMRGraph(raysTf, lidarPose, beamDivAngle, true);
214+
constructMRGraph(raysTf, lidarPose, vlp16LidarHBeamDivergence, vlp16LidarVBeamDivergence, true);
213215

214216
// Lidar without MR
215217
EXPECT_RGL_SUCCESS(rgl_node_rays_from_mat3x4f(&rays, raysTf.data(), raysTf.size()));
@@ -264,7 +266,7 @@ TEST_F(GraphMultiReturn, stairs)
264266
// Scene
265267
const float stairsBaseHeight = 0.0f;
266268
const float stepWidth = 1.0f;
267-
const float stepHeight = vlp16LidarHBeamDiameter + 0.1f;
269+
const float stepHeight = vlp16LidarVBeamDiameter + 0.1f;
268270
const float stepDepth = 0.8f;
269271
const Vec3f stairsTranslation{2.0f, 0.0f, 0.0f};
270272

@@ -279,8 +281,7 @@ TEST_F(GraphMultiReturn, stairs)
279281
const rgl_mat3x4f lidarPose{(Mat3x4f::translation(lidarTransl + stairsTranslation)).toRGL()};
280282

281283
// Lidar with MR
282-
const float beamDivAngle = vlp16LidarHBeamDivergence;
283-
constructMRGraph(raysTf, lidarPose, beamDivAngle, true);
284+
constructMRGraph(raysTf, lidarPose, vlp16LidarHBeamDivergence, vlp16LidarVBeamDivergence, true);
284285

285286
// Camera
286287
rgl_mat3x4f cameraPose = Mat3x4f::translation({0.0f, -1.5f, stepHeight * 3 + 1.0f}).toRGL();
@@ -289,8 +290,9 @@ TEST_F(GraphMultiReturn, stairs)
289290

290291
int frameId = 0;
291292
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));
294296

295297
ASSERT_RGL_SUCCESS(rgl_graph_run(mrRaytrace));
296298

@@ -330,4 +332,63 @@ TEST_F(GraphMultiReturn, multiple_ray_beams)
330332
ASSERT_RGL_SUCCESS(rgl_graph_run(cameraRays));
331333
ASSERT_RGL_SUCCESS(rgl_graph_run(mrRays));
332334
}
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+
}
333394
#endif

0 commit comments

Comments
 (0)