18#include "DrawDebugHelpers.h"
19#include "Engine/CollisionProfile.h"
20#include "Runtime/Engine/Classes/Kismet/KismetMathLibrary.h"
21#include "Runtime/Core/Public/Async/ParallelFor.h"
31 : Super(ObjectInitializer)
33 PrimaryActorTick.bCanEverTick =
true;
38 Super::Set(ActorDescription);
41 Set(LidarDescription);
55 check(NumberOfLasers > 0u);
56 const float DeltaAngle = NumberOfLasers == 1u ? 0.f :
58 static_cast<float>(NumberOfLasers - 1);
60 for(
auto i = 0u; i < NumberOfLasers; ++i)
62 const float VerticalAngle =
74 auto SensorTransform = DataStream.GetSensorTransform();
76 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"Send Stream");
77 DataStream.SerializeAndSend(*
this,
SemanticLidarData, DataStream.PopBufferFromPool());
80 #if defined(WITH_ROS2)
82 if (ROS2->IsEnabled())
84 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"ROS2 Send");
86 AActor* ParentActor = GetAttachParentActor();
89 FTransform LocalTransformRelativeToParent = GetActorTransform().GetRelativeTransform(ParentActor->GetActorTransform());
90 ROS2->ProcessDataFromSemanticLidar(DataStream.GetSensorType(), StreamId, LocalTransformRelativeToParent,
SemanticLidarData,
this);
94 ROS2->ProcessDataFromSemanticLidar(DataStream.GetSensorType(), StreamId, SensorTransform,
SemanticLidarData,
this);
104 const uint32 PointsToScanWithOneLaser =
105 FMath::RoundHalfFromZero(
108 if (PointsToScanWithOneLaser <= 0)
113 TEXT(
"%s: no points requested this frame, try increasing the number of points per second."),
124 const float AngleDistanceOfLaserMeasure = AngleDistanceOfTick / PointsToScanWithOneLaser;
129 GetWorld()->GetPhysicsScene()->GetPxScene()->lockRead();
131 TRACE_CPUPROFILER_EVENT_SCOPE(ParallelFor);
132 ParallelFor(ChannelCount, [&](int32 idxChannel) {
133 TRACE_CPUPROFILER_EVENT_SCOPE(ParallelForTask);
135 FCollisionQueryParams TraceParams = FCollisionQueryParams(FName(TEXT(
"Laser_Trace")),
true,
this);
136 TraceParams.bTraceComplex =
true;
137 TraceParams.bReturnPhysicalMaterial =
false;
139 for (
auto idxPtsOneLaser = 0u; idxPtsOneLaser < PointsToScanWithOneLaser; idxPtsOneLaser++) {
140 FHitResult HitResult;
142 const float HorizAngle = std::fmod(CurrentHorizontalAngle + AngleDistanceOfLaserMeasure
146 if (PreprocessResult &&
ShootLaser(VertAngle, HorizAngle, HitResult, TraceParams)) {
152 GetWorld()->GetPhysicsScene()->GetPxScene()->unlockRead();
154 FTransform ActorTransf = GetTransform();
167 hits.reserve(MaxPointsPerChannel);
176 conds.resize(MaxPointsPerChannel);
177 std::fill(conds.begin(), conds.end(),
true);
182 TRACE_CPUPROFILER_EVENT_SCOPE_STR(__FUNCTION__);
188 TRACE_CPUPROFILER_EVENT_SCOPE_STR(__FUNCTION__);
206 const FVector HitPoint = HitInfo.ImpactPoint;
207 Detection.
point = SensorTransf.Inverse().TransformPosition(HitPoint);
209 const FVector VecInc = - (HitPoint - SensorTransf.GetLocation()).GetSafeNormal();
210 Detection.
cos_inc_angle = FVector::DotProduct(VecInc, HitInfo.ImpactNormal);
214 const AActor* actor = HitInfo.Actor.Get();
216 Detection.
object_tag =
static_cast<uint32_t
>(HitInfo.Component->CustomDepthStencilValue);
218 if (actor !=
nullptr) {
226 UE_LOG(LogCarla, Warning, TEXT(
"Actor not valid %p!!!!"), actor);
233 TRACE_CPUPROFILER_EVENT_SCOPE_STR(__FUNCTION__);
235 FHitResult HitInfo(ForceInit);
237 FTransform ActorTransf = GetTransform();
238 FVector LidarBodyLoc = ActorTransf.GetLocation();
239 FRotator LidarBodyRot = ActorTransf.Rotator();
241 FRotator LaserRot (VerticalAngle, HorizontalAngle, 0);
242 FRotator ResultRot = UKismetMathLibrary::ComposeRotators(
248 FVector EndTrace = Range * UKismetMathLibrary::GetForwardVector(ResultRot) + LidarBodyLoc;
250 GetWorld()->ParallelLineTraceSingleByChannel(
254 ECC_GameTraceChannel2,
256 FCollisionResponseParams::DefaultResponseParam
259 if (HitInfo.bBlockingHit) {
#define DEBUG_ASSERT(predicate)
carla::sensor::data::SemanticLidarData FSemanticLidarData
static FActorDefinition GetSensorDefinition()
std::vector< uint32_t > PointsPerChannel
virtual void ComputeAndSaveDetections(const FTransform &SensorTransform)
This method uses all the saved FHitResults, compute the RawDetections and then send it to the LidarDa...
void SimulateLidar(const float DeltaTime)
Updates LidarMeasurement with the points read in DeltaTime.
virtual void PreprocessRays(uint32_t Channels, uint32_t MaxPointsPerChannel)
Method that allow to preprocess if the rays will be traced.
void CreateLasers()
Creates a Laser for each channel.
TArray< float > LaserAngles
void WritePointAsync(uint32_t Channel, FHitResult &Detection)
Saving the hits the raycast returns per channel
virtual void PostPhysTick(UWorld *World, ELevelTick TickType, float DeltaTime) override
void ComputeRawDetection(const FHitResult &HitInfo, const FTransform &SensorTransf, FSemanticDetection &Detection) const
Compute all raw detection information
virtual void Set(const FActorDescription &Description) override
ARayCastSemanticLidar(const FObjectInitializer &ObjectInitializer)
std::vector< std::vector< bool > > RayPreprocessCondition
void ResetRecordedHits(uint32_t Channels, uint32_t MaxPointsPerChannel)
Clear the recorded data structure
std::vector< std::vector< FHitResult > > RecordedHits
bool ShootLaser(const float VerticalAngle, float HorizontalAngle, FHitResult &HitResult, FCollisionQueryParams &TraceParams) const
Shoot a laser ray-trace, return whether the laser hit something.
FLidarDescription Description
FSemanticLidarData SemanticLidarData
auto GetToken() const
Return the token that allows subscribing to this sensor's stream.
FAsyncDataStream GetDataStream(const SensorT &Self)
Return the FDataStream associated with this sensor.
const UCarlaEpisode & GetEpisode() const
A registry of all the Carla actors.
FCarlaActor * FindCarlaActor(IdType Id)
A view over an actor and its properties.
IdType GetActorId() const
static void SetLidar(const FActorDescription &Description, FLidarDescription &Lidar)
static FActorDefinition MakeLidarDefinition(const FString &Id)
const FActorRegistry & GetActorRegistry() const
static constexpr T ToRadians(T deg)
static constexpr T ToDegrees(T rad)
static std::shared_ptr< ROS2 > GetInstance()
virtual void WriteChannelCount(std::vector< uint32_t > points_per_channel)
float GetHorizontalAngle() const
virtual void ResetMemory(std::vector< uint32_t > points_per_channel)
void SetHorizontalAngle(float angle)
virtual void WritePointSync(SemanticLidarDetection &detection)
Helper class to store and serialize the data generated by a RawLidar.
Serializes a stream endpoint.
const auto & get_stream_id() const
A definition of a Carla Actor with all the variation and attributes.
A description of a Carla Actor with all its variation.
float HorizontalFov
Horizontal field of view
float LowerFovLimit
Lower laser angle, counts from horizontal, negative values means under horizontal line.
float Range
Measure distance in centimeters.
uint32 Channels
Number of lasers.
uint32 PointsPerSecond
Points generated by all lasers per second.
float RotationFrequency
Lidar rotation frequency.
float UpperFovLimit
Upper laser angle, counts from horizontal, positive values means above horizontal line.