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) {
UE_LOG(LogCarla, Log, TEXT("UActorDispatcher::Destroying actor: '%s' %x"), *Id, Actor)
TSharedPtr< const FActorInfo > carla::rpc::ActorState UWorld * World
#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
FCarlaActor * FindCarlaActor(IdType Id)
IdType GetActorId() const
static void SetLidar(const FActorDescription &Description, FLidarDescription &Lidar)
static FActorDefinition MakeLidarDefinition(const FString &Id)
创建一个激光雷达参与者定义。
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.
uint32_t object_idx
表示检测光线与被击中物体法线之间夹角的余弦值,初始化为0。
uint32_t object_tag
被检测物体的索引
float cos_inc_angle
表示检测到的点的位置信息
静态断言,用于确保token_data结构体的大小与Token::data的大小相同。
const auto & get_stream_id() const
获取流ID的引用。
float HorizontalFov
水平视野(以度为单位),0 - 360。
float LowerFovLimit
最低激光的角度(以度为单位),从水平开始计数,负值表示在水平线以下。
uint32 PointsPerSecond
每秒钟所有激光产生的点。
float RotationFrequency
激光雷达旋转频率
float UpperFovLimit
最高激光的角度(以度为单位),从水平线开始计数,正值表示水平线以上。