CARLA
Loading...
Searching...
No Matches
RayCastSemanticLidar.h
Go to the documentation of this file.
1// Copyright (c) 2026 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
7
8
9#pragma once
10
11#include "Carla/Sensor/Sensor.h"
15
19
20#include <numeric>
21#include <type_traits>
22#include <vector>
23
24#include "RayCastSemanticLidar.generated.h"
25
26/// A ray-cast based Lidar sensor.
27UCLASS()
28class CARLA_API ARayCastSemanticLidar : public ASensor
29{
30 GENERATED_BODY()
31
32protected:
33
36
37public:
38 static FActorDefinition GetSensorDefinition();
39
40 ARayCastSemanticLidar(const FObjectInitializer &ObjectInitializer);
41
42 virtual void Set(const FActorDescription &Description) override;
43 virtual void Set(const FLidarDescription &LidarDescription);
44
45 virtual void SimulateLidar(const float DeltaTime, bool bLockPhysics = true);
46
47 virtual void SendData(const float DeltaTime);
48
49 void GetMirrorState(carla::multigpu::SensorState &State) const override;
50
51 void SetMirrorState(const carla::multigpu::SensorState &State) override;
52
53protected:
54 virtual void BeginPlay() override;
55 virtual void EndPlay(EEndPlayReason::Type EndPlayReason) override;
56
57 /// Creates a Laser for each channel.
58 void CreateLasers();
59
60 /// Shoot a laser ray-trace, return whether the laser hit something.
61 bool ShootLaser(const float VerticalAngle, float HorizontalAngle, FHitResult &HitResult, FCollisionQueryParams& TraceParams,
62 const FVector &LidarBodyLocation, const FRotator &LidarBodyRotation) const;
63
64 /// Method that allow to preprocess if the rays will be traced.
65 virtual void PreprocessRays(uint32_t Channels, uint32_t MaxPointsPerChannel);
66
67 /// Compute all raw detection information
68 void ComputeRawDetection(const FHitResult &HitInfo, const FTransform &InverseSensorTransform, const FVector &SensorLocation, FSemanticDetection &Detection) const;
69
70 /// Computes the detection of a hit inside the raycast ParallelFor.
71 virtual void WriteDetectionAsync(uint32_t Channel, const FHitResult &HitInfo, const FTransform &InverseSensorTransform, const FVector &SensorLocation);
72
73 /// Clear the per-channel detection buffers
74 virtual void ResetDetections(uint32_t Channels, uint32_t MaxPointsPerChannel);
75
76 /// Copies the per-channel detections into the LidarData structure.
77 virtual void ComputeAndSaveDetections(const FTransform &SensorTransform);
78
79 /// Clears every channel buffer and reserves room for a full scan.
80 template <typename DetectionT>
81 static void ResetChannelDetections(std::vector<std::vector<DetectionT>> &Detections, uint32_t Channels, uint32_t MaxPointsPerChannel)
82 {
83 Detections.resize(Channels);
84 for (auto &ChannelDetections : Detections)
85 {
86 ChannelDetections.clear();
87 ChannelDetections.reserve(MaxPointsPerChannel);
88 }
89 }
90
91 /// Post-processes the detections channel by channel, drops the rejected ones and writes the rest to LidarData.
92 /// Runs sequentially in channel and point order, so the random sequence for noise and drop-off is unchanged.
93 template <typename DetectionT, typename LidarDataT, typename PostprocessT>
95 std::vector<std::vector<DetectionT>> &Detections,
96 std::vector<uint32_t> &OutPointsPerChannel,
97 uint32_t Channels,
98 LidarDataT &LidarData,
99 PostprocessT &&Postprocess)
100 {
101 for (uint32_t Channel = 0u; Channel < Channels; ++Channel)
102 {
103 auto &ChannelDetections = Detections[Channel];
104 size_t Kept = 0;
105 for (DetectionT &Detection : ChannelDetections)
106 {
107 if (Postprocess(Detection))
108 {
109 ChannelDetections[Kept++] = Detection;
110 }
111 }
112 ChannelDetections.resize(Kept);
113 OutPointsPerChannel[Channel] = static_cast<uint32_t>(Kept);
114 }
115
116 LidarData.ResetMemory(OutPointsPerChannel);
117 for (uint32_t Channel = 0u; Channel < Channels; ++Channel)
118 {
119 LidarData.WritePoints(Detections[Channel]);
120 }
121 LidarData.WriteChannelCount(OutPointsPerChannel);
122 }
123
124 /// Copies the kept detections into a flat x, y, z, intensity array (editor debug point cloud).
125 template <typename DetectionT>
127 const std::vector<std::vector<DetectionT>> &Detections,
128 const std::vector<uint32_t> &InPointsPerChannel,
129 TArray<float> &PointCloud)
130 {
131 static_assert(sizeof(DetectionT) == sizeof(float) * 4, "Detection must be 4 packed floats");
132 static_assert(std::is_trivially_copyable_v<DetectionT>, "Detection must be trivially copyable");
133
134 const uint32_t TotalPoints = std::accumulate(InPointsPerChannel.begin(), InPointsPerChannel.end(), 0u);
135 PointCloud.SetNumUninitialized(static_cast<int32>(TotalPoints * 4));
136
137 float *Dest = PointCloud.GetData();
138 for (const auto &ChannelDetections : Detections)
139 {
140 if (ChannelDetections.empty())
141 {
142 continue;
143 }
144 FMemory::Memcpy(Dest, ChannelDetections.data(), ChannelDetections.size() * sizeof(DetectionT));
145 Dest += ChannelDetections.size() * 4;
146 }
147 }
148
149 UPROPERTY(EditAnywhere)
150 FLidarDescription Description;
151
152 TArray<float> LaserAngles;
153
154 std::vector<std::vector<bool>> RayPreprocessCondition;
155 std::vector<uint32_t> PointsPerChannel;
156
157private:
158 FSemanticLidarData SemanticLidarData;
159
160 std::vector<std::vector<FSemanticDetection>> SemanticDetections;
161
162};
A ray-cast based Lidar sensor.
static void CompactAndWriteDetections(std::vector< std::vector< DetectionT > > &Detections, std::vector< uint32_t > &OutPointsPerChannel, uint32_t Channels, LidarDataT &LidarData, PostprocessT &&Postprocess)
Post-processes the detections channel by channel, drops the rejected ones and writes the rest to Lida...
static void ResetChannelDetections(std::vector< std::vector< DetectionT > > &Detections, uint32_t Channels, uint32_t MaxPointsPerChannel)
Clears every channel buffer and reserves room for a full scan.
static void CopyDetectionsToPointCloud(const std::vector< std::vector< DetectionT > > &Detections, const std::vector< uint32_t > &InPointsPerChannel, TArray< float > &PointCloud)
Copies the kept detections into a flat x, y, z, intensity array (editor debug point cloud).
Helper class to store and serialize the data generated by a RawLidar.
A definition of a Carla Actor with all the variation and attributes.
A description of a Carla Actor with all its variation.
One record of frame data packet 27: the runtime state a sensor of the primary starts this frame's tic...
Definition sensorSync.h:87