CARLA
Loading...
Searching...
No Matches
FrameData.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
7#include "FrameData.h"
8
19#include "Carla/Sensor/Sensor.h"
22
27
28#include <util/ue-header-guard-begin.h>
29#include "GameFramework/Character.h"
30#include "GameFramework/CharacterMovementComponent.h"
31#include <util/ue-header-guard-end.h>
32
33void FFrameData::GetFrameData(UCarlaEpisode *ThisEpisode, bool bAdditionalData, bool bIncludeActorsAgain)
34{
35 Episode = ThisEpisode;
36 // PlatformTime.UpdateTime();
37 const FActorRegistry &Registry = Episode->GetActorRegistry();
38
39 if (bIncludeActorsAgain)
40 {
42 }
43
44 // through all actors in registry
45 for (auto It = Registry.begin(); It != Registry.end(); ++It)
46 {
47 FCarlaActor* View = It->Value.Get();
48
49 if (bAdditionalData)
50 {
51 AddActorAppearance(View, bIncludeActorsAgain);
52 }
53
54 switch (View->GetActorType())
55 {
56 // save the transform for props
58 AddActorPosition(View);
59 // a prop that simulates physics moves: mirrors need its velocities
60 if (bAdditionalData && !View->IsDormant() && (View->GetActor() != nullptr))
61 {
62 const auto *Root = Cast<UPrimitiveComponent>(View->GetActor()->GetRootComponent());
63 if ((Root != nullptr) && Root->IsSimulatingPhysics())
64 {
66 }
67 }
68 break;
69
71 AddActorPosition(View);
72 if (bAdditionalData)
73 {
74 AddSensorTick(View);
75 }
76 break;
77
78 // save the transform of all vehicles
80 AddActorPosition(View);
82 AddVehicleLight(View);
83 AddVehicleParts(View);
84 if (bAdditionalData)
85 {
87 }
88 break;
89
90 // save the transform of all walkers
92 AddActorPosition(View);
94 if (bAdditionalData)
95 {
97 }
98 break;
99
100 // save the state of each traffic light
103 if (bAdditionalData)
104 {
105 // its timings too, cheap and self-healing for a secondary
106 if (const auto *TrafficLight = Cast<ATrafficLightBase>(View->GetActor()))
107 {
109 View->GetActorId(),
110 TrafficLight->GetGreenTime(),
111 TrafficLight->GetYellowTime(),
112 TrafficLight->GetRedTime()});
113 }
114 }
115 break;
116 }
117 }
118 if (bAdditionalData)
119 {
120 // Forget the appearance of the actors gone.
121 auto &Appearances = Episode->GetMultiGpuWorldState().Appearances;
122 if (Appearances.size() > static_cast<size_t>(Registry.Num()))
123 {
124 for (auto It = Appearances.begin(); It != Appearances.end();)
125 {
126 It = Registry.Contains(It->first) ? std::next(It) : Appearances.erase(It);
127 }
128 }
129 AddWorldState(bIncludeActorsAgain);
130 }
132}
133
134namespace
135{
136 CarlaRecorderWeather FFrameData_ToRecord(const FWeatherParameters &Weather)
137 {
139 Record.Cloudiness = Weather.Cloudiness;
140 Record.Precipitation = Weather.Precipitation;
141 Record.PrecipitationDeposits = Weather.PrecipitationDeposits;
142 Record.WindIntensity = Weather.WindIntensity;
143 Record.SunAzimuthAngle = Weather.SunAzimuthAngle;
144 Record.SunAltitudeAngle = Weather.SunAltitudeAngle;
145 Record.FogDensity = Weather.FogDensity;
146 Record.FogDistance = Weather.FogDistance;
147 Record.FogFalloff = Weather.FogFalloff;
148 Record.Wetness = Weather.Wetness;
149 Record.ScatteringIntensity = Weather.ScatteringIntensity;
150 Record.MieScatteringScale = Weather.MieScatteringScale;
151 Record.RayleighScatteringScale = Weather.RayleighScatteringScale;
152 Record.DustStorm = Weather.DustStorm;
153 return Record;
154 }
155
156 std::vector<uint64_t> FFrameData_SortedIds(const TSet<uint64> &Ids)
157 {
158 std::vector<uint64_t> Sorted;
159 Sorted.reserve(Ids.Num());
160 for (const uint64 Id : Ids)
161 {
162 Sorted.push_back(Id);
163 }
164 std::sort(Sorted.begin(), Sorted.end());
165 return Sorted;
166 }
167
168 TSet<uint64> FFrameData_IdSet(const std::vector<uint64_t> &Ids)
169 {
170 TSet<uint64> Set;
171 Set.Reserve(static_cast<int32>(Ids.size()));
172 for (const uint64_t Id : Ids)
173 {
174 Set.Add(Id);
175 }
176 return Set;
177 }
178
179 FWeatherParameters FFrameData_FromRecord(const CarlaRecorderWeather &Record)
180 {
183 Weather.Precipitation = Record.Precipitation;
184 Weather.PrecipitationDeposits = Record.PrecipitationDeposits;
185 Weather.WindIntensity = Record.WindIntensity;
186 Weather.SunAzimuthAngle = Record.SunAzimuthAngle;
187 Weather.SunAltitudeAngle = Record.SunAltitudeAngle;
188 Weather.FogDensity = Record.FogDensity;
189 Weather.FogDistance = Record.FogDistance;
190 Weather.FogFalloff = Record.FogFalloff;
191 Weather.Wetness = Record.Wetness;
192 Weather.ScatteringIntensity = Record.ScatteringIntensity;
193 Weather.MieScatteringScale = Record.MieScatteringScale;
194 Weather.RayleighScatteringScale = Record.RayleighScatteringScale;
195 Weather.DustStorm = Record.DustStorm;
196 return Weather;
197 }
198} // namespace
199
200void FFrameData::AddActorAppearance(FCarlaActor *CarlaActor, bool bFullResync)
201{
202 const AActor *Actor = CarlaActor->IsDormant() ? nullptr : CarlaActor->GetActor();
203 if (Actor == nullptr)
204 {
205 return;
206 }
207 FMirroredAppearance Appearance;
208 Appearance.bCollisions = Actor->GetActorEnableCollision();
209 Appearance.bHidden = Actor->IsHidden();
210 Appearance.Scale = Actor->GetActorScale3D();
212 const auto It = Sent.find(CarlaActor->GetActorId());
213 if (!bFullResync && (It != Sent.end()) && (It->second == Appearance))
214 {
215 return;
216 }
217 Sent[CarlaActor->GetActorId()] = Appearance;
219 Record.actor_id = CarlaActor->GetActorId();
220 Record.collisions = Appearance.bCollisions;
221 Record.hidden = Appearance.bHidden;
222 Record.scale = std::array<double, 3>{Appearance.Scale.X, Appearance.Scale.Y, Appearance.Scale.Z};
223 MirrorAppearances.actors.push_back(std::move(Record));
224}
225
226void FFrameData::AddWorldState(bool bFullResync)
227{
229 UWorld *World = Episode->GetWorld();
231 UCarlaLightSubsystem *LightSubsystem = World ? World->GetSubsystem<UCarlaLightSubsystem>() : nullptr;
232
233 // Applied again with the same values is still an apply to mirror.
235 {
236 if (bFullResync || (Weather->GetApplySerial() != Sent.WeatherSerial))
237 {
238 Sent.WeatherSerial = Weather->GetApplySerial();
239 Weathers.Add(FFrameData_ToRecord(Weather->GetCurrentWeather()));
240 }
241 }
242
244 if (GameMode != nullptr)
245 {
246 Globals.map_layers = static_cast<uint16_t>(GameMode->GetLoadedMapLayers());
247 Globals.imu_gravity = GameMode->IMUSensorGravity;
248 }
249 if (LightSubsystem != nullptr)
250 {
251 Globals.day_night_cycle = LightSubsystem->GetDayNightCycle();
252 Globals.has_day_time_state = LightSubsystem->GetDayTimeState(Globals.last_is_day);
253 }
254#if defined(WITH_ROS2)
255 auto ROS2 = carla::ros2::ROS2::GetInstance();
256 if (ROS2 && ROS2->IsEnabled())
257 {
258 Globals.publish_tf = ROS2->GetPublishTF();
259 }
260#endif
261 MirrorWorldGlobals = Globals;
262
263 if ((GameMode != nullptr) &&
264 (bFullResync || (GameMode->GetEnvironmentObjectsSerial() != Sent.EnvironmentObjectsSerial)))
265 {
268 FFrameData_SortedIds(GameMode->GetDisabledEnvironmentObjects());
269 }
270
271 // Each light's state at the end of this frame, after any weather change.
272 if (LightSubsystem != nullptr)
273 {
274 if (bFullResync)
275 {
276 for (const auto &Light : LightSubsystem->GetLights())
277 {
278 if (IsValid(Light.Value) && IsValid(Light.Value->GetOwner()))
279 {
280 AddEventLightSceneChanged(Light.Value);
281 }
282 }
283 }
284 else
285 {
286 for (const int32 LightId : Sent.ChangedLights)
287 {
288 UCarlaLight *Light = LightSubsystem->GetLight(LightId);
289 if (IsValid(Light) && IsValid(Light->GetOwner()))
290 {
292 }
293 }
294 }
295 }
296 Sent.ChangedLights.Reset();
297}
298
299namespace
300{
301 /// The local actor a primary id was replayed onto, if any.
302 template <typename MapT>
303 std::optional<uint32_t> FindMirror(const MapT &MappedId, uint32_t PrimaryId)
304 {
305 const auto It = MappedId.find(PrimaryId);
306 return (It != MappedId.end()) ? std::optional<uint32_t>(It->second) : std::nullopt;
307 }
308} // namespace
309
311 UCarlaEpisode *ThisEpisode,
312 std::unordered_map<uint32_t, uint32_t>& MappedId,
313 FMirrorState &MirrorState,
314 TFunctionRef<void(uint32_t, uint32_t, bool)> OnActorAdded,
315 TFunctionRef<void(uint32_t)> OnActorRemoved)
316{
317 Episode = ThisEpisode;
318 const bool bFullResync = MultiGpuFrameTime && MultiGpuFrameTime->full_resync;
319 std::unordered_set<uint32_t> AddedIds;
320
321 // First: what the rest of the frame sets can live in a map layer.
323
325 {
326 uint32_t OldId = EventAdd.DatabaseId;
327 auto Result = ProcessReplayerEventAdd(
328 EventAdd.Location,
329 EventAdd.Rotation,
330 EventAdd.Description,
331 EventAdd.DatabaseId,
332 false,
333 true,
334 MappedId);
335 switch (Result.first)
336 {
337 // actor not created
338 case 0:
339 UE_LOG(LogCarla, Log, TEXT("actor could not be created"));
340 break;
341
342 // actor created but with different id
343 case 1:
344 // mapping id (recorded Id is a new Id in replayer)
345 MappedId[OldId] = Result.second;
346 MirrorState.CreatedIds.insert(Result.second);
347 PrepareMirroredActor(Episode->FindCarlaActor(Result.second), OldId);
348 UE_LOG(LogCarla, Log, TEXT("actor created"));
349 OnActorAdded(OldId, Result.second, true);
350 break;
351
352 // actor reused from existing
353 case 2:
354 // mapping id (say desired Id is mapped to what)
355 MappedId[OldId] = Result.second;
356 PrepareMirroredActor(Episode->FindCarlaActor(Result.second), OldId);
357 UE_LOG(LogCarla, Log, TEXT("actor reused"));
358 OnActorAdded(OldId, Result.second, false);
359 break;
360 }
361 AddedIds.insert(OldId);
362 }
363
364 // Attachments, retrying those whose actors were not mirrored yet.
365 {
366 std::vector<std::pair<uint32_t, uint32_t>> Parents = std::move(MirrorState.PendingParents);
367 MirrorState.PendingParents.clear();
369 {
370 Parents.emplace_back(EventParent.DatabaseId, EventParent.DatabaseIdParent);
371 }
372 for (const auto &Parent : Parents)
373 {
374 if (!ProcessReplayerEventParent(Parent.first, Parent.second, MappedId))
375 {
376 MirrorState.PendingParents.push_back(Parent);
377 }
378 }
379 }
380
381 std::unordered_set<uint32_t> RemovedIds;
383 {
384 if (const std::optional<uint32_t> Local = FindMirror(MappedId, EventDel.DatabaseId))
385 {
387 MirrorState.CreatedIds.erase(*Local);
388 MappedId.erase(EventDel.DatabaseId);
389 }
390 RemovedIds.insert(EventDel.DatabaseId);
391 OnActorRemoved(EventDel.DatabaseId);
392 }
393
394 if (bFullResync)
395 {
396 // A full resync announces every live actor of the primary: a mirror this
397 // secondary spawned for any other one outlived its actor (its removal was
398 // missed) and goes away.
399 for (auto It = MappedId.begin(); It != MappedId.end();)
400 {
401 const uint32_t PrimaryId = It->first;
402 const uint32_t LocalId = It->second;
403 if ((AddedIds.count(PrimaryId) == 0u) && (MirrorState.CreatedIds.count(LocalId) != 0u))
404 {
406 MirrorState.CreatedIds.erase(LocalId);
407 It = MappedId.erase(It);
408 RemovedIds.insert(PrimaryId);
409 OnActorRemoved(PrimaryId);
410 }
411 else
412 {
413 ++It;
414 }
415 }
416 }
417 if (!RemovedIds.empty() || bFullResync)
418 {
419 // An attachment can no longer be replayed once either actor is gone.
420 auto &Pending = MirrorState.PendingParents;
421 Pending.erase(std::remove_if(Pending.begin(), Pending.end(), [&](const auto &Parent)
422 {
423 const auto Gone = [&](uint32_t Id)
424 {
425 return (RemovedIds.count(Id) != 0u) || (bFullResync && (AddedIds.count(Id) == 0u));
426 };
427 return Gone(Parent.first) || Gone(Parent.second);
428 }),
429 Pending.end());
430 }
431
432 PlayAppearances(MappedId);
433 PlayPositions(MappedId, MirrorState);
434 PlayKinematics(MappedId);
435
436 for (const CarlaRecorderTrafficLightTime &Time : TrafficLightTimes.GetTrafficLightTimes())
437 {
438 const std::optional<uint32_t> Local = FindMirror(MappedId, Time.DatabaseId);
439 FCarlaActor *CarlaActor = Local ? Episode->FindCarlaActor(*Local) : nullptr;
440 auto *TrafficLight = CarlaActor ? Cast<ATrafficLightBase>(CarlaActor->GetActor()) : nullptr;
441 if (TrafficLight == nullptr)
442 {
443 continue;
444 }
445 if (TrafficLight->GetGreenTime() != Time.GreenTime)
446 {
447 TrafficLight->SetGreenTime(Time.GreenTime);
448 }
449 if (TrafficLight->GetYellowTime() != Time.YellowTime)
450 {
451 TrafficLight->SetYellowTime(Time.YellowTime);
452 }
453 if (TrafficLight->GetRedTime() != Time.RedTime)
454 {
455 TrafficLight->SetRedTime(Time.RedTime);
456 }
457 }
458
459 for (const CarlaRecorderStateTrafficLight &State : States.GetStates())
460 {
461 if (const std::optional<uint32_t> Local = FindMirror(MappedId, State.DatabaseId))
462 {
463 CarlaRecorderStateTrafficLight StateTrafficLight = State;
464 StateTrafficLight.DatabaseId = *Local;
465 ProcessReplayerStateTrafficLight(StateTrafficLight);
466 }
467 }
468
469 // Before packet 8: the control replayed there takes the manual gear shift
470 // from the drivetrain set here.
471 PlayVehicleParts(MappedId);
472
473 for (const CarlaRecorderAnimVehicle &AnimVehicle : Vehicles.GetVehicles())
474 {
475 if (const std::optional<uint32_t> Local = FindMirror(MappedId, AnimVehicle.DatabaseId))
476 {
478 Vehicle.DatabaseId = *Local;
479 ProcessReplayerAnimVehicle(Vehicle);
480 }
481 }
482
483 for (const CarlaRecorderAnimWalker &AnimWalker : Walkers.GetWalkers())
484 {
485 if (const std::optional<uint32_t> Local = FindMirror(MappedId, AnimWalker.DatabaseId))
486 {
488 Walker.DatabaseId = *Local;
489 ProcessReplayerAnimWalker(Walker);
490 }
491 }
492
493 for (const CarlaRecorderAnimBiker &AnimBiker : Bikers.GetBikers())
494 {
495 if (const std::optional<uint32_t> Local = FindMirror(MappedId, AnimBiker.DatabaseId))
496 {
498 Biker.DatabaseId = *Local;
499 ProcessReplayerAnimBiker(Biker);
500 }
501 }
502
503 for (const CarlaRecorderLightVehicle &LightVehicle : LightVehicles.GetLightVehicles())
504 {
505 if (const std::optional<uint32_t> Local = FindMirror(MappedId, LightVehicle.DatabaseId))
506 {
507 CarlaRecorderLightVehicle Light = LightVehicle;
508 Light.DatabaseId = *Local;
509 ProcessReplayerLightVehicle(Light);
510 }
511 }
512
513 // Before the scene lights: a day/night change switches lights, and the
514 // lights then get the state the primary's had at the end of the frame.
515 PlayWorldState(MirrorState);
516
517 for (const CarlaRecorderLightScene &Light : LightScenes.GetLights())
518 {
519 ProcessReplayerLightScene(Light);
520 }
521
522 // Sensors last, once their mirrors exist: the state each primary sensor
523 // starts this frame's tick from, then which of them tick, with what delta.
524 const auto FindSensor = [&](uint32_t PrimaryId) -> ASensor *
525 {
526 const std::optional<uint32_t> Local = FindMirror(MappedId, PrimaryId);
527 FCarlaActor *CarlaActor = Local ? Episode->FindCarlaActor(*Local) : nullptr;
528 return CarlaActor ? Cast<ASensor>(CarlaActor->GetActor()) : nullptr;
529 };
530 for (const carla::multigpu::SensorState &State : MirrorSensorStates.states)
531 {
532 if (ASensor *Sensor = FindSensor(State.actor_id))
533 {
534 Sensor->SetMirrorState(State);
535 }
536 }
537 for (const carla::multigpu::SensorTick &Tick : MirrorSensorTicks.ticks)
538 {
539 if (ASensor *Sensor = FindSensor(Tick.actor_id))
540 {
541 Sensor->SetPrimaryTick(Tick.delta_seconds);
542 }
543 }
544
545 SetFrameCounter();
546}
547
549{
551 if (!MirrorWorldGlobals || (GameMode == nullptr))
552 {
553 return;
554 }
555 // Both flush level streaming: the layers are there for the rest of the frame.
556 const std::pair<uint16_t, uint16_t> Diff = carla::multigpu::ComputeMapLayerDiff(
557 static_cast<uint16_t>(GameMode->GetLoadedMapLayers()), MirrorWorldGlobals->map_layers);
558 if (Diff.first != 0u)
559 {
560 GameMode->LoadMapLayer(Diff.first);
561 }
562 if (Diff.second != 0u)
563 {
564 GameMode->UnLoadMapLayer(Diff.second);
565 }
566}
567
568void FFrameData::PlayAppearances(const std::unordered_map<uint32_t, uint32_t>& MappedId)
569{
571 {
572 const std::optional<uint32_t> Local = FindMirror(MappedId, Appearance.actor_id);
573 FCarlaActor *CarlaActor = Local ? Episode->FindCarlaActor(*Local) : nullptr;
574 AActor *Actor = ((CarlaActor != nullptr) && !CarlaActor->IsDormant()) ? CarlaActor->GetActor() : nullptr;
575 if (Actor == nullptr)
576 {
577 continue;
578 }
579 if (Appearance.collisions && (Actor->GetActorEnableCollision() != *Appearance.collisions))
580 {
581 Actor->SetActorEnableCollision(*Appearance.collisions);
582 }
583 if (Appearance.hidden && (Actor->IsHidden() != *Appearance.hidden))
584 {
585 Actor->SetActorHiddenInGame(*Appearance.hidden);
586 }
587 if (Appearance.scale)
588 {
589 const FVector Scale((*Appearance.scale)[0], (*Appearance.scale)[1], (*Appearance.scale)[2]);
590 if (!Actor->GetActorScale3D().Equals(Scale, 0.0))
591 {
592 USceneComponent *Root = Actor->GetRootComponent();
593 if ((Root != nullptr) && (Root->GetMobility() != EComponentMobility::Movable))
594 {
595 Root->SetMobility(EComponentMobility::Movable);
596 }
597 Actor->SetActorScale3D(Scale);
598 }
599 }
600 }
601}
602
604{
605 UWorld *World = Episode->GetWorld();
607 UCarlaLightSubsystem *LightSubsystem = World ? World->GetSubsystem<UCarlaLightSubsystem>() : nullptr;
608
610 {
612 if (GameMode != nullptr)
613 {
614 GameMode->IMUSensorGravity = Globals.imu_gravity;
615 }
616 // Before the weather, which switches lights only with the cycle on.
617 if ((LightSubsystem != nullptr) && (LightSubsystem->GetDayNightCycle() != Globals.day_night_cycle))
618 {
619 LightSubsystem->SetDayNightCycle(Globals.day_night_cycle);
620 }
621#if defined(WITH_ROS2)
622 auto ROS2 = carla::ros2::ROS2::GetInstance();
623 if (ROS2 && ROS2->IsEnabled() && (ROS2->GetPublishTF() != Globals.publish_tf))
624 {
625 ROS2->SetPublishTF(Globals.publish_tf);
626 }
627#endif
628 }
629
631 {
632 for (const CarlaRecorderWeather &Record : Weathers.GetWeathers())
633 {
634 Weather->ApplyWeather(FFrameData_FromRecord(Record));
635 }
636 }
637
638 // The day/night state the primary's lights follow, even where this
639 // server's own threshold decided otherwise.
640 if (MirrorWorldGlobals && (LightSubsystem != nullptr) &&
641 MirrorWorldGlobals->day_night_cycle && MirrorWorldGlobals->has_day_time_state)
642 {
643 bool bIsDay = true;
644 if (!LightSubsystem->GetDayTimeState(bIsDay) || (bIsDay != MirrorWorldGlobals->last_is_day))
645 {
646 LightSubsystem->NotifyDayTimeChange(MirrorWorldGlobals->last_is_day);
647 }
648 }
649
650 // Environment objects: again whenever this server registers its objects
651 // anew, for those of a layer that was still streaming in.
652 bool bApplyObjects = false;
654 {
656 bApplyObjects = true;
657 }
658 if ((GameMode != nullptr) && MirrorState.DisabledObjects &&
659 (bApplyObjects || (GameMode->GetEnvironmentObjectsRegistrations() != MirrorState.DisabledObjectsRegistrations)))
660 {
662 const auto Diff = carla::multigpu::DiffSortedIds(
663 FFrameData_SortedIds(GameMode->GetDisabledEnvironmentObjects()), *MirrorState.DisabledObjects);
664 if (!Diff.second.empty())
665 {
666 GameMode->EnableEnvironmentObjects(FFrameData_IdSet(Diff.second), true);
667 }
668 if (!Diff.first.empty())
669 {
670 GameMode->EnableEnvironmentObjects(FFrameData_IdSet(Diff.first), false);
671 }
672 }
673}
674
676 const std::unordered_map<uint32_t, uint32_t>& MappedId,
677 FMirrorState &MirrorState)
678{
679 MirrorState.PlayedPoses.clear();
680 if (MirrorPositions.positions.empty())
681 {
682 // A frame from a primary without packet 34.
684 {
685 if (const std::optional<uint32_t> Local = FindMirror(MappedId, Position.DatabaseId))
686 {
688 Pos.DatabaseId = *Local;
689 ProcessReplayerPosition(Pos, Pos, 0.0, 0.0);
690 }
691 }
692 return;
693 }
694
695 std::vector<uint32_t> LocalIds;
696 std::unordered_map<uint32_t, FTransform> Poses;
697 std::unordered_map<uint32_t, uint32_t> Parents;
698 LocalIds.reserve(MirrorPositions.positions.size());
700 {
701 const std::optional<uint32_t> Local = FindMirror(MappedId, Position.id);
702 FCarlaActor *CarlaActor = Local ? Episode->FindCarlaActor(*Local) : nullptr;
703 if (CarlaActor == nullptr)
704 {
705 continue;
706 }
707 LocalIds.push_back(*Local);
708 Poses.emplace(*Local, FTransform(
709 FQuat(Position.rotation[0], Position.rotation[1], Position.rotation[2], Position.rotation[3]),
710 FVector(Position.location[0], Position.location[1], Position.location[2])));
711 if (CarlaActor->GetParent() != 0u)
712 {
713 Parents.emplace(*Local, CarlaActor->GetParent());
714 }
715 }
716 // Parents first: moving a parent moves its attached children, which then
717 // get their own exact pose.
718 for (const uint32_t LocalId : carla::multigpu::OrderParentsFirst(LocalIds, Parents))
719 {
720 FCarlaActor *CarlaActor = Episode->FindCarlaActor(LocalId);
721 const FTransform &Pose = Poses[LocalId];
722 PlaceMirror(*CarlaActor, Pose);
723 MirrorState.PlayedPoses.emplace_back(LocalId, Pose);
724 }
725}
726
727/// What the engine reads when no CARLA code asks the episode: the mirror's
728/// movement component, vehicle motion and root velocity.
729static void FFrameData_SetMirroredMotion(FCarlaActor &CarlaActor, const FVector &Velocity)
730{
731 if (CarlaActor.IsDormant() || (CarlaActor.GetActor() == nullptr))
732 {
733 return;
734 }
735 AActor *Actor = CarlaActor.GetActor();
736 if (auto *Vehicle = Cast<ACarlaWheeledVehicle>(Actor))
737 {
738 Vehicle->SetMirroredMotion(Velocity, FVector::DotProduct(Velocity, Vehicle->GetActorForwardVector()));
739 }
740 else if (auto *Character = Cast<ACharacter>(Actor))
741 {
742 if (UCharacterMovementComponent *Movement = Character->GetCharacterMovement())
743 {
744 Movement->Velocity = Velocity;
745 }
746 }
747 if (USceneComponent *Root = Actor->GetRootComponent())
748 {
749 Root->ComponentVelocity = Velocity;
750 }
751}
752
753void FFrameData::PlayKinematics(const std::unordered_map<uint32_t, uint32_t>& MappedId)
754{
755 const uint64_t ThisFrame = FrameCounter.FrameCounter;
756 for (const CarlaRecorderKinematics &Kinematic : Kinematics.GetKinematics())
757 {
758 const std::optional<uint32_t> Local = FindMirror(MappedId, Kinematic.DatabaseId);
759 FCarlaActor *CarlaActor = Local ? Episode->FindCarlaActor(*Local) : nullptr;
760 if (CarlaActor != nullptr)
761 {
762 CarlaActor->SetMirroredKinematics(Kinematic.LinearVelocity, Kinematic.AngularVelocity, ThisFrame);
763 FFrameData_SetMirroredMotion(*CarlaActor, Kinematic.LinearVelocity);
764 }
765 }
766 // A mirror this frame carries no velocities for (a prop that came to
767 // rest) stands still, rather than keep the last ones it got.
768 for (const auto &Mapped : MappedId)
769 {
770 FCarlaActor *CarlaActor = Episode->FindCarlaActor(Mapped.second);
771 if ((CarlaActor != nullptr) && CarlaActor->HasMirroredKinematics() &&
772 (CarlaActor->GetMirroredKinematicsFrame() != ThisFrame))
773 {
774 CarlaActor->ClearMirroredKinematics();
775 FFrameData_SetMirroredMotion(*CarlaActor, FVector::ZeroVector);
776 }
777 }
778}
779
780void FFrameData::PlaceMirror(FCarlaActor &CarlaActor, FTransform Transform)
781{
782 if (CarlaActor.IsDormant())
783 {
784 if (const FActorData *Data = CarlaActor.GetActorData())
785 {
786 Transform.SetScale3D(Data->Scale);
787 }
788 CarlaActor.SetActorGlobalTransform(Transform, ETeleportType::None);
789 return;
790 }
791 AActor *Actor = CarlaActor.GetActor();
792 if (Actor == nullptr)
793 {
794 return;
795 }
796 // The primary's pose, the mirror's own scale (a spawn attribute).
797 Transform.SetScale3D(Actor->GetActorScale3D());
798 USceneComponent *Root = Actor->GetRootComponent();
799 if ((Root != nullptr) && (Root->GetMobility() != EComponentMobility::Movable))
800 {
801 // A static actor that moved on the primary: such a root refuses to move.
802 if (CarlaActor.GetActorGlobalTransform().Equals(Transform, 1e-3))
803 {
804 return;
805 }
806 Root->SetMobility(EComponentMobility::Movable);
807 }
808 // No teleport: the renderer keeps the previous pose for motion vectors.
809 CarlaActor.SetActorGlobalTransform(Transform, ETeleportType::None);
810}
811
812void FFrameData::PrepareMirroredActor(FCarlaActor *CarlaActor, uint32_t PrimaryActorId)
813{
814 if (CarlaActor == nullptr)
815 {
816 return;
817 }
818 CarlaActor->SetPrimaryActorId(PrimaryActorId);
819 switch (CarlaActor->GetActorType())
820 {
822 // ProcessReplayerEventAdd disabled its physics already.
823 break;
824
826 // No local movement: MOVE_None, so it cannot drift between frames.
827 CarlaActor->SetActorSimulatePhysics(false);
828 break;
829
831 if (!CarlaActor->IsDormant() && (CarlaActor->GetActor() != nullptr))
832 {
833 // Not FCarlaActor::SetActorSimulatePhysics, which also changes the
834 // collision settings the primary's prop has.
835 if (auto *Root = Cast<UPrimitiveComponent>(CarlaActor->GetActor()->GetRootComponent()))
836 {
837 if (Root->IsSimulatingPhysics())
838 {
839 Root->SetSimulatePhysics(false);
840 }
841 }
842 }
843 break;
844
845 default:
846 break;
847 }
848}
849
880
881static_assert(
883 "packet ids are fixed: see LibCarla/source/carla/multigpu");
884static_assert(
886 "packet ids are fixed: see LibCarla/source/carla/multigpu");
887static_assert(
889 "packet ids are fixed: see LibCarla/source/carla/multigpu");
890static_assert(
892 "packet ids are fixed: see LibCarla/source/carla/multigpu");
893static_assert(
895 "packet ids are fixed: see LibCarla/source/carla/multigpu");
896static_assert(
898 "packet ids are fixed: see LibCarla/source/carla/multigpu");
899static_assert(
901 "packet ids are fixed: see LibCarla/source/carla/multigpu");
902static_assert(
904 "packet ids are fixed: see LibCarla/source/carla/multigpu");
905
906void FFrameData::Write(std::ostream& OutStream)
907{
908 // First, so that a secondary knows the frame's time before anything else.
910 {
911 MultiGpuFrameTime->Write(OutStream);
912 }
913 EventsAdd.Write(OutStream);
914 EventsDel.Write(OutStream);
915 EventsParent.Write(OutStream);
916 MirrorPositions.Write(OutStream);
917 Kinematics.Write(OutStream);
918 States.Write(OutStream);
919 Vehicles.Write(OutStream);
920 MirrorVehicleParts.Write(OutStream);
921 Walkers.Write(OutStream);
922 Bikers.Write(OutStream);
923 LightVehicles.Write(OutStream);
924 LightScenes.Write(OutStream);
925 TrafficLightTimes.Write(OutStream);
926 Weathers.Write(OutStream);
928 {
929 MirrorWorldGlobals->Write(OutStream);
930 }
932 {
933 MirrorWorldObjects.Write(OutStream);
934 }
935 if (!MirrorAppearances.actors.empty())
936 {
937 MirrorAppearances.Write(OutStream);
938 }
939 if (!MirrorSensorStates.states.empty())
940 {
941 MirrorSensorStates.Write(OutStream);
942 }
943 // Always, even when empty: a secondary's mirrors tick only on what it lists.
944 MirrorSensorTicks.Write(OutStream);
945 FrameCounter.Write(OutStream);
946}
947
948static_assert(
950 "the frame data codec reads the frame counter itself");
951
953{
954 Clear();
956 [this](uint8_t Id, std::istream &InStream, uint32_t PacketSize)
957 {
958 switch (static_cast<CarlaRecorderPacketId>(Id))
959 {
961 EventsAdd.Read(InStream);
962 return true;
964 EventsDel.Read(InStream);
965 return true;
967 EventsParent.Read(InStream);
968 return true;
970 Positions.Read(InStream);
971 return true;
973 States.Read(InStream);
974 return true;
976 Vehicles.Read(InStream);
977 return true;
979 Walkers.Read(InStream);
980 return true;
982 MirrorVehicleParts.Read(InStream, PacketSize);
983 return true;
985 Bikers.Read(InStream);
986 return true;
988 LightVehicles.Read(InStream);
989 return true;
991 LightScenes.Read(InStream);
992 return true;
994 Kinematics.Read(InStream);
995 return true;
997 TrafficLightTimes.Read(InStream);
998 return true;
1000 Weathers.Read(InStream);
1001 return true;
1003 {
1005 // A short packet fails InStream, so the codec stops there.
1006 if (Globals.Read(InStream, PacketSize))
1007 {
1008 MirrorWorldGlobals = Globals;
1009 }
1010 return true;
1011 }
1013 MirrorWorldObjects.Read(InStream, PacketSize);
1014 return true;
1016 MirrorAppearances.Read(InStream, PacketSize);
1017 return true;
1019 bHasSensorTicks = MirrorSensorTicks.Read(InStream, PacketSize);
1020 return true;
1022 MirrorSensorStates.Read(InStream, PacketSize);
1023 return true;
1025 // A short packet fails InStream, so the codec stops there.
1026 MirrorPositions.Read(InStream, PacketSize);
1027 return true;
1029 {
1031 // A short packet fails InStream, so the codec stops there.
1032 if (Time.Read(InStream, PacketSize))
1033 {
1034 MultiGpuFrameTime = Time;
1035 }
1036 return true;
1037 }
1038 default:
1039 // Unknown here (written by another build): the codec skips it.
1040 return false;
1041 }
1042 });
1043 FrameCounter.FrameCounter = Result.frame.value_or(0u);
1044 carla::multigpu::FrameDataReadResult Checked = Result;
1046 {
1049 }
1050 return Checked;
1051}
1052
1054{
1055 Time.synchronous_mode = Settings.bSynchronousMode;
1056 Time.no_rendering_mode = Settings.bNoRenderingMode;
1057 Time.fixed_delta_seconds.reset();
1058 if (Settings.FixedDeltaSeconds.IsSet())
1059 {
1060 Time.fixed_delta_seconds = Settings.FixedDeltaSeconds.GetValue();
1061 }
1062 Time.substepping = Settings.bSubstepping;
1064 Time.max_substeps = Settings.MaxSubsteps;
1069 Time.spectator_as_ego = Settings.SpectatorAsEgo;
1071}
1072
1074{
1075 Settings.bSynchronousMode = Time.synchronous_mode;
1076 Settings.FixedDeltaSeconds.Reset();
1077 if (Time.fixed_delta_seconds)
1078 {
1079 Settings.FixedDeltaSeconds = *Time.fixed_delta_seconds;
1080 }
1081 Settings.bSubstepping = Time.substepping;
1083 Settings.MaxSubsteps = Time.max_substeps;
1088 Settings.SpectatorAsEgo = Time.spectator_as_ego;
1090}
1091
1093 uint32_t DatabaseId,
1094 uint8_t Type,
1095 const FTransform &Transform,
1096 FActorDescription ActorDescription,
1097 bool bAddOtherRelatedInfo)
1098{
1100 Description.UId = ActorDescription.UId;
1101 Description.Id = ActorDescription.Id;
1102
1103 // attributes
1104 Description.Attributes.reserve(ActorDescription.Variations.Num());
1105 for (const auto &item : ActorDescription.Variations)
1106 {
1108 Attr.Type = static_cast<uint8_t>(item.Value.Type);
1109 Attr.Id = item.Value.Id;
1110 Attr.Value = item.Value.Value;
1111 // check for empty attributes
1112 if (!Attr.Id.IsEmpty())
1113 {
1114 Description.Attributes.emplace_back(std::move(Attr));
1115 }
1116 }
1117
1118 // recorder event
1119 CarlaRecorderEventAdd RecEvent
1120 {
1121 DatabaseId,
1122 Type,
1123 Transform.GetTranslation(),
1124 Transform.GetRotation().Euler(),
1125 std::move(Description)
1126 };
1127 AddEvent(std::move(RecEvent));
1128
1129 if (!bAddOtherRelatedInfo)
1130 {
1131 return;
1132 }
1133
1134 // Other events related to spawning actors
1135 FCarlaActor* CarlaActor = Episode->FindCarlaActor(DatabaseId);
1136 if (!CarlaActor)
1137 {
1138 return;
1139 }
1140
1141 // check if it is a vehicle to get initial physics control
1142 ACarlaWheeledVehicle* Vehicle = Cast<ACarlaWheeledVehicle>(CarlaActor->GetActor());
1143 if (Vehicle)
1144 {
1146 }
1147
1148 ATrafficLightBase* TrafficLight = Cast<ATrafficLightBase>(CarlaActor->GetActor());
1149 if (TrafficLight)
1150 {
1152 }
1153
1154 ATrafficSignBase* TrafficSign = Cast<ATrafficSignBase>(CarlaActor->GetActor());
1155 if (TrafficSign)
1156 {
1157 // Trigger volume in global coordinates
1158 AddTriggerVolume(*TrafficSign);
1159 }
1160 else
1161 {
1162 // Bounding box in local coordinates
1163 AddActorBoundingBox(CarlaActor);
1164 }
1165}
1166
1167
1169{
1170 check(CarlaActor != nullptr);
1171
1172 // As a quaternion: an Euler round trip snaps pitch near +-90 degrees.
1173 const FTransform Transform = CarlaActor->GetActorGlobalTransform();
1174 const FVector Location = Transform.GetLocation();
1175 const FQuat Rotation = Transform.GetRotation();
1177 Position.id = CarlaActor->GetActorId();
1178 Position.location[0] = Location.X;
1179 Position.location[1] = Location.Y;
1180 Position.location[2] = Location.Z;
1181 Position.rotation[0] = Rotation.X;
1182 Position.rotation[1] = Rotation.Y;
1183 Position.rotation[2] = Rotation.Z;
1184 Position.rotation[3] = Rotation.W;
1186}
1187
1189{
1190 check(CarlaActor != nullptr);
1191
1192 if (CarlaActor->IsPendingKill())
1193 {
1194 return;
1195 }
1196
1197 FVehicleControl Control;
1198 CarlaActor->GetVehicleControl(Control);
1199
1200 // save
1202 Record.DatabaseId = CarlaActor->GetActorId();
1203 Record.Steering = Control.Steer;
1204 Record.Throttle = Control.Throttle;
1205 Record.Brake = Control.Brake;
1206 Record.bHandbrake = Control.bHandBrake;
1207 Record.Gear = Control.Gear;
1208 AddAnimVehicle(Record);
1209}
1210
1212{
1213 check(CarlaActor != nullptr)
1214 if (CarlaActor->IsPendingKill() || CarlaActor->IsDormant())
1215 return;
1216 if (CarlaActor->GetActorType() != FCarlaActor::ActorType::Vehicle)
1217 return;
1218
1219 ACarlaWheeledVehicle* CarlaVehicle = Cast<ACarlaWheeledVehicle>(CarlaActor->GetActor());
1220 if (CarlaVehicle == nullptr)
1221 return;
1222
1223 const UChaosWheeledVehicleMovementComponent* Movement = CarlaVehicle->GetChaosWheeledVehicleMovementComponent();
1224 if (Movement == nullptr)
1225 return;
1226
1228 Parts.actor_id = CarlaActor->GetActorId();
1229 Parts.wheels.reserve(Movement->WheelSetups.Num());
1230
1231 // Send the pose the server drew, not the Chaos output, which can be a frame apart.
1232 for (int32 i = 0; CarlaVehicle->HasWheel(i); ++i)
1233 {
1234 const FWheelAnimationData Pose = CarlaVehicle->GetDrawnWheelPose(i);
1235 Parts.wheels.push_back(carla::multigpu::WheelPose{
1236 static_cast<float>(Pose.RotOffset.Yaw),
1237 static_cast<float>(Pose.RotOffset.Pitch),
1238 static_cast<float>(-FVector::DotProduct(Pose.LocOffset, CarlaVehicle->GetWheelSuspensionAxis(i)))});
1239 }
1240 Parts.current_gear = CarlaVehicle->GetVehicleCurrentGear();
1242 const auto *Root = Cast<UPrimitiveComponent>(CarlaVehicle->GetRootComponent());
1243 Parts.simulating_physics = (Root != nullptr) && Root->IsSimulatingPhysics();
1244 for (const TPair<int32, FTransform> &Door : CarlaVehicle->GetOpenDoorPoses())
1245 {
1247 Pose.door = static_cast<uint8_t>(Door.Key);
1248 const FVector Location = Door.Value.GetLocation();
1249 const FQuat Rotation = Door.Value.GetRotation();
1250 Pose.location = {Location.X, Location.Y, Location.Z};
1251 Pose.rotation = {Rotation.X, Rotation.Y, Rotation.Z, Rotation.W};
1252 Parts.open_doors.push_back(Pose);
1253 }
1254 MirrorVehicleParts.vehicles.push_back(std::move(Parts));
1255
1256 if (CarlaVehicle->IsTwoWheeledVehicle())
1257 {
1259 {
1260 CarlaActor->GetActorId(),
1261 Movement->GetForwardSpeed(),
1262 Movement->GetEngineRotationSpeed() / Movement->GetEngineMaxRotationSpeed()
1263 });
1264 }
1265}
1266
1268{
1269 check(CarlaActor != nullptr);
1270
1271 if (!CarlaActor->IsPendingKill())
1272 {
1273 FWalkerControl Control;
1274 CarlaActor->GetWalkerControl(Control);
1276 {
1277 CarlaActor->GetActorId(),
1278 Control.Speed
1279 });
1280 }
1281}
1282
1284{
1285 check(CarlaActor != nullptr);
1286
1287 ETrafficLightState LightState = CarlaActor->GetTrafficLightState();
1288 UTrafficLightController* Controller = CarlaActor->GetTrafficLightController();
1289 if (Controller)
1290 {
1291 ATrafficLightGroup* Group = Controller->GetGroup();
1292 if (Group)
1293 {
1295 {
1296 CarlaActor->GetActorId(),
1297 Group->IsFrozen(),
1298 Controller->GetElapsedTime(),
1299 static_cast<char>(LightState)
1300 });
1301 }
1302 }
1303}
1304
1306{
1307 check(CarlaActor != nullptr);
1308
1309 FVehicleLightState LightState;
1310 CarlaActor->GetVehicleLightState(LightState);
1311 CarlaRecorderLightVehicle LightVehicle;
1312 LightVehicle.DatabaseId = CarlaActor->GetActorId();
1313 LightVehicle.State = carla::rpc::VehicleLightState(LightState).light_state;
1314 AddLightVehicle(LightVehicle);
1315}
1316
1318{
1319 check(CarlaActor != nullptr);
1320
1321 // World frame, in UE units: cm/s and rad/s (for Multi-GPU secondaries; the
1322 // .log recorder writes its own kinematics).
1323 CarlaRecorderKinematics Kinematic =
1324 {
1325 CarlaActor->GetActorId(),
1326 CarlaActor->GetActorVelocity(),
1327 FMath::DegreesToRadians(CarlaActor->GetActorAngularVelocity())
1328 };
1329 AddKinematics(Kinematic);
1330}
1331
1333{
1334 check(CarlaActor != nullptr);
1335 // Still set here: the frame is built before the sensors capture, which
1336 // clears it. Its state is therefore the one this tick starts from.
1337 const ASensor *Sensor = Cast<ASensor>(CarlaActor->GetActor());
1338 if ((Sensor == nullptr) || !Sensor->IsReadyToTick())
1339 {
1340 return;
1341 }
1342 MirrorSensorTicks.ticks.push_back(
1345 State.actor_id = CarlaActor->GetActorId();
1346 Sensor->GetMirrorState(State);
1347 if (!State.empty())
1348 {
1349 MirrorSensorStates.states.push_back(std::move(State));
1350 }
1351}
1352
1354{
1355 check(CarlaActor != nullptr);
1356
1357 const auto &Box = CarlaActor->GetActorInfo()->BoundingBox;
1359 {
1360 CarlaActor->GetActorId(),
1361 {Box.Origin, Box.Extent}
1362 };
1363
1365}
1366
1368{
1369 TArray<UBoxComponent*> Triggers = TrafficSign.GetTriggerVolumes();
1370 if(!Triggers.Num())
1371 {
1372 return;
1373 }
1374 auto CarlaActor = Episode->GetActorRegistry().FindCarlaActor(&TrafficSign);
1375 if (!CarlaActor)
1376 {
1377 return;
1378 }
1379 UBoxComponent* Trigger = Triggers.Top();
1380 auto VolumeOrigin = Trigger->GetComponentLocation();
1381 auto VolumeExtent = Trigger->GetScaledBoxExtent();
1383 {
1384 CarlaActor->GetActorId(),
1385 {VolumeOrigin, VolumeExtent}
1386 };
1388}
1389
1391{
1392 if (auto CarlaActor = Episode->GetActorRegistry().FindCarlaActor(&Vehicle))
1393 {
1395 Control.DatabaseId = CarlaActor->GetActorId();
1396 Control.VehiclePhysicsControl = Vehicle.GetVehiclePhysicsControl();
1397 PhysicsControls.Add(Control);
1398 }
1399}
1400
1402{
1403 if (auto CarlaActor = Episode->GetActorRegistry().FindCarlaActor(&TrafficLight))
1404 {
1405 auto DatabaseId = CarlaActor->GetActorId();
1407 DatabaseId,
1408 TrafficLight.GetGreenTime(),
1409 TrafficLight.GetYellowTime(),
1410 TrafficLight.GetRedTime()
1411 };
1413 }
1414}
1415
1420
1422{
1423 EventsAdd.Add(std::move(Event));
1424}
1425
1427{
1428 // An actor destroyed through the episode is reported again when the engine
1429 // destroys it; a secondary needs it once.
1430 for (const CarlaRecorderEventDel &Existing : EventsDel.GetEvents())
1431 {
1432 if (Existing.DatabaseId == Event.DatabaseId)
1433 {
1434 return;
1435 }
1436 }
1437 EventsDel.Add(std::move(Event));
1438}
1439
1441{
1442 EventsParent.Add(std::move(Event));
1443}
1444
1446{
1448
1449 // // some inits
1450 // Collision.Id = NextCollisionId++;
1451 // Collision.IsActor1Hero = false;
1452 // Collision.IsActor2Hero = false;
1453
1454 // // check actor 1
1455 // FCarlaActor *FoundActor1 = Episode->GetActorRegistry().FindCarlaActor(Actor1);
1456 // if (FoundActor1 != nullptr) {
1457 // if (FoundActor1->GetActorInfo() != nullptr)
1458 // {
1459 // auto Role = FoundActor1->GetActorInfo()->Description.Variations.Find("role_name");
1460 // if (Role != nullptr)
1461 // Collision.IsActor1Hero = (Role->Value == "hero");
1462 // }
1463 // Collision.DatabaseId1 = FoundActor1->GetActorId();
1464 // }
1465 // else {
1466 // Collision.DatabaseId1 = uint32_t(-1); // actor1 is not a registered Carla actor
1467 // }
1468
1469 // // check actor 2
1470 // FCarlaActor *FoundActor2 = Episode->GetActorRegistry().FindCarlaActor(Actor2);
1471 // if (FoundActor2 != nullptr) {
1472 // if (FoundActor2->GetActorInfo() != nullptr)
1473 // {
1474 // auto Role = FoundActor2->GetActorInfo()->Description.Variations.Find("role_name");
1475 // if (Role != nullptr)
1476 // Collision.IsActor2Hero = (Role->Value == "hero");
1477 // }
1478 // Collision.DatabaseId2 = FoundActor2->GetActorId();
1479 // }
1480 // else {
1481 // Collision.DatabaseId2 = uint32_t(-1); // actor2 is not a registered Carla actor
1482 // }
1483
1484 Collisions.Add(std::move(Collision));
1485}
1486
1491
1496
1498{
1499 Bikers.Add(Biker);
1500}
1501
1503{
1504 Walkers.Add(Walker);
1505}
1506
1508{
1509 LightVehicles.Add(LightVehicle);
1510}
1511
1512void FFrameData::AddEventLightSceneChanged(const UCarlaLight* Light)
1513{
1514 CarlaRecorderLightScene LightScene =
1515 {
1516 Light->GetId(),
1517 Light->GetLightIntensity(),
1518 Light->GetLightColor(),
1519 Light->GetLightOn(),
1520 static_cast<uint8>(Light->GetLightType())
1521 };
1522
1523 LightScenes.Add(LightScene);
1524}
1525
1527{
1528 Kinematics.Add(ActorKinematics);
1529}
1530
1532{
1533 BoundingBoxes.Add(ActorBoundingBox);
1534}
1535
1540
1541namespace
1542{
1543 // Local actors as seen by carla::multigpu::PlanReplayedActor.
1544 class FReplayedActorLookup
1545 {
1546 public:
1547 FReplayedActorLookup(UCarlaEpisode &InEpisode, const FActorDescription &InDescription, const FVector &InLocation)
1548 : Episode(InEpisode), Description(InDescription), Location(InLocation) {}
1549
1550 bool IsSameKind(uint32_t LocalId) const
1551 {
1552 const FActorInfo *Info = FindInfo(LocalId);
1553 return (Info != nullptr) && (Info->Description.Id == Description.Id);
1554 }
1555
1556 std::optional<uint32_t> FindMapActor() const
1557 {
1558 if (Description.Id == TEXT("spectator"))
1559 {
1560 APawn *Spectator = Episode.GetSpectatorPawn();
1561 const FCarlaActor *CarlaActor = (Spectator != nullptr) ? Episode.FindCarlaActor(Spectator) : nullptr;
1562 return (CarlaActor != nullptr) ? std::optional<uint32_t>(CarlaActor->GetActorId()) : std::nullopt;
1563 }
1564 if (Description.Id != TEXT("static.prop.mesh"))
1565 {
1566 return std::nullopt;
1567 }
1568 // Same truncated location as FindTrafficSignAt.
1569 const FIntVector Cell(static_cast<int32>(Location.X), static_cast<int32>(Location.Y), static_cast<int32>(Location.Z));
1570 for (auto It = Episode.GetActorRegistry().begin(); It != Episode.GetActorRegistry().end(); ++It)
1571 {
1572 const FCarlaActor *CarlaActor = It->Value.Get();
1573 if ((CarlaActor == nullptr) || !IsMapActorLike(CarlaActor->GetActorId()))
1574 {
1575 continue;
1576 }
1577 const FVector Other = CarlaActor->GetActorGlobalLocation();
1578 if (Cell == FIntVector(static_cast<int32>(Other.X), static_cast<int32>(Other.Y), static_cast<int32>(Other.Z)))
1579 {
1580 return CarlaActor->GetActorId();
1581 }
1582 }
1583 return std::nullopt;
1584 }
1585
1586 // The map registers the spectator and movable static meshes at BeginPlay
1587 // (UCarlaEpisode::InitializeAtBeginPlay); the primary resends them on a
1588 // full resync.
1589 bool IsMapActorLike(uint32_t LocalId) const
1590 {
1591 const FActorInfo *Info = FindInfo(LocalId);
1592 if ((Info == nullptr) || (Info->Description.Id != Description.Id))
1593 {
1594 return false;
1595 }
1596 if (Description.Id == TEXT("spectator"))
1597 {
1598 return true;
1599 }
1600 if (Description.Id != TEXT("static.prop.mesh"))
1601 {
1602 return false;
1603 }
1604 const FActorAttribute *Mesh = Description.Variations.Find(TEXT("mesh_path"));
1605 const FActorAttribute *OtherMesh = Info->Description.Variations.Find(TEXT("mesh_path"));
1606 return (Mesh != nullptr) && (OtherMesh != nullptr) && (Mesh->Value == OtherMesh->Value);
1607 }
1608
1609 bool Contains(uint32_t LocalId) const
1610 {
1611 return Episode.GetActorRegistry().Contains(LocalId);
1612 }
1613
1614 private:
1615 const FActorInfo *FindInfo(uint32_t LocalId) const
1616 {
1617 const FCarlaActor *CarlaActor = Episode.FindCarlaActor(LocalId);
1618 return (CarlaActor != nullptr) ? CarlaActor->GetActorInfo() : nullptr;
1619 }
1620
1621 UCarlaEpisode &Episode;
1622 const FActorDescription &Description;
1623 const FVector &Location;
1624 };
1625}
1626
1627// create or reuse an actor for replaying
1628std::pair<int, FCarlaActor*> FFrameData::CreateOrReuseActor(
1629 FVector &Location,
1630 FVector &Rotation,
1631 FActorDescription &ActorDesc,
1632 uint32_t DesiredId,
1633 bool SpawnSensors,
1634 std::unordered_map<uint32_t, uint32_t>& MappedId)
1635{
1636 check(Episode != nullptr);
1637
1638 // check type of actor we need
1639 if (ActorDesc.Id.StartsWith("traffic."))
1640 {
1641 FCarlaActor* CarlaActor = FindTrafficSignAt(Location);
1642 if (CarlaActor != nullptr)
1643 {
1644 // reuse that actor
1645 UE_LOG(LogCarla, Log, TEXT("TrafficLight found"));
1646 return std::pair<int, FCarlaActor*>(2, CarlaActor);
1647 }
1648 else
1649 {
1650 // actor not found
1651 UE_LOG(LogCarla, Log, TEXT("TrafficLight not found"));
1652 return std::pair<int, FCarlaActor*>(0, nullptr);
1653 }
1654 }
1655 else if (SpawnSensors || !ActorDesc.Id.StartsWith("sensor."))
1656 {
1658 MappedId, DesiredId, FReplayedActorLookup(*Episode, ActorDesc, Location));
1659 if (Plan.reuse)
1660 {
1661 FCarlaActor *CarlaActor = Episode->FindCarlaActor(*Plan.reuse);
1662 FRotator Rot = FRotator::MakeFromEuler(Rotation);
1663 PlaceMirror(*CarlaActor, FTransform(Rot, Location));
1664 return std::pair<int, FCarlaActor*>(2, CarlaActor);
1665 }
1666 // create new actor
1667 // create the transform
1668 FRotator Rot = FRotator::MakeFromEuler(Rotation);
1669 FTransform Trans(Rot, FVector(0, 0, 100000), FVector(1, 1, 1));
1670 // create as new actor
1671 TPair<EActorSpawnResultStatus, FCarlaActor*> Result = Episode->SpawnActorWithInfo(Trans, ActorDesc, Plan.spawn_id);
1672 if (Result.Key == EActorSpawnResultStatus::Success)
1673 {
1674 // relocate, keeping the scale the actor was spawned with (and moving
1675 // a static root, e.g. a mass-less prop, which refuses to move otherwise)
1676 PlaceMirror(*Result.Value, FTransform(Rot, Location));
1677 ALargeMapManager * LargeMapManager = UCarlaStatics::GetLargeMapManager(Episode->GetWorld());
1678 if (LargeMapManager)
1679 {
1680 LargeMapManager->OnActorSpawned(*Result.Value);
1681 }
1682 return std::pair<int, FCarlaActor*>(1, Result.Value);
1683 }
1684 else
1685 {
1686 UE_LOG(LogCarla, Log, TEXT("Actor could't be created"));
1687 return std::pair<int, FCarlaActor*>(0, Result.Value);
1688 }
1689 }
1690 else
1691 {
1692 // actor ignored
1693 return std::pair<int, FCarlaActor*>(0, nullptr);
1694 }
1695}
1696
1697// replay event for creating actor
1699 FVector Location,
1700 FVector Rotation,
1702 uint32_t DesiredId,
1703 bool bIgnoreHero,
1704 bool ReplaySensors,
1705 std::unordered_map<uint32_t, uint32_t>& MappedId)
1706{
1707 check(Episode != nullptr);
1708 FActorDescription ActorDesc;
1709 bool IsHero = false;
1710
1711 // prepare actor description
1712 ActorDesc.UId = Description.UId;
1713 ActorDesc.Id = Description.Id;
1714 for (const auto &Item : Description.Attributes)
1715 {
1716 FActorAttribute Attr;
1717 Attr.Type = static_cast<EActorAttributeType>(Item.Type);
1718 Attr.Id = Item.Id;
1719 Attr.Value = Item.Value;
1720 ActorDesc.Variations.Add(Attr.Id, std::move(Attr));
1721 // check for hero
1722 if (Item.Id == "role_name" && Item.Value == "hero")
1723 IsHero = true;
1724 }
1725
1726 auto result = CreateOrReuseActor(
1727 Location,
1728 Rotation,
1729 ActorDesc,
1730 DesiredId,
1731 ReplaySensors,
1732 MappedId);
1733
1734 if (result.first != 0)
1735 {
1736 // disable physics and autopilot on vehicles
1737 if (result.second->GetActorType() == FCarlaActor::ActorType::Vehicle)
1738 {
1739 // ignore hero ?
1740 if (!(bIgnoreHero && IsHero))
1741 {
1742 // disable physics
1743 SetActorSimulatePhysics(result.second, false);
1744 // disable autopilot
1745 // SetActorAutopilot(result.second, false, false);
1746 }
1747 else
1748 {
1749 // reenable physics just in case
1750 SetActorSimulatePhysics(result.second, true);
1751 }
1752 }
1753 return std::make_pair(result.first, result.second->GetActorId());
1754 }
1755 return std::make_pair(result.first, 0);
1756}
1757
1758// replay event for removing actor
1760{
1761 check(Episode != nullptr);
1762 FCarlaActor* CarlaActor = Episode->FindCarlaActor(DatabaseId);
1763 if (CarlaActor == nullptr)
1764 {
1765 UE_LOG(LogCarla, Log, TEXT("Actor %d not found to destroy"), DatabaseId);
1766 return false;
1767 }
1768 Episode->DestroyActor(CarlaActor->GetActorId());
1769 return true;
1770}
1771
1772// replay event for parenting actors
1774 uint32_t ChildId,
1775 uint32_t ParentId,
1776 const std::unordered_map<uint32_t, uint32_t>& MappedId)
1777{
1778 check(Episode != nullptr);
1779 const std::optional<uint32_t> LocalChild = FindMirror(MappedId, ChildId);
1780 const std::optional<uint32_t> LocalParent = FindMirror(MappedId, ParentId);
1781 FCarlaActor *Child = LocalChild ? Episode->FindCarlaActor(*LocalChild) : nullptr;
1782 FCarlaActor *Parent = LocalParent ? Episode->FindCarlaActor(*LocalParent) : nullptr;
1783 if ((Child == nullptr) || (Parent == nullptr))
1784 {
1785 return false;
1786 }
1787 // Every full resync replays every attachment: only a new one registers the
1788 // ROS 2 parent names, which pile up otherwise ("hero/hero").
1789 const bool bNewParent = (Child->GetParent() != Parent->GetActorId());
1790 Child->SetParent(Parent->GetActorId());
1792 Parent->AddChildren(Child->GetActorId());
1793 if (Parent->IsDormant())
1794 {
1795 // Putting a parent to sleep puts its children to sleep too.
1796 if (!Child->IsDormant())
1797 {
1799 }
1800 }
1801 else if (!Child->IsDormant() && (Child->GetActor() != nullptr) && (Parent->GetActor() != nullptr))
1802 {
1803 // Always rigid, keeping the child where it is: every frame sets its exact
1804 // pose (after its parent's), whatever attachment the primary used.
1805 AActor *ChildActor = Child->GetActor();
1806 AActor *ParentActor = Parent->GetActor();
1807 if (ChildActor->GetAttachParentActor() != ParentActor)
1808 {
1809 ChildActor->AttachToActor(ParentActor, FAttachmentTransformRules::KeepWorldTransform);
1810 }
1811 // Sensors read their parent's motion through their owner (the IMU). A
1812 // collision sensor binds its owner's hit event in SetOwner.
1813 if (ChildActor->GetOwner() != ParentActor)
1814 {
1815 ChildActor->SetOwner(ParentActor);
1816 }
1817 }
1818 if (bNewParent)
1819 {
1820 Episode->AddRosParentNames(*Child);
1821 }
1822 return true;
1823}
1824
1825// reposition actors
1827{
1828 check(Episode != nullptr);
1829 FCarlaActor* CarlaActor = Episode->FindCarlaActor(Pos1.DatabaseId);
1830 FVector Location;
1831 FRotator Rotation;
1832 if(CarlaActor)
1833 {
1834 // check to assign first position or interpolate between both
1835 if (Per == 0.0)
1836 {
1837 // assign position 1
1838 Location = FVector(Pos1.Location);
1839 Rotation = FRotator::MakeFromEuler(Pos1.Rotation);
1840 }
1841 else
1842 {
1843 // interpolate positions
1844 Location = FMath::Lerp(FVector(Pos1.Location), FVector(Pos2.Location), Per);
1845 Rotation = FMath::Lerp(FRotator::MakeFromEuler(Pos1.Rotation), FRotator::MakeFromEuler(Pos2.Rotation), Per);
1846 }
1847 // set new transform
1848 FTransform Trans(Rotation, Location, FVector(1, 1, 1));
1849 CarlaActor->SetActorGlobalTransform(Trans, ETeleportType::None);
1850 return true;
1851 }
1852 return false;
1853}
1854
1855// reposition the camera
1856bool FFrameData::SetCameraPosition(uint32_t Id, FVector Offset, FQuat Rotation)
1857{
1858 check(Episode != nullptr);
1859
1860 // get the actor to follow
1861 FCarlaActor* CarlaActor = Episode->FindCarlaActor(Id);
1862 if (!CarlaActor)
1863 return false;
1864 // get specator pawn
1865 APawn *Spectator = Episode->GetSpectatorPawn();
1866 if (!Spectator)
1867 return false;
1868
1869 FCarlaActor* CarlaSpectator = Episode->FindCarlaActor(Spectator);
1870 if (!CarlaSpectator)
1871 return false;
1872
1873 FTransform ActorTransform = CarlaActor->GetActorGlobalTransform();
1874 // set the new position
1875 FQuat ActorRot = ActorTransform.GetRotation();
1876 FVector Pos = ActorTransform.GetTranslation() + (ActorRot.RotateVector(Offset));
1877 CarlaSpectator->SetActorGlobalTransform(FTransform(ActorRot * Rotation, Pos, FVector(1,1,1)));
1878
1879 return true;
1880}
1881
1883{
1884 check(Episode != nullptr);
1885 FCarlaActor* CarlaActor = Episode->FindCarlaActor(State.DatabaseId);
1886 if(CarlaActor)
1887 {
1888 CarlaActor->SetTrafficLightState(static_cast<ETrafficLightState>(State.State));
1889 UTrafficLightController* Controller = CarlaActor->GetTrafficLightController();
1890 if(Controller)
1891 {
1892 Controller->SetElapsedTime(State.ElapsedTime);
1893 ATrafficLightGroup* Group = Controller->GetGroup();
1894 if (Group)
1895 {
1896 Group->SetFrozenGroup(State.IsFrozen);
1897 }
1898 }
1899 return true;
1900 }
1901 return false;
1902}
1903
1904// set the animation for Vehicles
1906{
1907 check(Episode != nullptr);
1908 FCarlaActor *CarlaActor = Episode->FindCarlaActor(Vehicle.DatabaseId);
1909 if (CarlaActor)
1910 {
1911 FVehicleControl Control;
1912 Control.Throttle = Vehicle.Throttle;
1913 Control.Steer = Vehicle.Steering;
1914 Control.Brake = Vehicle.Brake;
1915 Control.bHandBrake = Vehicle.bHandbrake;
1916 Control.bReverse = (Vehicle.Gear < 0);
1917 Control.Gear = Vehicle.Gear;
1918 const auto *CarlaVehicle = Cast<ACarlaWheeledVehicle>(CarlaActor->GetActor());
1919 Control.bManualGearShift = (CarlaVehicle != nullptr) && CarlaVehicle->GetMirroredManualGearShift();
1920 CarlaActor->ApplyControlToVehicle(Control, EVehicleInputPriority::User);
1921 }
1922}
1923
1924void FFrameData::PlayVehicleParts(const std::unordered_map<uint32_t, uint32_t>& MappedId)
1925{
1927 {
1928 const std::optional<uint32_t> Local = FindMirror(MappedId, Parts.actor_id);
1929 FCarlaActor *CarlaActor = Local ? Episode->FindCarlaActor(*Local) : nullptr;
1930 auto *CarlaVehicle = ((CarlaActor != nullptr) && !CarlaActor->IsDormant()) ?
1931 Cast<ACarlaWheeledVehicle>(CarlaActor->GetActor()) : nullptr;
1932 if (CarlaVehicle == nullptr)
1933 {
1934 continue;
1935 }
1936 // Without it the wheels cannot be posed, and roll on their own instead.
1937 if (CarlaVehicle->HasCarlaVehicleAnimation())
1938 {
1939 if (!CarlaVehicle->IsWheelAnimationOverridden())
1940 {
1941 CarlaVehicle->SetWheelAnimationOverride(true);
1942 }
1943 for (int32 i = 0; (i < static_cast<int32>(Parts.wheels.size())) && CarlaVehicle->HasWheel(i); ++i)
1944 {
1945 const EVehicleWheelLocation Location = static_cast<EVehicleWheelLocation>(i);
1946 CarlaVehicle->SetWheelSteerDirection(Location, Parts.wheels[i].steer);
1947 CarlaVehicle->SetWheelPitchAngle(Location, Parts.wheels[i].spin);
1948 CarlaVehicle->SetWheelSuspensionOffset(Location, Parts.wheels[i].suspension_offset);
1949 }
1950 }
1951 if (Parts.current_gear)
1952 {
1953 CarlaVehicle->SetMirroredDrivetrain(*Parts.current_gear, Parts.manual_gear_shift, Parts.simulating_physics);
1954 }
1955 TArray<TPair<int32, FTransform>> OpenDoors;
1956 for (const carla::multigpu::DoorPose &Door : Parts.open_doors)
1957 {
1958 OpenDoors.Emplace(Door.door, FTransform(
1959 FQuat(Door.rotation[0], Door.rotation[1], Door.rotation[2], Door.rotation[3]),
1960 FVector(Door.location[0], Door.location[1], Door.location[2])));
1961 }
1962 CarlaVehicle->SetMirroredDoorPoses(OpenDoors);
1963 }
1964}
1965
1966// set the lights for vehicles
1968{
1969 check(Episode != nullptr);
1970 FCarlaActor * CarlaActor = Episode->FindCarlaActor(LightVehicle.DatabaseId);
1971 if (CarlaActor)
1972 {
1973 carla::rpc::VehicleLightState LightState(LightVehicle.State);
1974 CarlaActor->SetVehicleLightState(FVehicleLightState(LightState));
1975 }
1976}
1977
1979{
1980 check(Episode != nullptr);
1981 UWorld* World = Episode->GetWorld();
1982 if(World)
1983 {
1984 UCarlaLightSubsystem* CarlaLightSubsystem = World->GetSubsystem<UCarlaLightSubsystem>();
1985 if (!CarlaLightSubsystem)
1986 {
1987 return;
1988 }
1989 auto* CarlaLight = CarlaLightSubsystem->GetLight(LightScene.LightId);
1990 if (CarlaLight)
1991 {
1992 // Through the call the primary's light changes take (the client's
1993 // LightManager), which several lamp blueprints handle differently from
1994 // the separate setters, with the primary's exact color.
1995 CarlaLight->SetLightState(
1996 LightScene.Intensity,
1997 LightScene.Color,
1998 static_cast<ELightType>(LightScene.Type),
1999 LightScene.bOn);
2000 }
2001 }
2002}
2003
2004// set the animation for walkers
2009
2011{
2012 check(Episode != nullptr);
2013 FCarlaActor * CarlaActor = Episode->FindCarlaActor(Biker.DatabaseId);
2014 if (CarlaActor == nullptr)
2015 return;
2016 ACarlaWheeledVehicle* CarlaVehicle = Cast<ACarlaWheeledVehicle>(CarlaActor->GetActor());
2017 check(CarlaVehicle != nullptr)
2018 CarlaVehicle->SetSpeedAnim(Biker.ForwardSpeed);
2019 CarlaVehicle->SetRotationAnim(Biker.EngineRotation);
2020}
2021
2022
2023// replay finish
2024bool FFrameData::ProcessReplayerFinish(bool bApplyAutopilot, bool bIgnoreHero, std::unordered_map<uint32_t, bool> &IsHero)
2025{
2026 // set autopilot and physics to all AI vehicles
2027 const FActorRegistry& Registry = Episode->GetActorRegistry();
2028 for (auto& It : Registry)
2029 {
2030 FCarlaActor* CarlaActor = It.Value.Get();
2031
2032 // enable physics only on vehicles
2033 switch (CarlaActor->GetActorType())
2034 {
2035
2036 // vehicles
2038 // check for hero
2039 if (!(bIgnoreHero && IsHero[CarlaActor->GetActorId()]))
2040 {
2041 // stop all vehicles
2042 SetActorSimulatePhysics(CarlaActor, true);
2043 if (auto* CarlaVehicle = Cast<ACarlaWheeledVehicle>(CarlaActor->GetActor()))
2044 {
2045 CarlaVehicle->SetWheelAnimationOverride(false);
2046 }
2047 SetActorVelocity(CarlaActor, FVector(0, 0, 0));
2048 FVehicleControl Control;
2049 Control.Throttle = 0.0f;
2050 Control.Steer = 0.0f;
2051 Control.Brake = 0.0f;
2052 Control.bHandBrake = false;
2053 Control.bReverse = false;
2054 Control.Gear = 1;
2055 Control.bManualGearShift = false;
2056 CarlaActor->ApplyControlToVehicle(Control, EVehicleInputPriority::User);
2057 }
2058 break;
2059
2060 // walkers
2062 // stop walker
2063 SetWalkerSpeed(CarlaActor->GetActorId(), 0.0f);
2064 break;
2065 }
2066 }
2067 return true;
2068}
2069
2070void FFrameData::SetActorVelocity(FCarlaActor *CarlaActor, FVector Velocity)
2071{
2072 if (!CarlaActor)
2073 {
2074 return;
2075 }
2076 CarlaActor->SetActorTargetVelocity(Velocity);
2077}
2078
2079// set the animation speed for walkers
2080void FFrameData::SetWalkerSpeed(uint32_t ActorId, float Speed)
2081{
2082 check(Episode != nullptr);
2083 FCarlaActor * CarlaActor = Episode->FindCarlaActor(ActorId);
2084 if (!CarlaActor)
2085 {
2086 return;
2087 }
2088 FWalkerControl Control;
2089 Control.Speed = Speed;
2090 CarlaActor->ApplyControlToWalker(Control);
2091}
2092
2093// enable / disable physics for an actor
2094bool FFrameData::SetActorSimulatePhysics(FCarlaActor* CarlaActor, bool bEnabled)
2095{
2096 if (!CarlaActor)
2097 {
2098 return false;
2099 }
2100 ECarlaServerResponse Response =
2101 CarlaActor->SetActorSimulatePhysics(bEnabled);
2102 if (Response != ECarlaServerResponse::Success)
2103 {
2104 return false;
2105 }
2106 return true;
2107}
2108
2113
2115{
2116 check(Episode != nullptr);
2117 auto World = Episode->GetWorld();
2118 check(World != nullptr);
2119
2120 // get its position (truncated as int's)
2121 int x = static_cast<int>(Location.X);
2122 int y = static_cast<int>(Location.Y);
2123 int z = static_cast<int>(Location.Z);
2124
2125 const FActorRegistry &Registry = Episode->GetActorRegistry();
2126 // through all actors in registry
2127 for (auto It = Registry.begin(); It != Registry.end(); ++It)
2128 {
2129 FCarlaActor* CarlaActor = It->Value.Get();
2131 {
2132 FVector vec = CarlaActor->GetActorGlobalLocation();
2133 int x2 = static_cast<int>(vec.X);
2134 int y2 = static_cast<int>(vec.Y);
2135 int z2 = static_cast<int>(vec.Z);
2136 if ((x2 == x) && (y2 == y) && (z2 == z))
2137 {
2138 // actor found
2139 return CarlaActor;
2140 }
2141 }
2142 }
2143 // actor not found
2144 return nullptr;
2145}
2146
2148{
2149 // registring all existing actors in first frame
2150 const FActorRegistry &Registry = Episode->GetActorRegistry();
2151 for (auto& It : Registry)
2152 {
2153 const FCarlaActor* CarlaActor = It.Value.Get();
2154 if (CarlaActor != nullptr)
2155 {
2156 // create event
2158 CarlaActor->GetActorId(),
2159 static_cast<uint8_t>(CarlaActor->GetActorType()),
2160 CarlaActor->GetActorGlobalTransform(),
2161 CarlaActor->GetActorInfo()->Description,
2162 false);
2163 }
2164 }
2165 // and their attachments, for a secondary that rebuilds from scratch
2166 for (auto& It : Registry)
2167 {
2168 const FCarlaActor* CarlaActor = It.Value.Get();
2169 if ((CarlaActor != nullptr) && (CarlaActor->GetParent() != 0u) &&
2170 (Registry.FindCarlaActor(CarlaActor->GetParent()) != nullptr))
2171 {
2172 AddEvent(CarlaRecorderEventParent{CarlaActor->GetActorId(), CarlaActor->GetParent()});
2173 }
2174 }
2175}
float y
float x
float z
ELightType
Definition CarlaLight.h:30
CarlaRecorderPacketId
ECarlaServerResponse
EVehicleWheelLocation
static void FFrameData_SetMirroredMotion(FCarlaActor &CarlaActor, const FVector &Velocity)
What the engine reads when no CARLA code asks the episode: the mirror's movement component,...
void FrameTimeFromSettings(const FEpisodeSettings &Settings, carla::multigpu::FrameTime &Time)
Copies the episode settings into a FrameTime and back.
void SettingsFromFrameTime(const carla::multigpu::FrameTime &Time, FEpisodeSettings &Settings)
static bool IsValid(const ACarlaWheeledVehicle *Vehicle)
EActorAttributeType
List of valid types for actor attributes.
Base class for the CARLA Game Mode.
void UnLoadMapLayer(int32 MapLayers)
uint64 GetEnvironmentObjectsRegistrations() const
How many times the environment objects were registered (on every map layer streamed in or out).
void EnableEnvironmentObjects(const TSet< uint64 > &EnvObjectIds, bool Enable)
float IMUSensorGravity
Gravitational acceleration used by IMU sensors.
void LoadMapLayer(int32 MapLayers)
uint64 GetEnvironmentObjectsSerial() const
const TSet< uint64 > & GetDisabledEnvironmentObjects() const
The registered environment objects disabled now, and a count of the changes to that set: Multi-GPU se...
int32 GetLoadedMapLayers() const
rpc::MapLayer bits of the layers loaded now.
Base class for CARLA wheeled vehicles.
UChaosWheeledVehicleMovementComponent * GetChaosWheeledVehicleMovementComponent() const
Get chaos wheeled vehicle movement component casted.
int32 GetVehicleCurrentGear() const
Active gear of the vehicle.
FVector GetWheelSuspensionAxis(int32 WheelIndex) const
Unit vector, component space, along which the wheel's suspension drops.
const FVehicleControl & GetVehicleControl() const
Vehicle control currently applied to this vehicle.
FWheelAnimationData GetDrawnWheelPose(int32 WheelIndex) const
Wheel pose the animation instance drew this frame (else GetWheelPose); what secondaries must draw.
bool HasWheel(int32 WheelIndex) const
void SetRotationAnim(float Rotation)
void SetSpeedAnim(float Speed)
TArray< TPair< int32, FTransform > > GetOpenDoorPoses() const
Every door open now (a physics body of its own while open), by door index, with its pose relative to ...
void OnActorSpawned(const FCarlaActor &CarlaActor)
virtual void GetMirrorState(carla::multigpu::SensorState &State) const
Multi-GPU: the runtime state this sensor starts its next tick from (noise generator,...
Class which implements the state changing of traffic lights.
void SetFrozenGroup(bool InFreeze)
TArray< UBoxComponent * > GetTriggerVolumes() const
void Add(const CarlaRecorderActorBoundingBox &InObj)
void Add(const CarlaRecorderActorBoundingBox &InObj)
const std::vector< CarlaRecorderKinematics > & GetKinematics() const
void Add(const CarlaRecorderKinematics &InObj)
void Write(std::ostream &OutFile)
void Write(std::ostream &OutFile) const
void Add(const CarlaRecorderAnimBiker &InObj)
void Read(std::istream &InFile)
void Write(std::ostream &OutFile)
void Read(std::istream &InFile)
void Add(const CarlaRecorderAnimVehicle &InObj)
void Add(const CarlaRecorderAnimWalker &InObj)
void Read(std::istream &InFile)
void Write(std::ostream &OutFile)
void Add(const CarlaRecorderCollision &Collision)
void Add(const CarlaRecorderEventAdd &Event)
void Read(std::istream &InFile)
void Write(std::ostream &OutFile)
const std::vector< CarlaRecorderEventAdd > & GetEvents()
void Add(const CarlaRecorderEventDel &Event)
const std::vector< CarlaRecorderEventDel > & GetEvents()
void Write(std::ostream &OutFile)
void Read(std::istream &InFile)
const std::vector< CarlaRecorderEventParent > & GetEvents()
void Write(std::ostream &OutFile)
void Read(std::istream &InFile)
void Add(const CarlaRecorderEventParent &Event)
void Add(const CarlaRecorderPhysicsControl &InObj)
const std::vector< CarlaRecorderPosition > & GetPositions()
void Add(const CarlaRecorderPosition &InObj)
void Read(std::istream &InFile)
void Write(std::ostream &OutFile)
void Add(const CarlaRecorderStateTrafficLight &State)
void Read(std::istream &InFile)
void Add(const CarlaRecorderTrafficLightTime &InObj)
void Read(std::istream &InFile)
const std::vector< CarlaRecorderWeather > & GetWeathers() const
void Write(std::ostream &OutFile)
void Add(const CarlaRecorderWeather &InObj)
A registry of all the Carla actors.
int32 Num() const
bool Contains(uint32 Id) const
auto begin() const noexcept
FCarlaActor * FindCarlaActor(IdType Id)
auto end() const noexcept
A view over an actor and its properties.
Definition CarlaActor.h:25
void SetMirroredKinematics(const FVector &Velocity, const FVector &AngularVelocityRadians, uint64 Frame)
Multi-GPU secondary: the primary's velocities of the actor this one mirrors, in the world frame (cm/s...
Definition CarlaActor.h:159
IdType GetParent() const
Definition CarlaActor.h:121
ActorType GetActorType() const
Definition CarlaActor.h:86
void ClearMirroredKinematics()
Definition CarlaActor.h:167
bool IsDormant() const
Definition CarlaActor.h:71
AActor * GetActor()
Definition CarlaActor.h:91
virtual ECarlaServerResponse SetVehicleLightState(const FVehicleLightState &)
Definition CarlaActor.h:364
bool HasMirroredKinematics() const
Definition CarlaActor.h:174
virtual ECarlaServerResponse ApplyControlToVehicle(const FVehicleControl &, const EVehicleInputPriority &)
Definition CarlaActor.h:404
FVector GetActorAngularVelocity() const
void SetParent(IdType InParentId)
Definition CarlaActor.h:116
void SetAttachmentType(carla::rpc::AttachmentType InAttachmentType)
Definition CarlaActor.h:189
uint64 GetMirroredKinematicsFrame() const
Definition CarlaActor.h:179
void SetPrimaryActorId(IdType InPrimaryActorId)
Multi-GPU secondary: the id the primary gave the actor this one mirrors.
Definition CarlaActor.h:143
virtual ECarlaServerResponse GetVehicleLightState(FVehicleLightState &)
Definition CarlaActor.h:344
FTransform GetActorGlobalTransform() const
virtual FVector GetActorVelocity() const
void SetActorGlobalTransform(const FTransform &Transform, ETeleportType Teleport=ETeleportType::TeleportPhysics)
virtual ECarlaServerResponse ApplyControlToWalker(const FWalkerControl &)
Definition CarlaActor.h:504
virtual ECarlaServerResponse GetVehicleControl(FVehicleControl &)
Definition CarlaActor.h:416
FActorData * GetActorData()
Definition CarlaActor.h:205
FVector GetActorGlobalLocation() const
bool IsPendingKill() const
Definition CarlaActor.h:76
void AddChildren(IdType ChildId)
Definition CarlaActor.h:126
virtual ETrafficLightState GetTrafficLightState() const
Definition CarlaActor.h:469
virtual UTrafficLightController * GetTrafficLightController()
Definition CarlaActor.h:474
virtual ECarlaServerResponse GetWalkerControl(FWalkerControl &)
Definition CarlaActor.h:509
const FActorInfo * GetActorInfo() const
Definition CarlaActor.h:101
IdType GetActorId() const
Definition CarlaActor.h:81
ECarlaServerResponse SetActorTargetVelocity(const FVector &Velocity)
virtual ECarlaServerResponse SetActorSimulatePhysics(bool bEnabled)
virtual ECarlaServerResponse SetTrafficLightState(const ETrafficLightState &)
Definition CarlaActor.h:464
static uint64_t GetFrameCounter()
Definition CarlaEngine.h:73
static void ResetFrameCounter(uint64_t Value=0)
Definition CarlaEngine.h:89
void AddPhysicsControl(const ACarlaWheeledVehicle &Vehicle)
void AddAnimVehicle(const CarlaRecorderAnimVehicle &Vehicle)
CarlaRecorderEventsDel EventsDel
Definition FrameData.h:126
void ProcessReplayerLightVehicle(CarlaRecorderLightVehicle LightVehicle)
bool ProcessReplayerEventDel(uint32_t DatabaseId)
CarlaRecorderLightVehicles LightVehicles
Definition FrameData.h:134
void GetFrameData(UCarlaEpisode *ThisEpisode, bool bAdditionalData=false, bool bIncludeActorsAgain=false)
Definition FrameData.cpp:33
CarlaRecorderCollisions Collisions
Definition FrameData.h:128
CarlaRecorderWeathers Weathers
Definition FrameData.h:144
std::pair< int, FCarlaActor * > CreateOrReuseActor(FVector &Location, FVector &Rotation, FActorDescription &ActorDesc, uint32_t DesiredId, bool SpawnSensors, std::unordered_map< uint32_t, uint32_t > &MappedId)
void SetActorVelocity(FCarlaActor *CarlaActor, FVector Velocity)
carla::multigpu::MirroredVehicleParts MirrorVehicleParts
Definition FrameData.h:150
bool ProcessReplayerStateTrafficLight(CarlaRecorderStateTrafficLight State)
CarlaRecorderEventsParent EventsParent
Definition FrameData.h:127
bool ProcessReplayerPosition(CarlaRecorderPosition Pos1, CarlaRecorderPosition Pos2, double Per, double DeltaTime)
void AddActorBoundingBox(FCarlaActor *CarlaActor)
bool ProcessReplayerFinish(bool bApplyAutopilot, bool bIgnoreHero, std::unordered_map< uint32_t, bool > &IsHero)
void PlaceMirror(FCarlaActor &CarlaActor, FTransform Transform)
void Write(std::ostream &OutStream)
void ProcessReplayerLightScene(CarlaRecorderLightScene LightScene)
void AddExistingActors(void)
void AddAnimBiker(const CarlaRecorderAnimBiker &Biker)
CarlaRecorderLightScenes LightScenes
Definition FrameData.h:135
void AddVehicleParts(FCarlaActor *CarlaActor)
CarlaRecorderActorTriggerVolumes TriggerVolumes
Definition FrameData.h:138
carla::multigpu::MirroredPositions MirrorPositions
Definition FrameData.h:148
void PlayKinematics(const std::unordered_map< uint32_t, uint32_t > &MappedId)
void PlayWorldState(FMirrorState &MirrorState)
CarlaRecorderAnimBikers Bikers
Definition FrameData.h:133
void SetFrameCounter()
bool SetActorSimulatePhysics(FCarlaActor *CarlaActor, bool bEnabled)
void AddState(const CarlaRecorderStateTrafficLight &State)
void ProcessReplayerAnimVehicle(CarlaRecorderAnimVehicle Vehicle)
CarlaRecorderActorBoundingBoxes BoundingBoxes
Definition FrameData.h:137
void AddCollision(AActor *Actor1, AActor *Actor2)
void AddLightVehicle(const CarlaRecorderLightVehicle &LightVehicle)
void AddVehicleAnimation(FCarlaActor *CarlaActor)
void AddVehicleLight(FCarlaActor *CarlaActor)
bool bHasSensorTicks
Definition FrameData.h:155
CarlaRecorderTrafficLightTimes TrafficLightTimes
Definition FrameData.h:141
void AddTriggerVolume(const ATrafficSignBase &TrafficSign)
CarlaRecorderAnimVehicles Vehicles
Definition FrameData.h:131
void AddSensorTick(FCarlaActor *CarlaActor)
void PlayAppearances(const std::unordered_map< uint32_t, uint32_t > &MappedId)
void ProcessReplayerAnimBiker(CarlaRecorderAnimBiker Biker)
CarlaRecorderFrameCounter FrameCounter
Definition FrameData.h:142
CarlaRecorderEventsAdd EventsAdd
Definition FrameData.h:125
bool ProcessReplayerEventParent(uint32_t ChildId, uint32_t ParentId, const std::unordered_map< uint32_t, uint32_t > &MappedId)
carla::multigpu::WorldObjects MirrorWorldObjects
Definition FrameData.h:158
void AddActorPosition(FCarlaActor *CarlaActor)
std::optional< carla::multigpu::FrameTime > MultiGpuFrameTime
Definition FrameData.h:146
void AddWalkerAnimation(FCarlaActor *CarlaActor)
void AddActorAppearance(FCarlaActor *CarlaActor, bool bFullResync)
bool SetCameraPosition(uint32_t Id, FVector Offset, FQuat Rotation)
carla::multigpu::SensorStates MirrorSensorStates
Definition FrameData.h:154
void AddTrafficLightTime(const ATrafficLightBase &TrafficLight)
void AddPosition(const CarlaRecorderPosition &Position)
void SetWalkerSpeed(uint32_t ActorId, float Speed)
CarlaRecorderPositions Positions
Definition FrameData.h:129
void PrepareMirroredActor(FCarlaActor *CarlaActor, uint32_t PrimaryActorId)
void AddActorKinematics(FCarlaActor *CarlaActor)
CarlaRecorderPhysicsControls PhysicsControls
Definition FrameData.h:140
carla::multigpu::FrameDataReadResult Read(const uint8_t *Data, size_t Size)
Parses one SEND_FRAME payload.
CarlaRecorderStates States
Definition FrameData.h:130
void ProcessReplayerAnimWalker(CarlaRecorderAnimWalker Walker)
CarlaRecorderActorsKinematics Kinematics
Definition FrameData.h:136
void AddEvent(const CarlaRecorderEventAdd &Event)
FCarlaActor * FindTrafficSignAt(FVector Location)
CarlaRecorderAnimWalkers Walkers
Definition FrameData.h:132
carla::multigpu::ActorAppearances MirrorAppearances
Definition FrameData.h:159
void GetFrameCounter()
void CreateRecorderEventAdd(uint32_t DatabaseId, uint8_t Type, const FTransform &Transform, FActorDescription ActorDescription, bool bAddOtherRelatedInfo=true)
std::pair< int, uint32_t > ProcessReplayerEventAdd(FVector Location, FVector Rotation, CarlaRecorderActorDescription Description, uint32_t DesiredId, bool bIgnoreHero, bool ReplaySensors, std::unordered_map< uint32_t, uint32_t > &MappedId)
void AddWorldState(bool bFullResync)
UCarlaEpisode * Episode
Definition FrameData.h:318
void PlayMapLayers()
void PlayPositions(const std::unordered_map< uint32_t, uint32_t > &MappedId, FMirrorState &MirrorState)
std::optional< carla::multigpu::WorldGlobals > MirrorWorldGlobals
Definition FrameData.h:157
void AddEventLightSceneChanged(const UCarlaLight *Light)
void AddAnimWalker(const CarlaRecorderAnimWalker &Walker)
void AddKinematics(const CarlaRecorderKinematics &ActorKinematics)
void PlayVehicleParts(const std::unordered_map< uint32_t, uint32_t > &MappedId)
void AddTrafficLightState(FCarlaActor *CarlaActor)
carla::multigpu::SensorTicks MirrorSensorTicks
Definition FrameData.h:153
void Clear()
void PlayFrameData(UCarlaEpisode *ThisEpisode, std::unordered_map< uint32_t, uint32_t > &MappedId, FMirrorState &MirrorState, TFunctionRef< void(uint32_t, uint32_t, bool)> OnActorAdded, TFunctionRef< void(uint32_t)> OnActorRemoved)
OnActorAdded receives (primary actor id, local actor id, whether it was just created rather than reus...
void AddBoundingBox(const CarlaRecorderActorBoundingBox &ActorBoundingBox)
A simulation episode.
FPrimaryWorldState & GetMultiGpuWorldState()
Multi-GPU primary: the world state the frames sent so far carried.
void PutActorToSleep(carla::rpc::ActorId ActorId)
FCarlaActor * FindCarlaActor(FCarlaActor::IdType ActorId)
Find a Carla actor by id.
AWeather * GetWeather() const
TPair< EActorSpawnResultStatus, FCarlaActor * > SpawnActorWithInfo(const FTransform &Transform, FActorDescription thisActorDescription, FCarlaActor::IdType DesiredId=0)
Spawns an actor based on ActorDescription at Transform.
APawn * GetSpectatorPawn() const
void AddRosParentNames(FCarlaActor &Child)
ROS 2: registers the ros_name of each of Child's ancestors as one of its parent frames.
const FActorRegistry & GetActorRegistry() const
bool DestroyActor(AActor *Actor)
std::vector< carla::rpc::LightState > GetLights(FString Client)
bool GetDayTimeState(bool &bOutIsDay) const
The day/night state last broadcast, if any.
void NotifyDayTimeChange(bool bIsDay)
Broadcast a day/night change and then re-apply the UE4->UE5 component intensity conversion on every r...
void SetDayNightCycle(const bool active)
UCarlaLight * GetLight(int Id)
static ALargeMapManager * GetLargeMapManager(const UObject *WorldContextObject)
static ACarlaGameModeBase * GetGameMode(const UObject *WorldContextObject)
Maps a controller from OpenDrive.
void SetElapsedTime(float InElapsedTime)
ATrafficLightGroup * GetGroup()
static std::shared_ptr< ROS2 > GetInstance()
Definition ROS2.h:61
Defines the physical appearance of a vehicle whitch is obtained by the sensors.
flag_type light_state
Lights state flag, all turned off by default.
@ Inconsistent
Packets that contradict each other (set by the reader's owner, e.g.
FrameDataReadResult ReadFrameData(const uint8_t *data, std::size_t size, ReadPacket &&read_packet)
Walks the packets of one frame.
ReplayedActorPlan PlanReplayedActor(const MirroredActorMap &mirrors, uint32_t primary_id, const LocalActors &local)
Where a secondary replays the add event of primary actor primary_id.
std::pair< std::vector< uint64_t >, std::vector< uint64_t > > DiffSortedIds(const std::vector< uint64_t > &current, const std::vector< uint64_t > &desired)
Ids in desired and not in current (first), and the other way round (second).
Definition worldState.h:236
constexpr uint8_t kFrameCounterPacketId
Id of the frame counter packet, the last packet of every complete frame.
std::pair< uint16_t, uint16_t > ComputeMapLayerDiff(uint16_t current, uint16_t desired)
The map layers to load and to unload to go from current to desired.
Definition worldState.h:230
std::vector< uint32_t > OrderParentsFirst(const std::vector< uint32_t > &ids, const std::unordered_map< uint32_t, uint32_t > &parents)
Order in which to place actors so that every parent is placed before its children: by attachment dept...
geom::Location Location
std::vector< CarlaRecorderActorAttribute > Attributes
void Write(std::ostream &OutFile)
void Read(std::istream &InFile)
void Write(std::ostream &OutFile)
void Add(const CarlaRecorderLightScene &InObj)
void Write(std::ostream &OutFile)
void Add(const CarlaRecorderLightVehicle &InObj)
FVehiclePhysicsControl VehiclePhysicsControl
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.
uint32 UId
UId of the definition in which this description was based.
A view over an actor and its properties.
Definition ActorInfo.h:18
FBoundingBox BoundingBox
Definition ActorInfo.h:25
FActorDescription Description
Definition ActorInfo.h:21
What a Multi-GPU secondary keeps between the primary frames it plays.
Definition FrameData.h:59
uint64 DisabledObjectsRegistrations
Definition FrameData.h:77
std::vector< std::pair< uint32_t, FTransform > > PlayedPoses
The poses the last frame played set, by local id, to check before the capture that nothing moved a mi...
Definition FrameData.h:70
std::optional< std::vector< uint64_t > > DisabledObjects
The environment objects the primary has disabled (sorted), once a frame said so, and the registration...
Definition FrameData.h:76
std::vector< std::pair< uint32_t, uint32_t > > PendingParents
Attachments not replayed yet, as (child, parent) primary ids: one of the two is not mirrored yet.
Definition FrameData.h:66
std::unordered_set< uint32_t > CreatedIds
Local ids of the mirrors this secondary spawned, as opposed to map actors it reused (traffic lights,...
Definition FrameData.h:62
An actor's appearance, as a Multi-GPU primary last sent it.
Definition FrameData.h:91
What a Multi-GPU primary remembers between the frames it sends, to send the world state only when it ...
Definition FrameData.h:106
uint64 WeatherSerial
AWeather::GetApplySerial() of the weather last sent.
Definition FrameData.h:108
TSet< int32 > ChangedLights
The scene lights changed since the last frame sent, by light id.
Definition FrameData.h:114
uint64 EnvironmentObjectsSerial
ACarlaGameModeBase::GetEnvironmentObjectsSerial() of the set last sent.
Definition FrameData.h:111
std::unordered_map< uint32_t, FMirroredAppearance > Appearances
The appearance last sent, by actor id.
Definition FrameData.h:117
An actor's appearance on the primary that a mirror does not get from its spawn attributes or pose.
Definition worldState.h:140
std::optional< bool > hidden
Definition worldState.h:144
std::optional< std::array< double, 3 > > scale
Definition worldState.h:142
std::optional< bool > collisions
Definition worldState.h:143
std::vector< ActorAppearance > actors
Definition worldState.h:158
bool Read(std::istream &in, uint32_t size)
Definition worldState.h:184
void Write(std::ostream &out) const
Definition worldState.h:160
static constexpr uint8_t kPacketId
Definition worldState.h:150
An open door, which on the primary is a physics body of its own: its pose relative to the vehicle,...
std::array< double, 3 > location
std::array< double, 4 > rotation
bool IsComplete() const
Only a complete frame may be played.
std::optional< uint64_t > frame
Value of the frame counter packet, if it was read.
uint8_t packet_id
Id, offset and declared size of the last packet looked at.
Frame data packet 25: the primary's clocks and episode settings for one frame.
Definition frameTime.h:20
bool synchronous_mode
The primary's episode settings after frame N (FEpisodeSettings, in UE units).
Definition frameTime.h:49
bool Read(std::istream &in, uint32_t size)
Reads a payload of size bytes.
Definition frameTime.h:93
static constexpr uint8_t kPacketId
Definition frameTime.h:22
std::optional< double > fixed_delta_seconds
Definition frameTime.h:51
One record of frame data packet 34: an actor's world pose as the primary holds it,...
bool Read(std::istream &in, uint32_t size)
Reads a payload of size bytes; records that grew in a newer build are read up to the fields known her...
void Write(std::ostream &out) const
static constexpr uint8_t kPacketId
std::vector< MirroredPosition > positions
static constexpr uint8_t kPacketId
std::vector< VehicleParts > vehicles
void Write(std::ostream &out) const
bool Read(std::istream &in, uint32_t size)
std::optional< uint32_t > reuse
Local actor to reuse; if empty, spawn a new one.
uint32_t spawn_id
Id to request for the new actor, 0 for a fresh one.
One record of frame data packet 27: the runtime state a sensor of the primary starts this frame's tic...
Definition sensorSync.h:87
std::vector< SensorState > states
Definition sensorSync.h:121
void Write(std::ostream &out) const
Definition sensorSync.h:123
static constexpr uint8_t kPacketId
Definition sensorSync.h:110
bool Read(std::istream &in, uint32_t size)
Definition sensorSync.h:159
One record of frame data packet 26: a sensor of the primary that ticks in this frame,...
Definition sensorSync.h:24
static constexpr uint8_t kPacketId
Definition sensorSync.h:36
std::vector< SensorTick > ticks
Definition sensorSync.h:40
void Write(std::ostream &out) const
Definition sensorSync.h:42
bool Read(std::istream &in, uint32_t size)
Definition sensorSync.h:52
A vehicle's moving parts: every wheel, by wheel index, and the doors open (any other door is closed),...
std::vector< DoorPose > open_doors
std::vector< WheelPose > wheels
std::optional< int32_t > current_gear
bool simulating_physics
Whether the primary's body simulates physics (it reports no angular velocity otherwise).
A wheel as the primary draws it: degrees and cm.
Frame data packet 28, on every frame: world-wide state a client can change on the primary that change...
Definition worldState.h:26
float imu_gravity
The IMU's gravity, m/s^2.
Definition worldState.h:36
bool publish_tf
ROS 2: whether TF frames are published.
Definition worldState.h:45
uint16_t map_layers
rpc::MapLayer bits of the layers loaded.
Definition worldState.h:33
bool Read(std::istream &in, uint32_t size)
Definition worldState.h:61
static constexpr uint8_t kPacketId
Definition worldState.h:28
bool day_night_cycle
UCarlaLightSubsystem: whether street lights follow the sun, and the last day/night state it broadcast...
Definition worldState.h:40
bool Read(std::istream &in, uint32_t size)
Definition worldState.h:112
void Write(std::ostream &out) const
Definition worldState.h:99
static constexpr uint8_t kPacketId
Definition worldState.h:86
std::optional< std::vector< uint64_t > > disabled_environment_objects
Definition worldState.h:93