CARLA
Loading...
Searching...
No Matches
Sensor.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>
15
16#include <util/ue-header-guard-begin.h>
17#include <Engine/CollisionProfile.h>
18#include <util/ue-header-guard-end.h>
19
20ASensor::ASensor(const FObjectInitializer &ObjectInitializer)
21 : Super(ObjectInitializer)
22{
23 auto *Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("CamMesh"));
24 Mesh->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName);
25 Mesh->bHiddenInGame = true;
26 Mesh->CastShadow = false;
27 RootComponent = Mesh;
28}
29
31{
32 UCarlaEpisode* CurrentEpisode = UCarlaStatics::GetCurrentEpisode(GetWorld());
33 if (CurrentEpisode && !CurrentEpisode->bIsPrimaryServer)
34 {
35 // A mirror ticks every engine frame, and acts only on the frames the
36 // primary's sensor ticked (SetPrimaryTick); before the tick registers.
37 bPrimaryDrivenTick = true;
38 SetActorTickInterval(0.0f);
39 }
40 Super::BeginPlay();
41 FSensorManager& SensorManager = CurrentEpisode->GetSensorManager();
42 SensorManager.RegisterSensor(this);
43}
44
45void ASensor::Set(const FActorDescription &Description)
46{
47 // make a copy
48 SensorDescription = Description;
49
50 // set the tick interval of the sensor
51 if (Description.Variations.Contains("sensor_tick"))
52 {
53 SetActorTickInterval(
55 0.0f));
56 }
57}
58
59std::optional<FActorAttribute> ASensor::GetAttribute(const FString Name)
60{
61 if (SensorDescription.Variations.Contains(Name))
62 {
63 return SensorDescription.Variations[Name];
64 }
65 else
66 return {};
67}
68
69void ASensor::Tick(const float DeltaTime)
70{
71 TRACE_CPUPROFILER_EVENT_SCOPE(ASensor::Tick);
72 float SensorDeltaTime = DeltaTime;
74 {
75 if (PrimaryTickFrame != GFrameCounter)
76 {
77 return;
78 }
79 SensorDeltaTime = PrimaryTickDeltaSeconds;
80 }
81 Super::Tick(SensorDeltaTime);
83 {
85 {
87 bClientsListening = false;
88 }
89 }
90 else
91 {
93 {
95 bClientsListening = true;
96 }
97 }
98
99 ReadyToTick = true;
100 ReadyToTickDeltaSeconds = SensorDeltaTime;
101 PrePhysTick(SensorDeltaTime);
102}
103
104void ASensor::SetSeed(const int32 InSeed)
105{
106 check(RandomEngine != nullptr);
107 Seed = InSeed;
108 RandomEngine->Seed(InSeed);
109}
110
112{
113 Super::PostActorCreated();
114
115#if WITH_EDITOR
116 auto *StaticMeshComponent = Cast<UStaticMeshComponent>(RootComponent);
117 if (StaticMeshComponent && !IsRunningCommandlet() && !StaticMeshComponent->GetStaticMesh())
118 {
119 UStaticMesh *CamMesh = LoadObject<UStaticMesh>(
120 NULL,
121 TEXT("/Engine/EditorMeshes/MatineeCam_SM.MatineeCam_SM"),
122 NULL,
123 LOAD_None,
124 NULL);
125 StaticMeshComponent->SetStaticMesh(CamMesh);
126 }
127#endif // WITH_EDITOR
128}
129
130void ASensor::EndPlay(EEndPlayReason::Type EndPlayReason)
131{
132 Super::EndPlay(EndPlayReason);
133
134 // close all sessions associated to the sensor stream
135 auto *GameInstance = UCarlaStatics::GetGameInstance(GetEpisode().GetWorld());
136 auto &StreamingServer = GameInstance->GetServer().GetStreamingServer();
138 StreamingServer.CloseStream(StreamId);
139
140 UCarlaEpisode* CurrentEpisode = UCarlaStatics::GetCurrentEpisode(GetWorld());
141 if(CurrentEpisode)
142 {
143 FSensorManager& SensorManager = CurrentEpisode->GetSensorManager();
144 SensorManager.DeRegisterSensor(this);
145 }
146}
147
148void ASensor::PostPhysTickInternal(UWorld *World, ELevelTick TickType, [[maybe_unused]] float DeltaSeconds)
149{
150 TRACE_CPUPROFILER_EVENT_SCOPE(ASensor::PostPhysTickInternal);
151 if(ReadyToTick)
152 {
153 // DeltaSeconds is only the current physics substep's delta; this sensor's
154 // own tick interval may span several substeps, so the correct elapsed
155 // time is ReadyToTickDeltaSeconds (captured in Tick(), see Sensor.h).
156 PostPhysTick(World, TickType, ReadyToTickDeltaSeconds);
157 ReadyToTick = false;
158 }
159}
void EndPlay(EEndPlayReason::Type EndPlayReason) override
Definition Sensor.cpp:130
void Tick(const float DeltaTime) final
Definition Sensor.cpp:69
bool ReadyToTick
Allows the sensor to tick using the configured UE5 tick interval.
bool bPrimaryDrivenTick
Multi-GPU secondary: ticks are driven by the primary's frames.
float ReadyToTickDeltaSeconds
Elapsed time computed by UE5's tick scheduler for the most recent Tick().
int32 Seed
Seed of the pseudo-random engine.
virtual void Set(const FActorDescription &Description)
Definition Sensor.cpp:45
std::optional< FActorAttribute > GetAttribute(const FString Name)
Definition Sensor.cpp:59
void PostActorCreated() override
Definition Sensor.cpp:111
URandomEngine * RandomEngine
Random Engine used to provide noise for sensor output.
void PostPhysTickInternal(UWorld *World, ELevelTick TickType, float DeltaSeconds)
Definition Sensor.cpp:148
virtual void PostPhysTick(UWorld *World, ELevelTick TickType, float DeltaSeconds)
virtual void BeginPlay()
Definition Sensor.cpp:30
ASensor(const FObjectInitializer &ObjectInitializer)
Definition Sensor.cpp:20
void SetSeed(int32 InSeed)
Definition Sensor.cpp:104
auto GetToken() const
Return the token that allows subscribing to this stream.
Definition DataStream.h:53
bool AreClientsListening()
Definition DataStream.h:65
void DeRegisterSensor(ASensor *Sensor)
void RegisterSensor(ASensor *Sensor)
static float ActorAttributeToFloat(const FActorAttribute &ActorAttribute, float Default)
A simulation episode.
FSensorManager & GetSensorManager()
static UCarlaGameInstance * GetGameInstance(const UObject *WorldContextObject)
static UCarlaEpisode * GetCurrentEpisode(const UObject *WorldContextObject)
void Seed(int32 InSeed)
Seed the random engine.
Serializes a stream endpoint.
A description of a Carla Actor with all its variation.
TMap< FString, FActorAttribute > Variations
User selected variations of the actor.