Some sensors are forced to be always on the primary server in multi-gpu mode

This commit is contained in:
bernatx 2022-12-13 10:51:22 +01:00 committed by bernat
parent 12fb78ffab
commit c9552887a0
6 changed files with 73 additions and 21 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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 <compiler/disable-ue4-macros.h>
#include "carla/streaming/Token.h"
#include "carla/streaming/detail/Token.h"
#include <compiler/enable-ue4-macros.h>
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<ASensor>(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("");
}

View File

@ -19,16 +19,16 @@
/// A registry of all the Carla actors.
class FActorRegistry
{
private:
// using DatabaseType = std::unordered_map<FCarlaActor::IdType, FCarlaActor>;
using DatabaseType = TMap<FCarlaActor::IdType, TSharedPtr<FCarlaActor>>;
public:
using IdType = FCarlaActor::IdType;
using ValueType = TSharedPtr<FCarlaActor>;
private:
// using DatabaseType = std::unordered_map<IdType, FCarlaActor>;
using DatabaseType = TMap<IdType, TSharedPtr<FCarlaActor>>;
// ===========================================================================
/// @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);
/// @}
// ===========================================================================

View File

@ -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 -------------------------------------------------
// ===========================================================================

View File

@ -771,14 +771,31 @@ void FCarlaServer::FPimpl::BindActions()
R<carla::streaming::Token>
{
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);
}
};