CARLA
Loading...
Searching...
No Matches
Radar.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"
12
14#include <carla/geom/Math.h>
15#include <carla/ros2/ROS2.h>
17
18#include <util/ue-header-guard-begin.h>
19#include "Kismet/KismetMathLibrary.h"
20#include "Async/ParallelFor.h"
21#include "PhysicsEngine/PhysicsObjectExternalInterface.h"
22#include <util/ue-header-guard-end.h>
23
28
29ARadar::ARadar(const FObjectInitializer& ObjectInitializer)
30 : Super(ObjectInitializer)
31{
32 PrimaryActorTick.bCanEverTick = true;
33
34 RandomEngine = CreateDefaultSubobject<URandomEngine>(TEXT("RandomEngine"));
35
36 TraceParams = FCollisionQueryParams(FName(TEXT("Laser_Trace")), true, this);
37 TraceParams.bTraceComplex = true;
38 TraceParams.bReturnPhysicalMaterial = false;
39
40}
41
42void ARadar::Set(const FActorDescription &ActorDescription)
43{
44 Super::Set(ActorDescription);
45 UActorBlueprintFunctionLibrary::SetRadar(ActorDescription, this);
46}
47
48void ARadar::SetHorizontalFOV(float NewHorizontalFOV)
49{
50 HorizontalFOV = NewHorizontalFOV;
51}
52
53void ARadar::SetVerticalFOV(float NewVerticalFOV)
54{
55 VerticalFOV = NewVerticalFOV;
56}
57
58void ARadar::SetRange(float NewRange)
59{
60 Range = NewRange;
61}
62
63void ARadar::SetPointsPerSecond(int NewPointsPerSecond)
64{
65 PointsPerSecond = NewPointsPerSecond;
67}
68
72
74{
75 Super::BeginPlay();
76
77 PrevLocation = GetActorLocation();
78}
79
80void ARadar::PostPhysTick(UWorld *World, ELevelTick TickType, float DeltaTime)
81{
82 TRACE_CPUPROFILER_EVENT_SCOPE(ARadar::PostPhysTick);
83 CalculateCurrentVelocity(DeltaTime);
84
86 SendLineTraces(DeltaTime);
87
88 auto DataStream = GetDataStream(*this);
89
90 // ROS2
91 #if defined(WITH_ROS2)
93 if (ROS2->IsEnabled())
94 {
95 TRACE_CPUPROFILER_EVENT_SCOPE_STR("ARadar::PostPhysTick ROS2 Send");
97 AActor* ParentActor = GetAttachParentActor();
98 if (ParentActor)
99 {
100 FTransform LocalTransformRelativeToParent = GetActorTransform().GetRelativeTransform(ParentActor->GetActorTransform());
101 ROS2->ProcessDataFromRadar(DataStream.GetSensorType(), StreamId, LocalTransformRelativeToParent, RadarData, this);
102 }
103 else
104 {
105 ROS2->ProcessDataFromRadar(DataStream.GetSensorType(), StreamId, DataStream.GetSensorTransform(), RadarData, this);
106 }
107 }
108 #endif
109
110 {
111 TRACE_CPUPROFILER_EVENT_SCOPE_STR("Send Stream");
112 DataStream.SerializeAndSend(*this, RadarData, DataStream.PopBufferFromPool());
113 }
114}
115
116void ARadar::CalculateCurrentVelocity(const float DeltaTime)
117{
118 const FVector RadarLocation = GetActorLocation();
119 CurrentVelocity = (RadarLocation - PrevLocation) / DeltaTime;
120 PrevLocation = RadarLocation;
121}
122
123void ARadar::SendLineTraces(float DeltaTime)
124{
125 TRACE_CPUPROFILER_EVENT_SCOPE(ARadar::SendLineTraces);
126 constexpr float TO_METERS = 1e-2;
127 const FTransform& ActorTransform = GetActorTransform();
128 const FRotator& TransformRotator = ActorTransform.Rotator();
129 const FVector& RadarLocation = GetActorLocation();
130 const FVector& ForwardVector = GetActorForwardVector();
131 const FVector TransformXAxis = ActorTransform.GetUnitAxis(EAxis::X);
132 const FVector TransformYAxis = ActorTransform.GetUnitAxis(EAxis::Y);
133 const FVector TransformZAxis = ActorTransform.GetUnitAxis(EAxis::Z);
134
135 // Maximum radar radius in horizontal and vertical direction
136 const float MaxRx = FMath::Tan(FMath::DegreesToRadians(HorizontalFOV * 0.5f)) * Range;
137 const float MaxRy = FMath::Tan(FMath::DegreesToRadians(VerticalFOV * 0.5f)) * Range;
138 const int NumPoints = (int)(PointsPerSecond * DeltaTime);
139
140 // Generate the parameters of the rays in a deterministic way
141 Rays.clear();
142 Rays.resize(NumPoints);
143 for (int i = 0; i < Rays.size(); i++) {
144 Rays[i].Radius = RandomEngine->GetUniformFloat();
145 Rays[i].Angle = RandomEngine->GetUniformFloatInRange(0.0f, carla::geom::Math::Pi2<float>());
146 Rays[i].Hitted = false;
147 }
148
149 auto LockedPhysObject = FPhysicsObjectExternalInterface::LockRead(GetWorld()->GetPhysicsScene());
150 {
151 TRACE_CPUPROFILER_EVENT_SCOPE(ParallelFor);
152 ParallelFor(NumPoints, [&](int32 idx) {
153 TRACE_CPUPROFILER_EVENT_SCOPE(ParallelForTask);
154 FHitResult OutHit(ForceInit);
155 const float Radius = Rays[idx].Radius;
156 const float Angle = Rays[idx].Angle;
157
158 float Sin, Cos;
159 FMath::SinCos(&Sin, &Cos, Angle);
160
161 const FVector EndLocation = RadarLocation + TransformRotator.RotateVector({
162 Range,
163 MaxRx * Radius * Cos,
164 MaxRy * Radius * Sin
165 });
166
167 const bool Hitted = GetWorld()->ParallelLineTraceSingleByChannel(
168 OutHit,
169 RadarLocation,
170 EndLocation,
171 ECC_GameTraceChannel2,
173 FCollisionResponseParams::DefaultResponseParam
174 );
175
176 const TWeakObjectPtr<AActor> HittedActor = OutHit.GetActor();
177 if (Hitted && HittedActor.Get()) {
178 Rays[idx].Hitted = true;
179
180 Rays[idx].RelativeVelocity = CalculateRelativeVelocity(OutHit, RadarLocation);
181
182 Rays[idx].AzimuthAndElevation = FMath::GetAzimuthAndElevation (
183 (EndLocation - RadarLocation).GetSafeNormal() * Range,
184 TransformXAxis,
185 TransformYAxis,
186 TransformZAxis
187 );
188
189 Rays[idx].Distance = OutHit.Distance * TO_METERS;
190 }
191 });
192 }
193 LockedPhysObject.Release();
194
195 // Write the detections in the output structure
196 for (auto& ray : Rays)
197 {
198 if (ray.Hitted)
199 {
201 {
202 ray.RelativeVelocity,
203 UKismetMathLibrary::Conv_DoubleToFloat(ray.AzimuthAndElevation.X),
204 UKismetMathLibrary::Conv_DoubleToFloat(ray.AzimuthAndElevation.Y),
205 ray.Distance
206 });
207 }
208 }
209}
210
211float ARadar::CalculateRelativeVelocity(const FHitResult& OutHit, const FVector& RadarLocation)
212{
213 constexpr float TO_METERS = 1e-2;
214
215 const TWeakObjectPtr<AActor> HittedActor = OutHit.GetActor();
216 const FVector TargetVelocity = HittedActor->GetVelocity();
217 const FVector TargetLocation = OutHit.ImpactPoint;
218 const FVector Direction = (TargetLocation - RadarLocation).GetSafeNormal();
219 const FVector DeltaVelocity = (TargetVelocity - CurrentVelocity);
220 const float V = TO_METERS * FVector::DotProduct(DeltaVelocity, Direction);
221
222 return V;
223}
224
226{
227 if (RandomEngine != nullptr)
228 {
229 State.random_engine = RandomEngine->GetState();
230 }
231 // In the world frame: a large map rebases each server's local origin on its own.
232 const ALargeMapManager *LargeMap = UCarlaStatics::GetLargeMapManager(GetWorld());
233 const FVector World = (LargeMap != nullptr) ? LargeMap->LocalToGlobalLocation(PrevLocation) : PrevLocation;
234 State.radar_previous_location = std::array<double, 3>{World.X, World.Y, World.Z};
235}
236
238{
239 if (State.random_engine && (RandomEngine != nullptr))
240 {
241 RandomEngine->SetState(*State.random_engine);
242 }
243 if (State.radar_previous_location)
244 {
245 const auto &World = *State.radar_previous_location;
246 const FVector Location(World[0], World[1], World[2]);
247 const ALargeMapManager *LargeMap = UCarlaStatics::GetLargeMapManager(GetWorld());
248 PrevLocation = (LargeMap != nullptr) ? LargeMap->GlobalToLocalLocation(Location) : Location;
249 }
250}
FVector GlobalToLocalLocation(const FVector &InLocation) const
FVector LocalToGlobalLocation(const FVector &InLocation) const
static FActorDefinition GetSensorDefinition()
Definition Radar.cpp:24
float Range
Definition Radar.h:59
float VerticalFOV
Definition Radar.h:65
void BeginPlay() override
Definition Radar.cpp:73
void GetMirrorState(carla::multigpu::SensorState &State) const override
Multi-GPU: the runtime state this sensor starts its next tick from (noise generator,...
Definition Radar.cpp:225
FVector CurrentVelocity
Definition Radar.h:82
float CalculateRelativeVelocity(const FHitResult &OutHit, const FVector &RadarLocation)
Definition Radar.cpp:211
int PointsPerSecond
Definition Radar.h:68
std::vector< RayData > Rays
Definition Radar.h:96
void SetPointsPerSecond(int NewPointsPerSecond)
Definition Radar.cpp:63
void SetHorizontalFOV(float NewHorizontalFOV)
Definition Radar.cpp:48
FVector PrevLocation
Used to compute the velocity of the radar.
Definition Radar.h:85
void SendLineTraces(float DeltaTime)
Definition Radar.cpp:123
FCollisionQueryParams TraceParams
Definition Radar.h:80
virtual void PostPhysTick(UWorld *World, ELevelTick TickType, float DeltaTime) override
Definition Radar.cpp:80
const FRadarData & GetRadarData() const
Definition Radar.cpp:69
ARadar(const FObjectInitializer &ObjectInitializer)
Definition Radar.cpp:29
void SetVerticalFOV(float NewVerticalFOV)
Definition Radar.cpp:53
void CalculateCurrentVelocity(const float DeltaTime)
Definition Radar.cpp:116
void SetRange(float NewRange)
Definition Radar.cpp:58
void Set(const FActorDescription &Description) override
Definition Radar.cpp:42
float HorizontalFOV
Definition Radar.h:62
FRadarData RadarData
Definition Radar.h:78
void SetMirrorState(const carla::multigpu::SensorState &State) override
Definition Radar.cpp:237
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.
static void SetRadar(const FActorDescription &Description, ARadar *Radar)
static ALargeMapManager * GetLargeMapManager(const UObject *WorldContextObject)
uint32 GetState() const
The engine's state, to continue its exact sequence elsewhere (a Multi-GPU secondary's mirror of a sen...
float GetUniformFloat()
float GetUniformFloatInRange(float Minimum, float Maximum)
void SetState(uint32 State)
Continue from State, as GetState returned it; an impossible value is ignored.
static std::shared_ptr< ROS2 > GetInstance()
Definition ROS2.h:61
void Reset()
Deletes the current detections.
Definition RadarData.h:64
void SetResolution(uint32_t resolution)
Set a new resolution for the RadarData.
Definition RadarData.h:49
void WriteDetection(RadarDetection detection)
Adds a new detection.
Definition RadarData.h:69
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.
One record of frame data packet 27: the runtime state a sensor of the primary starts this frame's tic...
Definition sensorSync.h:87