CARLA
 
载入中...
搜索中...
未找到
ActorRegistry.cpp
浏览该文件的文档.
1// 版权所有 (c) 2017 巴塞罗那自治大学 (UAB) 计算机视觉中心 (CVC)。
2//
3// 本作品根据 MIT 许可证的条款进行许可。
4// 有关副本,请参阅 <https://opensource.org/licenses/MIT>。
5
6// 包含Carla相关的主头文件,可能定义了Carla项目中一些基础的类型、宏以及常用的功能等,是整个Carla相关代码的核心头文件
7#include "Carla.h"
8// 包含Actor数据相关的头文件,可能定义了和Actor在Carla中存储、传递等相关的数据结构等内容
10// 包含Actor注册相关的头文件,大概率用于管理Actor在系统中的注册、查找等操作相关的类和函数声明等
12
13// 包含Carla游戏中标签相关功能的头文件,可能用于处理游戏中各种对象的标签设定、获取等操作
14#include "Carla/Game/Tagger.h"
15// 包含交通信号灯基础相关的头文件,用于定义交通信号灯相关的类以及操作函数等(和交通模拟相关的部分)
17// 包含用于计算边界框相关的头文件,可用于获取游戏中Actor的边界框信息(比如碰撞检测等场景会用到边界框)
19// 包含传感器相关的头文件,定义了Carla中传感器相关的类以及其操作函数等(用于模拟各种传感器行为)
20#include "Carla/Sensor/Sensor.h"
21
22// 包含用于禁用UE4相关宏的头文件,可能在编译时避免一些UE4宏定义带来的影响(特定编译环境需求)
24// 包含Carla流媒体相关的Token头文件,可能用于处理流媒体传输过程中的标识、验证等相关功能(涉及数据传输部分)
26// 包含Carla流媒体详细的Token头文件,可能是更具体深入的关于流媒体Token的定义和操作相关内容
28// 包含用于启用UE4相关宏的头文件,和前面禁用的对应,恢复UE4宏在编译时的正常作用
30
31// 使用命名空间别名crp来简化carla::rpc的书写,方便后续代码中使用rpc相关的类型、函数等
32namespace crp = carla::rpc;
33
34// 定义FActorRegistry类中的静态成员变量ID_COUNTER,用于为注册的Actor分配唯一的ID,初始值为0(无符号整数类型)
35FActorRegistry::IdType FActorRegistry::ID_COUNTER = 0u;
36
37// 定义一个静态函数FActorRegistry_GetActorType,用于根据传入的AActor指针判断其对应的Actor类型
38// 参数Actor为指向AActor类型的指针,代表需要判断类型的游戏中的Actor对象
40{
41 // 如果传入的Actor指针为空,说明没有有效的Actor对象,返回无效类型(INVALID)
42 if (!Actor)
43 {
45 }
46
47 // 判断传入的Actor是否可以转换为ACarlaWheeledVehicle类型,如果可以,说明是车辆类型的Actor,返回Vehicle类型
48 if (nullptr!= Cast<ACarlaWheeledVehicle>(Actor))
49 {
51 }
52 // 判断是否可以转换为ACharacter类型,如果可以,说明是行人(角色)类型的Actor,返回Walker类型
53 else if (nullptr!= Cast<ACharacter>(Actor))
54 {
56 }
57 // 判断是否可以转换为ATrafficLightBase类型,如果可以,说明是交通信号灯类型的Actor,返回TrafficLight类型
58 else if (nullptr!= Cast<ATrafficLightBase>(Actor))
59 {
61 }
62 // 判断是否可以转换为ATrafficSignBase类型,如果可以,说明是交通标识类型的Actor,返回TrafficSign类型
63 else if (nullptr!= Cast<ATrafficSignBase>(Actor))
64 {
66 }
67 // 判断是否可以转换为ASensor类型,如果可以,说明是传感器类型的Actor,返回Sensor类型
68 else if (nullptr!= Cast<ASensor>(Actor))
69 {
71 }
72 // 如果都不符合上述类型判断,返回其他类型(Other)表示不属于前面明确分类的Actor类型
73 else
74 {
76 }
77}
78
79// 定义函数CarlaGetRelevantTagAsString,用于从给定的语义标签集合中获取一个相关的、合适的标签字符串表示
80// 参数SemanticTags是一个包含crp::CityObjectLabel类型元素的集合,代表语义标签集合
81FString CarlaGetRelevantTagAsString(const TSet<crp::CityObjectLabel> &SemanticTags)
82{
83 // 遍历传入的语义标签集合SemanticTags
84 for (auto &&Tag : SemanticTags)
85 {
86 // 排除特定的无意义标签(None和Other),寻找合适的标签进行处理
87 if ((Tag!= crp::CityObjectLabel::None) && (Tag!= crp::CityObjectLabel::Other))
88 {
89 // 将标签转换为字符串并转换为小写形式
90 auto Str = ATagger::GetTagAsString(Tag).ToLower();
91 // 如果字符串以's'结尾,去除末尾的's'(可能是处理复数形式等情况),然后返回处理后的字符串
92 return (Str.EndsWith(TEXT("s"))? Str.LeftChop(1) : Str);
93 }
94 }
95 // 如果没有找到合适的标签,返回"unknown"表示未知标签情况
96 return TEXT("unknown");
97}
98
99// FActorRegistry类的成员函数Register,用于注册一个Actor到Actor注册系统中,返回注册后的FCarlaActor指针
100// 参数Actor是要注册的AActor类型的引用,代表实际的游戏Actor对象
101// 参数Description是FActorDescription类型,包含了Actor的描述信息(如名称、属性等)
102// 参数DesiredId是期望为Actor分配的ID(可选参数,若为0则自动分配)
104{
105 // 尝试查找具有指定DesiredId的已注册的FCarlaActor对象(可能是检查是否已存在或复用等情况)
106 FCarlaActor* CarlaActor = FindCarlaActor(DesiredId);
107 // 判断找到的CarlaActor是否存在且处于休眠状态(IsDormant为真表示休眠)
108 bool IsDormant = CarlaActor && (CarlaActor->IsDormant());
109 // 如果是休眠状态的已注册Actor,进行重新关联等操作
110 if (IsDormant)
111 {
112 // 将当前要注册的Actor关联到已有的CarlaActor对象上
113 CarlaActor->TheActor = &Actor;
114 // 在Actors映射中添加(或更新)Actor与指定ID的关联
115 Actors.Add(DesiredId, &Actor);
116 // 在Ids映射中添加(或更新)Actor指针与ID的反向关联
117 Ids.Add(&Actor, DesiredId);
118 // 返回已处理好的CarlaActor指针,表示注册完成(复用已有的)
119 return CarlaActor;
120 }
121
122 // 如果不是复用休眠状态的Actor,则为其分配一个新的ID,通过自增全局的ID计数器来获取新ID
123 IdType Id = ++FActorRegistry::ID_COUNTER;
124
125 // 如果传入了期望的ID(DesiredId)且新分配的ID与期望的ID不一致,则进行以下处理
126 if (DesiredId!= 0 && Id!= DesiredId) {
127 // 检查期望的ID是否没有被其他Actor占用,如果没被占用则使用期望的ID
128 if (!Actors.Contains(DesiredId))
129 {
130 Id = DesiredId;
131 // 如果全局ID计数器的值小于期望使用的ID,更新全局ID计数器的值为期望的ID(保证计数器始终是最大的ID值)
132 if (ID_COUNTER < Id)
133 ID_COUNTER = Id;
134 }
135 }
136
137 // 在Actors映射中添加新的Actor与分配的ID的关联
138 Actors.Emplace(Id, &Actor);
139 // 检查是否已经存在当前Actor指针的注册记录,如果存在则输出警告日志(可能存在重复注册等异常情况)
140 if (Ids.Contains(&Actor))
141 {
142 UE_LOG(
143 LogCarla,
144 Warning,
145 TEXT("This actor's memory address is already registered, "
146 "either you forgot to deregister the actor "
147 "or the actor was garbage collected."));
148 }
149 // 在Ids映射中添加Actor指针与新分配ID的反向关联
150 Ids.Emplace(&Actor, Id);
151
152 // 创建一个新的FCarlaActor的共享指针View,包含了Actor的各种信息(如ID、描述、状态等)
153 TSharedPtr<FCarlaActor> View =
154 MakeCarlaActor(Id, Actor, std::move(Description), crp::ActorState::Active);
155
156 // 将新创建的FCarlaActor共享指针添加到ActorDatabase映射中,使用分配的ID作为键,并获取添加后的引用(Result)
157 TSharedPtr<FCarlaActor>& Result = ActorDatabase.Emplace(Id, MoveTemp(View));
158
159 // 进行一致性检查,确保Actors映射中的元素数量和ActorDatabase映射中的元素数量相等(数据一致性校验)
160 check(static_cast<size_t>(Actors.Num()) == ActorDatabase.Num());
161 // 返回注册后的FCarlaActor的指针,代表注册成功后的Actor对象在系统中的表示
162 return Result.Get();
163}
164
165// FActorRegistry类的成员函数Deregister,用于根据指定的ID注销一个已注册的Actor
166// 参数Id是要注销的Actor的ID类型,通过这个ID来查找并移除对应的Actor注册信息
168{
169 // 根据传入的ID查找对应的FCarlaActor对象
170 FCarlaActor* CarlaActor = FindCarlaActor(Id);
171
172 // 如果没找到对应的Actor(CarlaActor为nullptr),直接返回,不进行后续注销操作
173 if (!CarlaActor) return;
174
175 // 获取要注销的Actor对应的AActor指针
176 AActor *Actor = CarlaActor->GetActor();
177
178 // 从ActorDatabase映射中移除指定ID对应的Actor记录
179 ActorDatabase.Remove(Id);
180 // 从Actors映射中移除指定ID与Actor的关联
181 Actors.Remove(Id);
182 // 从Ids映射中移除Actor指针与ID的反向关联
183 Ids.Remove(Actor);
184
185 // 将对应的FCarlaActor对象中的Actor指针置为空,表示已注销该Actor
186 CarlaActor->TheActor = nullptr;
187
188 // 进行一致性检查,确保Actors映射中的元素数量和ActorDatabase映射中的元素数量相等(数据一致性校验)
189 check(static_cast<size_t>(Actors.Num()) == ActorDatabase.Num());
190}
191
192// FActorRegistry类的成员函数Deregister的重载版本,用于根据传入的AActor指针注销对应的Actor
193// 参数Actor是指向要注销的AActor类型的指针,通过这个指针来查找并移除对应的Actor注册信息
195{
196 // 检查传入的Actor指针是否为空,确保有有效的Actor对象要注销
197 check(Actor!= nullptr);
198 // 根据传入的Actor指针查找对应的FCarlaActor对象
199 FCarlaActor* CarlaActor = FindCarlaActor(Actor);
200 // 检查找到的FCarlaActor对象对应的Actor指针是否和传入的Actor指针一致(确保查找正确)
201 check(CarlaActor->GetActor() == Actor);
202 // 调用另一个重载的Deregister函数,通过获取到的CarlaActor对象的ID来进行注销操作
203 Deregister(CarlaActor->GetActorId());
204}
205
206// FActorRegistry类的成员函数MakeCarlaActor,用于创建一个新的FCarlaActor对象,返回其共享指针
207// 参数Id是要创建的FCarlaActor的ID类型,用于标识这个Actor
208// 参数Actor是AActor类型的引用,代表实际的游戏Actor对象,用于关联到创建的FCarlaActor上
209// 参数Description是FActorDescription类型,包含了Actor的描述信息(如名称、属性等)
210// 参数InState是crp::ActorState类型,用于指定Actor的初始状态(如活跃、休眠等)
211TSharedPtr<FCarlaActor> FActorRegistry::MakeCarlaActor(
212 IdType Id,
213 AActor &Actor,
214 FActorDescription Description,
216{
217 // 创建一个新的FActorInfo的共享指针Info,用于存储Actor的详细信息
218 auto Info = MakeShared<FActorInfo>();
219 // 将传入的Description移动赋值给Info中的Description成员,转移所有权,存储Actor的描述信息
220 Info->Description = std::move(Description);
221 // 通过ATagger的函数获取Actor的语义标签,并存储到Info的SemanticTags成员中
223 // 通过边界框计算函数获取Actor的边界框信息,并存储到Info的BoundingBox成员中
225
226 // 如果Info中的Description的ID为空字符串,说明可能缺少明确标识,进行以下伪造身份处理
227 if (Info->Description.Id.IsEmpty())
228 {
229 // 根据Actor的语义标签获取一个相关的字符串作为标识,格式为"static."加上相关标签字符串
230 Info->Description.Id = TEXT("static.") + CarlaGetRelevantTagAsString(Info->SemanticTags);
231 }
232
233 // 将当前创建的FCarlaActor的ID赋值给Info中序列化数据的ID成员
234 Info->SerializedData.id = Id;
235 // 将Info中的Description赋值给Info中序列化数据的描述成员,存储描述信息
236 Info->SerializedData.description = Info->Description;
237 // 将Info中的边界框信息赋值给Info中序列化数据的边界框成员,存储边界框信息
238 Info->SerializedData.bounding_box = Info->BoundingBox;
239 // 预留一定空间用于存储语义标签序列化数据,数量和Info中的语义标签集合数量一致
240 Info->SerializedData.semantic_tags.reserve(Info->SemanticTags.Num());
241 // 遍历Info中的语义标签集合,将每个标签转换为合适的类型并添加到序列化数据的语义标签成员中
242 for (auto &&Tag : Info->SemanticTags)
243 {
244 using tag_t = decltype(Info->SerializedData.semantic_tags)::value_type;
245 Info->SerializedData.semantic_tags.emplace_back(static_cast<tag_t>(Tag));
246 }
247 // 将传入的Actor指针转换为ASensor类型指针,检查是否是传感器类型的Actor
248 auto *Sensor = Cast<ASensor>(&Actor);
249 if (Sensor!= nullptr)
250 {
251 // 获取传感器的Token信息,并将其转换为合适的数据类型存储到Info中序列化数据的流Token成员中
252 const auto &Token = Sensor->GetToken();
253 Info->SerializedData.stream_token = decltype(Info->SerializedData.stream_token)(
254 std::begin(Token.data),
255 std::end(Token.data));
256 }
257 // 通过函数FActorRegistry_GetActorType获取Actor的类型
258 auto Type = FActorRegistry_GetActorType(&Actor);
259 // 调用FCarlaActor的构造函数创建一个新的FCarlaActor对象,传入相关参数,并返回其共享指针
260 TSharedPtr<FCarlaActor> CarlaActor =
262 Id, &Actor,
263 std::move(Info), Type,
264 InState, Actor.GetWorld());
265 return CarlaActor;
266}
267
268// FActorRegistry类的成员函数PutActorToSleep,用于将指定ID的Actor及其子Actor设置为休眠状态
269// 参数Id是要设置为休眠状态的Actor的ID类型,通过这个ID来查找对应的Actor
270// 参数CarlaEpisode可能是和游戏场景、关卡等相关的对象指针,用于关联Actor与具体的游戏环境(具体依Carla架构而定)
271void FActorRegistry::PutActorToSleep(FCarlaActor::IdType Id, UCarlaEpisode* CarlaEpisode)
272{
273 // 根据传入的ID查找对应的FCarlaActor对象
274 FCarlaActor* CarlaActor = FindCarlaActor(Id);
275
276 // 更新Actors映射中指定ID对应的Actor指针为nullptr,表示该Actor进入休眠状态(从活跃关联中移除)
277 Actors[Id] = nullptr;
278 // 获取对应的AActor指针
279 AActor* Actor = CarlaActor->GetActor();
280 // 如果Actor指针不为空,从Ids映射中移除该Actor指针与ID的反向关联(解除关联)
281 if (Actor)
282 {
283 Ids.Remove(Actor);
284 }
285
286 // 调用FCarlaActor对象的PutActorToSleep函数,将其自身设置为休眠状态,并传入相关游戏环境对象指针
287 CarlaActor->PutActorToSleep(CarlaEpisode);
288 // 遍历该Actor的所有子Actor的ID列表,递归调用PutActorToSleep函数,将子Actor也设置为休眠状态
289 for (const FCarlaActor::IdType& ChildId : CarlaActor->GetChildren())
290 {
291 PutActorToSleep(ChildId, CarlaEpisode);
292 }
293 // TODO:更新ID映射,这里可能是后续需要完善的部分,比如进一步处理休眠状态下ID映射的一些细节调整等(目前代码未完整实现这部分功能)
294}
UE_LOG(LogCarla, Log, TEXT("UActorDispatcher::Destroying actor: '%s' %x"), *Id, Actor)
FString CarlaGetRelevantTagAsString(const TSet< crp::CityObjectLabel > &SemanticTags)
static FCarlaActor::ActorType FActorRegistry_GetActorType(const AActor *Actor)
TSharedPtr< FCarlaActor > MakeCarlaActor(IdType Id, AActor &Actor, FActorDescription Description, carla::rpc::ActorState InState) const
DatabaseType ActorDatabase
static IdType ID_COUNTER
TMap< IdType, AActor * > Actors
TMap< AActor *, IdType > Ids
void PutActorToSleep(IdType Id, UCarlaEpisode *CarlaEpisode)
TSharedPtr< const FActorInfo > carla::rpc::ActorState InState
TSharedPtr< const FActorInfo > Info
TSharedPtr< const FActorInfo > carla::rpc::ActorState UWorld Actor
static void GetTagsOfTaggedActor(const AActor &Actor, TSet< crp::CityObjectLabel > &Tags)
检索已标记的角色的标记。CityObjectLabel::None 为 未添加到数组中。
Definition Tagger.cpp:243
static FString GetTagAsString(crp::CityObjectLabel Tag)
检索已标记的角色的标记。CityObjectLabel::None 为 未添加到数组中。
Definition Tagger.cpp:257
FCarlaActor::IdType IdType
FCarlaActor * Register(AActor &Actor, FActorDescription Description, IdType DesiredId=0)
名称 参与者注册函数
void Deregister(IdType Id)
FCarlaActor * FindCarlaActor(IdType Id)
查看一个参与者和它的属性
Definition CarlaActor.h:23
static TSharedPtr< FCarlaActor > ConstructCarlaActor(IdType ActorId, AActor *Actor, TSharedPtr< const FActorInfo > Info, ActorType Type, carla::rpc::ActorState InState, UWorld *World)
bool IsDormant() const
Definition CarlaActor.h:59
AActor * GetActor()
Definition CarlaActor.h:75
uint32 IdType
Definition CarlaActor.h:25
AActor * TheActor
Definition CarlaActor.h:418
IdType GetActorId() const
Definition CarlaActor.h:67
void PutActorToSleep(UCarlaEpisode *CarlaEpisode)
static FBoundingBox GetActorBoundingBox(const AActor *Actor, uint8 InTagQueried=0xFF)
计算给定 Carla actor 的边界框。
包含CARLA流处理相关头文件和Boost.Asio网络库头文件。 包含CARLA的调试功能相关定义。 包含CARLA流处理的端点(EndPoint)类定义。 包含CARLA流处理的令牌(Token)类...