Skip to content

Commit c7b2e54

Browse files
jonyMarinoMarinaGloc
andauthored
Improved LiDAR response time (#122)
Co-authored-by: MarinaGloc <tu-correo-de-github@example.com>
1 parent 3c471f2 commit c7b2e54

File tree

2 files changed

+68
-47
lines changed

2 files changed

+68
-47
lines changed

unreal/Blocks/Plugins/ProjectAirSim/Source/ProjectAirSim/Private/Sensors/UnrealLidar.cpp

Lines changed: 61 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,24 @@ void UUnrealLidar::TickComponent(
5858

5959
// Move sensor data to pending report buffers
6060
if (!Settings.report_no_return_points) {
61+
size_t NumReturns = 0;
62+
for (const uint8_t bReturned : ReturnCloud) {
63+
NumReturns += (bReturned != 0) ? 1 : 0;
64+
}
65+
66+
if (Settings.report_point_cloud) {
67+
PointCloudPending.reserve(PointCloudPending.size() + NumReturns * 3);
68+
}
69+
if (Settings.report_azimuth_elevation_range) {
70+
AzimuthElevationRangeCloudPending.reserve(
71+
AzimuthElevationRangeCloudPending.size() + NumReturns * 3);
72+
}
73+
SegmentationCloudPending.reserve(SegmentationCloudPending.size() + NumReturns);
74+
IntensityCloudPending.reserve(IntensityCloudPending.size() + NumReturns);
75+
LaserIndexCloudPending.reserve(LaserIndexCloudPending.size() + NumReturns);
76+
6177
// Filter through the arrays and remove all no-return points
62-
for (int32 i = 0; i < ReturnCloud.size(); i++) {
78+
for (size_t i = 0; i < ReturnCloud.size(); ++i) {
6379
if (ReturnCloud[i]) {
6480
if (Settings.report_point_cloud) {
6581
PointCloudPending.push_back(PointCloud[i * 3]);
@@ -130,8 +146,8 @@ void UUnrealLidar::TickComponent(
130146
LaserIndexCloud.size());
131147
LaserIndexCloudPending.insert(
132148
LaserIndexCloudPending.end(),
133-
std::make_move_iterator(IntensityCloud.begin()),
134-
std::make_move_iterator(IntensityCloud.end()));
149+
std::make_move_iterator(LaserIndexCloud.begin()),
150+
std::make_move_iterator(LaserIndexCloud.end()));
135151
}
136152
}
137153
AzimuthElevationRangeCloud.clear();
@@ -216,6 +232,15 @@ void UUnrealLidar::SetupLidarFromSettings(
216232
: projectairsim::SimClock::Get()->SecToNanos(
217233
1.0f / Settings.report_frequency);
218234

235+
LidarRangeCentimeters =
236+
projectairsim::TransformUtils::ToCentimeters(Settings.range);
237+
LaserTraceParams =
238+
FCollisionQueryParams(SCENE_QUERY_STAT(UnrealLidar), true);
239+
LaserTraceParams.bReturnPhysicalMaterial = false;
240+
if (Settings.disable_self_hits && OwnerActor) {
241+
LaserTraceParams.AddIgnoredActor(OwnerActor);
242+
}
243+
219244
// Save scan axis orientation
220245
{
221246
auto quaternion = Settings.scan_orientation.normalized();
@@ -256,7 +281,8 @@ void UUnrealLidar::InitializePose(const projectairsim::Transform& PoseNed) {
256281
// Simulate shooting a laser via Unreal ray-tracing.
257282
FHitResult UUnrealLidar::ShootSingleLaser(const LaserDirection& LaserDir,
258283
const FVector& LidarBodyLoc,
259-
const FRotator& LidarBodyRot) {
284+
const FRotator& LidarBodyRot,
285+
const FCollisionQueryParams& TraceParams) {
260286
const FRotator LaserRotInSensorFrame(LaserDir.VerticalAngleDeg, /*pitch*/
261287
LaserDir.HorizontalAngleDeg, /*yaw*/
262288
0 /*roll*/);
@@ -272,17 +298,9 @@ FHitResult UUnrealLidar::ShootSingleLaser(const LaserDirection& LaserDir,
272298
LaserDir.OffsetDistanceVertical;
273299

274300
// Calculate "EndTrace": point corresponding to end of ray trace.
275-
const FVector EndTrace =
276-
LaserLoc + (projectairsim::TransformUtils::ToCentimeters(Settings.range) *
277-
RayDirectionVector);
301+
const FVector EndTrace = LaserLoc + (LidarRangeCentimeters * RayDirectionVector);
278302

279303
// Shoot ray via LineTraceSingleByChannel, result is saved in HitInfo
280-
FCollisionQueryParams TraceParams;
281-
if (Settings.disable_self_hits) {
282-
TraceParams.AddIgnoredActor(OwnerActor); // don't hit yourself
283-
}
284-
TraceParams.bTraceComplex = true;
285-
TraceParams.bReturnPhysicalMaterial = false;
286304

287305
FHitResult HitInfo(ForceInit);
288306

@@ -351,42 +369,45 @@ void UUnrealLidar::Simulate(const float SimTimeDeltaSec) {
351369
const bool bReportPointCloud = Settings.report_point_cloud;
352370
const bool bReportAzimuthElevationRange =
353371
Settings.report_azimuth_elevation_range;
372+
const bool bDrawDebugPoints = Settings.draw_debug_points;
354373

355-
FCriticalSection Mutex;
356374
TArray<FHitResult> GroundTruthHits;
375+
FCriticalSection GroundTruthHitsMutex;
376+
377+
const int32 NumLasers = LasersToShoot.Num();
378+
if (NumLasers <= 0) {
379+
PScanPattern->EndScan();
380+
return;
381+
}
382+
383+
if (bDrawDebugPoints) {
384+
GroundTruthHits.Reserve(NumLasers);
385+
}
357386

358387
if (bReportPointCloud) {
359-
for (int32 i = 0; i < LasersToShoot.Num(); i++) {
360-
PointCloud.push_back(NoReturnX);
361-
PointCloud.push_back(NoReturnY);
362-
PointCloud.push_back(NoReturnZ);
388+
PointCloud.resize(NumLasers * 3);
389+
for (int32 i = 0; i < NumLasers; ++i) {
390+
PointCloud[i * 3] = NoReturnX;
391+
PointCloud[i * 3 + 1] = NoReturnY;
392+
PointCloud[i * 3 + 2] = NoReturnZ;
363393
}
364394
}
365395
if (bReportAzimuthElevationRange) {
366-
AzimuthElevationRangeCloud.insert(AzimuthElevationRangeCloud.begin(),
367-
LasersToShoot.Num() * 3, 0);
396+
AzimuthElevationRangeCloud.resize(NumLasers * 3, 0.0f);
368397
}
369-
SegmentationCloud.insert(SegmentationCloud.begin(), LasersToShoot.Num(), 0);
370-
IntensityCloud.insert(IntensityCloud.begin(), LasersToShoot.Num(), 0);
371-
LaserIndexCloud.insert(LaserIndexCloud.begin(), LasersToShoot.Num(), 0);
372-
ReturnCloud.insert(ReturnCloud.begin(), LasersToShoot.Num(), false);
398+
SegmentationCloud.resize(NumLasers, NoSegmentationID);
399+
IntensityCloud.resize(NumLasers, 0.0f);
400+
LaserIndexCloud.resize(NumLasers, 0);
401+
ReturnCloud.resize(NumLasers, 0);
373402

374-
ParallelFor(LasersToShoot.Num(), [&](int32 Idx) {
403+
ParallelFor(NumLasers, [&](int32 Idx) {
375404
const FHitResult HitInfo =
376-
ShootSingleLaser(LasersToShoot[Idx], LidarBodyLoc, LidarScanRot);
405+
ShootSingleLaser(LasersToShoot[Idx], LidarBodyLoc, LidarScanRot,
406+
LaserTraceParams);
377407

378408
if (HitInfo.bBlockingHit == false) {
379409
// No laser return
380410
if (bReportNoReturnPoints) {
381-
// Add a special point value indicating no laser return
382-
Mutex.Lock();
383-
384-
if (bReportPointCloud) {
385-
PointCloud[Idx * 3] = NoReturnX;
386-
PointCloud[Idx * 3 + 1] = NoReturnY;
387-
PointCloud[Idx * 3 + 2] = NoReturnZ;
388-
}
389-
390411
if (bReportAzimuthElevationRange) {
391412
double Azimuth = LasersToShoot[Idx].HorizontalAngleDeg;
392413
double Elevation = LasersToShoot[Idx].VerticalAngleDeg;
@@ -398,9 +419,7 @@ void UUnrealLidar::Simulate(const float SimTimeDeltaSec) {
398419
SegmentationCloud[Idx] = NoSegmentationID;
399420
IntensityCloud[Idx] = 0.0f;
400421
LaserIndexCloud[Idx] = LasersToShoot[Idx].Channel;
401-
ReturnCloud[Idx] = false;
402-
403-
Mutex.Unlock();
422+
ReturnCloud[Idx] = 0;
404423
}
405424
} else {
406425
// Get CustomDepthStencilValue directly from the hit component
@@ -417,8 +436,6 @@ void UUnrealLidar::Simulate(const float SimTimeDeltaSec) {
417436
const projectairsim::Vector3 PointNed =
418437
UnrealTransform::UnrealToNedLinear(Point);
419438

420-
Mutex.Lock();
421-
422439
if (bReportPointCloud) {
423440
PointCloud[Idx * 3] = PointNed.x();
424441
PointCloud[Idx * 3 + 1] = PointNed.y();
@@ -440,19 +457,18 @@ void UUnrealLidar::Simulate(const float SimTimeDeltaSec) {
440457
SegmentationCloud[Idx] = SegmentationID;
441458
IntensityCloud[Idx] = CalculateIntensity(HitInfo);
442459
LaserIndexCloud[Idx] = LasersToShoot[Idx].Channel;
443-
ReturnCloud[Idx] = true;
460+
ReturnCloud[Idx] = 1;
444461

445-
if (Settings.draw_debug_points) {
462+
if (bDrawDebugPoints) {
463+
FScopeLock ScopeLock(&GroundTruthHitsMutex);
446464
GroundTruthHits.Add(HitInfo);
447465
}
448-
449-
Mutex.Unlock();
450466
}
451467
});
452468

453469
// 3. Optional - draw debug hit points on Unreal scene
454470

455-
if (Settings.draw_debug_points && UnrealWorld) {
471+
if (bDrawDebugPoints && UnrealWorld) {
456472
for (const auto& HitInfo : GroundTruthHits) {
457473
DrawDebugPoint(UnrealWorld, HitInfo.ImpactPoint,
458474
10, // size

unreal/Blocks/Plugins/ProjectAirSim/Source/ProjectAirSim/Private/Sensors/UnrealLidar.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#pragma once
1010

11+
#include <cstdint>
1112
#include <vector>
1213

1314
#include "CoreMinimal.h"
@@ -153,7 +154,8 @@ UCLASS() class UUnrealLidar : public UUnrealSensor {
153154

154155
FHitResult ShootSingleLaser(const LaserDirection& LaserDir,
155156
const FVector& LidarBodyLoc,
156-
const FRotator& LidarBodyRot);
157+
const FRotator& LidarBodyRot,
158+
const FCollisionQueryParams& TraceParams);
157159

158160
void Simulate(const float DeltaTime);
159161

@@ -177,7 +179,8 @@ UCLASS() class UUnrealLidar : public UUnrealSensor {
177179
microsoft::projectairsim::Lidar Lidar; // Corresponding sim sensor object
178180
AActor* OwnerActor; // Owning engine actor
179181
std::vector<float> PointCloud; // Sensor returns from current simulation pass
180-
std::vector<bool> ReturnCloud; // Marks if points were returned for each index
182+
std::vector<uint8_t>
183+
ReturnCloud; // Marks if points were returned for each index
181184
std::vector<float>
182185
PointCloudPending; // Sensor returns waiting to be reported
183186
std::vector<float> AzimuthElevationRangeCloud; // Sensor returns from current
@@ -198,6 +201,8 @@ UCLASS() class UUnrealLidar : public UUnrealSensor {
198201
microsoft::projectairsim::LidarSettings Settings; // Sensor settings
199202
TimeNano SimTimeDeltaReportTarget =
200203
0; // Desired sensor report interval (0 = as soon as possible)
204+
float LidarRangeCentimeters = 0.0f;
205+
FCollisionQueryParams LaserTraceParams;
201206

202207
bool ReportPointCloud = true;
203208
bool ReportAzimuthElevationRange = false;

0 commit comments

Comments
 (0)