41#include <util/ue-header-guard-begin.h>
42#include "Engine/Engine.h"
43#include "Engine/GameViewportClient.h"
44#include "EngineUtils.h"
45#include "GameFramework/WorldSettings.h"
46#include "HAL/FileManager.h"
47#include "HAL/IConsoleManager.h"
48#include "HAL/PlatformProcess.h"
49#include "HAL/PlatformTime.h"
51#include "Misc/FileHelper.h"
52#include "Misc/Paths.h"
53#include "PhysicsEngine/PhysicsSettings.h"
54#include "SceneInterface.h"
55#include "Engine/Engine.h"
56#include "Engine/GameViewportClient.h"
57#include <util/ue-header-guard-end.h>
73 return std::max(std::thread::hardware_concurrency(), 4u) - 2u;
78 TEXT(
"carla.MultiGpu.VerifyFrames"),
80 TEXT(
"Multi-GPU primary: read every frame sent to the secondaries back and log an error when it ")
81 TEXT(
"does not parse completely with this build (1 = on, 0 = off)."),
87 return FApp::IsBenchmarking() ? FApp::GetFixedDeltaTime() : TOptional<double>{};
92 FApp::SetBenchmarking(FixedDeltaSeconds.IsSet());
93 FApp::SetFixedDeltaTime(FixedDeltaSeconds.Get(0.0));
101 const FWorldContext *Context = (GEngine && World) ? GEngine->GetWorldContextFromWorld(World) :
nullptr;
102 return (Context !=
nullptr) && !Context->TravelURL.IsEmpty();
128 IFileManager::Get().Delete(*XODRPath,
false,
true,
true);
133 TArray<uint8> OpenDrive;
134 OpenDrive.Append(
reinterpret_cast<const uint8 *
>(Extras.
opendrive->data()),
135 static_cast<int32
>(Extras.
opendrive->size()));
136 if (!FFileHelper::SaveArrayToFile(OpenDrive, *XODRPath))
138 UE_LOG(LogCarla, Error, TEXT(
"Multi-GPU: cannot write the primary's OpenDRIVE world to %s"), *XODRPath);
149 carla::MsgPack::UnPack<carla::rpc::OpendriveGenerationParameters>(
153 catch (
const std::exception &e)
155 UE_LOG(LogCarla, Error, TEXT(
"Multi-GPU: the primary's OpenDRIVE generation parameters do not read: %s"),
156 UTF8_TO_TCHAR(e.what()));
173 FApp::SetUseFixedTimeStep(
false);
175 IFileManager::Get().DeleteDirectory(
181 #if defined(WITH_ROS2)
183 if (ROS2->IsEnabled())
200 TRACE_CPUPROFILER_EVENT_SCOPE_STR(__FUNCTION__);
208 ContentPacks->Discover();
223 TEXT(
"OpenDrive/MultiGpuSecondary-%s"), *FApp::GetInstanceId().ToString()));
228 const auto PrimaryIP = Settings.
PrimaryIP;
241 catch (
const std::exception &e)
243 UE_LOG(LogCarla, Error,
244 TEXT(
"CARLA server failed to start on RPC port %d: %s. "
245 "Another CARLA server is probably running on this port -- "
246 "close it or launch with a different -carla-rpc-port. "
248 Settings.
RPCPort, UTF8_TO_TCHAR(e.what()));
254 "ERROR: CARLA server failed to start on RPC port %d: %s. "
255 "Another CARLA server is probably running on this port -- "
256 "close it or launch with a different -carla-rpc-port.\n",
257 static_cast<int>(Settings.
RPCPort), e.what());
260 FPlatformMisc::RequestExit(
true);
280 if (!PrimaryIP.empty())
291 const auto BroadcastStreamId =
298 -> std::optional<carla::streaming::detail::stream_id_type>
301 if (Data.size() <
sizeof(PrimaryStreamId))
305 std::memcpy(&PrimaryStreamId, Data.data(),
sizeof(PrimaryStreamId));
314 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"MultiGPUCommand::SEND_FRAME");
321 bool bReportDrop =
false;
322 bool bReportFormat =
false;
336 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"FramesToProcess.emplace_back");
345 static constexpr int32 BacklogWarningThreshold = 5;
346 static constexpr int32 BacklogRecoveryThreshold = 2;
350 UE_LOG(LogCarla, Warning,
351 TEXT(
"Secondary server is falling behind the primary: %d frames queued"),
357 UE_LOG(LogCarla, Log, TEXT(
"Secondary server has caught up with the primary"));
367 static_cast<uint32_t
>(Result.
packet_id),
"(offset", Result.
offset,
"declaring",
369 "byte frame. Every server must run the same CARLA build.");
374 Result.
skipped,
"packets this build does not know (first id",
376 "packets longer than it reads. Every server must run the same CARLA build.");
383 std::string_view(
reinterpret_cast<const char *
>(Data.data()), Data.size()));
398 std::optional<carla::streaming::detail::token_type> Token;
399 if (Data.size() >=
sizeof(Request))
401 std::memcpy(&Request, Data.data(),
sizeof(Request));
406 carla::log_warning(
"multigpu: cannot provide a token for sensor actor ", Request.actor_id,
407 " (", Data.size(),
"-byte request); replying not ready");
414 carla::Buffer Reply(
reinterpret_cast<const unsigned char *
>(&*Token),
sizeof(*Token));
415 carla::log_info(
"responding with a token for port ", Token->get_port());
421 std::string msg(
"Yes, I'm alive");
422 carla::Buffer buf((
unsigned char *) msg.c_str(), (
size_t) msg.size());
429 const auto sensor_id = FindAliasedStream(Data);
434 const bool res = sensor_id.has_value();
435 carla::Buffer buf(
reinterpret_cast<const unsigned char *
>(&res),
sizeof(res));
442 const auto sensor_id = FindAliasedStream(Data);
447 const bool res = sensor_id.has_value();
448 carla::Buffer buf(
reinterpret_cast<const unsigned char *
>(&res),
sizeof(res));
455 const auto sensor_id = FindAliasedStream(Data);
457 carla::Buffer buf(
reinterpret_cast<const unsigned char *
>(&res),
sizeof(res));
465 Secondary = std::make_shared<carla::multigpu::Secondary>(PrimaryIP, PrimaryPort, CommandExecutor);
471 FApp::SetBenchmarking(
false);
476 [
this](UWorld *, ETravelFailure::Type,
const FString &Error)
479 carla::log_error(
"multigpu: failed to load the map the primary loaded:", TCHAR_TO_UTF8(*Error));
482 if (!FApp::CanEverRender())
484 UE_LOG(LogCarla, Warning,
485 TEXT(
"Multi-GPU secondary started without rendering (-nullrhi): camera sensors routed here will produce no data"));
496 UE_LOG(LogCarla, Log, TEXT(
"New secondary connection detected"));
498 if (!FApp::CanEverRender())
500 UE_LOG(LogCarla, Log,
501 TEXT(
"Rendering disabled (-nullrhi): running as a non-rendering, authority-only primary. Camera sensors need a connected rendering secondary server to produce data."));
507 #if defined(WITH_ROS2)
510 UE_LOG(LogCarla, Log, TEXT(
"ROS2: Creating ROS2 Instance..."));
512 const std::string Rmw = TCHAR_TO_UTF8(*Settings.RmwName);
516 UE_LOG(LogCarla, Error,
517 TEXT(
"ROS2: unrecognized --rmw value '%s'. Available: %s. ROS2 is DISABLED for this session."),
523 int32 DomainId = Settings.ROS2DomainId;
526 UE_LOG(LogCarla, Error,
527 TEXT(
"ROS2: --ros-domain-id=%d is out of range [%d, %d]; using the default domain."),
531 if (!ROS2->Enable(
true, Parsed.middleware, DomainId))
533 UE_LOG(LogCarla, Error,
534 TEXT(
"ROS2: --rmw='%s' is not compiled into this binary. Available: %s. ROS2 is DISABLED for this session."),
540 UE_LOG(LogCarla, Log, TEXT(
"ROS2: enabled with middleware '%s'."), *Settings.RmwName);
541 if (Settings.RmwName == TEXT(
"fastdds"))
547 const char *TransportsEnv = std::getenv(
"FASTDDS_BUILTIN_TRANSPORTS");
548 if (TransportsEnv !=
nullptr)
550 UE_LOG(LogCarla, Log,
551 TEXT(
"ROS2: Fast-DDS builtin transports set from FASTDDS_BUILTIN_TRANSPORTS='%s'."),
552 UTF8_TO_TCHAR(TransportsEnv));
556 UE_LOG(LogCarla, Log,
557 TEXT(
"ROS2: Fast-DDS transport: UDPv4 only (default; set FASTDDS_BUILTIN_TRANSPORTS=DEFAULT to re-enable shared memory)."));
567 UE_LOG(LogCarla, Log, TEXT(
"ROS2: ROS2 enabled..."));
570 UE_LOG(LogCarla, Log, TEXT(
"ROS2: ROS2 extension not build..."));
578 TRACE_CPUPROFILER_EVENT_SCOPE_STR(__FUNCTION__);
608 TrafficLightManager->SetAdjustSignsHeightToGround(
true);
613 TrafficLightManager->GetAdjustSignsHeightToGround();
659 if (
auto *Root = Cast<UPrimitiveComponent>(CarlaActor->
GetActor()->GetRootComponent()))
661 if (Root->IsSimulatingPhysics())
663 Root->SetSimulatePhysics(
false);
673 DetachFromPrimary(
"could not load the primary's map; all servers must run the same build with the same content");
679 UE_LOG(LogCarla, Warning, TEXT(
"Multi-GPU: the primary loaded %s and this secondary is on %s"),
701 for (TActorIterator<AOpenDriveGenerator> It(
CurrentEpisode->GetWorld()); It; ++It)
703 if (It->IsStreetFurnitureGenerating())
709 UE_LOG(LogCarla, Log, TEXT(
"Multi-GPU: episode content ready after %.2f s, sending EPISODE_READY"),
722 carla::log_error(
"multigpu:", Reason,
"- this secondary stops mirroring the primary until it is restarted");
735 FApp::SetUseFixedTimeStep(
false);
742 uint64_t Dropped = 0u;
754 carla::log_error(
"multigpu: dropped", Dropped,
"incomplete frames from the primary in this episode");
782 UE_LOG(LogCarla, Warning,
783 TEXT(
"Multi-GPU: ignoring replayed sensor %u (primary actor %u): the episode of the latest map load is not open here (did the level load fail?); its clients get no data until it is"),
784 LocalActorId, PrimaryActorId);
791 const bool bSensorHasStream = (Sensor !=
nullptr) && Sensor->
IsStreamReady();
792 std::optional<carla::streaming::detail::stream_id_type> OwnStreamId;
793 if (bSensorHasStream)
799 if (DormantData->Stream.IsStreamReady())
806 UE_LOG(LogCarla, Warning,
807 TEXT(
"Multi-GPU: replayed sensor %u (primary actor %u) has no stream; its clients get no data"),
808 LocalActorId, PrimaryActorId);
814 const bool bCanAdopt = bCreated && bSensorHasStream;
830 TRACE_CPUPROFILER_EVENT_SCOPE_STR(__FUNCTION__);
831 static constexpr double TimeoutSeconds = 30.0;
832 const double Start = FPlatformTime::Seconds();
833 const double Deadline = Start + TimeoutSeconds;
834 UE_LOG(LogCarla, Log, TEXT(
"Multi-GPU: waiting for secondary servers to load the new episode"));
842 if (FPlatformTime::Seconds() >= Deadline)
844 UE_LOG(LogCarla, Warning,
845 TEXT(
"Multi-GPU: secondary servers did not load the new episode within %.0f s (waited %.0f ms); ticking without waiting"),
846 TimeoutSeconds, (FPlatformTime::Seconds() - Start) * 1000.0);
852 UE_LOG(LogCarla, Log, TEXT(
"Multi-GPU: all secondary servers loaded the new episode after %.0f ms"),
853 (FPlatformTime::Seconds() - Start) * 1000.0);
858 TRACE_CPUPROFILER_EVENT_SCOPE_STR(__FUNCTION__);
859 if (TickType != ELevelTick::LEVELTICK_All)
892 TEXT(
"the primary loaded %s, which this server does not have"), *MapToLoad)));
896 UGameplayStatics::OpenLevel(
CurrentEpisode->GetWorld(), *MapToLoad,
true);
908 std::optional<FFrameData> Frame;
927 UE_LOG(LogCarla, Warning, TEXT(
"Multi-GPU: primary frame %llu, prepared for this engine frame, is gone"),
974 Time.
TimeDilation = WorldSettings ? WorldSettings->GetEffectiveTimeDilation() : 1.0f;
989 TRACE_CPUPROFILER_EVENT_SCOPE_STR(__FUNCTION__);
997 const bool bConnected =
Secondary->IsConnected();
1000 carla::log_warning(
"multigpu: lost the connection to the primary; this secondary stops mirroring "
1001 "it and runs on its own clock until it is restarted");
1007 const double Now = FPlatformTime::Seconds();
1012 UE_LOG(LogCarla, Log, TEXT(
"Multi-GPU: missed state of the primary; asking it for a resync"));
1025 State.exit_requested = IsEngineExitRequested();
1033 static constexpr double MinFrameSeconds = 1.0 / 50.0;
1035 if (Elapsed < MinFrameSeconds)
1037 FPlatformProcess::Sleep(
static_cast<float>(MinFrameSeconds - Elapsed));
1040 FApp::SetUseFixedTimeStep(
false);
1048 std::optional<uint64_t> Frame;
1049 std::optional<float> Delta;
1062 FPlatformProcess::SleepNoStats(0.0005f);
1071 Delta = Time->delta_seconds;
1081 FApp::SetUseFixedTimeStep(bTimed);
1084 FApp::SetFixedDeltaTime(
static_cast<double>(*Delta));
1091 TRACE_CPUPROFILER_EVENT_SCOPE_STR(__FUNCTION__);
1101 "s time step instead of the primary's", Time->
delta_seconds,
"s");
1134 UE_LOG(LogCarla, Log, TEXT(
"Multi-GPU: following the primary's clock from frame %llu (elapsed %.6f s)"),
1141 carla::log_warning(
"multigpu: the primary does not say which sensors tick; no sensor of this "
1142 "secondary will produce data. Every server must run the same CARLA build.");
1147 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"FramesToProcess.PlayFrameData");
1153 [
this](uint32_t PrimaryActorId, uint32_t LocalActorId,
bool bCreated)
1157 [
this](uint32_t PrimaryActorId)
1173 carla::log_warning(
"multigpu: the primary sends frames without its clock (an older build?); "
1174 "this secondary stamps them with its own. Every server must run the same CARLA build.");
1184 TRACE_CPUPROFILER_EVENT_SCOPE_STR(__FUNCTION__);
1188 if ((CarlaActor ==
nullptr) || CarlaActor->
IsDormant() || (CarlaActor->
GetActor() ==
nullptr))
1193 const FTransform &Pose = Played.second;
1196 !Current.GetLocation().Equals(Pose.GetLocation(), 1e-3) ||
1197 (Current.GetRotation().AngularDistance(Pose.GetRotation()) > FMath::DegreesToRadians(1e-4));
1203 FTransform Restored = Pose;
1204 Restored.SetScale3D(Actor->GetActorScale3D());
1207 const FName ClassName = Actor->GetClass()->GetFName();
1211 UE_LOG(LogCarla, Warning,
1212 TEXT(
"Multi-GPU: a %s mirror moved on its own between playing frame %llu and its capture; restored the primary's pose"),
1243 UE_LOG(LogCarla, Log, TEXT(
"Multi-GPU: mirroring the primary's settings (fixed delta %s, substepping %s)"),
1251 TRACE_CPUPROFILER_EVENT_SCOPE_STR(__FUNCTION__);
1256 static const bool bRenderOffScreen =
1257 FParse::Param(FCommandLine::Get(), TEXT(
"RenderOffScreen"));
1258 if (bRenderOffScreen && GEngine && GEngine->GameViewport &&
1259 !GEngine->GameViewport->bDisableWorldRendering)
1261 GEngine->GameViewport->bDisableWorldRendering =
true;
1270 if (World && World->Scene && GEngine && GEngine->GameViewport &&
1271 GEngine->GameViewport->bDisableWorldRendering)
1273 World->Scene->IncrementFrameNumber();
1281 if (EpisodeRecorder)
1283 EpisodeRecorder->
Ticking(DeltaSeconds);
1309 std::ostringstream OutStream;
1310 FrameData.
Write(OutStream);
1313 std::string Tmp(OutStream.str());
1316#if !UE_BUILD_SHIPPING
1321 Check.
Read(
reinterpret_cast<const uint8_t *
>(Tmp.data()), Tmp.size());
1324 UE_LOG(LogCarla, Error,
1325 TEXT(
"Multi-GPU: the frame sent to the secondaries does not read back: %s at packet %u (offset %llu), %u unknown and %u longer packets"),
1327 static_cast<uint32
>(Result.
packet_id),
static_cast<uint64
>(Result.
offset),
1336 if (bWasNewConnection)
1338 const std::size_t Rerouted =
SecondaryServer->GetCommander().RerouteLostSensors();
1341 UE_LOG(LogCarla, Log, TEXT(
"Multi-GPU: routed %d sensors of a lost secondary to a new one"),
1342 static_cast<int32
>(Rerouted));
1357 if ((TickType == ELevelTick::LEVELTICK_All) && (
CurrentEpisode !=
nullptr) && bCaptureThisFrame)
1365 bool LightUpdatePending =
false;
1369 if (CarlaLightSubsystem)
1392 static const TCHAR *CVarName = TEXT(
"p.Chaos.AccelerationStructureUseDynamicTree");
1393 IConsoleVariable *CVar = IConsoleManager::Get().FindConsoleVariable(CVarName);
1394 if (CVar ==
nullptr)
1398 UE_LOG(LogCarla, Warning, TEXT(
"%s not found: collisions are not deterministic"), CVarName);
1408 CVar->Set(0, ECVF_SetByCode);
1425 if (GEngine && GEngine->GameViewport)
1429 GEngine->GameViewport->bDisableWorldRendering = Settings.
bNoRenderingMode ||
1430 FParse::Param(FCommandLine::Get(), TEXT(
"RenderOffScreen"));
1445 UPhysicsSettings* PhysSett = UPhysicsSettings::Get();
1452 if (LargeMapManager)
static void FCarlaEngine_SetFixedDeltaSeconds(TOptional< double > FixedDeltaSeconds)
static bool FCarlaEngine_IsWorldTravelPending(const UWorld *World)
Whether a travel to another map is scheduled for World: load_world() only schedules it,...
static void FCarlaEngine_PrepareGeneratedWorld(UWorld *World, const carla::multigpu::LoadMapExtras &Extras)
Multi-GPU secondary: the world the primary generated from OpenDRIVE, where this server's OpenDriveMap...
static TAutoConsoleVariable< int32 > CVarCarlaMultiGpuVerifyFrames(TEXT("carla.MultiGpu.VerifyFrames"), 1, TEXT("does not parse completely with this build (1 = on, 0 = off)."), ECVF_Default)
static uint32 FCarlaEngine_GetNumberOfThreadsForRPCServer()
static bool FCarlaEngine_SameSettings(const FEpisodeSettings &A, const FEpisodeSettings &B)
static TOptional< double > FCarlaEngine_GetFixedDeltaSeconds()
FDataStreamTmpl< carla::streaming::Stream > FDataStream
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)
Base class for the CARLA Game Mode.
ATrafficLightManager * GetTrafficLightManager()
void Ticking(float DeltaSeconds)
CarlaReplayer * GetReplayer(void)
void SetEpisode(UCarlaEpisode *ThisEpisode)
float GetLayerStreamingDistance() const
void SetActorStreamingDistance(float Distance)
void SetLayerStreamingDistance(float Distance)
float GetActorStreamingDistance() const
auto GetToken() const
Return the token that allows subscribing to this sensor's stream.
void SetDataStream(FDataStream InStream)
Replace the FDataStream associated with this sensor.
Class In charge of creating and assigning traffic light groups, controllers and components.
void CheckPlayAfterMapLoaded(void)
A view over an actor and its properties.
ActorType GetActorType() const
FTransform GetActorGlobalTransform() const
void SetActorGlobalTransform(const FTransform &Transform, ETeleportType Teleport=ETeleportType::TeleportPhysics)
FActorData * GetActorData()
void SendEpisodeReadyWhenContentReady()
Sends EPISODE_READY once the world's generated content has finished spawning.
void OnEpisodeSettingsChanged(const FEpisodeSettings &Settings)
FDelegateHandle OnEpisodeSettingsChangeHandle
std::shared_ptr< carla::multigpu::Router > SecondaryServer
std::atomic< size_t > QueuedFrames
std::mutex FrameToProcessMutex
void OnPreTick(UWorld *World, ELevelTick TickType, float DeltaSeconds)
TSet< FName > RestoredPoseClasses
bool bWarnedSensorBindRefused
static uint64_t FrameCounter
carla::multigpu::SensorStreamRegistry::epoch_type PendingLoadEpoch
static uint64_t GetFrameCounter()
void ResetSimulationState()
void MirrorPrimarySettings(const carla::multigpu::FrameTime &Time)
FWorldObserver WorldObserver
FDelegateHandle OnBeginFrameHandle
static void ResetFrameCounter(uint64_t Value=0)
bool bWarnedNoSensorTicks
void OnBeginFrame()
Secondary only (FCoreDelegates::OnBeginFrame, before the engine computes this frame's delta): waits f...
std::atomic< bool > bResyncRequested
double LastOwnClockFrameSeconds
bool bFramesToProcessBacklogged
std::unordered_map< uint32_t, uint32_t > MappedId
double EpisodeReadyPendingSince
FEpisodeSettings CurrentSettings
carla::multigpu::SensorStreamRegistry::epoch_type LoadingEpoch
bool bEpisodeReadyPending
static uint64_t UpdateFrameCounter()
void SendEpisodeReady()
Secondary only: tells the primary this episode is ready, which also makes it send a full resync.
std::atomic< bool > bLoadMapPending
UCarlaEpisode * CurrentEpisode
FDelegateHandle OnPreWorldInitializationHandle
std::vector< FFrameData > FramesToProcess
void DetachFromPrimary(const char *Reason)
Secondary only: stops mirroring the primary for good (it is gone, or this server cannot load its map)...
void BindReplayedSensor(uint32_t PrimaryActorId, uint32_t LocalActorId, bool bCreated)
Secondary only: binds a sensor replayed from the primary to the stream its clients were given (see ca...
carla::multigpu::LoadMapExtras PendingLoadMapExtras
std::atomic< bool > bNewConnection
std::optional< uint64_t > PreparedFrame
void NotifyBeginEpisode(UCarlaEpisode &Episode)
void NotifyInitGame(const UCarlaSettings &Settings)
TOptional< int32 > DynamicTreeBeforeDeterministicCollisions
Value of p.Chaos.AccelerationStructureUseDynamicTree before deterministic collisions changed it; unse...
carla::multigpu::load_map_id_type LoadingLoadMapId
std::optional< FPendingFrameTime > PendingFrameTime
ACarlaRecorder * Recorder
void PlayPrimaryFrame(UWorld &World, float DeltaSeconds, FFrameData &Frame)
Secondary only: plays the primary's frame on the frame OnBeginFrame prepared, with the primary's cloc...
bool bWarnedUnpairedFrame
bool bFramePlayedThisTick
double LastResyncRequestSeconds
void WaitForSecondaryEpisodes()
Primary only: keeps processing RPC until every secondary sent LOAD_MAP reports its episode ready (bou...
FDelegateHandle OnPreTickHandle
std::optional< uint64_t > LastPlayedFrame
void RestorePlayedPoses()
Secondary only: puts back any mirror that moved since its frame was played (a local mover the mirror ...
carla::multigpu::SensorStreamRegistry SensorStreams
bool bWasConnectedToPrimary
FDelegateHandle OnTravelFailureHandle
FDelegateHandle OnPostTickHandle
std::shared_ptr< carla::multigpu::Secondary > Secondary
UCarlaEpisode * GetCurrentEpisode()
void OnPreWorldInitialization(UWorld *World, const UWorld::InitializationValues IVS)
Applies FEpisodeSettings::bDeterministicCollisions to the world about to be created.
carla::multigpu::load_map_id_type PendingLoadMapId
void OnPostTick(UWorld *World, ELevelTick TickType, float DeltaSeconds)
std::shared_ptr< carla::multigpu::Router > GetSecondaryServer()
void RunSome(uint32 Milliseconds)
carla::streaming::Server & GetStreamingServer()
void NotifyBeginEpisode(UCarlaEpisode &Episode)
void SetIsSecondaryServer(bool bIsSecondary)
A Multi-GPU secondary refuses every call that would change its world.
FDataMultiStream Start(uint16_t RPCPort, uint16_t StreamingPort, uint16_t SecondaryPort)
void AsyncRun(uint32 NumberOfWorkerThreads)
static FOnEpisodeSettingsChange OnEpisodeSettingsChange
void GetFrameData(UCarlaEpisode *ThisEpisode, bool bAdditionalData=false, bool bIncludeActorsAgain=false)
void Write(std::ostream &OutStream)
void SetFrameTime(const carla::multigpu::FrameTime &Time)
bool HasSensorTicks() const
Whether the frame says which sensors tick (only older builds do not).
uint64_t GetFrameNumber() const
carla::multigpu::FrameDataReadResult Read(const uint8_t *Data, size_t Size)
Parses one SEND_FRAME payload.
const carla::multigpu::FrameTime * GetFrameTime() const
The primary's clocks and settings of this frame; null for a frame from an older primary.
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 PostPhysTick(UWorld *World, ELevelTick TickType, float DeltaSeconds)
auto GetToken() const
Return the token that allows subscribing to this sensor's stream.
void SetStream(FDataMultiStream InStream)
Replace the Stream associated with this sensor.
void BroadcastTick(const UCarlaEpisode &Episode, float DeltaSeconds, bool MapChange, bool PendingLightUpdate)
Send a message to every connected client with the info about the given Episode.
Mounts CARLA content packs (content-only Unreal plugins cooked as DLC against a base release,...
static UCarlaContentPackManager * Get()
FFrameData & GetFrameData()
double GetVisualGameTime() const
Visual game seconds.
FEpisodeSettings EpisodeSettings
static void ClearGeneratedWorldFiles()
Delete Saved/OpenDrive|Nav/OpenDriveMap.
FCarlaActor * FindCarlaActor(FCarlaActor::IdType ActorId)
Find a Carla actor by id.
const FString & GetMapName() const
void ApplySettings(const FEpisodeSettings &Settings)
double GetElapsedGameTime() const
Game seconds since the start of this episode.
const FEpisodeSettings & GetSettings() const
void SetRecorder(ACarlaRecorder *Rec)
void SetTimers(double InElapsedGameTime, double InVisualGameTime)
Multi-GPU secondary: adopt the primary's clocks for the frame being played.
void TickTimers(float DeltaSeconds)
const FActorRegistry & GetActorRegistry() const
ACarlaRecorder * GetRecorder() const
FSensorManager & GetSensorManager()
The game instance contains elements that must be kept alive in between levels.
void SetOpendriveGenerationParameters(const carla::rpc::OpendriveGenerationParameters &Parameters)
bool IsUpdatePending() const
Global settings for CARLA.
uint32 StreamingPort
setting for the streaming port.
std::string PrimaryIP
setting for the IP and Port of the primary server to connect.
uint32 RPCPort
World port to listen for client connections.
uint32 SecondaryPort
setting for the secondary servers port.
static FString FindMapPath(const FString &MapName)
static UCarlaGameInstance * GetGameInstance(const UObject *WorldContextObject)
static ALargeMapManager * GetLargeMapManager(const UObject *WorldContextObject)
static ACarlaGameModeBase * GetGameMode(const UObject *WorldContextObject)
static FString GetSavedXODRPath(const FString &MapName)
Where a generated OpenDRIVE world stores its xodr: <ProjectSavedDir>/OpenDrive/<MapName>....
static void SetSavedXODRDirectory(const FString &Directory)
Multi-GPU secondary: a folder of this process for the generated worlds the primary sends,...
std::optional< token_type > Resolve(carla::streaming::Server &server, actor_id_type actor_id, stream_id_type primary_stream_id)
Token that serves primary actor actor_id under primary_stream_id, reserving a local stream if the sen...
epoch_type BeginEpisodeChange(carla::streaming::Server &server)
The primary switched episode: forgets every actor and returns the epoch the secondary must pass to Op...
bool IsEpisodeOpen()
Whether Bind()/Unbind() are accepted, i.e.
void OpenEpisode(epoch_type epoch)
Accepts binding if epoch is the latest one BeginEpisodeChange() issued.
std::optional< carla::streaming::Stream > Bind(carla::streaming::Server &server, actor_id_type actor_id, stream_id_type sensor_stream_id, bool can_adopt)
Returns the stream reserved for actor_id if can_adopt (the sensor has never ticked) and the sensor mu...
void Unbind(carla::streaming::Server &server, actor_id_type actor_id)
Forgets actor_id, closing its reserved stream if no sensor adopted it.
static std::shared_ptr< ROS2 > GetInstance()
std::optional< stream_id > FindStreamAlias(stream_id alias)
carla::streaming::detail::stream_id_type stream_id
bool IsEnabledForROS(stream_id sensor_id)
void CloseStream(carla::streaming::detail::stream_id_type id)
void EnableForROS(stream_id sensor_id)
void SetStreamAlias(stream_id alias, stream_id target)
void SetROS2TopicVisibilityDefaultEnabled(bool enabled)
void DisableForROS(stream_id sensor_id)
void SetSynchronousMode(bool is_synchro)
void SetSessionsUseStreamAliases(bool enabled)
Serializes a stream endpoint.
const auto & get_stream_id() const
bool IsConsecutive(std::optional< uint64_t > last_played, uint64_t frame)
Whether frame directly follows the last frame this secondary played.
bool IsUsableDelta(float delta_seconds)
Whether a primary's delta can be this engine frame's time step.
BeginFrameAction DecideBeginFrame(const BeginFrameState &state)
const char * FrameDataStatusName(FrameDataStatus status)
LoadMapRequest ParseLoadMapPayload(std::string_view payload)
PreTickAction DecidePreTick(bool load_map_pending, bool has_episode, bool frame_prepared, bool episode_world)
BeginFrameAction
What a secondary does at the start of an engine frame, before the engine computes the frame's time st...
@ OwnClock
Not connected to a primary: run on this server's own clock.
@ Wait
Wait for the primary's next frame and take its time step.
bool NeedsResync(std::optional< uint64_t > last_played, uint64_t frame, bool full_resync)
Whether playing frame shows that this secondary missed primary state (a frame went missing) that only...
PreTickAction
What a secondary does when its world starts ticking.
@ Skip
No primary frame: let the frame pass without simulation time.
@ OpenLevel
Open the map the primary loaded; nothing else this frame.
constexpr std::string_view kTokenNotReadyMarker
GET_TOKEN reply when the secondary cannot resolve the sensor to a stream (or the request is malformed...
std::string MakeEpisodeReadyMessage(load_map_id_type load_id)
Episode-ready message: the marker followed by the load id of the LOAD_MAP that started the episode,...
std::string GetAvailableMiddleware()
bool IsValidDomainId(int id)
constexpr int kMinDomainId
Lowest valid ROS 2 domain id.
constexpr int kMaxDomainId
Highest valid ROS 2 domain id (RTPS maximum).
constexpr int kUnsetDomainId
Sentinel domain id meaning "no domain id was configured on the command line"; each middleware falls b...
MiddlewareParseResult MiddlewareFromString(const std::string &name)
Parse a middleware name string (lowercase).
static void log_error(Args &&... args)
static void log_info(Args &&... args)
static void log_warning(Args &&... args)
double UnpausedTimeSeconds
bool bDeterministicRagdolls
bool bAdjustSignsHeightToGround
float TileStreamingDistance
bool bDeterministicCollisions
float ActorActiveDistance
double MaxSubstepDeltaTime
TOptional< double > FixedDeltaSeconds
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...
bool IsComplete() const
Only a complete frame may be played.
uint32_t skipped
Packets whose id this build does not know.
uint32_t grown
Known packets with trailing bytes this build does not read (written by a newer build).
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.
double world_audio_time_seconds
double elapsed_game_time
UCarlaEpisode clocks at the end of frame N.
double world_unpaused_time_seconds
float delta_seconds
The raw DeltaSeconds that UWorld::Tick(N) received, before time dilation and clamping.
uint64_t frame
Frame counter of frame N; equal to the frame's FrameCounter packet.
bool full_resync
Set on the frame that rebuilds a secondary from scratch (a new or reconnected secondary,...
float time_dilation
AWorldSettings::GetEffectiveTimeDilation() of frame N.
double world_real_time_seconds
double world_time_seconds
UWorld clocks at the start of frame N, before UWorld::Tick adds the delta to them.
GET_TOKEN request payload.