CARLA
CarlaRecorder.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"
19 #include "Components/BoxComponent.h"
20 
24 
25 #include "CarlaRecorder.h"
26 #include "CarlaReplayerHelper.h"
27 
28 #include <ctime>
29 #include <sstream>
30 
32 {
33  PrimaryActorTick.TickGroup = TG_PrePhysics;
34  Disable();
35 }
36 
37 ACarlaRecorder::ACarlaRecorder(const FObjectInitializer &ObjectInitializer)
38  : Super(ObjectInitializer)
39 {
40  PrimaryActorTick.TickGroup = TG_PrePhysics;
41  Disable();
42 }
43 
44 std::string ACarlaRecorder::ShowFileInfo(std::string Name, bool bShowAll)
45 {
46  return Query.QueryInfo(Name, bShowAll);
47 }
48 
49 std::string ACarlaRecorder::ShowFileCollisions(std::string Name, char Type1, char Type2)
50 {
51  return Query.QueryCollisions(Name, Type1, Type2);
52 }
53 
54 std::string ACarlaRecorder::ShowFileActorsBlocked(std::string Name, double MinTime, double MinDistance)
55 {
56  return Query.QueryBlocked(Name, MinTime, MinDistance);
57 }
58 
59 std::string ACarlaRecorder::ReplayFile(std::string Name, double TimeStart, double Duration,
60  uint32_t FollowId, bool ReplaySensors)
61 {
62  Stop();
63  return Replayer.ReplayFile(Name, TimeStart, Duration, FollowId, ReplaySensors);
64 }
65 
67 {
68  Replayer.SetTimeFactor(TimeFactor);
69 }
70 
72 {
73  Replayer.SetIgnoreHero(IgnoreHero);
74 }
75 
76 void ACarlaRecorder::StopReplayer(bool KeepActors)
77 {
78  Replayer.Stop(KeepActors);
79 }
80 
81 void ACarlaRecorder::Ticking(float DeltaSeconds)
82 {
83  TRACE_CPUPROFILER_EVENT_SCOPE(ACarlaRecorder::Ticking);
84  Super::Tick(DeltaSeconds);
85 
86  if (!Episode)
87  return;
88 
89  // check if recording
90  if (Enabled)
91  {
93  const FActorRegistry &Registry = Episode->GetActorRegistry();
94 
95  // through all actors in registry
96  for (auto It = Registry.begin(); It != Registry.end(); ++It)
97  {
98  FCarlaActor* View = It.Value().Get();
99 
100  switch (View->GetActorType())
101  {
102  // save the transform for props
104  AddActorPosition(View);
105  break;
106 
107  // save the transform of all vehicles
109  AddActorPosition(View);
110  AddVehicleAnimation(View);
111  AddVehicleLight(View);
112  if (bAdditionalData)
113  {
114  AddActorKinematics(View);
115  }
116  break;
117 
118  // save the transform of all walkers
120  AddActorPosition(View);
121  AddWalkerAnimation(View);
122  if (bAdditionalData)
123  {
124  AddActorKinematics(View);
125  }
126  break;
127 
128  // save the state of each traffic light
130  AddTrafficLightState(View);
131  break;
132  }
133  }
134 
135  // write all data for this frame
136  Write(DeltaSeconds);
137  }
138  else if (Episode->GetReplayer()->IsEnabled())
139  {
140  // replayer
141  Episode->GetReplayer()->Tick(DeltaSeconds);
142  }
143 }
144 
146 {
147  PrimaryActorTick.bCanEverTick = true;
148  Enabled = true;
149 }
150 
152 {
153  PrimaryActorTick.bCanEverTick = false;
154  Enabled = false;
155 }
156 
158 {
159  check(CarlaActor != nullptr);
160 
161  FTransform Transform = CarlaActor->GetActorGlobalTransform();
162  // get position of the vehicle
164  {
165  CarlaActor->GetActorId(),
166  Transform.GetLocation(),
167  Transform.GetRotation().Euler()
168  });
169 }
170 
172 {
173  check(CarlaActor != nullptr);
174 
175  if (CarlaActor->IsPendingKill())
176  {
177  return;
178  }
179 
180  FVehicleControl Control;
181  CarlaActor->GetVehicleControl(Control);
182 
183  // save
185  Record.DatabaseId = CarlaActor->GetActorId();
186  Record.Steering = Control.Steer;
187  Record.Throttle = Control.Throttle;
188  Record.Brake = Control.Brake;
189  Record.bHandbrake = Control.bHandBrake;
190  Record.Gear = Control.Gear;
191  AddAnimVehicle(Record);
192 }
193 
195 {
196  check(CarlaActor != nullptr);
197 
198  if (!CarlaActor->IsPendingKill())
199  {
200  FWalkerControl Control;
201  CarlaActor->GetWalkerControl(Control);
203  {
204  CarlaActor->GetActorId(),
205  Control.Speed
206  });
207  }
208 }
209 
211 {
212  check(CarlaActor != nullptr);
213 
214  ETrafficLightState LightState = CarlaActor->GetTrafficLightState();
215  UTrafficLightController* Controller = CarlaActor->GetTrafficLightController();
216  if (Controller)
217  {
218  ATrafficLightGroup* Group = Controller->GetGroup();
219  if (Group)
220  {
222  {
223  CarlaActor->GetActorId(),
224  Group->IsFrozen(),
225  Controller->GetElapsedTime(),
226  static_cast<char>(LightState)
227  });
228  }
229  }
230 }
231 
233 {
234  check(CarlaActor != nullptr);
235 
236  FVehicleLightState LightState;
237  CarlaActor->GetVehicleLightState(LightState);
238  CarlaRecorderLightVehicle LightVehicle;
239  LightVehicle.DatabaseId = CarlaActor->GetActorId();
240  LightVehicle.State = carla::rpc::VehicleLightState(LightState).light_state;
241  AddLightVehicle(LightVehicle);
242 }
243 
245 {
246  check(CarlaActor != nullptr);
247 
248  FVector Velocity, AngularVelocity;
249  constexpr float TO_METERS = 1e-2;
250  Velocity = TO_METERS* CarlaActor->GetActorVelocity();
251  AngularVelocity = CarlaActor->GetActorAngularVelocity();
252  CarlaRecorderKinematics Kinematic =
253  {
254  CarlaActor->GetActorId(),
255  Velocity,
256  AngularVelocity
257  };
258  AddKinematics(Kinematic);
259 }
261 {
262  check(CarlaActor != nullptr);
263 
264  const auto &Box = CarlaActor->GetActorInfo()->BoundingBox;
266  {
267  CarlaActor->GetActorId(),
268  {Box.Origin, Box.Extent}
269  };
270 
271  AddBoundingBox(BoundingBox);
272 }
273 
275 {
276  if (bAdditionalData)
277  {
278  TArray<UBoxComponent*> Triggers = TrafficSign.GetTriggerVolumes();
279  if(!Triggers.Num())
280  {
281  return;
282  }
283  UBoxComponent* Trigger = Triggers.Top();
284  auto VolumeOrigin = Trigger->GetComponentLocation();
285  auto VolumeExtent = Trigger->GetScaledBoxExtent();
287  {
289  {VolumeOrigin, VolumeExtent}
290  };
291  TriggerVolumes.Add(TriggerVolume);
292  }
293 }
294 
296 {
297  if (bAdditionalData)
298  {
300  Control.DatabaseId = Episode->GetActorRegistry().FindCarlaActor(&Vehicle)->GetActorId();
302  PhysicsControls.Add(Control);
303  }
304 }
305 
307 {
308  if (bAdditionalData)
309  {
310  auto DatabaseId = Episode->GetActorRegistry().FindCarlaActor(&TrafficLight)->GetActorId();
312  DatabaseId,
313  TrafficLight.GetGreenTime(),
314  TrafficLight.GetYellowTime(),
315  TrafficLight.GetRedTime()
316  };
318  }
319 }
320 
321 std::string ACarlaRecorder::Start(std::string Name, FString MapName, bool AdditionalData)
322 {
323  // stop replayer if any in course
324  if (Replayer.IsEnabled())
325  Replayer.Stop();
326 
327  // stop recording
328  Stop();
329 
330  // reset collisions Id
331  NextCollisionId = 0;
332 
333  // get the final path + filename
334  std::string Filename = GetRecorderFilename(Name);
335 
336  // binary file
337  File.open(Filename, std::ios::binary);
338  if (!File.is_open())
339  {
340  return "";
341  }
342 
343  // save info
344  Info.Version = 1;
345  Info.Magic = TEXT("CARLA_RECORDER");
346  Info.Date = std::time(0);
347  Info.Mapfile = MapName;
348 
349  // write general info
350  Info.Write(File);
351 
352  Frames.Reset();
354 
355  Enable();
356 
357  bAdditionalData = AdditionalData;
358 
359  // add all existing actors
361 
362  return std::string(Filename);
363 }
364 
366 {
367  Disable();
368 
369  if (File)
370  {
371  File.close();
372  }
373 
374  Clear();
375 }
376 
378 {
379  EventsAdd.Clear();
380  EventsDel.Clear();
382  Collisions.Clear();
383  Positions.Clear();
384  States.Clear();
385  Vehicles.Clear();
386  Walkers.Clear();
388  LightScenes.Clear();
389  Kinematics.Clear();
394 }
395 
396 void ACarlaRecorder::Write(double DeltaSeconds)
397 {
398  // update this frame data
399  Frames.SetFrame(DeltaSeconds);
400 
401  // start
403 
404  // events
409 
410  // positions and states
412  States.Write(File);
413 
414  // animations
416  Walkers.Write(File);
419 
420  // additional info
421  if (bAdditionalData)
422  {
429  }
430 
431  // end
433 
434  Clear();
435 }
436 
438 {
439  if (Enabled)
440  {
441  Positions.Add(Position);
442  }
443 }
444 
446 {
447  if (Enabled)
448  {
449  EventsAdd.Add(std::move(Event));
450  }
451 }
452 
454 {
455  if (Enabled)
456  {
457  EventsDel.Add(std::move(Event));
458  }
459 }
460 
462 {
463  if (Enabled)
464  {
465  EventsParent.Add(std::move(Event));
466  }
467 }
468 
470 {
471  if (Enabled)
472  {
474 
475  // some inits
476  Collision.Id = NextCollisionId++;
477  Collision.IsActor1Hero = false;
478  Collision.IsActor2Hero = false;
479 
480  // check actor 1
481  FCarlaActor *FoundActor1 = Episode->GetActorRegistry().FindCarlaActor(Actor1);
482  if (FoundActor1 != nullptr) {
483  if (FoundActor1->GetActorInfo() != nullptr)
484  {
485  auto Role = FoundActor1->GetActorInfo()->Description.Variations.Find("role_name");
486  if (Role != nullptr)
487  Collision.IsActor1Hero = (Role->Value == "hero");
488  }
489  Collision.DatabaseId1 = FoundActor1->GetActorId();
490  }
491  else {
492  Collision.DatabaseId1 = uint32_t(-1); // actor1 is not a registered Carla actor
493  }
494 
495  // check actor 2
496  FCarlaActor *FoundActor2 = Episode->GetActorRegistry().FindCarlaActor(Actor2);
497  if (FoundActor2 != nullptr) {
498  if (FoundActor2->GetActorInfo() != nullptr)
499  {
500  auto Role = FoundActor2->GetActorInfo()->Description.Variations.Find("role_name");
501  if (Role != nullptr)
502  Collision.IsActor2Hero = (Role->Value == "hero");
503  }
504  Collision.DatabaseId2 = FoundActor2->GetActorId();
505  }
506  else {
507  Collision.DatabaseId2 = uint32_t(-1); // actor2 is not a registered Carla actor
508  }
509 
510  Collisions.Add(std::move(Collision));
511  }
512 }
513 
515 {
516  if (Enabled)
517  {
518  States.Add(State);
519  }
520 }
521 
523 {
524  if (Enabled)
525  {
526  Vehicles.Add(Vehicle);
527  }
528 }
529 
531 {
532  if (Enabled)
533  {
534  Walkers.Add(Walker);
535  }
536 }
537 
539 {
540  if (Enabled)
541  {
542  LightVehicles.Add(LightVehicle);
543  }
544 }
545 
546 void ACarlaRecorder::AddEventLightSceneChanged(const UCarlaLight* Light)
547 {
548  if (Enabled)
549  {
550  CarlaRecorderLightScene LightScene =
551  {
552  Light->GetId(),
553  Light->GetLightIntensity(),
554  Light->GetLightColor(),
555  Light->GetLightOn(),
556  static_cast<uint8>(Light->GetLightType())
557  };
558 
559  LightScenes.Add(LightScene);
560  }
561 }
562 
564 {
565  if (Enabled)
566  {
567  Kinematics.Add(ActorKinematics);
568  }
569 }
570 
572 {
573  if (Enabled)
574  {
575  BoundingBoxes.Add(ActorBoundingBox);
576  }
577 }
578 
580 {
581  // registring all existing actors in first frame
583  for (auto& It : Registry)
584  {
585  const FCarlaActor* CarlaActor = It.Value.Get();
586  if (CarlaActor != nullptr)
587  {
588  // create event
590  CarlaActor->GetActorId(),
591  static_cast<uint8_t>(CarlaActor->GetActorType()),
592  CarlaActor->GetActorGlobalTransform(),
593  CarlaActor->GetActorInfo()->Description);
594  }
595  }
596 
597  UWorld *World = GetWorld();
598  if(World)
599  {
600  UCarlaLightSubsystem* CarlaLightSubsystem = World->GetSubsystem<UCarlaLightSubsystem>();
601  const auto& Lights = CarlaLightSubsystem->GetLights();
602  for (const auto& LightPair : Lights)
603  {
604  UCarlaLight* Light = LightPair.Value;
606  }
607  }
608 
609 }
610 
612  uint32_t DatabaseId,
613  uint8_t Type,
614  const FTransform &Transform,
615  FActorDescription ActorDescription)
616 {
617  CarlaRecorderActorDescription Description;
618  Description.UId = ActorDescription.UId;
619  Description.Id = ActorDescription.Id;
620 
621  // attributes
622  Description.Attributes.reserve(ActorDescription.Variations.Num());
623  for (const auto &item : ActorDescription.Variations)
624  {
626  Attr.Type = static_cast<uint8_t>(item.Value.Type);
627  Attr.Id = item.Value.Id;
628  Attr.Value = item.Value.Value;
629  // check for empty attributes
630  if (!Attr.Id.IsEmpty())
631  {
632  Description.Attributes.emplace_back(std::move(Attr));
633  }
634  }
635 
636  // recorder event
637  CarlaRecorderEventAdd RecEvent
638  {
639  DatabaseId,
640  Type,
641  Transform.GetTranslation(),
642  Transform.GetRotation().Euler(),
643  std::move(Description)
644  };
645  AddEvent(std::move(RecEvent));
646 
647  FCarlaActor* CarlaActor = Episode->FindCarlaActor(DatabaseId);
648  // Other events related to spawning actors
649  // check if it is a vehicle to get initial physics control
650  ACarlaWheeledVehicle* Vehicle = Cast<ACarlaWheeledVehicle>(CarlaActor->GetActor());
651  if (Vehicle)
652  {
653  AddPhysicsControl(*Vehicle);
654  }
655 
656  ATrafficLightBase* TrafficLight = Cast<ATrafficLightBase>(CarlaActor->GetActor());
657  if (TrafficLight)
658  {
659  AddTrafficLightTime(*TrafficLight);
660  }
661 
662  ATrafficSignBase* TrafficSign = Cast<ATrafficSignBase>(CarlaActor->GetActor());
663  if (TrafficSign)
664  {
665  // Trigger volume in global coordinates
666  AddTriggerVolume(*TrafficSign);
667  }
668  else
669  {
670  // Bounding box in local coordinates
671  AddActorBoundingBox(CarlaActor);
672  }
673 }
void AddEventLightSceneChanged(const UCarlaLight *Light)
FCarlaActor * FindCarlaActor(FCarlaActor::IdType ActorId)
Find a Carla actor by id.
Definition: CarlaEpisode.h:152
CarlaReplayer * GetReplayer() const
Definition: CarlaEpisode.h:281
CarlaRecorderTrafficLightTimes TrafficLightTimes
CarlaRecorderFrames Frames
CarlaRecorderQuery Query
bool IsEnabled(void)
Definition: CarlaReplayer.h:65
void Add(const CarlaRecorderAnimVehicle &InObj)
CarlaRecorderAnimVehicles Vehicles
auto end() const noexcept
std::vector< carla::rpc::LightState > GetLights(FString Client)
CarlaRecorderInfo Info
void SetTimeFactor(double NewTimeFactor)
Definition: CarlaReplayer.h:78
void StopReplayer(bool KeepActors=false)
A registry of all the Carla actors.
Definition: ActorRegistry.h:20
CarlaRecorderPlatformTime PlatformTime
void Add(const CarlaRecorderPosition &InObj)
std::string Start(std::string Name, FString MapName, bool AdditionalData=false)
FVehiclePhysicsControl GetVehiclePhysicsControl() const
TArray< UBoxComponent * > GetTriggerVolumes() const
FVector GetActorAngularVelocity() const
Definition: CarlaActor.cpp:371
virtual ETrafficLightState GetTrafficLightState() const
Definition: CarlaActor.h:351
std::string ShowFileCollisions(std::string Name, char Type1, char Type2)
virtual ECarlaServerResponse GetWalkerControl(FWalkerControl &)
Definition: CarlaActor.h:391
void Write(std::ofstream &OutFile)
CarlaReplayer Replayer
AActor * GetActor()
Definition: CarlaActor.h:90
CarlaRecorderLightScenes LightScenes
void Add(const CarlaRecorderCollision &Collision)
void AddAnimVehicle(const CarlaRecorderAnimVehicle &Vehicle)
CarlaRecorderAnimWalkers Walkers
void WriteStart(std::ofstream &OutFile)
void Add(const CarlaRecorderLightScene &InObj)
void Add(const CarlaRecorderTrafficLightTime &InObj)
void AddBoundingBox(const CarlaRecorderActorBoundingBox &ActorBoundingBox)
auto begin() const noexcept
void SetIgnoreHero(bool InIgnoreHero)
Definition: CarlaReplayer.h:84
void SetReplayerTimeFactor(double TimeFactor)
void AddAnimWalker(const CarlaRecorderAnimWalker &Walker)
void AddActorBoundingBox(FCarlaActor *CarlaActor)
Class which implements the state changing of traffic lights.
std::string ShowFileActorsBlocked(std::string Name, double MinTime=30, double MinDistance=10)
float GetGreenTime() const
void Add(const CarlaRecorderEventAdd &Event)
void AddVehicleLight(FCarlaActor *CarlaActor)
void AddEvent(const CarlaRecorderEventAdd &Event)
void Add(const CarlaRecorderStateTrafficLight &State)
void AddWalkerAnimation(FCarlaActor *CarlaActor)
void WriteEnd(std::ofstream &OutFile)
std::string QueryBlocked(std::string Filename, double MinTime=30, double MinDistance=10)
void Write(std::ofstream &OutFile)
CarlaRecorderActorBoundingBoxes BoundingBoxes
bg::model::box< Point3D > Box
Definition: InMemoryMap.h:45
void AddKinematics(const CarlaRecorderKinematics &ActorKinematics)
void Write(std::ofstream &OutFile)
void Clear(void)
void AddActorKinematics(FCarlaActor *CarlaActor)
void AddTrafficLightTime(const ATrafficLightBase &TrafficLight)
CarlaRecorderPhysicsControls PhysicsControls
CarlaRecorderLightVehicles LightVehicles
void Add(const CarlaRecorderPhysicsControl &InObj)
std::string QueryCollisions(std::string Filename, char Category1='a', char Category2='a')
void Add(const CarlaRecorderLightVehicle &InObj)
void AddCollision(AActor *Actor1, AActor *Actor2)
const FActorRegistry & GetActorRegistry() const
Definition: CarlaEpisode.h:134
void CreateRecorderEventAdd(uint32_t DatabaseId, uint8_t Type, const FTransform &Transform, FActorDescription ActorDescription)
TMap< FString, FActorAttribute > Variations
User selected variations of the actor.
CarlaRecorderEventsParent EventsParent
void Add(const CarlaRecorderActorBoundingBox &InObj)
void Add(const CarlaRecorderKinematics &InObj)
void Write(std::ofstream &File)
std::string ReplayFile(std::string Name, double TimeStart, double Duration, uint32_t FollowId, bool ReplaySensors)
UCarlaEpisode * Episode
void Write(std::ofstream &OutFile)
std::ofstream File
std::string QueryInfo(std::string Filename, bool bShowAll=false)
void SetFrame(double DeltaSeconds)
std::vector< CarlaRecorderActorAttribute > Attributes
CarlaRecorderEventsAdd EventsAdd
CarlaRecorderCollisions Collisions
void AddPosition(const CarlaRecorderPosition &Position)
void Write(std::ofstream &OutFile)
void Write(std::ofstream &OutFile)
A description of a Carla Actor with all its variation.
FVector GetActorVelocity() const
Definition: CarlaActor.cpp:359
FActorDescription Description
Definition: ActorInfo.h:26
void SetReplayerIgnoreHero(bool IgnoreHero)
const FActorInfo * GetActorInfo() const
Definition: CarlaActor.h:100
void AddTrafficLightState(FCarlaActor *CarlaActor)
FBoundingBox BoundingBox
Definition: ActorInfo.h:30
bool IsPendingKill() const
Definition: CarlaActor.h:75
float GetRedTime() const
void AddExistingActors(void)
void Ticking(float DeltaSeconds)
float GetYellowTime() const
void Write(std::ofstream &OutFile)
std::string ReplayFile(std::string Filename, double TimeStart=0.0f, double Duration=0.0f, uint32_t FollowId=0, bool ReplaySensors=false)
uint32_t NextCollisionId
CarlaRecorderActorsKinematics Kinematics
void AddVehicleAnimation(FCarlaActor *CarlaActor)
void Write(std::ofstream &OutFile)
virtual UTrafficLightController * GetTrafficLightController()
Definition: CarlaActor.h:356
std::string ShowFileInfo(std::string Name, bool bShowAll=false)
CarlaRecorderPositions Positions
void Write(std::ofstream &OutFile)
FTransform GetActorGlobalTransform() const
Definition: CarlaActor.cpp:198
void Tick(float Time)
uint32 UId
UId of the definition in which this description was based.
CarlaRecorderActorTriggerVolumes TriggerVolumes
void Write(std::ofstream &OutFile)
std::string GetRecorderFilename(std::string Filename)
CarlaRecorderEventsDel EventsDel
void Enable(void)
virtual ECarlaServerResponse GetVehicleLightState(FVehicleLightState &)
Definition: CarlaActor.h:251
virtual ECarlaServerResponse GetVehicleControl(FVehicleControl &)
Definition: CarlaActor.h:298
void Stop(bool KeepActors=false)
void Write(std::ofstream &OutFile)
IdType GetActorId() const
Definition: CarlaActor.h:80
void Add(const CarlaRecorderEventParent &Event)
void Add(const CarlaRecorderAnimWalker &InObj)
FCarlaActor * FindCarlaActor(IdType Id)
Definition: ActorRegistry.h:69
void Disable(void)
void Write(std::ofstream &OutFile)
void AddActorPosition(FCarlaActor *CarlaActor)
void AddLightVehicle(const CarlaRecorderLightVehicle &LightVehicle)
ATrafficLightGroup * GetGroup()
void Add(const CarlaRecorderActorBoundingBox &InObj)
void Add(const CarlaRecorderEventDel &Event)
flag_type light_state
Lights state flag, all turned off by default.
Base class for CARLA wheeled vehicles.
void Write(std::ofstream &OutFile)
Maps a controller from OpenDrive.
Defines the physical appearance of a vehicle whitch is obtained by the sensors.
CarlaRecorderStates States
void AddPhysicsControl(const ACarlaWheeledVehicle &Vehicle)
geom::Transform Transform
Definition: rpc/Transform.h:16
FVehiclePhysicsControl VehiclePhysicsControl
void Write(std::ofstream &OutFile)
void Write(double DeltaSeconds)
void AddTriggerVolume(const ATrafficSignBase &TrafficSign)
void AddState(const CarlaRecorderStateTrafficLight &State)
ActorType GetActorType() const
Definition: CarlaActor.h:85
A view over an actor and its properties.
Definition: CarlaActor.h:23