CARLA
RayCastLidar.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017 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 #include <PxScene.h>
8 #include <cmath>
9 #include "Carla.h"
12 #include "carla/geom/Math.h"
13 
15 #include "carla/geom/Math.h"
16 #include "carla/ros2/ROS2.h"
17 #include "carla/geom/Location.h"
19 
20 #include "DrawDebugHelpers.h"
21 #include "Engine/CollisionProfile.h"
22 #include "Runtime/Engine/Classes/Kismet/KismetMathLibrary.h"
23 
25 {
27 }
28 
29 
30 ARayCastLidar::ARayCastLidar(const FObjectInitializer& ObjectInitializer)
31  : Super(ObjectInitializer) {
32 
33  RandomEngine = CreateDefaultSubobject<URandomEngine>(TEXT("RandomEngine"));
35 }
36 
37 void ARayCastLidar::Set(const FActorDescription &ActorDescription)
38 {
39  ASensor::Set(ActorDescription);
40  FLidarDescription LidarDescription;
41  UActorBlueprintFunctionLibrary::SetLidar(ActorDescription, LidarDescription);
42  Set(LidarDescription);
43 }
44 
45 void ARayCastLidar::Set(const FLidarDescription &LidarDescription)
46 {
47  Description = LidarDescription;
49  CreateLasers();
51 
52  // Compute drop off model parameters
55  DropOffGenActive = Description.DropOffGenRate > std::numeric_limits<float>::epsilon();
56 }
57 
58 void ARayCastLidar::PostPhysTick(UWorld *World, ELevelTick TickType, float DeltaTime)
59 {
60  TRACE_CPUPROFILER_EVENT_SCOPE(ARayCastLidar::PostPhysTick);
61  SimulateLidar(DeltaTime);
62 
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)
72  auto ROS2 = carla::ros2::ROS2::GetInstance();
73  if (ROS2->IsEnabled())
74  {
75  TRACE_CPUPROFILER_EVENT_SCOPE_STR("ROS2 Send");
77  AActor* ParentActor = GetAttachParentActor();
78  if (ParentActor)
79  {
80  FTransform LocalTransformRelativeToParent = GetActorTransform().GetRelativeTransform(ParentActor->GetActorTransform());
81  ROS2->ProcessDataFromLidar(DataStream.GetSensorType(), StreamId, LocalTransformRelativeToParent, LidarData, this);
82  }
83  else
84  {
85  ROS2->ProcessDataFromLidar(DataStream.GetSensorType(), StreamId, SensorTransform, LidarData, this);
86  }
87  }
88  #endif
89 
90 
91 }
92 
93 float ARayCastLidar::ComputeIntensity(const FSemanticDetection& RawDetection) const
94 {
95  const carla::geom::Location HitPoint = RawDetection.point;
96  const float Distance = HitPoint.Length();
97 
98  const float AttenAtm = Description.AtmospAttenRate;
99  const float AbsAtm = exp(-AttenAtm * Distance);
100 
101  const float IntRec = AbsAtm;
102 
103  return IntRec;
104 }
105 
106 ARayCastLidar::FDetection ARayCastLidar::ComputeDetection(const FHitResult& HitInfo, const FTransform& SensorTransf) const
107 {
108  FDetection Detection;
109  const FVector HitPoint = HitInfo.ImpactPoint;
110  Detection.point = SensorTransf.Inverse().TransformPosition(HitPoint);
111 
112  const float Distance = Detection.point.Length();
113 
114  const float AttenAtm = Description.AtmospAttenRate;
115  const float AbsAtm = exp(-AttenAtm * Distance);
116 
117  const float IntRec = AbsAtm;
118 
119  Detection.intensity = IntRec;
120 
121  return Detection;
122 }
123 
124  void ARayCastLidar::PreprocessRays(uint32_t Channels, uint32_t MaxPointsPerChannel) {
125  Super::PreprocessRays(Channels, MaxPointsPerChannel);
126 
127  for (auto ch = 0u; ch < Channels; ch++) {
128  for (auto p = 0u; p < MaxPointsPerChannel; p++) {
130  }
131  }
132  }
133 
135  {
136  if (Description.NoiseStdDev > std::numeric_limits<float>::epsilon()) {
137  const auto ForwardVector = Detection.point.MakeUnitVector();
138  const auto Noise = ForwardVector * RandomEngine->GetNormalDistribution(0.0f, Description.NoiseStdDev);
139  Detection.point += Noise;
140  }
141 
142  const float Intensity = Detection.intensity;
143  if(Intensity > Description.DropOffIntensityLimit)
144  return true;
145  else
146  return RandomEngine->GetUniformFloat() < DropOffAlpha * Intensity + DropOffBeta;
147  }
148 
149  void ARayCastLidar::ComputeAndSaveDetections(const FTransform& SensorTransform) {
150  for (auto idxChannel = 0u; idxChannel < Description.Channels; ++idxChannel)
151  PointsPerChannel[idxChannel] = RecordedHits[idxChannel].size();
152 
154 
155  for (auto idxChannel = 0u; idxChannel < Description.Channels; ++idxChannel) {
156  for (auto& hit : RecordedHits[idxChannel]) {
157  FDetection Detection = ComputeDetection(hit, SensorTransform);
158  if (PostprocessDetection(Detection))
159  LidarData.WritePointSync(Detection);
160  else
161  PointsPerChannel[idxChannel]--;
162  }
163  }
164 
166  }
float DropOffGenRate
General drop off rate.
auto GetToken() const
Return the token that allows subscribing to this sensor&#39;s stream.
static FActorDefinition MakeLidarDefinition(const FString &Id)
void PreprocessRays(uint32_t Channels, uint32_t MaxPointsPerChannel) override
Method that allow to preprocess if the rays will be traced.
std::vector< std::vector< FHitResult > > RecordedHits
float DropOffIntensityLimit
General drop off rate.
virtual void ResetMemory(std::vector< uint32_t > points_per_channel)
Definition: LidarData.h:87
virtual void PostPhysTick(UWorld *World, ELevelTick TickType, float DeltaTime)
virtual void WriteChannelCount(std::vector< uint32_t > points_per_channel)
void SetSeed(int32 InSeed)
Definition: Sensor.cpp:87
static FActorDefinition GetSensorDefinition()
Helper class to store and serialize the data generated by a RawLidar.
void CreateLasers()
Creates a Laser for each channel.
ARayCastLidar(const FObjectInitializer &ObjectInitializer)
void SimulateLidar(const float DeltaTime)
Updates LidarMeasurement with the points read in DeltaTime.
A definition of a Carla Actor with all the variation and attributes.
FLidarDescription Description
float Length() const
Definition: geom/Vector3D.h:49
FDetection ComputeDetection(const FHitResult &HitInfo, const FTransform &SensorTransf) const
FLidarData LidarData
Definition: RayCastLidar.h:50
carla::sensor::data::LidarData FLidarData
Definition: RayCastLidar.h:28
static void SetLidar(const FActorDescription &Description, FLidarDescription &Lidar)
A description of a Carla Actor with all its variation.
std::vector< std::vector< bool > > RayPreprocessCondition
float AtmospAttenRate
Attenuation Rate in the atmosphere in m^-1.
bool PostprocessDetection(FDetection &Detection) const
uint32 Channels
Number of lasers.
float DropOffAtZeroIntensity
General drop off rate.
float ComputeIntensity(const FSemanticDetection &RawDetection) const
Compute the received intensity of the point.
float DropOffBeta
Definition: RayCastLidar.h:61
const auto & get_stream_id() const
Definition: detail/Token.h:116
float GetUniformFloat()
Definition: RandomEngine.h:56
float DropOffAlpha
Slope for the intensity dropoff of lidar points, it is calculated throught the dropoff limit and the ...
Definition: RayCastLidar.h:60
void WritePointSync(LidarDetection &detection)
Definition: LidarData.h:98
bool DropOffGenActive
Enable/Disable general dropoff of lidar points.
Definition: RayCastLidar.h:53
FAsyncDataStream GetDataStream(const SensorT &Self)
Return the FDataStream associated with this sensor.
int RandomSeed
Random seed for the noise/dropoff used by this sensor.
static std::shared_ptr< ROS2 > GetInstance()
Definition: ROS2.h:51
float GetNormalDistribution(float Mean, float StandardDeviation)
Definition: RandomEngine.h:110
Vector3D MakeUnitVector() const
Definition: geom/Vector3D.h:65
void ComputeAndSaveDetections(const FTransform &SensorTransform) override
This method uses all the saved FHitResults, compute the RawDetections and then send it to the LidarDa...
std::vector< uint32_t > PointsPerChannel
Helper class to store and serialize the data generated by a Lidar.
Definition: LidarData.h:52
carla::streaming::detail::token_type token_type
virtual void Set(const FActorDescription &Description)
Definition: Sensor.cpp:35
virtual void Set(const FActorDescription &Description) override
URandomEngine * RandomEngine
Random Engine used to provide noise for sensor output.