CARLA
Loading...
Searching...
No Matches
ActorRegistry.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"
10#include "Carla/Game/Tagger.h"
13#include "Carla/Sensor/Sensor.h"
14
19
20
21namespace crp = carla::rpc;
22
24
26{
27 if (!Actor)
28 {
30 }
31
32 if (nullptr != Cast<ACarlaWheeledVehicle>(Actor))
33 {
35 }
36 else if (nullptr != Cast<ACharacter>(Actor))
37 {
39 }
40 else if (nullptr != Cast<ATrafficLightBase>(Actor))
41 {
43 }
44 else if (nullptr != Cast<ATrafficSignBase>(Actor))
45 {
47 }
48 else if (nullptr != Cast<ASensor>(Actor))
49 {
51 }
52 else
53 {
55 }
56}
57
58FString CarlaGetRelevantTagAsString(const TSet<crp::CityObjectLabel> &SemanticTags)
59{
60 for (auto &&Tag : SemanticTags)
61 {
62 if ((Tag != crp::CityObjectLabel::None) && (Tag != crp::CityObjectLabel::Other))
63 {
64 auto Str = ATagger::GetTagAsString(Tag).ToLower();
65 return (Str.EndsWith(TEXT("s")) ? Str.LeftChop(1) : Str);
66 }
67 }
68 return TEXT("unknown");
69}
70
72{
73
74 FCarlaActor* CarlaActor = FindCarlaActor(DesiredId);
75 bool IsDormant = CarlaActor && (CarlaActor->IsDormant());
76 if(IsDormant)
77 {
78 CarlaActor->TheActor = &Actor;
79 Actors.Add(DesiredId, &Actor);
80 Ids.Add(&Actor, DesiredId);
81 return CarlaActor;
82 }
83
85
86 if (DesiredId != 0 && Id != DesiredId) {
87 // check if the desired Id is free, then use it instead
88 if (!Actors.Contains(DesiredId))
89 {
90 Id = DesiredId;
91 if (ID_COUNTER < Id)
92 ID_COUNTER = Id;
93 }
94 }
95
96 Actors.Emplace(Id, &Actor);
97 if (Ids.Contains(&Actor))
98 {
99 UE_LOG(
100 LogCarla,
101 Warning,
102 TEXT("This actor's memory address is already registered, "
103 "either you forgot to deregister the actor "
104 "or the actor was garbage collected."));
105 // Purge the stale entry: leaving it makes the old id alias the new
106 // actor through Actors/ActorDatabase, so operations on either id hit
107 // the same AActor with two conflicting FCarlaActor states.
108 const IdType StaleId = Ids[&Actor];
109 if (StaleId != Id)
110 {
111 if (FCarlaActor* StaleActor = FindCarlaActor(StaleId))
112 {
113 StaleActor->TheActor = nullptr;
114 }
115 ActorDatabase.Remove(StaleId);
116 Actors.Remove(StaleId);
117 }
118 }
119 Ids.Emplace(&Actor, Id);
120
121// Add the actor description to the Unreal actor as TAGs
122
123 for (const auto& Elem : Description.Variations)
124 {
125 const FString& Key = Elem.Key;
126 const FActorAttribute& Attribute = Elem.Value;
127
128 // Optional: You can use only the value, or a key-value combination as the tag
129 FString TagString = Key + TEXT(":") + Attribute.Value; // or just Attribute.Value
130 // FName asserts above NAME_SIZE (1024) characters; a lens lookup table
131 // ("lut" on the fisheye / rt_lens cameras) can be several thousand.
132 // The tag is informational, so keep a truncated prefix instead.
133 constexpr int32 MaxTagLength = 1000;
134 if (TagString.Len() > MaxTagLength)
135 TagString = TagString.Left(MaxTagLength) + TEXT("...");
136 Actor.Tags.Add(FName(*TagString));
137 }
138
139 TSharedPtr<FCarlaActor> View =
140 MakeCarlaActor(Id, Actor, std::move(Description), crp::ActorState::Active);
141
142 TSharedPtr<FCarlaActor>& Result = ActorDatabase.Emplace(Id, MoveTemp(View));
143
144 check(static_cast<size_t>(Actors.Num()) == ActorDatabase.Num());
145 return Result.Get();
146}
147
149{
150 FCarlaActor* CarlaActor = FindCarlaActor(Id);
151
152 if(!CarlaActor) return;
153
154 AActor *Actor = CarlaActor->GetActor();
155
156 ActorDatabase.Remove(Id);
157 Actors.Remove(Id);
158 Ids.Remove(Actor);
159
160 CarlaActor->TheActor = nullptr;
161
162 check(static_cast<size_t>(Actors.Num()) == ActorDatabase.Num());
163}
164
166{
167 check(Actor != nullptr);
168 FCarlaActor* CarlaActor = FindCarlaActor(Actor);
169 check(CarlaActor->GetActor() == Actor);
170 Deregister(CarlaActor->GetActorId());
171}
172
173TSharedPtr<FCarlaActor> FActorRegistry::MakeCarlaActor(
174 IdType Id,
175 AActor &Actor,
176 FActorDescription Description,
177 crp::ActorState InState) const
178{
179 auto Info = MakeShared<FActorInfo>();
180 Info->Description = std::move(Description);
181 ATagger::GetTagsOfTaggedActor(Actor, Info->SemanticTags);
182 Info->BoundingBox = UBoundingBoxCalculator::GetActorBoundingBox(&Actor);
183
184 if (Info->Description.Id.IsEmpty())
185 {
186 // This is a fake actor, let's fake the id based on their semantic tags.
187 Info->Description.Id = TEXT("static.") + CarlaGetRelevantTagAsString(Info->SemanticTags);
188 }
189
190 Info->SerializedData.id = Id;
191 Info->SerializedData.description = Info->Description;
192 Info->SerializedData.bounding_box = Info->BoundingBox;
193 Info->SerializedData.semantic_tags.reserve(Info->SemanticTags.Num());
194 for (auto &&Tag : Info->SemanticTags)
195 {
196 using tag_t = decltype(Info->SerializedData.semantic_tags)::value_type;
197 Info->SerializedData.semantic_tags.emplace_back(static_cast<tag_t>(Tag));
198 }
199 auto *Sensor = Cast<ASensor>(&Actor);
200 if (Sensor != nullptr)
201 {
202 const auto &Token = Sensor->GetToken();
203 Info->SerializedData.stream_token = decltype(Info->SerializedData.stream_token)(
204 std::begin(Token.data),
205 std::end(Token.data));
206 }
207 auto Type = FActorRegistry_GetActorType(&Actor);
208 TSharedPtr<FCarlaActor> CarlaActor =
210 Id, &Actor,
211 std::move(Info), Type,
212 InState, Actor.GetWorld());
213 return CarlaActor;
214}
215
217{
218 FCarlaActor* CarlaActor = FindCarlaActor(Id);
219
220 // update id maps
221 Actors[Id] = nullptr;
222 AActor* Actor = CarlaActor->GetActor();
223 if(Actor)
224 {
225 Ids.Remove(Actor);
226 }
227
228 CarlaActor->PutActorToSleep(CarlaEpisode);
229 for (const FCarlaActor::IdType& ChildId : CarlaActor->GetChildren())
230 {
231 PutActorToSleep(ChildId, CarlaEpisode);
232 }
233 // TODO: update id maps
234}
235
237{
238
239 FCarlaActor* CarlaActor = FindCarlaActor(Id);
240 CarlaActor->WakeActorUp(CarlaEpisode);
241 AActor* Actor = CarlaActor->GetActor();
242 if (Actor)
243 {
244 // update ids
245 Actors[Id] = Actor;
246 Ids.Add(Actor, Id);
247 if (CarlaActor->GetParent())
248 {
249 FCarlaActor* ParentView = FindCarlaActor(CarlaActor->GetParent());
250 if (ParentView && !ParentView->IsDormant() && ParentView->GetActor())
251 {
252 AActor* ParentActor = ParentView->GetActor();
253 CarlaEpisode->AttachActors(
254 Actor,
255 ParentActor,
256 static_cast<EAttachmentType>(CarlaActor->GetAttachmentType()));
257 }
258 else
259 {
260 UE_LOG(LogCarla, Error, TEXT("Failed to attach actor %d to %d during wake up"), Id, CarlaActor->GetParent());
261 }
262 }
263 }
264 for (const FCarlaActor::IdType& ChildId : CarlaActor->GetChildren())
265 {
266 WakeActorUp(ChildId, CarlaEpisode);
267 }
268}
269
271{
272 for (auto &Item : ActorDatabase)
273 {
274 const ASensor *Sensor = Cast<ASensor>(Item.Value->GetActor());
275 if (Sensor == nullptr)
276 {
277 continue;
278 }
279
280 const carla::streaming::detail::token_type Token(Sensor->GetToken());
281 if (Token.get_stream_id() == Id)
282 {
283 return Item.Value.Get();
284 }
285 }
286 return nullptr;
287}
288
290{
291 const FCarlaActor *CarlaActor = FindCarlaActorFromStream(Id);
292 if (CarlaActor == nullptr)
293 {
294 return FString("");
295 }
296 return CarlaActor->GetActorInfo()->Description.Id;
297}
EAttachmentType
FString CarlaGetRelevantTagAsString(const TSet< crp::CityObjectLabel > &SemanticTags)
static FCarlaActor::ActorType FActorRegistry_GetActorType(const AActor *Actor)
auto GetToken() const
Return the token that allows subscribing to this sensor's stream.
static void GetTagsOfTaggedActor(const AActor &Actor, TSet< crp::CityObjectLabel > &Tags)
Retrieve the tags of an already tagged actor.
Definition Tagger.cpp:221
static FString GetTagAsString(crp::CityObjectLabel Tag)
Transform a CityObjectLabel into a string.
Definition Tagger.cpp:269
FString GetDescriptionFromStream(carla::streaming::detail::stream_id_type Id)
TMap< AActor *, IdType > Ids
TSharedPtr< FCarlaActor > MakeCarlaActor(IdType Id, AActor &Actor, FActorDescription Description, carla::rpc::ActorState InState) const
static IdType ID_COUNTER
FCarlaActor * FindCarlaActorFromStream(carla::streaming::detail::stream_id_type Id)
Returns the sensor whose data stream has id Id, or nullptr.
FCarlaActor::IdType IdType
FCarlaActor * Register(AActor &Actor, FActorDescription Description, IdType DesiredId=0)
Register the Actor in the database.
TMap< IdType, AActor * > Actors
DatabaseType ActorDatabase
void Deregister(IdType Id)
FCarlaActor * FindCarlaActor(IdType Id)
void PutActorToSleep(IdType Id, UCarlaEpisode *CarlaEpisode)
void WakeActorUp(IdType Id, UCarlaEpisode *CarlaEpisode)
A view over an actor and its properties.
Definition CarlaActor.h:25
carla::rpc::AttachmentType GetAttachmentType() const
Definition CarlaActor.h:194
static TSharedPtr< FCarlaActor > ConstructCarlaActor(IdType ActorId, AActor *Actor, TSharedPtr< const FActorInfo > Info, ActorType Type, carla::rpc::ActorState InState, UWorld *World)
IdType GetParent() const
Definition CarlaActor.h:121
bool IsDormant() const
Definition CarlaActor.h:71
AActor * GetActor()
Definition CarlaActor.h:91
uint32 IdType
Definition CarlaActor.h:28
TWeakObjectPtr< AActor > TheActor
Weak: World Partition can stream out (destroy) the actor without going through the episode,...
Definition CarlaActor.h:567
const FActorInfo * GetActorInfo() const
Definition CarlaActor.h:101
IdType GetActorId() const
Definition CarlaActor.h:81
void WakeActorUp(UCarlaEpisode *CarlaEpisode)
const TArray< IdType > & GetChildren() const
Definition CarlaActor.h:137
void PutActorToSleep(UCarlaEpisode *CarlaEpisode)
static FBoundingBox GetActorBoundingBox(const AActor *Actor, uint8 InTagQueried=0xFF)
Compute the bounding box of the given Carla actor.
A simulation episode.
void AttachActors(AActor *Child, AActor *Parent, EAttachmentType InAttachmentType=EAttachmentType::Rigid)
Attach Child to Parent.
Serializes a stream endpoint.
An actor attribute, may be an intrinsic (non-modifiable) attribute of the actor or an user-defined ac...
A description of a Carla Actor with all its variation.
TMap< FString, FActorAttribute > Variations
User selected variations of the actor.
FActorDescription Description
Definition ActorInfo.h:21