From 0551fd458e9310ec1e2a36ad368b49adaec538bc Mon Sep 17 00:00:00 2001 From: Jose <44341347+JoseM98@users.noreply.github.com> Date: Fri, 16 Feb 2024 11:08:56 +0100 Subject: [PATCH] Added the option to save SceneCapture images to disk on SensorSpawnerActor. (#7152) --- .../Source/Carla/Util/SensorSpawnerActor.cpp | 62 +++++++++++++++++-- .../Source/Carla/Util/SensorSpawnerActor.h | 31 +++++++++- 2 files changed, 84 insertions(+), 9 deletions(-) diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/SensorSpawnerActor.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/SensorSpawnerActor.cpp index d968b5d8c..f8b05c963 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/SensorSpawnerActor.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/SensorSpawnerActor.cpp @@ -4,14 +4,17 @@ #include "Util/SensorSpawnerActor.h" #include "Carla/Game/CarlaEpisode.h" #include "Game/CarlaGameModeBase.h" +#include "Sensor/SceneCaptureCamera.h" #include "Sensor/Sensor.h" DEFINE_LOG_CATEGORY_STATIC(LogSensorSpawnerActor, Verbose, All); ASensorSpawnerActor::ASensorSpawnerActor() { - PrimaryActorTick.bCanEverTick = false; - + PrimaryActorTick.bCanEverTick = true; + PrimaryActorTick.bStartWithTickEnabled = false; + PrimaryActorTick.TickInterval = TickInterval; + SceneComp = CreateDefaultSubobject(TEXT("SceneComp")); RootComponent = SceneComp; } @@ -19,14 +22,19 @@ ASensorSpawnerActor::ASensorSpawnerActor() void ASensorSpawnerActor::BeginPlay() { Super::BeginPlay(); - + // Wait for the CarlaEpisode initialisation. It is done on CarlaGameMode BeginPlay(). if(ACarlaGameModeBase* CarlaGameMode = Cast(UGameplayStatics::GetGameMode(GetWorld()))) { CarlaGameMode->OnEpisodeInitialisedDelegate.AddDynamic(this, &ASensorSpawnerActor::OnEpisodeInitialised); } + + SetActorTickInterval(TickInterval); + SaveImagePath = FPaths::ProjectSavedDir() + "/SensorSpawnerCaptures/" + FString::Printf(TEXT("%lld"), FDateTime::Now().ToUnixTimestamp()); } + + void ASensorSpawnerActor::OnEpisodeInitialised(UCarlaEpisode* InitialisedEpisode) { if(IsValid(InitialisedEpisode)) @@ -83,14 +91,19 @@ const FActorDefinition* ASensorSpawnerActor::GetActorDefinitionByClass(const TSu return ActorDefinition; } -void ASensorSpawnerActor::SpawnSensorActor(const FActorDescription& SensorDescription) const +void ASensorSpawnerActor::SpawnSensorActor(const FActorDescription& SensorDescription) { if(IsValid(CarlaEpisode)) { FTransform Transform; GetRandomTransform(Transform); - CarlaEpisode->SpawnActorWithInfo(Transform, SensorDescription); + const TPair SpawnResult = CarlaEpisode->SpawnActorWithInfo(Transform, SensorDescription); + + if(bSaveCameraToDisk && SpawnResult.Value) + { + StartSavingCapturesToDisk(SpawnResult.Value->GetActor()); + } } } @@ -144,4 +157,41 @@ void ASensorSpawnerActor::SpawnSensorsDelayed() { SensorsToSpawnCopy.RemoveAt(0); } -} \ No newline at end of file +} + +void ASensorSpawnerActor::Tick(float DeltaSeconds) +{ + Super::Tick(DeltaSeconds); + + for(const ASceneCaptureCamera* CaptureCamera : SceneCaptureCameras) + { + if(CaptureCamera) + { + CaptureCamera->SaveCaptureToDisk(SaveImagePath + "/" + CaptureCamera->GetName() + "/" + FString::Printf(TEXT("%lld"), FDateTime::Now().ToUnixTimestamp()) + ".png" ); + } + } +} + +void ASensorSpawnerActor::RemoveSceneCaptureCameras() +{ + if(SceneCaptureCameras.IsValidIndex(0)) + { + SceneCaptureCameras.RemoveAt(0); + } + + if(SceneCaptureCameras.IsEmpty()) + { + SetActorTickEnabled(false); + } +} + +void ASensorSpawnerActor::StartSavingCapturesToDisk(const AActor* Actor) +{ + if(const ASceneCaptureCamera* CaptureCamera = Cast(Actor)) + { + SceneCaptureCameras.Add(CaptureCamera); + SetActorTickEnabled(true); + FTimerHandle CaptureTimerHandle; + GetWorldTimerManager().SetTimer(CaptureTimerHandle, this, &ASensorSpawnerActor::RemoveSceneCaptureCameras, CaptureTime); + } +} diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/SensorSpawnerActor.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/SensorSpawnerActor.h index cb3315f5c..74f385c02 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/SensorSpawnerActor.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Util/SensorSpawnerActor.h @@ -43,6 +43,8 @@ protected: // Called when the game starts or when spawned. virtual void BeginPlay() override; + virtual void Tick(float DeltaSeconds) override; + // Root UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Components") USceneComponent* SceneComp; @@ -67,6 +69,18 @@ protected: UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Config") FVector MinSpawnLocation {-120000.f, -110000.f, 9300.f}; + // Enables that all SceneCaptures cameras save captures to /Saved/SensorSpawnerCaptures folder. + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Config|SceneCapture") + bool bSaveCameraToDisk = false; + + // How often ticking is done and a SceneCapture image is taken. + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Config|SceneCapture") + float TickInterval = 1.f; + + // Amount of time each camera takes captures. + UPROPERTY(EditAnywhere, BlueprintReadOnly, meta=(ClampMin=1.f), Category="Config|SceneCapture") + float CaptureTime = 30.f; + private: UFUNCTION() @@ -74,13 +88,18 @@ private: UFUNCTION() void SpawnSensorsDelayed(); + + UFUNCTION() + void RemoveSceneCaptureCameras(); + + void StartSavingCapturesToDisk(const AActor* Actor); void GenerateSensorActorDescription(const FActorDefinition* Definition, FActorDescription& SensorDescription) const; // Gets a transform with a random location between MaxSpawnLocation and MinSpawnLocation. void GetRandomTransform(FTransform &Transform) const; - void SpawnSensorActor(const FActorDescription& SensorDescription) const; + void SpawnSensorActor(const FActorDescription& SensorDescription); const FActorDefinition* GetActorDefinitionByClass(const TSubclassOf ActorClass) const; @@ -89,9 +108,15 @@ private: UPROPERTY() UCarlaEpisode* CarlaEpisode; - // Used for delayed spawn + // Used for delayed spawn. FTimerHandle SpawnSensorsDelayedTimerHandle; - // Used for delayed spawn + // Used for delayed spawn. Track cameras taking pictures on tick. TArray SensorsToSpawnCopy; + + // Track cameras saving pictures on tick. + TArray SceneCaptureCameras; + + // Path to the /Saved/SensorSpawnerCaptures project folder. + FString SaveImagePath; };