CARLA
CarlaReplayerHelper.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017 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 
7 #include "Carla.h"
9 
13 #include "Carla/Actor/CarlaActor.h"
27 #include "Components/BoxComponent.h"
28 #include "Engine/StaticMeshActor.h"
29 
33 
34 
35 #include "EngineUtils.h"
36 
37 // create or reuse an actor for replaying
39  FVector &Location,
40  FVector &Rotation,
41  FActorDescription &ActorDesc,
42  uint32_t DesiredId,
43  bool SpawnSensors)
44 {
45  check(Episode != nullptr);
46 
47  // check type of actor we need
48  if (ActorDesc.Id.StartsWith("traffic."))
49  {
50  FCarlaActor* CarlaActor = FindTrafficLightAt(Location);
51  if (CarlaActor != nullptr)
52  {
53  // reuse that actor
54  return std::pair<int, FCarlaActor*>(2, CarlaActor);
55  }
56  else
57  {
58  // actor not found
59  UE_LOG(LogCarla, Log, TEXT("TrafficLight not found"));
60  return std::pair<int, FCarlaActor*>(0, nullptr);
61  }
62  }
63  else if (SpawnSensors || !ActorDesc.Id.StartsWith("sensor."))
64  {
65  // check if an actor of that type already exist with same id
66  if (Episode->GetActorRegistry().Contains(DesiredId))
67  {
68  auto* CarlaActor = Episode->FindCarlaActor(DesiredId);
69  const FActorDescription *desc = &CarlaActor->GetActorInfo()->Description;
70  if (desc->Id == ActorDesc.Id)
71  {
72  // we don't need to create, actor of same type already exist
73  // relocate
74  FRotator Rot = FRotator::MakeFromEuler(Rotation);
75  FTransform Trans2(Rot, Location, FVector(1, 1, 1));
76  CarlaActor->SetActorGlobalTransform(Trans2);
77  return std::pair<int, FCarlaActor*>(2, CarlaActor);
78  }
79  }
80  // create the transform
81  FRotator Rot = FRotator::MakeFromEuler(Rotation);
82  FTransform Trans(Rot, FVector(0, 0, 100000), FVector(1, 1, 1));
83  // create as new actor
84  TPair<EActorSpawnResultStatus, FCarlaActor*> Result = Episode->SpawnActorWithInfo(Trans, ActorDesc, DesiredId);
85  if (Result.Key == EActorSpawnResultStatus::Success)
86  {
87  // relocate
88  FTransform Trans2(Rot, Location, FVector(1, 1, 1));
89  Result.Value->SetActorGlobalTransform(Trans2);
90  ALargeMapManager * LargeMapManager = UCarlaStatics::GetLargeMapManager(Episode->GetWorld());
91  if (LargeMapManager)
92  {
93  LargeMapManager->OnActorSpawned(*Result.Value);
94  }
95  return std::pair<int, FCarlaActor*>(1, Result.Value);
96  }
97  else
98  {
99  UE_LOG(LogCarla, Log, TEXT("Actor could't be created by replayer"));
100  return std::pair<int, FCarlaActor*>(0, Result.Value);
101  }
102  }
103  else
104  {
105  // actor ignored
106  return std::pair<int, FCarlaActor*>(0, nullptr);
107  }
108 }
109 
111 {
112  check(Episode != nullptr);
113  auto World = Episode->GetWorld();
114  check(World != nullptr);
115 
116  // get its position (truncated as int's)
117  int x = static_cast<int>(Location.X);
118  int y = static_cast<int>(Location.Y);
119  int z = static_cast<int>(Location.Z);
120 
121  const FActorRegistry &Registry = Episode->GetActorRegistry();
122  // through all actors in registry
123  for (auto It = Registry.begin(); It != Registry.end(); ++It)
124  {
125  FCarlaActor* CarlaActor = It.Value().Get();
127  {
128  FVector vec = CarlaActor->GetActorGlobalLocation();
129  int x2 = static_cast<int>(vec.X);
130  int y2 = static_cast<int>(vec.Y);
131  int z2 = static_cast<int>(vec.Z);
132  if ((x2 == x) && (y2 == y) && (z2 == z))
133  {
134  // actor found
135  return CarlaActor;
136  }
137  }
138  }
139  // actor not found
140  return nullptr;
141 }
142 
143 // enable / disable physics for an actor
145 {
146  if (!CarlaActor)
147  {
148  return false;
149  }
150  ECarlaServerResponse Response =
151  CarlaActor->SetActorSimulatePhysics(bEnabled);
152  if (Response != ECarlaServerResponse::Success)
153  {
154  return false;
155  }
156  return true;
157 }
158 
159 // enable / disable autopilot for an actor
160 bool CarlaReplayerHelper::SetActorAutopilot(FCarlaActor* CarlaActor, bool bEnabled, bool bKeepState)
161 {
162  if (!CarlaActor)
163  {
164  return false;
165  }
166  ECarlaServerResponse Response =
167  CarlaActor->SetActorAutopilot(bEnabled, bKeepState);
168  if (Response != ECarlaServerResponse::Success)
169  {
170  return false;
171  }
172  return true;
173 }
174 
175 // replay event for creating actor
177  FVector Location,
178  FVector Rotation,
179  CarlaRecorderActorDescription Description,
180  uint32_t DesiredId,
181  bool bIgnoreHero,
182  bool ReplaySensors)
183 {
184  check(Episode != nullptr);
185  FActorDescription ActorDesc;
186  bool IsHero = false;
187 
188  // prepare actor description
189  ActorDesc.UId = Description.UId;
190  ActorDesc.Id = Description.Id;
191  for (const auto &Item : Description.Attributes)
192  {
193  FActorAttribute Attr;
194  Attr.Type = static_cast<EActorAttributeType>(Item.Type);
195  Attr.Id = Item.Id;
196  Attr.Value = Item.Value;
197  ActorDesc.Variations.Add(Attr.Id, std::move(Attr));
198  // check for hero
199  if (Item.Id == "role_name" && Item.Value == "hero")
200  IsHero = true;
201  }
202 
203  auto result = TryToCreateReplayerActor(
204  Location,
205  Rotation,
206  ActorDesc,
207  DesiredId,
208  ReplaySensors);
209 
210  if (result.first != 0)
211  {
212  // disable physics and autopilot on vehicles
213  if (result.second->GetActorType() == FCarlaActor::ActorType::Vehicle)
214  {
215  // ignore hero ?
216  if (!(bIgnoreHero && IsHero))
217  {
218  // disable physics
219  SetActorSimulatePhysics(result.second, false);
220  // disable autopilot
221  SetActorAutopilot(result.second, false, false);
222  }
223  else
224  {
225  // reenable physics just in case
226  SetActorSimulatePhysics(result.second, true);
227  }
228  }
229  return std::make_pair(result.first, result.second->GetActorId());
230  }
231  return std::make_pair(result.first, 0);
232 }
233 
234 // replay event for removing actor
236 {
237  check(Episode != nullptr);
238  FCarlaActor* CarlaActor = Episode->FindCarlaActor(DatabaseId);
239  if (CarlaActor == nullptr)
240  {
241  UE_LOG(LogCarla, Log, TEXT("Actor %d not found to destroy"), DatabaseId);
242  return false;
243  }
244  Episode->DestroyActor(CarlaActor->GetActorId());
245  return true;
246 }
247 
248 // replay event for parenting actors
249 bool CarlaReplayerHelper::ProcessReplayerEventParent(uint32_t ChildId, uint32_t ParentId)
250 {
251  check(Episode != nullptr);
252  FCarlaActor * Child = Episode->FindCarlaActor(ChildId);
253  FCarlaActor * Parent = Episode->FindCarlaActor(ParentId);
254  if(!Child)
255  {
256  UE_LOG(LogCarla, Log, TEXT("Parenting Child actors not found"));
257  return false;
258  }
259  if(!Parent)
260  {
261  UE_LOG(LogCarla, Log, TEXT("Parenting Parent actors not found"));
262  return false;
263  }
264  Child->SetParent(ParentId);
266  Parent->AddChildren(Child->GetActorId());
267  if(!Parent->IsDormant())
268  {
269  if(!Child->IsDormant())
270  {
272  Child->GetActor(),
273  Parent->GetActor(),
275  }
276  }
277  else
278  {
280  }
281  return true;
282 }
283 
284 // reposition actors
286 {
287  check(Episode != nullptr);
288  FCarlaActor* CarlaActor = Episode->FindCarlaActor(Pos1.DatabaseId);
289  FVector Location;
290  FRotator Rotation;
291  if(CarlaActor)
292  {
293  // check to assign first position or interpolate between both
294  if (Per == 0.0)
295  {
296  // assign position 1
297  Location = FVector(Pos1.Location);
298  Rotation = FRotator::MakeFromEuler(Pos1.Rotation);
299  }
300  else
301  {
302  // interpolate positions
303  Location = FMath::Lerp(FVector(Pos1.Location), FVector(Pos2.Location), Per);
304  Rotation = FMath::Lerp(FRotator::MakeFromEuler(Pos1.Rotation), FRotator::MakeFromEuler(Pos2.Rotation), Per);
305  }
306  // set new transform
307  FTransform Trans(Rotation, Location, FVector(1, 1, 1));
308  CarlaActor->SetActorGlobalTransform(Trans, ETeleportType::None);
309  return true;
310  }
311  return false;
312 }
313 
314 // reposition the camera
315 bool CarlaReplayerHelper::SetCameraPosition(uint32_t Id, FVector Offset, FQuat Rotation)
316 {
317  check(Episode != nullptr);
318 
319  // get the actor to follow
320  FCarlaActor* CarlaActor = Episode->FindCarlaActor(Id);
321  if (!CarlaActor)
322  return false;
323  // get specator pawn
324  APawn *Spectator = Episode->GetSpectatorPawn();
325  if (!Spectator)
326  return false;
327 
328  FCarlaActor* CarlaSpectator = Episode->FindCarlaActor(Spectator);
329  if (!CarlaSpectator)
330  return false;
331 
332  FTransform ActorTransform = CarlaActor->GetActorGlobalTransform();
333  // set the new position
334  FQuat ActorRot = ActorTransform.GetRotation();
335  FVector Pos = ActorTransform.GetTranslation() + (ActorRot.RotateVector(Offset));
336  CarlaSpectator->SetActorGlobalTransform(FTransform(ActorRot * Rotation, Pos, FVector(1,1,1)));
337 
338  return true;
339 }
340 
342 {
343  check(Episode != nullptr);
344  FCarlaActor* CarlaActor = Episode->FindCarlaActor(State.DatabaseId);
345  if(CarlaActor)
346  {
347  CarlaActor->SetTrafficLightState(static_cast<ETrafficLightState>(State.State));
348  UTrafficLightController* Controller = CarlaActor->GetTrafficLightController();
349  if(Controller)
350  {
351  Controller->SetElapsedTime(State.ElapsedTime);
352  ATrafficLightGroup* Group = Controller->GetGroup();
353  if (Group)
354  {
355  Group->SetFrozenGroup(State.IsFrozen);
356  }
357  }
358  return true;
359  }
360  return false;
361 }
362 
363 // set the animation for Vehicles
365 {
366  check(Episode != nullptr);
367  FCarlaActor *CarlaActor = Episode->FindCarlaActor(Vehicle.DatabaseId);
368  if (CarlaActor)
369  {
370  FVehicleControl Control;
371  Control.Throttle = Vehicle.Throttle;
372  Control.Steer = Vehicle.Steering;
373  Control.Brake = Vehicle.Brake;
374  Control.bHandBrake = Vehicle.bHandbrake;
375  Control.bReverse = (Vehicle.Gear < 0);
376  Control.Gear = Vehicle.Gear;
377  Control.bManualGearShift = false;
378  CarlaActor->ApplyControlToVehicle(Control, EVehicleInputPriority::User);
379  }
380 }
381 
382 // set the lights for vehicles
384 {
385  check(Episode != nullptr);
386  FCarlaActor * CarlaActor = Episode->FindCarlaActor(LightVehicle.DatabaseId);
387  if (CarlaActor)
388  {
389  carla::rpc::VehicleLightState LightState(LightVehicle.State);
390  CarlaActor->SetVehicleLightState(FVehicleLightState(LightState));
391  }
392 }
393 
395 {
396  check(Episode != nullptr);
397  UWorld* World = Episode->GetWorld();
398  if(World)
399  {
400  UCarlaLightSubsystem* CarlaLightSubsystem = World->GetSubsystem<UCarlaLightSubsystem>();
401  if (!CarlaLightSubsystem)
402  {
403  return;
404  }
405  auto* CarlaLight = CarlaLightSubsystem->GetLight(LightScene.LightId);
406  if (CarlaLight)
407  {
408  CarlaLight->SetLightIntensity(LightScene.Intensity);
409  CarlaLight->SetLightColor(LightScene.Color);
410  CarlaLight->SetLightOn(LightScene.bOn);
411  CarlaLight->SetLightType(static_cast<ELightType>(LightScene.Type));
412  }
413  }
414 }
415 
416 // set the animation for walkers
418 {
419  SetWalkerSpeed(Walker.DatabaseId, Walker.Speed);
420 }
421 
422 // set walker bones
424 {
425  check(Episode != nullptr);
426 
427  FCarlaActor* CarlaActor = Episode->FindCarlaActor(WalkerBones.DatabaseId);
428  if (!CarlaActor) return;
429 
430  AActor* Actor = CarlaActor->GetActor();
431  auto Walker = Cast<APawn>(Actor);
432  if (!Walker) return;
433 
434  AWalkerController *Controller = Cast<AWalkerController>(Walker->GetController());
435  if (!Controller) return;
436 
437  // build bones structure
438  FWalkerBoneControlIn BonesIn;
439  for (const auto &Bone : WalkerBones.Bones)
440  {
441  FTransform Trans(FRotator::MakeFromEuler(Bone.Rotation), Bone.Location, FVector(1, 1, 1));
442  BonesIn.BoneTransforms.Add(Bone.Name, Trans);
443  }
444 
445  // set the pose and blend
446  Controller->SetBonesTransform(BonesIn);
447  Controller->BlendPose(1.0f);
448 }
449 
450 // replay finish
451 bool CarlaReplayerHelper::ProcessReplayerFinish(bool bApplyAutopilot, bool bIgnoreHero, std::unordered_map<uint32_t, bool> &IsHero)
452 {
453  // set autopilot and physics to all AI vehicles
454  const FActorRegistry& Registry = Episode->GetActorRegistry();
455  for (auto& It : Registry)
456  {
457  FCarlaActor* CarlaActor = It.Value.Get();
458 
459  // enable physics only on vehicles
460  switch (CarlaActor->GetActorType())
461  {
462 
463  // vehicles
465  // check for hero
466  if (!(bIgnoreHero && IsHero[CarlaActor->GetActorId()]))
467  {
468  // stop all vehicles
469  SetActorSimulatePhysics(CarlaActor, true);
470  SetActorVelocity(CarlaActor, FVector(0, 0, 0));
471  FVehicleControl Control;
472  Control.Throttle = 0.0f;
473  Control.Steer = 0.0f;
474  Control.Brake = 0.0f;
475  Control.bHandBrake = false;
476  Control.bReverse = false;
477  Control.Gear = 1;
478  Control.bManualGearShift = false;
479  CarlaActor->ApplyControlToVehicle(Control, EVehicleInputPriority::User);
480  }
481  break;
482 
483  // walkers
485  // stop walker
486  SetWalkerSpeed(CarlaActor->GetActorId(), 0.0f);
487  break;
488  }
489  }
490  return true;
491 }
492 
493 void CarlaReplayerHelper::SetActorVelocity(FCarlaActor *CarlaActor, FVector Velocity)
494 {
495  if (!CarlaActor)
496  {
497  return;
498  }
499  CarlaActor->SetActorTargetVelocity(Velocity);
500 }
501 
502 // set the animation speed for walkers
503 void CarlaReplayerHelper::SetWalkerSpeed(uint32_t ActorId, float Speed)
504 {
505  check(Episode != nullptr);
506  FCarlaActor * CarlaActor = Episode->FindCarlaActor(ActorId);
507  if (!CarlaActor)
508  {
509  return;
510  }
511  FWalkerControl Control;
512  Control.Speed = Speed;
513  CarlaActor->ApplyControlToWalker(Control);
514 }
515 
517 {
518  check(Episode != nullptr);
519  auto World = Episode->GetWorld();
520  for (TActorIterator<AStaticMeshActor> It(World); It; ++It)
521  {
522  auto Actor = *It;
523  check(Actor != nullptr);
524  auto MeshComponent = Actor->GetStaticMeshComponent();
525  check(MeshComponent != nullptr);
526  if (MeshComponent->Mobility == EComponentMobility::Movable)
527  {
528  Actor->Destroy();
529  }
530  }
531 }
UCarlaLight * GetLight(int Id)
FCarlaActor * FindCarlaActor(FCarlaActor::IdType ActorId)
Find a Carla actor by id.
Definition: CarlaEpisode.h:172
virtual ECarlaServerResponse SetVehicleLightState(const FVehicleLightState &)
Definition: CarlaActor.h:271
void BlendPose(float Blend)
auto end() const noexcept
A registry of all the Carla actors.
Definition: ActorRegistry.h:20
bool DestroyActor(AActor *Actor)
Definition: CarlaEpisode.h:243
FCarlaActor * FindTrafficLightAt(FVector Location)
void SetActorVelocity(FCarlaActor *CarlaActor, FVector Velocity)
void ProcessReplayerLightVehicle(CarlaRecorderLightVehicle LightVehicle)
void ProcessReplayerAnimVehicle(CarlaRecorderAnimVehicle Vehicle)
void SetElapsedTime(float InElapsedTime)
EActorAttributeType
List of valid types for actor attributes.
AActor * GetActor()
Definition: CarlaActor.h:90
EAttachmentType
Definition: ActorAttacher.h:20
bool SetActorSimulatePhysics(FCarlaActor *CarlaActor, bool bEnabled)
void SetWalkerSpeed(uint32_t ActorId, float Speed)
auto begin() const noexcept
bool ProcessReplayerStateTrafficLight(CarlaRecorderStateTrafficLight State)
Class which implements the state changing of traffic lights.
bool SetActorAutopilot(FCarlaActor *CarlaActor, bool bEnabled, bool bKeepState=false)
void ProcessReplayerWalkerBones(const CarlaRecorderWalkerBones &Walker)
void PutActorToSleep(carla::rpc::ActorId ActorId)
Definition: CarlaEpisode.h:271
void OnActorSpawned(const FCarlaActor &CarlaActor)
virtual ECarlaServerResponse ApplyControlToVehicle(const FVehicleControl &, const EVehicleInputPriority &)
Definition: CarlaActor.h:286
virtual ECarlaServerResponse SetTrafficLightState(const ETrafficLightState &)
Definition: CarlaActor.h:346
geom::Location Location
Definition: rpc/Location.h:14
const FActorRegistry & GetActorRegistry() const
Definition: CarlaEpisode.h:154
TMap< FString, FActorAttribute > Variations
User selected variations of the actor.
ECarlaServerResponse
carla::SharedPtr< cc::Actor > Actor
void ProcessReplayerLightScene(CarlaRecorderLightScene LightScene)
TPair< EActorSpawnResultStatus, FCarlaActor * > SpawnActorWithInfo(const FTransform &Transform, FActorDescription thisActorDescription, FCarlaActor::IdType DesiredId=0)
Spawns an actor based on ActorDescription at Transform.
bool ProcessReplayerFinish(bool bApplyAutopilot, bool bIgnoreHero, std::unordered_map< uint32_t, bool > &IsHero)
void SetAttachmentType(carla::rpc::AttachmentType InAttachmentType)
Definition: CarlaActor.h:140
std::pair< int, uint32_t > ProcessReplayerEventAdd(FVector Location, FVector Rotation, CarlaRecorderActorDescription Description, uint32_t DesiredId, bool bIgnoreHero, bool ReplaySensors)
virtual ECarlaServerResponse ApplyControlToWalker(const FWalkerControl &)
Definition: CarlaActor.h:386
std::vector< CarlaRecorderActorAttribute > Attributes
bool Contains(uint32 Id) const
Definition: ActorRegistry.h:64
bool ProcessReplayerPosition(CarlaRecorderPosition Pos1, CarlaRecorderPosition Pos2, double Per, double DeltaTime)
A description of a Carla Actor with all its variation.
uint32_t ActorId
Definition: ActorId.h:14
bool ProcessReplayerEventParent(uint32_t ChildId, uint32_t ParentId)
virtual ECarlaServerResponse SetActorAutopilot(bool, bool bKeepState=false)
Definition: CarlaActor.h:318
ECarlaServerResponse SetActorTargetVelocity(const FVector &Velocity)
Definition: CarlaActor.cpp:389
geom::Rotation Rotation
Definition: rpc/Transform.h:14
APawn * GetSpectatorPawn() const
Definition: CarlaEpisode.h:143
void AttachActors(AActor *Child, AActor *Parent, EAttachmentType InAttachmentType=EAttachmentType::Rigid)
Attach Child to Parent.
void AddChildren(IdType ChildId)
Definition: CarlaActor.h:125
virtual UTrafficLightController * GetTrafficLightController()
Definition: CarlaActor.h:356
static ALargeMapManager * GetLargeMapManager(const UObject *WorldContextObject)
Definition: CarlaStatics.h:100
FTransform GetActorGlobalTransform() const
Definition: CarlaActor.cpp:198
uint32 UId
UId of the definition in which this description was based.
void SetFrozenGroup(bool InFreeze)
bool IsDormant() const
Definition: CarlaActor.h:70
virtual ECarlaServerResponse SetActorSimulatePhysics(bool bEnabled)
Definition: CarlaActor.cpp:559
void SetParent(IdType InParentId)
Definition: CarlaActor.h:115
UCarlaEpisode * Episode
IdType GetActorId() const
Definition: CarlaActor.h:80
bool ProcessReplayerEventDel(uint32_t DatabaseId)
void SetBonesTransform(const FWalkerBoneControlIn &WalkerBones)
std::pair< int, FCarlaActor * > TryToCreateReplayerActor(FVector &Location, FVector &Rotation, FActorDescription &ActorDesc, uint32_t DesiredId, bool SpawnSensors)
ATrafficLightGroup * GetGroup()
Maps a controller from OpenDrive.
Defines the physical appearance of a vehicle whitch is obtained by the sensors.
An actor attribute, may be an intrinsic (non-modifiable) attribute of the actor or an user-defined ac...
bool SetCameraPosition(uint32_t Id, FVector Offset, FQuat Rotation)
void SetActorGlobalTransform(const FTransform &Transform, ETeleportType Teleport=ETeleportType::TeleportPhysics)
Definition: CarlaActor.cpp:332
std::vector< CarlaRecorderWalkerBone > Bones
FVector GetActorGlobalLocation() const
Definition: CarlaActor.cpp:239
ActorType GetActorType() const
Definition: CarlaActor.h:85
A view over an actor and its properties.
Definition: CarlaActor.h:23
void ProcessReplayerAnimWalker(CarlaRecorderAnimWalker Walker)