Skip to content

Commit 0db92eb

Browse files
Add energy computation to RadarPostProcessNode (#255)
* Fix bugs * Add ray area computation * Fix calculating ray polarization. Update ray directions calculation. Signed-off-by: Paweł Liberadzki <[email protected]> * Add RAY_POSE field * Implement BU, BR computation on GPU * Call energy computation in RadarPostprocessPointsNode * Review fixes --------- Signed-off-by: Paweł Liberadzki <[email protected]> Co-authored-by: Paweł Liberadzki <[email protected]>
1 parent 8dd6da9 commit 0db92eb

File tree

13 files changed

+257
-25
lines changed

13 files changed

+257
-25
lines changed

include/rgl/api/core.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,11 @@ typedef enum : int32_t
298298
*/
299299
RGL_FIELD_INCIDENT_ANGLE_F32,
300300

301+
/**
302+
* 3x4 matrix describing pose of the ray in the world coordinate system.
303+
*/
304+
RGL_FIELD_RAY_POSE_MAT3x4_F32,
305+
301306
// Dummy fields
302307
RGL_FIELD_PADDING_8 = 1024,
303308
RGL_FIELD_PADDING_16,
@@ -712,8 +717,12 @@ RGL_API rgl_status_t rgl_node_points_from_array(rgl_node_t* node, const void* po
712717
* @param node If (*node) == nullptr, a new Node will be created. Otherwise, (*node) will be modified.
713718
* @param distance_separation The maximum distance difference to create a new radar cluster (in simulation units).
714719
* @param azimuth_separation The maximum azimuth difference to create a new radar cluster (in radians).
720+
* @param ray_azimuth_step The azimuth step between rays (in radians).
721+
* @param ray_elevation_step The elevation step between rays (in radians).
722+
* @param frequency The frequency of the radar (in Hz).
715723
*/
716-
RGL_API rgl_status_t rgl_node_points_radar_postprocess(rgl_node_t* node, float distance_separation, float azimuth_separation);
724+
RGL_API rgl_status_t rgl_node_points_radar_postprocess(rgl_node_t* node, float distance_separation, float azimuth_separation,
725+
float ray_azimuth_step, float ray_elevation_step, float frequency);
717726

718727
/**
719728
* Creates or modifies FilterGroundPointsNode.

src/RGLFields.hpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <vector>
2020

2121
#include <math/Vector.hpp>
22+
#include <math/Mat3x4f.hpp>
2223
#include <rgl/api/core.h>
2324

2425
/*
@@ -56,6 +57,7 @@ typedef unsigned char TextureTexelFormat;
5657
#define SNR_F32 RGL_FIELD_SNR_F32
5758
#define NORMAL_VEC3_F32 RGL_FIELD_NORMAL_VEC3_F32
5859
#define INCIDENT_ANGLE_F32 RGL_FIELD_INCIDENT_ANGLE_F32
60+
#define RAY_POSE_MAT3x4_F32 RGL_FIELD_RAY_POSE_MAT3x4_F32
5961
#define PADDING_8 RGL_FIELD_PADDING_8
6062
#define PADDING_16 RGL_FIELD_PADDING_16
6163
#define PADDING_32 RGL_FIELD_PADDING_32
@@ -84,6 +86,7 @@ inline const std::set<rgl_field_t>& getAllRealFields()
8486
SNR_F32,
8587
NORMAL_VEC3_F32,
8688
INCIDENT_ANGLE_F32,
89+
RAY_POSE_MAT3x4_F32,
8790
};
8891
return allRealFields;
8992
}
@@ -134,6 +137,7 @@ FIELD(NOISE_F32, float);
134137
FIELD(SNR_F32, float);
135138
FIELD(NORMAL_VEC3_F32, Vec3f);
136139
FIELD(INCIDENT_ANGLE_F32, float);
140+
FIELD(RAY_POSE_MAT3x4_F32, Mat3x4f);
137141

138142
inline std::size_t getFieldSize(rgl_field_t type)
139143
{
@@ -159,6 +163,7 @@ inline std::size_t getFieldSize(rgl_field_t type)
159163
case SNR_F32: return Field<SNR_F32>::size;
160164
case NORMAL_VEC3_F32: return Field<NORMAL_VEC3_F32>::size;
161165
case INCIDENT_ANGLE_F32: return Field<INCIDENT_ANGLE_F32>::size;
166+
case RAY_POSE_MAT3x4_F32: return Field<RAY_POSE_MAT3x4_F32>::size;
162167
case PADDING_8: return Field<PADDING_8>::size;
163168
case PADDING_16: return Field<PADDING_16>::size;
164169
case PADDING_32: return Field<PADDING_32>::size;
@@ -218,6 +223,7 @@ inline std::shared_ptr<IAnyArray> createArray(rgl_field_t type, Args&&... args)
218223
case SNR_F32: return Subclass<Field<SNR_F32>::type>::create(std::forward<Args>(args)...);
219224
case NORMAL_VEC3_F32: return Subclass<Field<NORMAL_VEC3_F32>::type>::create(std::forward<Args>(args)...);
220225
case INCIDENT_ANGLE_F32: return Subclass<Field<INCIDENT_ANGLE_F32>::type>::create(std::forward<Args>(args)...);
226+
case RAY_POSE_MAT3x4_F32: return Subclass<Field<RAY_POSE_MAT3x4_F32>::type>::create(std::forward<Args>(args)...);
221227
}
222228
throw std::invalid_argument(fmt::format("createArray: unknown RGL field {}", type));
223229
}
@@ -246,6 +252,7 @@ inline std::string toString(rgl_field_t type)
246252
case SNR_F32: return "SNR_F32";
247253
case NORMAL_VEC3_F32: return "NORMAL_VEC3_F32";
248254
case INCIDENT_ANGLE_F32: return "INCIDENT_ANGLE_F32";
255+
case RAY_POSE_MAT3x4_F32: return "RAY_POSE_MAT3x4_F32";
249256
case PADDING_8: return "PADDING_8";
250257
case PADDING_16: return "PADDING_16";
251258
case PADDING_32: return "PADDING_32";
@@ -288,6 +295,15 @@ inline std::vector<uint8_t> toRos2Fields(rgl_field_t type)
288295
return {sensor_msgs::msg::PointField::FLOAT32, sensor_msgs::msg::PointField::FLOAT32,
289296
sensor_msgs::msg::PointField::FLOAT32};
290297
case INCIDENT_ANGLE_F32: return {sensor_msgs::msg::PointField::FLOAT32};
298+
case RAY_POSE_MAT3x4_F32:
299+
return {
300+
sensor_msgs::msg::PointField::FLOAT32, sensor_msgs::msg::PointField::FLOAT32,
301+
sensor_msgs::msg::PointField::FLOAT32, sensor_msgs::msg::PointField::FLOAT32,
302+
sensor_msgs::msg::PointField::FLOAT32, sensor_msgs::msg::PointField::FLOAT32,
303+
sensor_msgs::msg::PointField::FLOAT32, sensor_msgs::msg::PointField::FLOAT32,
304+
sensor_msgs::msg::PointField::FLOAT32, sensor_msgs::msg::PointField::FLOAT32,
305+
sensor_msgs::msg::PointField::FLOAT32, sensor_msgs::msg::PointField::FLOAT32,
306+
};
291307
case PADDING_8: return {};
292308
case PADDING_16: return {};
293309
case PADDING_32: return {};
@@ -319,6 +335,7 @@ inline std::vector<std::string> toRos2Names(rgl_field_t type)
319335
case SNR_F32: return {"snr"};
320336
case NORMAL_VEC3_F32: return {"nx", "ny", "nz"};
321337
case INCIDENT_ANGLE_F32: return {"incident_angle"};
338+
case RAY_POSE_MAT3x4_F32: return {"m00", "m01", "m02", "m03", "m10", "m11", "m12", "m13", "m20", "m21", "m22", "m23"};
322339
case PADDING_8: return {};
323340
case PADDING_16: return {};
324341
case PADDING_32: return {};
@@ -334,6 +351,11 @@ inline std::vector<std::size_t> toRos2Sizes(rgl_field_t type)
334351
case ABSOLUTE_VELOCITY_VEC3_F32: return {sizeof(float), sizeof(float), sizeof(float)};
335352
case RELATIVE_VELOCITY_VEC3_F32: return {sizeof(float), sizeof(float), sizeof(float)};
336353
case NORMAL_VEC3_F32: return {sizeof(float), sizeof(float), sizeof(float)};
354+
case RAY_POSE_MAT3x4_F32:
355+
return {
356+
sizeof(float), sizeof(float), sizeof(float), sizeof(float), sizeof(float), sizeof(float),
357+
sizeof(float), sizeof(float), sizeof(float), sizeof(float), sizeof(float), sizeof(float),
358+
};
337359
default: return {getFieldSize(type)};
338360
}
339361
}

src/api/apiCore.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,26 +1032,31 @@ void TapeCore::tape_node_points_from_array(const YAML::Node& yamlNode, PlaybackS
10321032
state.nodes.insert({nodeId, node});
10331033
}
10341034

1035-
RGL_API rgl_status_t rgl_node_points_radar_postprocess(rgl_node_t* node, float distance_separation, float azimuth_separation)
1035+
RGL_API rgl_status_t rgl_node_points_radar_postprocess(rgl_node_t* node, float distance_separation, float azimuth_separation,
1036+
float ray_azimuth_step, float ray_elevation_step, float frequency)
10361037
{
10371038
auto status = rglSafeCall([&]() {
10381039
RGL_API_LOG("rgl_node_points_radar_postprocess(node={}, distance_separation={}, azimuth_separation={})", repr(node),
10391040
distance_separation, azimuth_separation);
10401041

10411042
CHECK_ARG(distance_separation > 0);
10421043
CHECK_ARG(azimuth_separation > 0);
1044+
CHECK_ARG(ray_azimuth_step > 0);
1045+
CHECK_ARG(ray_elevation_step > 0);
10431046

1044-
createOrUpdateNode<RadarPostprocessPointsNode>(node, distance_separation, azimuth_separation);
1047+
createOrUpdateNode<RadarPostprocessPointsNode>(node, distance_separation, azimuth_separation, ray_azimuth_step,
1048+
ray_elevation_step, frequency);
10451049
});
1046-
TAPE_HOOK(node, distance_separation, azimuth_separation);
1050+
TAPE_HOOK(node, distance_separation, azimuth_separation, ray_azimuth_step, ray_elevation_step, frequency);
10471051
return status;
10481052
}
10491053

10501054
void TapeCore::tape_node_points_radar_postprocess(const YAML::Node& yamlNode, PlaybackState& state)
10511055
{
10521056
auto nodeId = yamlNode[0].as<TapeAPIObjectID>();
10531057
rgl_node_t node = state.nodes.contains(nodeId) ? state.nodes.at(nodeId) : nullptr;
1054-
rgl_node_points_radar_postprocess(&node, yamlNode[1].as<float>(), yamlNode[2].as<float>());
1058+
rgl_node_points_radar_postprocess(&node, yamlNode[1].as<float>(), yamlNode[2].as<float>(), yamlNode[3].as<float>(),
1059+
yamlNode[4].as<float>(), yamlNode[5].as<float>());
10551060
state.nodes.insert({nodeId, node});
10561061
}
10571062

src/gpu/nodeKernels.cu

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include <thrust/device_ptr.h>
2222
#include <thrust/scan.h>
23+
#include <thrust/complex.h>
2324

2425
__global__ void kFormatSoaToAos(size_t pointCount, size_t pointSize, size_t fieldCount, const GPUFieldDesc* soaInData,
2526
char* aosOutData)
@@ -78,6 +79,87 @@ __global__ void kFilter(size_t count, const Field<RAY_IDX_U32>::type* indices, c
7879
memcpy(dst + tid * fieldSize, src + indices[tid] * fieldSize, fieldSize);
7980
}
8081

82+
__device__ Vec3f reflectPolarization(const Vec3f& pol, const Vec3f& hitNormal, const Vec3f& rayDir)
83+
{
84+
const auto diffCrossNormal = rayDir.cross(hitNormal);
85+
const auto polU = diffCrossNormal.normalized();
86+
const auto polR = rayDir.cross(polU).normalized();
87+
88+
const auto refDir = (rayDir - hitNormal * (2 * rayDir.dot(hitNormal))).normalized();
89+
const auto refPolU = -1.0f * polU;
90+
const auto refPolR = rayDir.cross(refPolU);
91+
92+
const auto polCompU = pol.dot(polU);
93+
const auto polCompR = pol.dot(polR);
94+
95+
return -polCompR * refPolR + polCompU * refPolU;
96+
}
97+
98+
__global__ void kRadarComputeEnergy(size_t count, float rayAzimuthStepRad, float rayElevationStepRad, float freq,
99+
const Field<RAY_POSE_MAT3x4_F32>::type* rayPose, const Field<DISTANCE_F32>::type* hitDist,
100+
const Field<NORMAL_VEC3_F32>::type* hitNorm, const Field<XYZ_VEC3_F32>::type* hitPos,
101+
Vector<3, thrust::complex<float>>* outBUBRFactor)
102+
{
103+
LIMIT(count);
104+
105+
constexpr float c0 = 299792458.0f;
106+
constexpr float reflectionCoef = 1.0f; // TODO
107+
const float waveLen = c0 / freq;
108+
const float waveNum = 2.0f * M_PIf / waveLen;
109+
const thrust::complex<float> i = {0, 1.0};
110+
const Vec3f dirX = {1, 0, 0};
111+
const Vec3f dirY = {0, 1, 0};
112+
const Vec3f dirZ = {0, 0, 1};
113+
114+
const Vec3f rayDirCts = rayPose[tid] * Vec3f{0, 0, 1};
115+
const Vec3f rayDirSph = rayDirCts.toSpherical();
116+
const float phi = rayDirSph[1]; // azimuth, 0 = X-axis, positive = CCW
117+
const float the = rayDirSph[2]; // elevation, 0 = Z-axis, 90 = XY-plane, -180 = negative Z-axis
118+
119+
// Consider unit vector of the ray direction, these are its projections:
120+
const float cp = cosf(phi); // X-dir component
121+
const float sp = sinf(phi); // Y-dir component
122+
const float ct = cosf(the); // Z-dir component
123+
const float st = sinf(the); // XY-plane component
124+
125+
const Vec3f dirP = {-sp, cp, 0};
126+
const Vec3f dirT = {cp * ct, sp * ct, -st};
127+
128+
const thrust::complex<float> kr = {waveNum * hitDist[tid], 0.0f};
129+
130+
const Vec3f rayDir = rayDirCts.normalized();
131+
const Vec3f rayPol = rayPose[tid] * Vec3f{-1, 0, 0}; // UP, perpendicular to ray
132+
const Vec3f reflectedPol = reflectPolarization(rayPol, hitNorm[tid], rayDir);
133+
134+
const Vector<3, thrust::complex<float>> rayPolCplx = {reflectedPol.x(), reflectedPol.y(), reflectedPol.z()};
135+
136+
const Vector<3, thrust::complex<float>> apE = reflectionCoef * exp(i * kr) * rayPolCplx;
137+
const Vector<3, thrust::complex<float>> apH = -apE.cross(rayDir);
138+
139+
const Vec3f vecK = waveNum * ((dirX * cp + dirY * sp) * st + dirZ * ct);
140+
141+
const float rayArea = hitDist[tid] * hitDist[tid] * std::sin(rayElevationStepRad) * rayAzimuthStepRad;
142+
143+
thrust::complex<float> BU = (-(apE.cross(-dirP) + apH.cross(dirT))).dot(rayDir);
144+
thrust::complex<float> BR = (-(apE.cross(dirT) + apH.cross(dirP))).dot(rayDir);
145+
thrust::complex<float> factor = thrust::complex<float>(0.0, ((waveNum * rayArea) / (4.0f * M_PIf))) *
146+
exp(-i * vecK.dot(hitPos[tid]));
147+
148+
// printf("GPU: point=%d ray=??: dist=%f, pos=(%.2f, %.2f, %.2f), norm=(%.2f, %.2f, %.2f), BU=(%.2f+%.2fi), BR=(%.2f+%.2fi), factor=(%.2f+%.2fi)\n", tid, hitDist[tid],
149+
// hitPos[tid].x(), hitPos[tid].y(), hitPos[tid].z(), hitNorm[tid].x(), hitNorm[tid].y(), hitNorm[tid].z(),
150+
// BU.real(), BU.imag(), BR.real(), BR.imag(), factor.real(), factor.imag());
151+
// Print variables:
152+
// printf("GPU: point=%d ray=??: rayDirCts=(%.2f, %.2f, %.2f), rayDirSph=(%.2f, %.2f, %.2f), phi=%.2f, the=%.2f, cp=%.2f, "
153+
// "sp=%.2f, ct=%.2f, st=%.2f, dirP=(%.2f, %.2f, %.2f), dirT=(%.2f, %.2f, %.2f), kr=(%.2f+%.2fi), rayDir=(%.2f, "
154+
// "%.2f, %.2f), rayPol=(%.2f, %.2f, %.2f), reflectedPol=(%.2f, %.2f, %.2f)\n",
155+
// tid, rayDirCts.x(), rayDirCts.y(), rayDirCts.z(), rayDirSph.x(), rayDirSph.y(),
156+
// rayDirSph.z(), phi, the, cp, sp, ct, st, dirP.x(), dirP.y(), dirP.z(), dirT.x(), dirT.y(), dirT.z(), kr.real(),
157+
// kr.imag(), rayDir.x(), rayDir.y(), rayDir.z(), rayPol.x(), rayPol.y(), rayPol.z(), reflectedPol.x(),
158+
// reflectedPol.y(), reflectedPol.z());
159+
160+
outBUBRFactor[tid] = {BU, BR, factor};
161+
}
162+
81163
__global__ void kFilterGroundPoints(size_t pointCount, const Vec3f sensor_up_vector, float ground_angle_threshold,
82164
const Field<XYZ_VEC3_F32>::type* inPoints, const Field<NORMAL_VEC3_F32>::type* inNormalsPtr,
83165
Field<IS_GROUND_I32>::type* outNonGround, Mat3x4f lidarTransform)
@@ -90,6 +172,7 @@ __global__ void kFilterGroundPoints(size_t pointCount, const Vec3f sensor_up_vec
90172
outNonGround[tid] = normalUpAngle > ground_angle_threshold;
91173
}
92174

175+
93176
void gpuFindCompaction(cudaStream_t stream, size_t pointCount, const int32_t* shouldCompact,
94177
CompactionIndexType* hitCountInclusive, size_t* outHitCount)
95178
{
@@ -153,3 +236,12 @@ void gpuFilterGroundPoints(cudaStream_t stream, size_t pointCount, const Vec3f s
153236
run(kFilterGroundPoints, stream, pointCount, sensor_up_vector, ground_angle_threshold, inPoints, inNormalsPtr, outNonGround,
154237
lidarTransform);
155238
}
239+
240+
void gpuRadarComputeEnergy(cudaStream_t stream, size_t count, float rayAzimuthStepRad, float rayElevationStepRad, float freq,
241+
const Field<RAY_POSE_MAT3x4_F32>::type* rayPose, const Field<DISTANCE_F32>::type* hitDist,
242+
const Field<NORMAL_VEC3_F32>::type* hitNorm, const Field<XYZ_VEC3_F32>::type* hitPos,
243+
Vector<3, thrust::complex<float>>* outBUBRFactor)
244+
{
245+
run(kRadarComputeEnergy, stream, count, rayAzimuthStepRad, rayElevationStepRad, freq, rayPose, hitDist, hitNorm, hitPos,
246+
outBUBRFactor);
247+
}

src/gpu/nodeKernels.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <gpu/GPUFieldDesc.hpp>
2222
#include <math/Mat3x4f.hpp>
2323
#include <RGLFields.hpp>
24+
#include <thrust/complex.h>
2425

2526
/*
2627
* The following functions are asynchronous!
@@ -46,3 +47,7 @@ void gpuFilter(cudaStream_t, size_t count, const Field<RAY_IDX_U32>::type* indic
4647
void gpuFilterGroundPoints(cudaStream_t stream, size_t pointCount, const Vec3f sensor_up_axis, float ground_angle_threshold,
4748
const Field<XYZ_VEC3_F32>::type* inPoints, const Field<NORMAL_VEC3_F32>::type* inNormalsPtr,
4849
Field<IS_GROUND_I32>::type* outNonGround, Mat3x4f lidarTransform);
50+
void gpuRadarComputeEnergy(cudaStream_t stream, size_t count, float rayAzimuthStepRad, float rayElevationStepRad, float freq,
51+
const Field<RAY_POSE_MAT3x4_F32>::type* rayPose, const Field<DISTANCE_F32>::type* hitDist,
52+
const Field<NORMAL_VEC3_F32>::type* hitNorm, const Field<XYZ_VEC3_F32>::type* hitPos,
53+
Vector<3, thrust::complex<float>>* outBUBRFactor);

src/graph/NodesCore.hpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ struct RaytraceNode : IPointsNode
116116
// Data getters
117117
IAnyArray::ConstPtr getFieldData(rgl_field_t field) override
118118
{
119+
if (field == RAY_POSE_MAT3x4_F32) {
120+
return raysNode->getRays();
121+
}
119122
return std::const_pointer_cast<const IAnyArray>(fieldData.at(field));
120123
}
121124

@@ -463,7 +466,8 @@ struct GaussianNoiseDistanceNode : IPointsNodeSingleInput
463466
struct RadarPostprocessPointsNode : IPointsNodeSingleInput
464467
{
465468
using Ptr = std::shared_ptr<RadarPostprocessPointsNode>;
466-
void setParameters(float distanceSeparation, float azimuthSeparation);
469+
void setParameters(float distanceSeparation, float azimuthSeparation, float rayAzimuthStepRad, float rayElevationStepRad,
470+
float frequency);
467471

468472
// Node
469473
void validateImpl() override;
@@ -487,9 +491,17 @@ struct RadarPostprocessPointsNode : IPointsNodeSingleInput
487491
HostPinnedArray<Field<DISTANCE_F32>::type>::Ptr distanceInputHost = HostPinnedArray<Field<DISTANCE_F32>::type>::create();
488492
HostPinnedArray<Field<AZIMUTH_F32>::type>::Ptr azimuthInputHost = HostPinnedArray<Field<AZIMUTH_F32>::type>::create();
489493
HostPinnedArray<Field<ELEVATION_F32>::type>::Ptr elevationInputHost = HostPinnedArray<Field<ELEVATION_F32>::type>::create();
494+
DeviceAsyncArray<Vector<3, thrust::complex<float>>>::Ptr outBUBRFactorDev =
495+
DeviceAsyncArray<Vector<3, thrust::complex<float>>>::create(arrayMgr);
496+
HostPinnedArray<Vector<3, thrust::complex<float>>>::Ptr outBUBRFactorHost =
497+
HostPinnedArray<Vector<3, thrust::complex<float>>>::create();
490498

491499
float distanceSeparation;
492500
float azimuthSeparation;
501+
float rayAzimuthStepRad;
502+
float rayElevationStepRad;
503+
float frequency;
504+
493505

494506
// RGL related members
495507
std::mutex getFieldDataMutex;

src/graph/RadarPostprocessPointsNode.cpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,24 @@
1717
#include <graph/NodesCore.hpp>
1818
#include <gpu/nodeKernels.hpp>
1919

20-
void RadarPostprocessPointsNode::setParameters(float distanceSeparation, float azimuthSeparation)
20+
void RadarPostprocessPointsNode::setParameters(float distanceSeparation, float azimuthSeparation, float rayAzimuthStepRad,
21+
float rayElevationStepRad, float frequency)
2122
{
2223
this->distanceSeparation = distanceSeparation;
2324
this->azimuthSeparation = azimuthSeparation;
25+
this->rayAzimuthStepRad = rayAzimuthStepRad;
26+
this->rayElevationStepRad = rayElevationStepRad;
27+
this->frequency = frequency;
2428
}
2529

2630
void RadarPostprocessPointsNode::validateImpl()
2731
{
2832
IPointsNodeSingleInput::validateImpl();
2933

34+
if (!input->isDense()) {
35+
throw InvalidPipeline("RadarComputeEnergyPointsNode requires dense input");
36+
}
37+
3038
// Needed to clear cache because fields in the pipeline may have changed
3139
// In fact, the cache manager is no longer useful here
3240
// To be kept/removed in some future refactor (when resolving comment in the `enqueueExecImpl`)
@@ -37,6 +45,28 @@ void RadarPostprocessPointsNode::enqueueExecImpl()
3745
{
3846
cacheManager.trigger();
3947

48+
auto rays = input->getFieldDataTyped<RAY_POSE_MAT3x4_F32>()->asSubclass<DeviceAsyncArray>()->getReadPtr();
49+
auto distance = input->getFieldDataTyped<DISTANCE_F32>()->asSubclass<DeviceAsyncArray>()->getReadPtr();
50+
auto normal = input->getFieldDataTyped<NORMAL_VEC3_F32>()->asSubclass<DeviceAsyncArray>()->getReadPtr();
51+
auto xyz = input->getFieldDataTyped<XYZ_VEC3_F32>()->asSubclass<DeviceAsyncArray>()->getReadPtr();
52+
outBUBRFactorDev->resize(input->getPointCount(), false, false);
53+
gpuRadarComputeEnergy(getStreamHandle(), input->getPointCount(), rayAzimuthStepRad, rayElevationStepRad, frequency, rays,
54+
distance, normal, xyz, outBUBRFactorDev->getWritePtr());
55+
outBUBRFactorHost->copyFrom(outBUBRFactorDev);
56+
CHECK_CUDA(cudaStreamSynchronize(getStreamHandle()));
57+
58+
// Computing RCS (example for all points)
59+
// std::complex<float> AU = 0;
60+
// std::complex<float> AR = 0;
61+
// for (int hitIdx = 0; hitIdx < outBUBRFactorHost->getCount(); ++hitIdx) {
62+
// std::complex<float> BU = {outBUBRFactorHost->at(hitIdx)[0].real(), outBUBRFactorHost->at(hitIdx)[0].imag()};
63+
// std::complex<float> BR = {outBUBRFactorHost->at(hitIdx)[1].real(), outBUBRFactorHost->at(hitIdx)[1].imag()};
64+
// std::complex<float> factor = {outBUBRFactorHost->at(hitIdx)[2].real(), outBUBRFactorHost->at(hitIdx)[2].imag()};
65+
// AU += BU * factor;
66+
// AR += BR * factor;
67+
// }
68+
// float rcs = 10.0f * log10f(4.0f * M_PIf * (pow(abs(AU), 2) + pow(abs(AR), 2)));
69+
4070
if (input->getPointCount() == 0) {
4171
filteredIndices->resize(0, false, false);
4272
return;

0 commit comments

Comments
 (0)