CARLA
Loading...
Searching...
No Matches
ActorData.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
18#include "Carla/Sensor/Sensor.h"
19#include "CarlaActor.h"
20
21#include <util/ue-header-guard-begin.h>
22#include "Components/SkinnedMeshComponent.h"
23#include "GameFramework/CharacterMovementComponent.h"
24#include <util/ue-header-guard-end.h>
25
27{
29 if (Actor == nullptr)
30 {
31 return Rig;
32 }
33 const FTransform ActorToWorld = Actor->GetActorTransform();
34
35 TArray<UActorComponent *> Components;
36 Actor->GetComponents(Components);
37 for (UActorComponent *ActorComponent : Components)
38 {
39 // Scene components only: the others have no transform to report.
40 USceneComponent *SceneComponent = Cast<USceneComponent>(ActorComponent);
41 if (SceneComponent == nullptr)
42 {
43 continue;
44 }
45 Rig.ComponentNames.Add(SceneComponent->GetName());
46 Rig.ComponentTransforms.Add(
47 SceneComponent->GetComponentTransform().GetRelativeTransform(ActorToWorld));
48
49 // Authored sockets only. A skinned mesh also reports each of its bones as a
50 // socket, which duplicates the bone lists and can repeat a name.
51 TArray<FComponentSocketDescription> Sockets;
52 SceneComponent->QuerySupportedSockets(Sockets);
53 for (const FComponentSocketDescription &Socket : Sockets)
54 {
55 if (Socket.Type != EComponentSocketType::Socket)
56 {
57 continue;
58 }
59 Rig.SocketNames.Add(Socket.Name.ToString());
60 Rig.SocketTransforms.Add(
61 SceneComponent->GetSocketTransform(Socket.Name, ERelativeTransformSpace::RTS_Actor));
62 }
63 }
64
65 TArray<USkinnedMeshComponent *> SkinnedMeshComponents;
66 Actor->GetComponents<USkinnedMeshComponent>(SkinnedMeshComponents);
67 for (USkinnedMeshComponent *SkinnedMeshComponent : SkinnedMeshComponents)
68 {
69 const FTransform ComponentToWorld = SkinnedMeshComponent->GetComponentTransform();
70 TArray<FName> BoneNames;
71 SkinnedMeshComponent->GetBoneNames(BoneNames);
72 // GetBoneNames walks the reference skeleton in bone-index order, the same
73 // order as GetBoneTransform, so names and transforms stay index-aligned.
74 const int32 NumBones = FMath::Min(BoneNames.Num(), SkinnedMeshComponent->GetNumBones());
75 for (int32 BoneIndex = 0; BoneIndex < NumBones; ++BoneIndex)
76 {
77 Rig.BoneNames.Add(BoneNames[BoneIndex].ToString());
78 Rig.BoneTransforms.Add(
79 SkinnedMeshComponent->GetBoneTransform(BoneIndex, ComponentToWorld)
80 .GetRelativeTransform(ActorToWorld));
81 }
82 }
83 return Rig;
84}
85
87{
88 FTransform SpawnTransform = GetLocalTransform(CarlaEpisode);
89 // hack to prevent wheel intersection with geometry
90 SpawnTransform.AddToTranslation(FVector(0,0,15));
91 return CarlaEpisode->ReSpawnActorWithInfo(SpawnTransform, Info.Description);
92}
93
95{
96 AActor* Actor = CarlaActor->GetActor();
97 FTransform Transform = Actor->GetTransform();
98 Location = FDVector(Transform.GetLocation()) + CarlaEpisode->GetCurrentMapOrigin();
99 Rotation = Transform.GetRotation();
100 Scale = Transform.GetScale3D();
101 UPrimitiveComponent* Component = Cast<UPrimitiveComponent>(Actor->GetRootComponent());
102 if (Component)
103 {
104 bSimulatePhysics = Component->IsSimulatingPhysics();
105 AngularVelocity = Component->GetPhysicsAngularVelocityInDegrees();
106 }
107 Velocity = Actor->GetVelocity();
108 // The AActor is destroyed right after this, so the rig has to be kept here or
109 // every component, bone and socket query fails for as long as it is dormant.
111}
112
114{
115 AActor* Actor = CarlaActor->GetActor();
116 Actor->SetActorTransform(GetLocalTransform(CarlaEpisode));
117 UPrimitiveComponent* Component = Cast<UPrimitiveComponent>(Actor->GetRootComponent());
118 if (Component)
119 {
120 Component->SetPhysicsLinearVelocity(
121 Velocity, false, "None");
122 Component->SetPhysicsAngularVelocityInDegrees(
123 AngularVelocity, false, "None");
124 }
125 auto* Character = Cast<ACharacter>(Actor);
126 auto* CarlaVehicle = Cast<ACarlaWheeledVehicle>(Actor);
127 // The physics in the vehicles works in a different way so to disable them.
128 if (CarlaVehicle != nullptr){
129 CarlaVehicle->SetSimulatePhysics(bSimulatePhysics);
130 }
131 // The physics in the walkers also works in a different way so to disable them,
132 // we need to do it in the UCharacterMovementComponent.
133 else if (Character != nullptr)
134 {
135
136 }
137 // In the rest of actors, the physics is controlled with the UPrimitiveComponent, so we use
138 // that for disable it.
139 else
140 {
141 auto RootComponent = Component;
142 if (RootComponent != nullptr)
143 {
144 RootComponent->SetSimulatePhysics(bSimulatePhysics);
145 RootComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
146 }
147 }
148}
149
150FTransform FActorData::GetLocalTransform(UCarlaEpisode* CarlaEpisode) const
151{
152 FVector LocalLocation = (Location - CarlaEpisode->GetCurrentMapOrigin()).ToFVector();
153 return FTransform(Rotation, LocalLocation, Scale);
154}
155
157{
158 FActorData::RecordActorData(CarlaActor, CarlaEpisode);
159 AActor* Actor = CarlaActor->GetActor();
160 ACarlaWheeledVehicle* Vehicle = Cast<ACarlaWheeledVehicle>(Actor);
162 {
163 PhysicsControl = Vehicle->GetVehiclePhysicsControl();
164 }
165 Control = Vehicle->GetVehicleControl();
166 AckermannControl = Vehicle->GetVehicleAckermannControl();
167 bAckermannControlActive = Vehicle->IsAckermannControlActive();
168 AckermannControllerSettings = Vehicle->GetAckermannControllerSettings();
169 LightState = Vehicle->GetVehicleLightState();
170 auto Controller = Cast<AWheeledVehicleAIController>(Vehicle->GetController());
171 if (Controller)
172 {
173 SpeedLimit = Controller->GetSpeedLimit();
174 }
175 FailureState = Vehicle->GetFailureState();
176}
177
179{
180 FActorData::RestoreActorData(CarlaActor, CarlaEpisode);
181 AActor* Actor = CarlaActor->GetActor();
182 ACarlaWheeledVehicle* Vehicle = Cast<ACarlaWheeledVehicle>(Actor);
183 Vehicle->SetSimulatePhysics(bSimulatePhysics);
185 {
186 Vehicle->ApplyVehiclePhysicsControl(PhysicsControl);
187 }
188 Vehicle->ApplyAckermannControllerSettings(AckermannControllerSettings);
190 {
191 Vehicle->ApplyVehicleControl(Control, EVehicleInputPriority::Client);
192 }
193 else
194 {
195 Vehicle->ApplyVehicleAckermannControl(AckermannControl, EVehicleInputPriority::Client);
196 }
197 Vehicle->SetVehicleLightState(LightState);
198 auto Controller = Cast<AWheeledVehicleAIController>(Vehicle->GetController());
199 if (Controller)
200 {
201 Controller->SetSpeedLimit(SpeedLimit);
202 }
203 Vehicle->SetFailureState(FailureState);
204}
205
207{
208 FActorData::RecordActorData(CarlaActor, CarlaEpisode);
209 AActor* Actor = CarlaActor->GetActor();
210 auto Walker = Cast<AWalkerBase>(Actor);
211 auto Controller = Walker != nullptr ? Cast<AWalkerController>(Walker->GetController()) : nullptr;
212 if (Controller != nullptr)
213 {
214 WalkerControl = carla::rpc::WalkerControl{Controller->GetWalkerControl()};
215 }
216 bAlive = Walker->bAlive;
217}
218
220{
221 FActorData::RestoreActorData(CarlaActor, CarlaEpisode);
222 AActor* Actor = CarlaActor->GetActor();
223 auto Walker = Cast<ACharacter>(Actor);
224 auto Controller = Walker != nullptr ? Cast<AWalkerController>(Walker->GetController()) : nullptr;
225 if (Controller != nullptr)
226 {
227 Controller->ApplyWalkerControl(WalkerControl);
228 }
229 auto CharacterMovement = Cast<UCharacterMovementComponent>(Walker->GetCharacterMovement());
230 // TODO: Handle death timer
231}
232
234{
235 FTransform SpawnTransform = GetLocalTransform(CarlaEpisode);
236 FActorSpawnParameters SpawnParams;
237 SpawnParams.SpawnCollisionHandlingOverride =
238 ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
239 return CarlaEpisode->GetWorld()->SpawnActor<ATrafficSignBase>(
240 Model,
241 SpawnTransform,
242 SpawnParams);
243}
244
246{
247 FActorData::RecordActorData(CarlaActor, CarlaEpisode);
248 AActor* Actor = CarlaActor->GetActor();
249 Model = Actor->GetClass();
250 ATrafficSignBase* TrafficSign = Cast<ATrafficSignBase>(Actor);
251 USignComponent* TrafficSignComponent =
252 Cast<USignComponent>(TrafficSign->FindComponentByClass<USignComponent>());
253 if (TrafficSignComponent)
254 {
255 SignModel = TrafficSignComponent->GetClass();
256 SignId = TrafficSignComponent->GetSignId();
257 }
258}
259
261{
262 AActor* Actor = CarlaActor->GetActor();
263 if (SignId.Len())
264 {
265 USignComponent* SignComponent =
266 NewObject<USignComponent>(Actor, SignModel);
267 SignComponent->SetSignId(SignId);
268 SignComponent->RegisterComponent();
269 SignComponent->AttachToComponent(
270 Actor->GetRootComponent(),
271 FAttachmentTransformRules::KeepRelativeTransform);
272 ACarlaGameModeBase *GameMode = UCarlaStatics::GetGameMode(CarlaEpisode->GetWorld());
273 SignComponent->InitializeSign(GameMode->GetMap().value());
274 }
275}
276
278{
279 FTransform SpawnTransform = GetLocalTransform(CarlaEpisode);
280 FActorSpawnParameters SpawnParams;
281 SpawnParams.SpawnCollisionHandlingOverride =
282 ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
283 return CarlaEpisode->GetWorld()->SpawnActor<ATrafficLightBase>(
284 Model,
285 SpawnTransform,
286 SpawnParams);
287}
288
290{
291 FActorData::RecordActorData(CarlaActor, CarlaEpisode);
292 AActor* Actor = CarlaActor->GetActor();
293 Model = Actor->GetClass();
294 ATrafficLightBase* TrafficLight = Cast<ATrafficLightBase>(Actor);
295 UTrafficLightComponent* Component = TrafficLight->GetTrafficLightComponent();
296 SignId = Component->GetSignId();
297 Controller = Component->GetController();
298 Controller->RemoveTrafficLight(Component);
300 LightState = TrafficLight->GetTrafficLightState();
301 PoleIndex = TrafficLight->GetPoleIndex();
302}
303
305{
306 AActor* Actor = CarlaActor->GetActor();
307 ATrafficLightBase* TrafficLight = Cast<ATrafficLightBase>(Actor);
308 UTrafficLightComponent* Component = TrafficLight->GetTrafficLightComponent();
309 Component->SetSignId(SignId);
311 Controller->AddTrafficLight(Component);
312 ACarlaGameModeBase *GameMode = UCarlaStatics::GetGameMode(CarlaEpisode->GetWorld());
313 Component->InitializeSign(GameMode->GetMap().value());
314 Component->SetLightState(Controller->GetCurrentState().State);
315 TrafficLight->SetPoleIndex(PoleIndex);
316 TrafficLight->SetTrafficLightState(LightState);
317}
318
320{
321 FActorData::RecordActorData(CarlaActor, CarlaEpisode);
322 AActor* Actor = CarlaActor->GetActor();
323 ASensor* Sensor = Cast<ASensor>(Actor);
324 Stream = Sensor->MoveDataStream();
325}
326
328{
329 FActorData::RestoreActorData(CarlaActor, CarlaEpisode);
330 AActor* Actor = CarlaActor->GetActor();
331 ASensor* Sensor = Cast<ASensor>(Actor);
332 Sensor->SetDataStream(std::move(Stream));
333}
Base class for the CARLA Game Mode.
const std::optional< carla::road::Map > & GetMap() const
Base class for CARLA wheeled vehicles.
void SetDataStream(FDataStream InStream)
Replace the FDataStream associated with this sensor.
virtual void RecordActorData(FCarlaActor *CarlaActor, UCarlaEpisode *CarlaEpisode)
Definition ActorData.cpp:94
virtual AActor * RespawnActor(UCarlaEpisode *CarlaEpisode, const FActorInfo &Info)
Definition ActorData.cpp:86
FQuat Rotation
Definition ActorData.h:53
FActorRigSnapshot Rig
Definition ActorData.h:51
virtual void RestoreActorData(FCarlaActor *CarlaActor, UCarlaEpisode *CarlaEpisode)
FVector Velocity
Definition ActorData.h:57
bool bSimulatePhysics
Definition ActorData.h:61
FVector AngularVelocity
Definition ActorData.h:59
FTransform GetLocalTransform(UCarlaEpisode *CarlaEpisode) const
FVector Scale
Definition ActorData.h:55
FDVector Location
Definition ActorData.h:48
FDataStream Stream
Definition ActorData.h:154
virtual void RestoreActorData(FCarlaActor *CarlaActor, UCarlaEpisode *CarlaEpisode) override
virtual void RecordActorData(FCarlaActor *CarlaActor, UCarlaEpisode *CarlaEpisode) override
A view over an actor and its properties.
Definition CarlaActor.h:25
AActor * GetActor()
Definition CarlaActor.h:91
virtual void RestoreActorData(FCarlaActor *CarlaActor, UCarlaEpisode *CarlaEpisode) override
ETrafficLightState LightState
Definition ActorData.h:134
UTrafficLightController * Controller
Definition ActorData.h:132
virtual void RecordActorData(FCarlaActor *CarlaActor, UCarlaEpisode *CarlaEpisode) override
TSubclassOf< AActor > Model
Definition ActorData.h:138
virtual AActor * RespawnActor(UCarlaEpisode *CarlaEpisode, const FActorInfo &Info) override
virtual void RecordActorData(FCarlaActor *CarlaActor, UCarlaEpisode *CarlaEpisode) override
TSubclassOf< UObject > SignModel
Definition ActorData.h:119
virtual AActor * RespawnActor(UCarlaEpisode *CarlaEpisode, const FActorInfo &Info) override
TSubclassOf< AActor > Model
Definition ActorData.h:117
virtual void RestoreActorData(FCarlaActor *CarlaActor, UCarlaEpisode *CarlaEpisode) override
bool bAckermannControlActive
Definition ActorData.h:84
virtual void RecordActorData(FCarlaActor *CarlaActor, UCarlaEpisode *CarlaEpisode) override
FVehicleLightState LightState
Definition ActorData.h:88
FVehicleControl Control
Definition ActorData.h:80
float SpeedLimit
Definition ActorData.h:90
virtual void RestoreActorData(FCarlaActor *CarlaActor, UCarlaEpisode *CarlaEpisode) override
carla::rpc::VehicleFailureState FailureState
Definition ActorData.h:92
FVehicleAckermannControl AckermannControl
Definition ActorData.h:82
FAckermannControllerSettings AckermannControllerSettings
Definition ActorData.h:86
FVehiclePhysicsControl PhysicsControl
Definition ActorData.h:78
carla::rpc::WalkerControl WalkerControl
Definition ActorData.h:103
virtual void RestoreActorData(FCarlaActor *CarlaActor, UCarlaEpisode *CarlaEpisode) override
virtual void RecordActorData(FCarlaActor *CarlaActor, UCarlaEpisode *CarlaEpisode) override
A simulation episode.
FIntVector GetCurrentMapOrigin() const
AActor * SpawnActor(const FTransform &Transform, FActorDescription ActorDescription)
Spawns an actor based on ActorDescription at Transform.
AActor * ReSpawnActorWithInfo(const FTransform &Transform, FActorDescription thisActorDescription)
Spawns an actor based on ActorDescription at Transform.
static ACarlaGameModeBase * GetGameMode(const UObject *WorldContextObject)
void RemoveCarlaActorTrafficLight(FCarlaActor *CarlaActor)
const FTrafficLightStage & GetCurrentState() const
void AddCarlaActorTrafficLight(FCarlaActor *CarlaActor)
void AddTrafficLight(UTrafficLightComponent *TrafficLight)
void RemoveTrafficLight(UTrafficLightComponent *TrafficLight)
A view over an actor and its properties.
Definition ActorInfo.h:18
FActorDescription Description
Definition ActorInfo.h:21
TArray< FString > SocketNames
Definition ActorData.h:36
TArray< FTransform > ComponentTransforms
Definition ActorData.h:33
TArray< FString > ComponentNames
Definition ActorData.h:32
TArray< FTransform > BoneTransforms
Definition ActorData.h:35
TArray< FString > BoneNames
Definition ActorData.h:34
static FActorRigSnapshot FromActor(const AActor *Actor)
Definition ActorData.cpp:26
TArray< FTransform > SocketTransforms
Definition ActorData.h:37
ETrafficLightState State