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) {
auto GetToken() const
Return the token that allows subscribing to this sensor's stream.
static FActorDefinition MakeLidarDefinition(const FString &Id)
std::vector< std::vector< FHitResult > > RecordedHits
A registry of all the Carla actors.
virtual void PreprocessRays(uint32_t Channels, uint32_t MaxPointsPerChannel)
Method that allow to preprocess if the rays will be traced.
carla::sensor::data::SemanticLidarData FSemanticLidarData
void WritePointAsync(uint32_t Channel, FHitResult &Detection)
Saving the hits the raycast returns per channel.
virtual void WriteChannelCount(std::vector< uint32_t > points_per_channel)
float Range
Measure distance in centimeters.
Helper class to store and serialize the data generated by a RawLidar.
const UCarlaEpisode & GetEpisode() const
void CreateLasers()
Creates a Laser for each channel.
FSemanticLidarData SemanticLidarData
float LowerFovLimit
Lower laser angle, counts from horizontal, negative values means under horizontal line...
void ComputeRawDetection(const FHitResult &HitInfo, const FTransform &SensorTransf, FSemanticDetection &Detection) const
Compute all raw detection information.
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
virtual void ComputeAndSaveDetections(const FTransform &SensorTransform)
This method uses all the saved FHitResults, compute the RawDetections and then send it to the LidarDa...
#define DEBUG_ASSERT(predicate)
const FActorRegistry & GetActorRegistry() const
ARayCastSemanticLidar(const FObjectInitializer &ObjectInitializer)
void ResetRecordedHits(uint32_t Channels, uint32_t MaxPointsPerChannel)
Clear the recorded data structure.
virtual void ResetMemory(std::vector< uint32_t > points_per_channel)
float RotationFrequency
Lidar rotation frequency.
static void SetLidar(const FActorDescription &Description, FLidarDescription &Lidar)
A description of a Carla Actor with all its variation.
std::vector< std::vector< bool > > RayPreprocessCondition
virtual void PostPhysTick(UWorld *World, ELevelTick TickType, float DeltaTime) override
virtual void WritePointSync(SemanticLidarDetection &detection)
uint32 Channels
Number of lasers.
float UpperFovLimit
Upper laser angle, counts from horizontal, positive values means above horizontal line...
const auto & get_stream_id() const
static constexpr T ToRadians(T deg)
bool ShootLaser(const float VerticalAngle, float HorizontalAngle, FHitResult &HitResult, FCollisionQueryParams &TraceParams) const
Shoot a laser ray-trace, return whether the laser hit something.
float HorizontalFov
Horizontal field of view.
FAsyncDataStream GetDataStream(const SensorT &Self)
Return the FDataStream associated with this sensor.
TArray< float > LaserAngles
void SetHorizontalAngle(float angle)
static std::shared_ptr< ROS2 > GetInstance()
static constexpr T ToDegrees(T rad)
IdType GetActorId() const
FCarlaActor * FindCarlaActor(IdType Id)
virtual void Set(const FActorDescription &Description) override
uint32 PointsPerSecond
Points generated by all lasers per second.
std::vector< uint32_t > PointsPerChannel
float GetHorizontalAngle() const
carla::streaming::detail::token_type token_type
static FActorDefinition GetSensorDefinition()
A view over an actor and its properties.