From c9552887a00eb638d34d48064d62a0b58a17e709 Mon Sep 17 00:00:00 2001 From: bernatx Date: Tue, 13 Dec 2022 10:51:22 +0100 Subject: [PATCH] Some sensors are forced to be always on the primary server in multi-gpu mode --- CHANGELOG.md | 1 + PythonAPI/examples/tutorial_gbuffer.py | 26 +++++++++---------- .../Source/Carla/Actor/ActorRegistry.cpp | 25 ++++++++++++++++++ .../Carla/Source/Carla/Actor/ActorRegistry.h | 15 ++++++----- .../Carla/Source/Carla/Game/CarlaEpisode.h | 8 ++++++ .../Carla/Source/Carla/Server/CarlaServer.cpp | 19 +++++++++++++- 6 files changed, 73 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5c2b2b1c..48839d59a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * Fixed bug causing traffic signals at the end points of a road to sometimes create malformed waypoints. * Fixed pedestrian skeleton frame, where sometimes it was draw displaced from the body * Fixed decals when importing maps. It was using other .json files found in other packages. + * In multi-GPU mode some sensors now are forced to be created on the primary server always (ex. collision sensor) * Added the speed limits for 100, 110 and 120 Km/h. * Fixing sensor destruction, now the stream and socket is succesfully destroyed. * Fixed bug at `Vehicle.get_traffic_light_state()` and `Vehicle.is_at_traffic_light()` causing vehicles to temporarily not lose the information of a traffic light if they moved away from it before it turned green. diff --git a/PythonAPI/examples/tutorial_gbuffer.py b/PythonAPI/examples/tutorial_gbuffer.py index 6373f7f2a..e8f2fe231 100644 --- a/PythonAPI/examples/tutorial_gbuffer.py +++ b/PythonAPI/examples/tutorial_gbuffer.py @@ -95,22 +95,22 @@ def main(): # Here we will register the callbacks for each gbuffer texture. # The function "listen_to_gbuffer" behaves like the regular listen function, # but you must first pass it the ID of the desired gbuffer texture. - camera.listen_to_gbuffer(carla.GBufferTextureID.SceneColor, lambda image: image.save_to_disk('_out/SceneColor-%06d.png' % image.frame)) - camera.listen_to_gbuffer(carla.GBufferTextureID.SceneDepth, lambda image: image.save_to_disk('_out/SceneDepth-%06d.png' % image.frame)) - camera.listen_to_gbuffer(carla.GBufferTextureID.SceneStencil, lambda image: image.save_to_disk('_out/SceneStencil-%06d.png' % image.frame)) - camera.listen_to_gbuffer(carla.GBufferTextureID.GBufferA, lambda image: image.save_to_disk('_out/GBufferA-%06d.png' % image.frame)) - camera.listen_to_gbuffer(carla.GBufferTextureID.GBufferB, lambda image: image.save_to_disk('_out/GBufferB-%06d.png' % image.frame)) - camera.listen_to_gbuffer(carla.GBufferTextureID.GBufferC, lambda image: image.save_to_disk('_out/GBufferC-%06d.png' % image.frame)) - camera.listen_to_gbuffer(carla.GBufferTextureID.GBufferD, lambda image: image.save_to_disk('_out/GBufferD-%06d.png' % image.frame)) + camera.listen_to_gbuffer(carla.GBufferTextureID.SceneColor, lambda image: image.save_to_disk('_out/GBuffer-SceneColor-%06d.png' % image.frame)) + camera.listen_to_gbuffer(carla.GBufferTextureID.SceneDepth, lambda image: image.save_to_disk('_out/GBuffer-SceneDepth-%06d.png' % image.frame)) + camera.listen_to_gbuffer(carla.GBufferTextureID.SceneStencil, lambda image: image.save_to_disk('_out/GBuffer-SceneStencil-%06d.png' % image.frame)) + camera.listen_to_gbuffer(carla.GBufferTextureID.GBufferA, lambda image: image.save_to_disk('_out/GBuffer-A-%06d.png' % image.frame)) + camera.listen_to_gbuffer(carla.GBufferTextureID.GBufferB, lambda image: image.save_to_disk('_out/GBuffer-B-%06d.png' % image.frame)) + camera.listen_to_gbuffer(carla.GBufferTextureID.GBufferC, lambda image: image.save_to_disk('_out/GBuffer-C-%06d.png' % image.frame)) + camera.listen_to_gbuffer(carla.GBufferTextureID.GBufferD, lambda image: image.save_to_disk('_out/GBuffer-D-%06d.png' % image.frame)) # Note that some gbuffer textures may not be available for a particular scene. # For example, the textures E and F are likely unavailable in this example, # which will result in them being sent as black images. - camera.listen_to_gbuffer(carla.GBufferTextureID.GBufferE, lambda image: image.save_to_disk('_out/GBufferE-%06d.png' % image.frame)) - camera.listen_to_gbuffer(carla.GBufferTextureID.GBufferF, lambda image: image.save_to_disk('_out/GBufferF-%06d.png' % image.frame)) - camera.listen_to_gbuffer(carla.GBufferTextureID.Velocity, lambda image: image.save_to_disk('_out/Velocity-%06d.png' % image.frame)) - camera.listen_to_gbuffer(carla.GBufferTextureID.SSAO, lambda image: image.save_to_disk('_out/SSAO-%06d.png' % image.frame)) - camera.listen_to_gbuffer(carla.GBufferTextureID.CustomDepth, lambda image: image.save_to_disk('_out/CustomDepth-%06d.png' % image.frame)) - camera.listen_to_gbuffer(carla.GBufferTextureID.CustomStencil, lambda image: image.save_to_disk('_out/CustomStencil-%06d.png' % image.frame)) + camera.listen_to_gbuffer(carla.GBufferTextureID.GBufferE, lambda image: image.save_to_disk('_out/GBuffer-E-%06d.png' % image.frame)) + camera.listen_to_gbuffer(carla.GBufferTextureID.GBufferF, lambda image: image.save_to_disk('_out/GBuffer-F-%06d.png' % image.frame)) + camera.listen_to_gbuffer(carla.GBufferTextureID.Velocity, lambda image: image.save_to_disk('_out/GBuffer-Velocity-%06d.png' % image.frame)) + camera.listen_to_gbuffer(carla.GBufferTextureID.SSAO, lambda image: image.save_to_disk('_out/GBuffer-SSAO-%06d.png' % image.frame)) + camera.listen_to_gbuffer(carla.GBufferTextureID.CustomDepth, lambda image: image.save_to_disk('_out/GBuffer-CustomDepth-%06d.png' % image.frame)) + camera.listen_to_gbuffer(carla.GBufferTextureID.CustomStencil, lambda image: image.save_to_disk('_out/GBuffer-CustomStencil-%06d.png' % image.frame)) time.sleep(10) diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorRegistry.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorRegistry.cpp index 8f20d965d..1a6011657 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorRegistry.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorRegistry.cpp @@ -7,6 +7,7 @@ #pragma once #include "Carla.h" +#include "Carla/Actor/ActorData.h" #include "Carla/Actor/ActorRegistry.h" #include "Carla/Game/Tagger.h" @@ -14,6 +15,12 @@ #include "Carla/Util/BoundingBoxCalculator.h" #include "Carla/Sensor/Sensor.h" +#include +#include "carla/streaming/Token.h" +#include "carla/streaming/detail/Token.h" +#include + + namespace crp = carla::rpc; FActorRegistry::IdType FActorRegistry::ID_COUNTER = 0u; @@ -231,3 +238,21 @@ void FActorRegistry::WakeActorUp(FCarlaActor::IdType Id, UCarlaEpisode* CarlaEpi WakeActorUp(ChildId, CarlaEpisode); } } + +FString FActorRegistry::GetDescriptionFromStream(carla::streaming::detail::stream_id_type Id) +{ + for (auto &Item : ActorDatabase) + { + // check for a sensor + ASensor *Sensor = Cast(Item.Value->GetActor()); + if (Sensor == nullptr) continue; + + carla::streaming::detail::token_type token(Sensor->GetToken()); + if (token.get_stream_id() == Id) + { + const FActorInfo *Info = Item.Value->GetActorInfo(); + return Info->Description.Id; + } + } + return FString(""); +} diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorRegistry.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorRegistry.h index fcb771979..ee079d7ea 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorRegistry.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/ActorRegistry.h @@ -19,16 +19,16 @@ /// A registry of all the Carla actors. class FActorRegistry { -private: - - // using DatabaseType = std::unordered_map; - using DatabaseType = TMap>; - public: using IdType = FCarlaActor::IdType; using ValueType = TSharedPtr; +private: + + // using DatabaseType = std::unordered_map; + using DatabaseType = TMap>; + // =========================================================================== /// @name Actor registry functions // =========================================================================== @@ -90,10 +90,11 @@ public: return PtrToId ? FindCarlaActor(*PtrToId) : nullptr; } + FString GetDescriptionFromStream(carla::streaming::detail::stream_id_type Id); - void PutActorToSleep(FCarlaActor::IdType Id, UCarlaEpisode* CarlaEpisode); + void PutActorToSleep(IdType Id, UCarlaEpisode* CarlaEpisode); - void WakeActorUp(FCarlaActor::IdType Id, UCarlaEpisode* CarlaEpisode); + void WakeActorUp(IdType Id, UCarlaEpisode* CarlaEpisode); /// @} // =========================================================================== diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.h index 5c4d0c8fe..bd538ae9e 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.h @@ -183,6 +183,14 @@ public: return ActorDispatcher->GetActorRegistry().FindCarlaActor(Actor); } + /// Get the description of the Carla actor (sensor) using specific stream id. + /// + /// If the actor is not found returns an empty string + FString GetActorDescriptionFromStream(carla::streaming::detail::stream_id_type StreamId) + { + return ActorDispatcher->GetActorRegistry().GetDescriptionFromStream(StreamId); + } + // =========================================================================== // -- Actor handling methods ------------------------------------------------- // =========================================================================== diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/CarlaServer.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/CarlaServer.cpp index 017331649..b38549f24 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/CarlaServer.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/CarlaServer.cpp @@ -771,14 +771,31 @@ void FCarlaServer::FPimpl::BindActions() R { REQUIRE_CARLA_EPISODE(); - if (SecondaryServer->HasClientsConnected() && sensor_id > 1) + bool ForceInPrimary = false; + + // check for the world observer (always in primary server) + if (sensor_id == 1) + { + ForceInPrimary = true; + } + + // collision sensor always in primary server in multi-gpu + FString Desc = Episode->GetActorDescriptionFromStream(sensor_id); + if (Desc == "" || Desc == "sensor.other.collision") + { + ForceInPrimary = true; + } + + if (SecondaryServer->HasClientsConnected() && !ForceInPrimary) { // multi-gpu + UE_LOG(LogCarla, Log, TEXT("Sensor %d '%s' created in secondary server"), sensor_id, *Desc); return SecondaryServer->GetCommander().SendGetToken(sensor_id); } else { // single-gpu + UE_LOG(LogCarla, Log, TEXT("Sensor %d '%s' created in primary server"), sensor_id, *Desc); return StreamingServer.GetToken(sensor_id); } };