Make adding capture cameras fully customizable in settings file

This commit is contained in:
nsubiron 2017-04-06 15:56:43 +02:00
parent 714fec71ac
commit c498ff357a
17 changed files with 276 additions and 335 deletions

View File

@ -15,15 +15,22 @@ WritePort=2001
ReadPort=2002 ReadPort=2002
[CARLA/SceneCapture] [CARLA/SceneCapture]
; Valid values: Mono, Stereo, NoCapture. ; Names of the scene capture cameras to attach to the player, each of them
; The mode is overriden by the client if networking is enabled. ; should be defined in its own subsection.
Mode=Mono Cameras=CameraStereoLeft/RGB,CameraStereoLeft/Depth,CameraStereoRight/RGB,CameraStereoRight/Depth
; Size of the captured image in pixels. ; Cameras=CameraMono
; Defaults for each camera can be set here, e.g.
ImageSizeX=720 ImageSizeX=720
ImageSizeY=512 ImageSizeY=512
[CARLA/SceneCapture/Mono] [CARLA/SceneCapture/CameraMono]
; Image size can also be changed by mode. ; Post-processing effect to be applied. Valid values:
; * None No effects applied.
; * SceneFinal Post-processing present at scene (bloom, fog, etc).
; * Depth Depth map only.
PostProcessing=SceneFinal
; Size of the captured image in pixels.
ImageSizeX=720 ImageSizeX=720
ImageSizeY=512 ImageSizeY=512
; Position of the camera relative to the car in centimeters. ; Position of the camera relative to the car in centimeters.
@ -35,18 +42,25 @@ CameraRotationPitch=0
CameraRotationRoll=0 CameraRotationRoll=0
CameraRotationYaw=0 CameraRotationYaw=0
[CARLA/SceneCapture/Stereo] [CARLA/SceneCapture/CameraStereoLeft]
; Position of the cameras relative to the car in centimeters. CameraPositionX=170
Camera0PositionX=170 CameraPositionY=-30
Camera0PositionY=30 CameraPositionZ=150
Camera0PositionZ=150 CameraRotationPitch=0
Camera1PositionX=170 CameraRotationRoll=0
Camera1PositionY=-30 CameraRotationYaw=0
Camera1PositionZ=150 [CARLA/SceneCapture/CameraStereoLeft/RGB]
; Rotation of the cameras relative to the car in degrees. PostProcessing=SceneFinal
Camera0RotationPitch=0 [CARLA/SceneCapture/CameraStereoLeft/Depth]
Camera0RotationRoll=0 PostProcessing=Depth
Camera0RotationYaw=0 [CARLA/SceneCapture/CameraStereoRight]
Camera1RotationPitch=0 CameraPositionX=170
Camera1RotationRoll=0 CameraPositionY=30
Camera1RotationYaw=0 CameraPositionZ=150
CameraRotationPitch=0
CameraRotationRoll=0
CameraRotationYaw=0
[CARLA/SceneCapture/CameraStereoRight/RGB]
PostProcessing=SceneFinal
[CARLA/SceneCapture/CameraStereoRight/Depth]
PostProcessing=Depth

View File

@ -14,7 +14,7 @@ DECLARE_LOG_CATEGORY_EXTERN(LogCarlaServer, Log, All);
// Options to compile with extra debug options. // Options to compile with extra debug options.
#ifdef WITH_EDITOR #ifdef WITH_EDITOR
// #define CARLA_ROAD_GENERATOR_PRINT_OUT /// @todo #1 Crashes in Linux. // #define CARLA_ROAD_GENERATOR_PRINT_OUT /// @todo #1 Crashes in Linux.
// #define CARLA_SERVER_CHECK_IMAGES // #define CARLA_SERVER_CHECK_IMAGES /// @todo #13 Uncomment and compile ;)
#endif // WITH_EDITOR #endif // WITH_EDITOR
class FCarlaModule : public IModuleInterface class FCarlaModule : public IModuleInterface

View File

@ -0,0 +1,32 @@
// CARLA, Copyright (C) 2017 Computer Vision Center (CVC)
#pragma once
#include "PostProcessEffect.h"
#include "CameraDescription.generated.h"
USTRUCT()
struct FCameraDescription
{
GENERATED_BODY()
/** X size in pixels of the captured image. */
UPROPERTY(Category = "Camera Description", EditDefaultsOnly)
uint32 ImageSizeX = 720u;
/** Y size in pixels of the captured image. */
UPROPERTY(Category = "Camera Description", EditDefaultsOnly)
uint32 ImageSizeY = 512u;
/** Position relative to the player. */
UPROPERTY(Category = "Camera Description", EditDefaultsOnly)
FVector Position = {170.0f, 0.0f, 150.0f};
/** Rotation relative to the player. */
UPROPERTY(Category = "Camera Description", EditDefaultsOnly)
FRotator Rotation = {0.0f, 0.0f, 0.0f};
/** Post-process effect to be applied to the captured image. */
UPROPERTY(Category = "Camera Description", EditDefaultsOnly)
EPostProcessEffect PostProcessEffect = EPostProcessEffect::SceneFinal;
};

View File

@ -0,0 +1,27 @@
// CARLA, Copyright (C) 2017 Computer Vision Center (CVC)
#pragma once
#include "PostProcessEffect.h"
#include "CapturedImage.generated.h"
/// Bitmap and meta info of a scene capture.
///
/// The bitmap may be empty if the capture failed.
USTRUCT()
struct FCapturedImage
{
GENERATED_BODY()
UPROPERTY(VisibleAnywhere)
uint32 SizeX = 0u;
UPROPERTY(VisibleAnywhere)
uint32 SizeY = 0u;
UPROPERTY(VisibleAnywhere)
EPostProcessEffect PostProcessEffect = EPostProcessEffect::INVALID;
UPROPERTY(VisibleAnywhere)
TArray<FColor> BitMap;
};

View File

@ -53,7 +53,7 @@ static void Set(std::vector<carla::Color> &cImage, const TArray<FColor> &BitMap)
static bool CheckImage( static bool CheckImage(
const FString &Tag, const FString &Tag,
const ACarlaPlayerState::Image &Image, const FCapturedImage &Image,
const std::vector<carla::Color> &ImageReward, const std::vector<carla::Color> &ImageReward,
uint32 SizeX, uint32 SizeX,
uint32 SizeY) uint32 SizeY)
@ -82,7 +82,7 @@ static bool CheckImageValidity(const ACarlaPlayerState &Player, const carla::Rew
// Wait for the scene init to be sent, return false if we need to restart the // Wait for the scene init to be sent, return false if we need to restart the
// server. // server.
/// @todo At the moment we just ignored what it is sent. /// @todo At the moment we just ignored what it is sent.
static bool ReadSceneInit(carla::CarlaServer &Server, ESceneCaptureMode &CaptureMode) static bool ReadSceneInit(carla::CarlaServer &Server)
{ {
carla::Mode Mode; carla::Mode Mode;
uint32 Scene; uint32 Scene;
@ -92,13 +92,6 @@ static bool ReadSceneInit(carla::CarlaServer &Server, ESceneCaptureMode &Capture
if (!Server.tryReadSceneInit(Mode, Scene, Success)) if (!Server.tryReadSceneInit(Mode, Scene, Success))
return false; return false;
} }
if (Mode == carla::Mode::MONO) {
CaptureMode = ESceneCaptureMode::Mono;
} else if (Mode == carla::Mode::STEREO) {
CaptureMode = ESceneCaptureMode::Stereo;
} else {
CaptureMode = ESceneCaptureMode::NoCapture;
}
return true; return true;
} }
@ -160,19 +153,8 @@ static bool SendReward(
Set(reward->collision_general, PlayerState.GetCollisionIntensityOther()); Set(reward->collision_general, PlayerState.GetCollisionIntensityOther());
Set(reward->intersect_other_lane, PlayerState.GetOtherLaneIntersectionFactor()); Set(reward->intersect_other_lane, PlayerState.GetOtherLaneIntersectionFactor());
Set(reward->intersect_offroad, PlayerState.GetOffRoadIntersectionFactor()); Set(reward->intersect_offroad, PlayerState.GetOffRoadIntersectionFactor());
{ // Add images. for (const auto &Image : PlayerState.GetImages()) {
using CPS = ACarlaPlayerState; /// @todo #13 Add images to reward.
auto &ImageRGB0 = PlayerState.GetImage(CPS::ImageRGB0);
if (ImageRGB0.BitMap.Num() > 0) {
// Do not add any camera if first is invalid, also assume all the images
// have the same size.
reward->image_width = ImageRGB0.SizeX;
reward->image_height = ImageRGB0.SizeY;
Set(reward->image_rgb_0, ImageRGB0.BitMap);
Set(reward->image_rgb_1, PlayerState.GetImage(CPS::ImageRGB1).BitMap);
Set(reward->image_depth_0, PlayerState.GetImage(CPS::ImageDepth0).BitMap);
Set(reward->image_depth_1, PlayerState.GetImage(CPS::ImageDepth1).BitMap);
}
} }
#ifdef CARLA_SERVER_CHECK_IMAGES #ifdef CARLA_SERVER_CHECK_IMAGES
check(CheckImageValidity(PlayerState, *reward)); check(CheckImageValidity(PlayerState, *reward));
@ -212,7 +194,7 @@ void CarlaGameController::Initialize(UCarlaSettings &CarlaSettings)
{ {
if (bServerNeedsRestart) { if (bServerNeedsRestart) {
UE_LOG(LogCarlaServer, Log, TEXT("Initializing CarlaServer")); UE_LOG(LogCarlaServer, Log, TEXT("Initializing CarlaServer"));
if (Server->init(1u) && ReadSceneInit(*Server, CarlaSettings.SceneCaptureMode)) { if (Server->init(1u) && ReadSceneInit(*Server)) {
bServerNeedsRestart = false; bServerNeedsRestart = false;
} else { } else {
UE_LOG(LogCarlaServer, Warning, TEXT("Failed to initialize, server needs restart")); UE_LOG(LogCarlaServer, Warning, TEXT("Failed to initialize, server needs restart"));

View File

@ -7,8 +7,6 @@
#include "EngineUtils.h" #include "EngineUtils.h"
#include "GameFramework/PlayerStart.h" #include "GameFramework/PlayerStart.h"
#include "SceneCaptureCamera.h"
#include "CarlaGameInstance.h" #include "CarlaGameInstance.h"
#include "CarlaGameState.h" #include "CarlaGameState.h"
#include "CarlaHUD.h" #include "CarlaHUD.h"
@ -89,85 +87,16 @@ void ACarlaGameMode::RegisterPlayer(AController &NewPlayer)
AttachCaptureCamerasToPlayer(*PlayerController); AttachCaptureCamerasToPlayer(*PlayerController);
} }
void ACarlaGameMode::RegisterCaptureCamera(
ASceneCaptureCamera &CaptureCamera,
AController &Player)
{
AddTickPrerequisiteActor(&CaptureCamera);
ACarlaVehicleController *Vehicle = Cast<ACarlaVehicleController>(&Player);
if (Vehicle != nullptr) {
Vehicle->RegisterCaptureCamera(CaptureCamera);
} else {
UE_LOG(LogCarla, Warning, TEXT("Trying to register camera but player is not a ACarlaVehicleController"));
}
}
static ASceneCaptureCamera *SpawnAndAttachCamera(
AController &Player,
const FVector &RelativeLocation,
const FRotator &RelativeRotation,
uint32 ImageSizeX,
uint32 ImageSizeY,
EPostProcessEffect PostProcessEffect)
{
auto Camera = Player.GetWorld()->SpawnActor<ASceneCaptureCamera>(RelativeLocation, RelativeRotation);
Camera->SetImageSize(ImageSizeX, ImageSizeY);
Camera->SetPostProcessEffect(PostProcessEffect);
Camera->AttachToActor(Player.GetPawn(), FAttachmentTransformRules::KeepRelativeTransform);
Camera->SetOwner(Player.GetPawn());
return Camera;
}
void ACarlaGameMode::AttachCaptureCamerasToPlayer(AController &Player) void ACarlaGameMode::AttachCaptureCamerasToPlayer(AController &Player)
{ {
ACarlaVehicleController *Vehicle = Cast<ACarlaVehicleController>(&Player);
if (Vehicle == nullptr) {
UE_LOG(LogCarla, Warning, TEXT("Trying to add capture cameras but player is not a ACarlaVehicleController"));
return;
}
auto &Settings = GameInstance->GetCarlaSettings(); auto &Settings = GameInstance->GetCarlaSettings();
if (Settings.SceneCaptureMode == ESceneCaptureMode::Mono) { for (const auto &Item : Settings.CameraDescriptions) {
auto TheCamera = Vehicle->AddSceneCaptureCamera(Item.Value);
SpawnAndAttachCamera(
Player,
Settings.Mono_CameraPosition,
Settings.Mono_CameraRotation,
Settings.Mono_ImageSizeX,
Settings.Mono_ImageSizeY,
EPostProcessEffect::SceneFinal);
RegisterCaptureCamera(*TheCamera, Player);
} else if (Settings.SceneCaptureMode == ESceneCaptureMode::Stereo) {
auto RGBCamera0 =
SpawnAndAttachCamera(
Player,
Settings.Stereo_Camera0Position,
Settings.Stereo_Camera0Rotation,
Settings.Stereo_ImageSizeX,
Settings.Stereo_ImageSizeY,
EPostProcessEffect::SceneFinal);
auto DepthCamera0 =
SpawnAndAttachCamera(
Player,
Settings.Stereo_Camera0Position,
Settings.Stereo_Camera0Rotation,
Settings.Stereo_ImageSizeX,
Settings.Stereo_ImageSizeY,
EPostProcessEffect::Depth);
auto RGBCamera1 =
SpawnAndAttachCamera(
Player,
Settings.Stereo_Camera1Position,
Settings.Stereo_Camera1Rotation,
Settings.Stereo_ImageSizeX,
Settings.Stereo_ImageSizeY,
EPostProcessEffect::SceneFinal);
auto DepthCamera1 =
SpawnAndAttachCamera(
Player,
Settings.Stereo_Camera1Position,
Settings.Stereo_Camera1Rotation,
Settings.Stereo_ImageSizeX,
Settings.Stereo_ImageSizeY,
EPostProcessEffect::Depth);
RegisterCaptureCamera(*RGBCamera0, Player);
RegisterCaptureCamera(*DepthCamera0, Player);
RegisterCaptureCamera(*RGBCamera1, Player);
RegisterCaptureCamera(*DepthCamera1, Player);
} }
} }

View File

@ -33,8 +33,6 @@ private:
void RegisterPlayer(AController &NewPlayer); void RegisterPlayer(AController &NewPlayer);
void RegisterCaptureCamera(ASceneCaptureCamera &CaptureCamera, AController &Player);
void AttachCaptureCamerasToPlayer(AController &Player); void AttachCaptureCamerasToPlayer(AController &Player);
/// Iterate all the APlayerStart present in the world and add the ones with /// Iterate all the APlayerStart present in the world and add the ones with

View File

@ -10,10 +10,7 @@ void ACarlaPlayerState::Reset()
CollisionIntensityCars = 0.0f; CollisionIntensityCars = 0.0f;
CollisionIntensityPedestrians = 0.0f; CollisionIntensityPedestrians = 0.0f;
CollisionIntensityOther = 0.0f; CollisionIntensityOther = 0.0f;
// Invalidate images. Images.Empty();
for (auto &image : Images) {
image = Image(); // Reset.
}
} }
void ACarlaPlayerState::CopyProperties(APlayerState *PlayerState) void ACarlaPlayerState::CopyProperties(APlayerState *PlayerState)

View File

@ -2,8 +2,8 @@
#pragma once #pragma once
#include <array>
#include "GameFramework/PlayerState.h" #include "GameFramework/PlayerState.h"
#include "CapturedImage.h"
#include "CarlaPlayerState.generated.h" #include "CarlaPlayerState.generated.h"
/// Current state of the player, updated every frame by ACarlaVehicleController. /// Current state of the player, updated every frame by ACarlaVehicleController.
@ -20,19 +20,6 @@ class CARLA_API ACarlaPlayerState : public APlayerState
// =========================================================================== // ===========================================================================
public: public:
enum ImageTag {
ImageRGB0,
ImageRGB1,
ImageDepth0,
ImageDepth1,
NUMBER_OF_IMAGES
};
struct Image {
uint32 SizeX = 0u;
uint32 SizeY = 0u;
TArray<FColor> BitMap;
};
// =========================================================================== // ===========================================================================
// -- APlayerState ----------------------------------------------------------- // -- APlayerState -----------------------------------------------------------
@ -48,64 +35,76 @@ public:
// =========================================================================== // ===========================================================================
public: public:
UFUNCTION()
int32 GetTimeStamp() const int32 GetTimeStamp() const
{ {
return TimeStamp; return TimeStamp;
} }
UFUNCTION()
const FVector &GetLocation() const const FVector &GetLocation() const
{ {
return Location; return Location;
} }
UFUNCTION()
const FVector &GetOrientation() const const FVector &GetOrientation() const
{ {
return Orientation; return Orientation;
} }
UFUNCTION()
const FVector &GetAcceleration() const const FVector &GetAcceleration() const
{ {
return Acceleration; return Acceleration;
} }
UFUNCTION()
float GetForwardSpeed() const float GetForwardSpeed() const
{ {
return ForwardSpeed; return ForwardSpeed;
} }
UFUNCTION()
int32 GetCurrentGear() const int32 GetCurrentGear() const
{ {
return CurrentGear; return CurrentGear;
} }
UFUNCTION()
float GetCollisionIntensityCars() const float GetCollisionIntensityCars() const
{ {
return CollisionIntensityCars; return CollisionIntensityCars;
} }
UFUNCTION()
float GetCollisionIntensityPedestrians() const float GetCollisionIntensityPedestrians() const
{ {
return CollisionIntensityPedestrians; return CollisionIntensityPedestrians;
} }
UFUNCTION()
float GetCollisionIntensityOther() const float GetCollisionIntensityOther() const
{ {
return CollisionIntensityOther; return CollisionIntensityOther;
} }
UFUNCTION()
float GetOtherLaneIntersectionFactor() const float GetOtherLaneIntersectionFactor() const
{ {
return OtherLaneIntersectionFactor; return OtherLaneIntersectionFactor;
} }
UFUNCTION()
float GetOffRoadIntersectionFactor() const float GetOffRoadIntersectionFactor() const
{ {
return OffRoadIntersectionFactor; return OffRoadIntersectionFactor;
} }
const Image &GetImage(ImageTag Tag) const UFUNCTION()
const TArray<FCapturedImage> &GetImages() const
{ {
return Images[Tag]; return Images;
} }
// =========================================================================== // ===========================================================================
@ -127,27 +126,39 @@ private:
// If you add another variable here, don't forget to copy it inside // If you add another variable here, don't forget to copy it inside
// CopyProperties if necessary. // CopyProperties if necessary.
UPROPERTY(VisibleAnywhere)
int32 TimeStamp; int32 TimeStamp;
UPROPERTY(VisibleAnywhere)
FVector Location; FVector Location;
UPROPERTY(VisibleAnywhere)
FVector Orientation; FVector Orientation;
UPROPERTY(VisibleAnywhere)
FVector Acceleration; FVector Acceleration;
UPROPERTY(VisibleAnywhere)
int32 CurrentGear; int32 CurrentGear;
UPROPERTY(VisibleAnywhere)
float ForwardSpeed = 0.0f; float ForwardSpeed = 0.0f;
UPROPERTY(VisibleAnywhere)
float CollisionIntensityCars = 0.0f; float CollisionIntensityCars = 0.0f;
UPROPERTY(VisibleAnywhere)
float CollisionIntensityPedestrians = 0.0f; float CollisionIntensityPedestrians = 0.0f;
UPROPERTY(VisibleAnywhere)
float CollisionIntensityOther = 0.0f; float CollisionIntensityOther = 0.0f;
UPROPERTY(VisibleAnywhere)
float OtherLaneIntersectionFactor = 0.0f; float OtherLaneIntersectionFactor = 0.0f;
UPROPERTY(VisibleAnywhere)
float OffRoadIntersectionFactor = 0.0f; float OffRoadIntersectionFactor = 0.0f;
std::array<Image, NUMBER_OF_IMAGES> Images; UPROPERTY(VisibleAnywhere)
TArray<FCapturedImage> Images;
}; };

View File

@ -11,8 +11,6 @@
// INI file sections. // INI file sections.
#define S_CARLA_SERVER TEXT("CARLA/Server") #define S_CARLA_SERVER TEXT("CARLA/Server")
#define S_CARLA_SCENECAPTURE TEXT("CARLA/SceneCapture") #define S_CARLA_SCENECAPTURE TEXT("CARLA/SceneCapture")
#define S_CARLA_SCENECAPTURE_MONO TEXT("CARLA/SceneCapture/Mono")
#define S_CARLA_SCENECAPTURE_STEREO TEXT("CARLA/SceneCapture/Stereo")
template <typename TARGET, typename SOURCE> template <typename TARGET, typename SOURCE>
static void SafeCastTo(SOURCE source, TARGET &target) static void SafeCastTo(SOURCE source, TARGET &target)
@ -62,16 +60,19 @@ public:
} }
} }
void GetSceneCaptureMode(const TCHAR* Section, const TCHAR* Key, ESceneCaptureMode &Target) const void GetPostProcessEffect(const TCHAR* Section, const TCHAR* Key, EPostProcessEffect &Target) const
{ {
FString ModeString; FString ValueString;
if (ConfigFile.GetString(Section, Key, ModeString)) { if (ConfigFile.GetString(Section, Key, ValueString)) {
if (ModeString == "Stereo") { if (ValueString == "None") {
Target = ESceneCaptureMode::Stereo; Target = EPostProcessEffect::None;
} else if (ModeString == "Mono") { } else if (ValueString == "SceneFinal") {
Target = ESceneCaptureMode::Mono; Target = EPostProcessEffect::SceneFinal;
} else if (ModeString == "NoCapture") { } else if (ValueString == "Depth") {
Target = ESceneCaptureMode::NoCapture; Target = EPostProcessEffect::Depth;
} else {
UE_LOG(LogCarla, Error, TEXT("Invalid post-processing \"%s\" in INI file"), *ValueString);
Target = EPostProcessEffect::INVALID;
} }
} }
} }
@ -85,6 +86,22 @@ private:
// -- Other static methods ----------------------------------------------------- // -- Other static methods -----------------------------------------------------
// ============================================================================= // =============================================================================
static void GetCameraDescription(
const INIFile &ConfigFile,
const TCHAR* Section,
FCameraDescription &Camera)
{
ConfigFile.GetInt(Section, TEXT("ImageSizeX"), Camera.ImageSizeX);
ConfigFile.GetInt(Section, TEXT("ImageSizeY"), Camera.ImageSizeY);
ConfigFile.GetInt(Section, TEXT("CameraPositionX"), Camera.Position.X);
ConfigFile.GetInt(Section, TEXT("CameraPositionY"), Camera.Position.Y);
ConfigFile.GetInt(Section, TEXT("CameraPositionZ"), Camera.Position.Z);
ConfigFile.GetInt(Section, TEXT("CameraRotationPitch"), Camera.Rotation.Pitch);
ConfigFile.GetInt(Section, TEXT("CameraRotationRoll"), Camera.Rotation.Roll);
ConfigFile.GetInt(Section, TEXT("CameraRotationYaw"), Camera.Rotation.Yaw);
ConfigFile.GetPostProcessEffect(Section, TEXT("PostProcessing"), Camera.PostProcessEffect);
}
static void LoadSettingsFromFile(const FString &FileName, UCarlaSettings &Settings) static void LoadSettingsFromFile(const FString &FileName, UCarlaSettings &Settings)
{ {
UE_LOG(LogCarla, Log, TEXT("Loading settings from \"%s\""), *FileName); UE_LOG(LogCarla, Log, TEXT("Loading settings from \"%s\""), *FileName);
@ -95,35 +112,24 @@ static void LoadSettingsFromFile(const FString &FileName, UCarlaSettings &Settin
ConfigFile.GetInt(S_CARLA_SERVER, TEXT("WritePort"), Settings.WritePort); ConfigFile.GetInt(S_CARLA_SERVER, TEXT("WritePort"), Settings.WritePort);
ConfigFile.GetInt(S_CARLA_SERVER, TEXT("ReadPort"), Settings.ReadPort); ConfigFile.GetInt(S_CARLA_SERVER, TEXT("ReadPort"), Settings.ReadPort);
// SceneCapture. // SceneCapture.
ConfigFile.GetSceneCaptureMode(S_CARLA_SCENECAPTURE, TEXT("Mode"), Settings.SceneCaptureMode); FString Cameras;
// SceneCapture - Mono. ConfigFile.GetString(S_CARLA_SCENECAPTURE, TEXT("Cameras"), Cameras);
ConfigFile.GetInt(S_CARLA_SCENECAPTURE, TEXT("ImageSizeX"), Settings.Mono_ImageSizeX); TArray<FString> CameraNames;
ConfigFile.GetInt(S_CARLA_SCENECAPTURE, TEXT("ImageSizeY"), Settings.Mono_ImageSizeY); Cameras.ParseIntoArray(CameraNames, TEXT(","), true);
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_MONO, TEXT("ImageSizeX"), Settings.Mono_ImageSizeX); for (FString &Name : CameraNames) {
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_MONO, TEXT("ImageSizeY"), Settings.Mono_ImageSizeY); FCameraDescription &Camera = Settings.CameraDescriptions.FindOrAdd(Name);
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_MONO, TEXT("CameraPositionX"), Settings.Mono_CameraPosition.X); GetCameraDescription(ConfigFile, S_CARLA_SCENECAPTURE, Camera);
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_MONO, TEXT("CameraPositionY"), Settings.Mono_CameraPosition.Y);
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_MONO, TEXT("CameraPositionZ"), Settings.Mono_CameraPosition.Z); TArray<FString> SubSections;
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_MONO, TEXT("CameraRotationPitch"), Settings.Mono_CameraRotation.Pitch); Name.ParseIntoArray(SubSections, TEXT("/"), true);
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_MONO, TEXT("CameraRotationRoll"), Settings.Mono_CameraRotation.Roll); check(SubSections.Num() > 0);
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_MONO, TEXT("CameraRotationYaw"), Settings.Mono_CameraRotation.Yaw); FString Section = S_CARLA_SCENECAPTURE;
// SceneCapture - Stereo. for (FString &SubSection : SubSections) {
ConfigFile.GetInt(S_CARLA_SCENECAPTURE, TEXT("ImageSizeX"), Settings.Stereo_ImageSizeX); Section += TEXT("/");
ConfigFile.GetInt(S_CARLA_SCENECAPTURE, TEXT("ImageSizeY"), Settings.Stereo_ImageSizeY); Section += SubSection;
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_STEREO, TEXT("ImageSizeX"), Settings.Stereo_ImageSizeX); GetCameraDescription(ConfigFile, *Section, Camera);
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_STEREO, TEXT("ImageSizeY"), Settings.Stereo_ImageSizeY); }
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_STEREO, TEXT("Camera0PositionX"), Settings.Stereo_Camera0Position.X); }
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_STEREO, TEXT("Camera0PositionY"), Settings.Stereo_Camera0Position.Y);
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_STEREO, TEXT("Camera0PositionZ"), Settings.Stereo_Camera0Position.Z);
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_STEREO, TEXT("Camera1PositionX"), Settings.Stereo_Camera1Position.X);
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_STEREO, TEXT("Camera1PositionY"), Settings.Stereo_Camera1Position.Y);
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_STEREO, TEXT("Camera1PositionZ"), Settings.Stereo_Camera1Position.Z);
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_STEREO, TEXT("Camera0RotationPitch"), Settings.Stereo_Camera0Rotation.Pitch);
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_STEREO, TEXT("Camera0RotationRoll"), Settings.Stereo_Camera0Rotation.Roll);
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_STEREO, TEXT("Camera0RotationYaw"), Settings.Stereo_Camera0Rotation.Yaw);
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_STEREO, TEXT("Camera1RotationPitch"), Settings.Stereo_Camera1Rotation.Pitch);
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_STEREO, TEXT("Camera1RotationRoll"), Settings.Stereo_Camera1Rotation.Roll);
ConfigFile.GetInt(S_CARLA_SCENECAPTURE_STEREO, TEXT("Camera1RotationYaw"), Settings.Stereo_Camera1Rotation.Yaw);
} }
static bool GetSettingsFileName(FString &Value) static bool GetSettingsFileName(FString &Value)
@ -167,14 +173,6 @@ void UCarlaSettings::LoadSettings()
void UCarlaSettings::LogSettings() void UCarlaSettings::LogSettings()
{ {
auto ModeAsString = [](ESceneCaptureMode Mode) {
switch (Mode) {
case ESceneCaptureMode::Mono: return TEXT("Mono");
case ESceneCaptureMode::Stereo: return TEXT("Stereo");
case ESceneCaptureMode::NoCapture: return TEXT("NoCapture");
default: return TEXT("INVALID");
};
};
UE_LOG(LogCarla, Log, TEXT("== CARLA Settings ==============================================================")); UE_LOG(LogCarla, Log, TEXT("== CARLA Settings =============================================================="));
UE_LOG(LogCarla, Log, TEXT("Settings file: %s"), *CurrentFileName); UE_LOG(LogCarla, Log, TEXT("Settings file: %s"), *CurrentFileName);
UE_LOG(LogCarla, Log, TEXT("[%s]"), S_CARLA_SERVER); UE_LOG(LogCarla, Log, TEXT("[%s]"), S_CARLA_SERVER);
@ -183,21 +181,16 @@ void UCarlaSettings::LogSettings()
UE_LOG(LogCarla, Log, TEXT("Write Port = %d"), WritePort); UE_LOG(LogCarla, Log, TEXT("Write Port = %d"), WritePort);
UE_LOG(LogCarla, Log, TEXT("Read Port = %d"), ReadPort); UE_LOG(LogCarla, Log, TEXT("Read Port = %d"), ReadPort);
UE_LOG(LogCarla, Log, TEXT("[%s]"), S_CARLA_SCENECAPTURE); UE_LOG(LogCarla, Log, TEXT("[%s]"), S_CARLA_SCENECAPTURE);
UE_LOG(LogCarla, Log, TEXT("Mode = %s"), ModeAsString(SceneCaptureMode)); UE_LOG(LogCarla, Log, TEXT("Added %d cameras."), CameraDescriptions.Num());
UE_LOG(LogCarla, Log, TEXT("[%s]"), S_CARLA_SCENECAPTURE_MONO); for (auto &Item : CameraDescriptions) {
UE_LOG(LogCarla, Log, TEXT("Image Size = %dx%d"), Mono_ImageSizeX, Mono_ImageSizeY); UE_LOG(LogCarla, Log, TEXT("[%s/%s]"), S_CARLA_SCENECAPTURE, *Item.Key);
UE_LOG(LogCarla, Log, TEXT("Camera Position = (%s)"), *Mono_CameraPosition.ToString()); UE_LOG(LogCarla, Log, TEXT("Image Size = %dx%d"), Item.Value.ImageSizeX, Item.Value.ImageSizeY);
UE_LOG(LogCarla, Log, TEXT("Camera Rotation = (%s)"), *Mono_CameraRotation.ToString()); UE_LOG(LogCarla, Log, TEXT("Camera Position = (%s)"), *Item.Value.Position.ToString());
UE_LOG(LogCarla, Log, TEXT("[%s]"), S_CARLA_SCENECAPTURE_STEREO); UE_LOG(LogCarla, Log, TEXT("Camera Rotation = (%s)"), *Item.Value.Rotation.ToString());
UE_LOG(LogCarla, Log, TEXT("ImageSize = %dx%d"), Stereo_ImageSizeX, Stereo_ImageSizeY); UE_LOG(LogCarla, Log, TEXT("Post-Processing = %s"), *PostProcessEffect::ToString(Item.Value.PostProcessEffect));
UE_LOG(LogCarla, Log, TEXT("Camera0 Position = (%s)"), *Stereo_Camera0Position.ToString()); }
UE_LOG(LogCarla, Log, TEXT("Camera0 Rotation = (%s)"), *Stereo_Camera0Rotation.ToString());
UE_LOG(LogCarla, Log, TEXT("Camera1 Position = (%s)"), *Stereo_Camera1Position.ToString());
UE_LOG(LogCarla, Log, TEXT("Camera1 Rotation = (%s)"), *Stereo_Camera1Rotation.ToString());
UE_LOG(LogCarla, Log, TEXT("================================================================================")); UE_LOG(LogCarla, Log, TEXT("================================================================================"));
} }
#undef S_CARLA_SERVER #undef S_CARLA_SERVER
#undef S_CARLA_SCENECAPTURE #undef S_CARLA_SCENECAPTURE
#undef S_CARLA_SCENECAPTURE_MONO
#undef S_CARLA_SCENECAPTURE_STEREO

View File

@ -3,16 +3,9 @@
#pragma once #pragma once
#include "UObject/NoExportTypes.h" #include "UObject/NoExportTypes.h"
#include "CameraDescription.h"
#include "CarlaSettings.generated.h" #include "CarlaSettings.generated.h"
UENUM(BlueprintType)
enum class ESceneCaptureMode : uint8
{
Mono UMETA(DisplayName = "Mono: Single RGB capture"),
Stereo UMETA(DisplayName = "Stereo: Stereo RGB captures and Depth maps"),
NoCapture UMETA(DisplayName = "No capture")
};
/// Global settings for CARLA. /// Global settings for CARLA.
UCLASS() UCLASS()
class CARLA_API UCarlaSettings : public UObject class CARLA_API UCarlaSettings : public UObject
@ -62,63 +55,9 @@ public:
/// @{ /// @{
public: public:
/** Controls the number and type of scene capture cameras that are added to the player. */ /** Descriptions of the cameras to be attached to the player. */
UPROPERTY(Category = "Scene Capture", EditDefaultsOnly) UPROPERTY(Category = "Scene Capture", EditDefaultsOnly)
ESceneCaptureMode SceneCaptureMode = ESceneCaptureMode::Mono; TMap<FString, FCameraDescription> CameraDescriptions;
/// @}
// ===========================================================================
/// @name Scene Capture - Mono
// ===========================================================================
/// @{
public:
/** X size in pixels of the captured image. */
UPROPERTY(Category = "Scene Capture|Mono", EditDefaultsOnly)
uint32 Mono_ImageSizeX = 720u;
/** Y size in pixels of the captured image. */
UPROPERTY(Category = "Scene Capture|Mono", EditDefaultsOnly)
uint32 Mono_ImageSizeY = 512u;
/** Camera position relative to the car. */
UPROPERTY(Category = "Scene Capture|Mono", EditDefaultsOnly)
FVector Mono_CameraPosition = {170.0f, 0.0f, 150.0f};
/** Camera rotation relative to the car. */
UPROPERTY(Category = "Scene Capture|Mono", EditDefaultsOnly)
FRotator Mono_CameraRotation = {0.0f, 0.0f, 0.0f};
/// @}
// ===========================================================================
/// @name Scene Capture - Stereo
// ===========================================================================
/// @{
public:
/** X size in pixels of the captured image. */
UPROPERTY(Category = "Scene Capture|Stereo", EditDefaultsOnly)
uint32 Stereo_ImageSizeX = 720u;
/** Y size in pixels of the captured image. */
UPROPERTY(Category = "Scene Capture|Stereo", EditDefaultsOnly)
uint32 Stereo_ImageSizeY = 512u;
/** Camera0 position relative to the car. */
UPROPERTY(Category = "Scene Capture|Stereo", EditDefaultsOnly)
FVector Stereo_Camera0Position = {170.0f, 30.0f, 150.0f};
/** Camera0 rotation relative to the car. */
UPROPERTY(Category = "Scene Capture|Stereo", EditDefaultsOnly)
FRotator Stereo_Camera0Rotation = {0.0f, 0.0f, 0.0f};
/** Camera1 position relative to the car. */
UPROPERTY(Category = "Scene Capture|Stereo", EditDefaultsOnly)
FVector Stereo_Camera1Position = {170.0f, -30.0f, 150.0f};
/** Camera1 rotation relative to the car. */
UPROPERTY(Category = "Scene Capture|Stereo", EditDefaultsOnly)
FRotator Stereo_Camera1Rotation = {0.0f, 0.0f, 0.0f};
/// @} /// @}
}; };

View File

@ -6,6 +6,7 @@
#include "Camera/CameraComponent.h" #include "Camera/CameraComponent.h"
#include "GameFramework/Pawn.h" #include "GameFramework/Pawn.h"
#include "GameFramework/SpringArmComponent.h" #include "GameFramework/SpringArmComponent.h"
#include "SceneCaptureCamera.h"
#include "WheeledVehicle.h" #include "WheeledVehicle.h"
#include "WheeledVehicleMovementComponent.h" #include "WheeledVehicleMovementComponent.h"
@ -93,16 +94,19 @@ void ACarlaVehicleController::Possess(APawn *aPawn)
} }
} }
static void ReadCameraPixels( void ACarlaVehicleController::BeginPlay()
const ASceneCaptureCamera *Camera,
ACarlaPlayerState::Image &Image)
{ {
if (Camera != nullptr) { CarlaPlayerState->Images.Empty();
if (Camera->ReadPixels(Image.BitMap)) { const auto NumberOfCameras = SceneCaptureCameras.Num();
if (NumberOfCameras > 0) {
CarlaPlayerState->Images.AddDefaulted(NumberOfCameras);
for (auto i = 0; i < NumberOfCameras; ++i) {
auto *Camera = SceneCaptureCameras[i];
check(Camera != nullptr);
auto &Image = CarlaPlayerState->Images[i];
Image.SizeX = Camera->GetImageSizeX(); Image.SizeX = Camera->GetImageSizeX();
Image.SizeY = Camera->GetImageSizeY(); Image.SizeY = Camera->GetImageSizeY();
} else { Image.PostProcessEffect = Camera->GetPostProcessEffect();
Image.BitMap.Empty(); // Clears the array.
} }
} }
} }
@ -120,12 +124,15 @@ void ACarlaVehicleController::Tick(float DeltaTime)
const FVector CurrentSpeed = CarlaPlayerState->ForwardSpeed * CarlaPlayerState->Orientation; const FVector CurrentSpeed = CarlaPlayerState->ForwardSpeed * CarlaPlayerState->Orientation;
CarlaPlayerState->Acceleration = (CurrentSpeed - PreviousSpeed) / DeltaTime; CarlaPlayerState->Acceleration = (CurrentSpeed - PreviousSpeed) / DeltaTime;
CarlaPlayerState->CurrentGear = GetVehicleCurrentGear(); CarlaPlayerState->CurrentGear = GetVehicleCurrentGear();
/// @todo Set intersection factors. /// @todo #15 Set intersection factors.
using CPS = ACarlaPlayerState; const auto NumberOfCameras = SceneCaptureCameras.Num();
ReadCameraPixels(RGBCameras[0u], CarlaPlayerState->Images[CPS::ImageRGB0]); check(NumberOfCameras == CarlaPlayerState->Images.Num());
ReadCameraPixels(RGBCameras[1u], CarlaPlayerState->Images[CPS::ImageRGB1]); for (auto i = 0; i < NumberOfCameras; ++i) {
ReadCameraPixels(DepthCameras[0u], CarlaPlayerState->Images[CPS::ImageDepth0]); auto &Image = CarlaPlayerState->Images[i];
ReadCameraPixels(DepthCameras[1u], CarlaPlayerState->Images[CPS::ImageDepth1]); if (!SceneCaptureCameras[i]->ReadPixels(Image.BitMap)) {
Image.BitMap.Empty();
}
}
} }
} }
@ -166,30 +173,20 @@ int32 ACarlaVehicleController::GetVehicleCurrentGear() const
// -- Scene capture ------------------------------------------------------------ // -- Scene capture ------------------------------------------------------------
// ============================================================================= // =============================================================================
void ACarlaVehicleController::RegisterCaptureCamera(ASceneCaptureCamera &CaptureCamera) void ACarlaVehicleController::AddSceneCaptureCamera(const FCameraDescription &Description)
{ {
AddTickPrerequisiteActor(&CaptureCamera); auto Camera = GetWorld()->SpawnActor<ASceneCaptureCamera>(Description.Position, Description.Rotation);
const auto Effect = CaptureCamera.GetPostProcessEffect(); Camera->Set(Description);
auto &Cameras = (Effect == EPostProcessEffect::Depth ? DepthCameras : RGBCameras); Camera->AttachToActor(GetPawn(), FAttachmentTransformRules::KeepRelativeTransform);
Camera->SetOwner(GetPawn());
for (auto i = 0u; i < Cameras.size(); ++i) { AddTickPrerequisiteActor(Camera);
if (Cameras[i] == nullptr) { SceneCaptureCameras.Add(Camera);
Cameras[i] = &CaptureCamera;
UE_LOG(
LogCarla,
Log,
TEXT("Registered capture camera %d with postprocess \"%s\""),
i,
*CaptureCamera.GetPostProcessEffectAsString());
return;
}
}
UE_LOG( UE_LOG(
LogCarla, LogCarla,
Warning, Log,
TEXT("Attempting to register a capture camera of type \"%d\" but already have %d, captures from this camera won't be sent"), TEXT("Created capture camera %d with postprocess \"%s\""),
*CaptureCamera.GetPostProcessEffectAsString(), SceneCaptureCameras.Num() - 1,
Cameras.size()); *PostProcessEffect::ToString(Camera->GetPostProcessEffect()));
} }
// ============================================================================= // =============================================================================

View File

@ -11,6 +11,7 @@ class ASceneCaptureCamera;
class UCameraComponent; class UCameraComponent;
class USpringArmComponent; class USpringArmComponent;
class UWheeledVehicleMovementComponent; class UWheeledVehicleMovementComponent;
struct FCameraDescription;
/** /**
* *
@ -41,6 +42,8 @@ public:
virtual void Possess(APawn *aPawn) override; virtual void Possess(APawn *aPawn) override;
virtual void BeginPlay() override;
virtual void Tick(float DeltaTime) override; virtual void Tick(float DeltaTime) override;
virtual void CalcCamera(float DeltaTime, FMinimalViewInfo& OutResult) override; virtual void CalcCamera(float DeltaTime, FMinimalViewInfo& OutResult) override;
@ -80,7 +83,7 @@ public:
/// @{ /// @{
public: public:
void RegisterCaptureCamera(ASceneCaptureCamera &CaptureCamera); void AddSceneCaptureCamera(const FCameraDescription &CameraDescription);
/// @} /// @}
// =========================================================================== // ===========================================================================
@ -175,6 +178,9 @@ private:
UPROPERTY() UPROPERTY()
UWheeledVehicleMovementComponent *MovementComponent; UWheeledVehicleMovementComponent *MovementComponent;
UPROPERTY()
TArray<ASceneCaptureCamera *> SceneCaptureCameras;
// Cast for quick access to the custom player state. // Cast for quick access to the custom player state.
UPROPERTY() UPROPERTY()
ACarlaPlayerState *CarlaPlayerState; ACarlaPlayerState *CarlaPlayerState;
@ -182,10 +188,4 @@ private:
// Cast for quick access to the custom HUD. // Cast for quick access to the custom HUD.
UPROPERTY() UPROPERTY()
ACarlaHUD *CarlaHUD; ACarlaHUD *CarlaHUD;
using CaptureCameraArray = std::array<const ASceneCaptureCamera *, 2u>;
CaptureCameraArray RGBCameras;
CaptureCameraArray DepthCameras;
}; };

View File

@ -0,0 +1,13 @@
// CARLA, Copyright (C) 2017 Computer Vision Center (CVC)
#include "Carla.h"
#include "PostProcessEffect.h"
#include "Package.h"
FString PostProcessEffect::ToString(EPostProcessEffect PostProcessEffect)
{
const UEnum* ptr = FindObject<UEnum>(ANY_PACKAGE, TEXT("EPostProcessEffect"), true);
if(!ptr)
return FString("Invalid");
return ptr->GetEnumName(static_cast<int32>(PostProcessEffect));
}

View File

@ -0,0 +1,23 @@
// CARLA, Copyright (C) 2017 Computer Vision Center (CVC)
#pragma once
#include "PostProcessEffect.generated.h"
UENUM(BlueprintType)
enum class EPostProcessEffect : uint8
{
None UMETA(DisplayName = "RGB without any post-processing"),
SceneFinal UMETA(DisplayName = "RGB with post-processing present at the scene"),
Depth UMETA(DisplayName = "Depth Map"),
SIZE UMETA(Hidden),
INVALID UMETA(Hidden),
};
/// Helper class for working with EPostProcessEffect.
class CARLA_API PostProcessEffect {
public:
static FString ToString(EPostProcessEffect PostProcessEffect);
};

View File

@ -1,4 +1,4 @@
// Fill out your copyright notice in the Description page of Project Settings. // CARLA, Copyright (C) 2017 Computer Vision Center (CVC)
#include "Carla.h" #include "Carla.h"
#include "SceneCaptureCamera.h" #include "SceneCaptureCamera.h"
@ -100,12 +100,10 @@ void ASceneCaptureCamera::SetPostProcessEffect(EPostProcessEffect otherPostProce
PostProcessEffect = otherPostProcessEffect; PostProcessEffect = otherPostProcessEffect;
} }
FString ASceneCaptureCamera::GetPostProcessEffectAsString() const void ASceneCaptureCamera::Set(const FCameraDescription &CameraDescription)
{ {
const UEnum* ptr = FindObject<UEnum>(ANY_PACKAGE, TEXT("EPostProcessEffect"), true); SetImageSize(CameraDescription.ImageSizeX, CameraDescription.ImageSizeY);
if(!ptr) SetPostProcessEffect(CameraDescription.PostProcessEffect);
return FString("Invalid");
return ptr->GetEnumName(static_cast<int32>(PostProcessEffect));
} }
bool ASceneCaptureCamera::ReadPixels(TArray<FColor> &BitMap) const bool ASceneCaptureCamera::ReadPixels(TArray<FColor> &BitMap) const

View File

@ -1,14 +1,10 @@
// Fill out your copyright notice in the Description page of Project Settings. // CARLA, Copyright (C) 2017 Computer Vision Center (CVC)
/**
* Own SceneCapture, re-implementing some of the methods since ASceneCapture
* cannot be subclassed.
*/
#pragma once #pragma once
#include "GameFramework/Actor.h" #include "GameFramework/Actor.h"
#include "StaticMeshResources.h" #include "StaticMeshResources.h"
#include "Game/CameraDescription.h"
#include "SceneCaptureCamera.generated.h" #include "SceneCaptureCamera.generated.h"
class UDrawFrustumComponent; class UDrawFrustumComponent;
@ -16,16 +12,8 @@ class USceneCaptureComponent2D;
class UStaticMeshComponent; class UStaticMeshComponent;
class UTextureRenderTarget2D; class UTextureRenderTarget2D;
UENUM(BlueprintType) /// Own SceneCapture, re-implementing some of the methods since ASceneCapture
enum class EPostProcessEffect : uint8 /// cannot be subclassed.
{
None UMETA(DisplayName = "RGB without any post-processing"),
SceneFinal UMETA(DisplayName = "RGB with post-processing present at the scene"),
Depth UMETA(DisplayName = "Depth Map"),
SIZE UMETA(Hidden)
};
UCLASS(hidecategories=(Collision, Attachment, Actor)) UCLASS(hidecategories=(Collision, Attachment, Actor))
class CARLA_API ASceneCaptureCamera : public AActor class CARLA_API ASceneCaptureCamera : public AActor
{ {
@ -62,7 +50,7 @@ public:
void SetPostProcessEffect(EPostProcessEffect PostProcessEffect); void SetPostProcessEffect(EPostProcessEffect PostProcessEffect);
FString GetPostProcessEffectAsString() const; void Set(const FCameraDescription &CameraDescription);
bool ReadPixels(TArray<FColor> &BitMap) const; bool ReadPixels(TArray<FColor> &BitMap) const;