CARLA
Loading...
Searching...
No Matches
RayCastLidar.cpp
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
8#include "Carla.h"
10
12#include "carla/geom/Math.h"
13#include "carla/ros2/ROS2.h"
14#include "carla/geom/Location.h"
16
17#include <util/ue-header-guard-begin.h>
18#include "DrawDebugHelpers.h"
19#include "Engine/CollisionProfile.h"
20#include "Kismet/KismetMathLibrary.h"
21#include <util/ue-header-guard-end.h>
22
23#include <cmath>
24
29
30
31ARayCastLidar::ARayCastLidar(const FObjectInitializer& ObjectInitializer)
32 : Super(ObjectInitializer) {
33
34 RandomEngine = CreateDefaultSubobject<URandomEngine>(TEXT("RandomEngine"));
36}
37
38void ARayCastLidar::Set(const FActorDescription &ActorDescription)
39{
40 ASensor::Set(ActorDescription);
41 FLidarDescription LidarDescription;
42 UActorBlueprintFunctionLibrary::SetLidar(ActorDescription, LidarDescription);
43 Set(LidarDescription);
44}
45
46void ARayCastLidar::Set(const FLidarDescription &LidarDescription)
47{
48 Description = LidarDescription;
53
54 // Compute drop off model parameters
57 DropOffGenActive = Description.DropOffGenRate > std::numeric_limits<float>::epsilon();
58}
59
60void ARayCastLidar::SendData(const float DeltaTime)
61{
62 TRACE_CPUPROFILER_EVENT_SCOPE(ARayCastLidar::SendData);
63 auto DataStream = GetDataStream(*this);
64 auto SensorTransform = DataStream.GetSensorTransform();
65
66 {
67 TRACE_CPUPROFILER_EVENT_SCOPE_STR("Send Stream");
68 DataStream.SerializeAndSend(*this, LidarData, DataStream.PopBufferFromPool());
69 }
70 // ROS2
71 #if defined(WITH_ROS2)
73 if (ROS2->IsEnabled())
74 {
75 TRACE_CPUPROFILER_EVENT_SCOPE_STR("ROS2 Send");
77 AActor* ParentActor = GetAttachParentActor();
78 // Passing the channel count and vertical FOV limits routes the publisher
79 // through the extended Autoware XYZIRCAEDT layout (tier4 autoware-support
80 // port); see ROS2::ProcessDataFromLidar.
81 if (ParentActor)
82 {
83 FTransform LocalTransformRelativeToParent = GetActorTransform().GetRelativeTransform(ParentActor->GetActorTransform());
84 ROS2->ProcessDataFromLidar(DataStream.GetSensorType(), StreamId, LocalTransformRelativeToParent,
86 }
87 else
88 {
89 ROS2->ProcessDataFromLidar(DataStream.GetSensorType(), StreamId, SensorTransform,
91 }
92 }
93 #endif
94}
95
97{
98 const carla::geom::Location HitPoint = RawDetection.point;
99 const float Distance = HitPoint.Length();
100
101 const float AttenAtm = Description.AtmospAttenRate;
102 const float AbsAtm = exp(-AttenAtm * Distance);
103
104 const float IntRec = AbsAtm;
105
106 return IntRec;
107}
108
109ARayCastLidar::FDetection ARayCastLidar::ComputeDetection(const FHitResult& HitInfo, const FTransform& InverseSensorTransform) const
110{
111 FDetection Detection;
112 const FVector HitPoint = HitInfo.ImpactPoint;
113 Detection.point = InverseSensorTransform.TransformPosition(HitPoint);
114
115 const float Distance = Detection.point.Length();
116
117 const float AttenAtm = Description.AtmospAttenRate;
118 const float AbsAtm = exp(-AttenAtm * Distance);
119
120 const float IntRec = AbsAtm;
121
122 Detection.intensity = IntRec;
123
124 return Detection;
125}
126
127 void ARayCastLidar::PreprocessRays(uint32_t Channels, uint32_t MaxPointsPerChannel) {
128 Super::PreprocessRays(Channels, MaxPointsPerChannel);
129
130 if (!DropOffGenActive)
131 {
132 return;
133 }
134
135 for (auto ch = 0u; ch < Channels; ch++) {
136 for (auto p = 0u; p < MaxPointsPerChannel; p++) {
138 }
139 }
140 }
141
143 {
144 if (Description.NoiseStdDev > std::numeric_limits<float>::epsilon()) {
145 const auto ForwardVector = Detection.point.MakeUnitVector();
146 const auto Noise = ForwardVector * RandomEngine->GetNormalDistribution(0.0f, Description.NoiseStdDev);
147 Detection.point += Noise;
148 }
149
150 const float Intensity = Detection.intensity;
151 if(Intensity > Description.DropOffIntensityLimit)
152 return true;
153 else
154 return RandomEngine->GetUniformFloat() < DropOffAlpha * Intensity + DropOffBeta;
155 }
156
157 void ARayCastLidar::ResetDetections(uint32_t Channels, uint32_t MaxPointsPerChannel)
158 {
159 ResetChannelDetections(Detections, Channels, MaxPointsPerChannel);
160 }
161
162 void ARayCastLidar::WriteDetectionAsync(uint32_t Channel, const FHitResult& HitInfo, const FTransform& InverseSensorTransform, const FVector& /*SensorLocation*/) {
163 DEBUG_ASSERT(GetChannelCount() > Channel);
164 Detections[Channel].emplace_back(ComputeDetection(HitInfo, InverseSensorTransform));
165 }
166
167 void ARayCastLidar::ComputeAndSaveDetections(const FTransform& SensorTransform)
168 {
169 TRACE_CPUPROFILER_EVENT_SCOPE_STR(__FUNCTION__);
170
172 [this](FDetection& Detection) { return PostprocessDetection(Detection); });
173
174#if WITH_EDITOR
176 {
178 }
179#endif
180 }
#define DEBUG_ASSERT(predicate)
Definition Debug.h:66
void ResetDetections(uint32_t Channels, uint32_t MaxPointsPerChannel) override
Clear the per-channel detection buffers.
carla::sensor::data::LidarData FLidarData
TArray< float > PointCloudLidarData
static FActorDefinition GetSensorDefinition()
FDetection ComputeDetection(const FHitResult &HitInfo, const FTransform &InverseSensorTransform) const
float ComputeIntensity(const FSemanticDetection &RawDetection) const
Compute the received intensity of the point.
void WriteDetectionAsync(uint32_t Channel, const FHitResult &HitInfo, const FTransform &InverseSensorTransform, const FVector &SensorLocation) override
Computes the detection of a hit inside the raycast ParallelFor.
bool PostprocessDetection(FDetection &Detection) const
FLidarData LidarData
void PreprocessRays(uint32_t Channels, uint32_t MaxPointsPerChannel) override
Method that allow to preprocess if the rays will be traced.
float DropOffAlpha
Slope for the intensity dropoff of lidar points, it is calculated throught the dropoff limit and the ...
virtual void Set(const FActorDescription &Description) override
bool DropOffGenActive
Enable/Disable general dropoff of lidar points.
ARayCastLidar(const FObjectInitializer &ObjectInitializer)
virtual void SendData(const float DeltaTime) override
std::vector< std::vector< FDetection > > Detections
void ComputeAndSaveDetections(const FTransform &SensorTransform) override
Copies the per-channel detections into the LidarData structure.
std::vector< uint32_t > PointsPerChannel
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...
void CreateLasers()
Creates a Laser for each channel.
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).
std::vector< std::vector< bool > > RayPreprocessCondition
FLidarDescription Description
virtual void Set(const FActorDescription &Description)
Definition Sensor.cpp:45
auto GetToken() const
Return the token that allows subscribing to this sensor's stream.
FAsyncDataStream GetDataStream(SensorType &&Self)
Return the FDataStream associated with this sensor.
URandomEngine * RandomEngine
Random Engine used to provide noise for sensor output.
void SetSeed(int32 InSeed)
Definition Sensor.cpp:104
static void SetLidar(const FActorDescription &Description, FLidarDescription &Lidar)
static FActorDefinition MakeLidarDefinition(const FString &Id)
float GetUniformFloat()
float GetNormalDistribution(float Mean, float StandardDeviation)
static std::shared_ptr< ROS2 > GetInstance()
Definition ROS2.h:61
Helper class to store and serialize the data generated by a Lidar.
Definition LidarData.h:54
Helper class to store and serialize the data generated by a RawLidar.
Serializes a stream endpoint.
A definition of a Carla Actor with all the variation and attributes.
A description of a Carla Actor with all its variation.
float DropOffAtZeroIntensity
General drop off rate.
int RandomSeed
Random seed for the noise/dropoff used by this sensor.
float LowerFovLimit
Lower laser angle, counts from horizontal, negative values means under horizontal line.
float DropOffGenRate
General drop off rate.
uint32 Channels
Number of lasers.
float DropOffIntensityLimit
General drop off rate.
float AtmospAttenRate
Attenuation Rate in the atmosphere in m^-1.
float UpperFovLimit
Upper laser angle, counts from horizontal, positive values means above horizontal line.
Vector3D MakeUnitVector(const float epsilon=2.0f *std::numeric_limits< float >::epsilon()) const
Return a unit-length copy of this vector.