Sensor factory (wip)

This commit is contained in:
nsubiron 2018-02-13 20:54:50 +01:00
parent cb43190184
commit e96a414e30
20 changed files with 344 additions and 362 deletions

View File

@ -18,6 +18,8 @@
#include "CarlaHUD.h" #include "CarlaHUD.h"
#include "CarlaPlayerState.h" #include "CarlaPlayerState.h"
#include "CarlaVehicleController.h" #include "CarlaVehicleController.h"
#include "Sensor/Sensor.h"
#include "Sensor/SensorFactory.h"
#include "Settings/CarlaSettings.h" #include "Settings/CarlaSettings.h"
#include "Tagger.h" #include "Tagger.h"
#include "TaggerDelegate.h" #include "TaggerDelegate.h"
@ -222,12 +224,9 @@ void ACarlaGameModeBase::AttachCaptureCamerasToPlayer()
OverridePostProcessParameters = &Weather->CameraPostProcessParameters; OverridePostProcessParameters = &Weather->CameraPostProcessParameters;
} }
for (const auto &Item : Settings.CameraDescriptions) { for (const auto &Item : Settings.SensorDescriptions) {
PlayerController->AddSceneCaptureCamera(Item.Value, OverridePostProcessParameters); auto *Sensor = FSensorFactory::Make(Item.Key, *Item.Value, *GetWorld());
} Sensor->AttachToActor(PlayerController->GetPawn());
for (const auto &Item : Settings.LidarDescriptions) {
PlayerController->AddSceneCaptureLidar(Item.Value);
} }
} }

View File

@ -15,8 +15,6 @@ void ACarlaPlayerState::Reset()
CollisionIntensityCars = 0.0f; CollisionIntensityCars = 0.0f;
CollisionIntensityPedestrians = 0.0f; CollisionIntensityPedestrians = 0.0f;
CollisionIntensityOther = 0.0f; CollisionIntensityOther = 0.0f;
Images.Empty();
LidarSegments.Empty();
} }
void ACarlaPlayerState::CopyProperties(APlayerState *PlayerState) void ACarlaPlayerState::CopyProperties(APlayerState *PlayerState)
@ -45,8 +43,6 @@ void ACarlaPlayerState::CopyProperties(APlayerState *PlayerState)
CollisionIntensityOther = Other->CollisionIntensityOther; CollisionIntensityOther = Other->CollisionIntensityOther;
OtherLaneIntersectionFactor = Other->OtherLaneIntersectionFactor; OtherLaneIntersectionFactor = Other->OtherLaneIntersectionFactor;
OffRoadIntersectionFactor = Other->OffRoadIntersectionFactor; OffRoadIntersectionFactor = Other->OffRoadIntersectionFactor;
Images = Other->Images;
LidarSegments = Other->LidarSegments;
UE_LOG(LogCarla, Log, TEXT("Copied properties of ACarlaPlayerState")); UE_LOG(LogCarla, Log, TEXT("Copied properties of ACarlaPlayerState"));
} }
} }

View File

@ -184,46 +184,6 @@ public:
return OffRoadIntersectionFactor; return OffRoadIntersectionFactor;
} }
/// @}
// ===========================================================================
/// @name Images
// ===========================================================================
/// @{
UFUNCTION(BlueprintCallable)
int32 GetNumberOfImages() const
{
return Images.Num();
}
UFUNCTION(BlueprintCallable)
bool HasImages() const
{
return GetNumberOfImages() > 0;
}
UFUNCTION(BlueprintCallable)
int32 GetNumberOfLidarsMeasurements() const
{
return LidarSegments.Num();
}
UFUNCTION(BlueprintCallable)
bool HasLidarsMeasurements() const
{
return GetNumberOfLidarsMeasurements() > 0;
}
const TArray<FCapturedImage> &GetImages() const
{
return Images;
}
const TArray<FCapturedLidarSegment> &GetLidarSegments() const
{
return LidarSegments;
}
/// @} /// @}
// =========================================================================== // ===========================================================================
// -- Modifiers -------------------------------------------------------------- // -- Modifiers --------------------------------------------------------------
@ -301,10 +261,4 @@ private:
UPROPERTY(VisibleAnywhere) UPROPERTY(VisibleAnywhere)
float OffRoadIntersectionFactor = 0.0f; float OffRoadIntersectionFactor = 0.0f;
UPROPERTY(VisibleAnywhere)
TArray<FCapturedImage> Images;
UPROPERTY(VisibleAnywhere)
TArray<FCapturedLidarSegment> LidarSegments;
}; };

View File

@ -70,78 +70,78 @@ static inline void Set(carla_transform &lhs, const FTransform &rhs)
Set(lhs.rotation, rhs.Rotator()); Set(lhs.rotation, rhs.Rotator());
} }
static void Set(carla_image &cImage, const FCapturedImage &uImage) // static void Set(carla_image &cImage, const FCapturedImage &uImage)
{ // {
if (uImage.BitMap.Num() > 0) { // if (uImage.BitMap.Num() > 0) {
cImage.width = uImage.SizeX; // cImage.width = uImage.SizeX;
cImage.height = uImage.SizeY; // cImage.height = uImage.SizeY;
cImage.type = PostProcessEffect::ToUInt(uImage.PostProcessEffect); // cImage.type = PostProcessEffect::ToUInt(uImage.PostProcessEffect);
cImage.fov = uImage.FOVAngle; // cImage.fov = uImage.FOVAngle;
cImage.data = &uImage.BitMap.GetData()->DWColor(); // cImage.data = &uImage.BitMap.GetData()->DWColor();
#ifdef CARLA_SERVER_EXTRA_LOG // #ifdef CARLA_SERVER_EXTRA_LOG
{ // {
const auto Size = uImage.BitMap.Num(); // const auto Size = uImage.BitMap.Num();
UE_LOG(LogCarlaServer, Log, TEXT("Sending image %dx%d (%d) type %d"), cImage.width, cImage.height, Size, cImage.type); // UE_LOG(LogCarlaServer, Log, TEXT("Sending image %dx%d (%d) type %d"), cImage.width, cImage.height, Size, cImage.type);
} // }
} else { // } else {
UE_LOG(LogCarlaServer, Warning, TEXT("Sending empty image")); // UE_LOG(LogCarlaServer, Warning, TEXT("Sending empty image"));
#endif // CARLA_SERVER_EXTRA_LOG // #endif // CARLA_SERVER_EXTRA_LOG
} // }
} // }
struct carla_lidar_measurement_data { // struct carla_lidar_measurement_data {
TUniquePtr<uint32_t[]> points_count_by_channel; // TUniquePtr<uint32_t[]> points_count_by_channel;
TUniquePtr<double[]> points; // TUniquePtr<double[]> points;
}; // };
static void Set( // static void Set(
carla_lidar_measurement &cLidarMeasurement, // carla_lidar_measurement &cLidarMeasurement,
const FCapturedLidarSegment &uLidarSegment, // const FCapturedLidarSegment &uLidarSegment,
carla_lidar_measurement_data &cLidarMeasurementData) // carla_lidar_measurement_data &cLidarMeasurementData)
{ // {
if (uLidarSegment.LidarLasersSegments.Num() > 0) { // if (uLidarSegment.LidarLasersSegments.Num() > 0) {
cLidarMeasurement.horizontal_angle = uLidarSegment.HorizontalAngle; // cLidarMeasurement.horizontal_angle = uLidarSegment.HorizontalAngle;
cLidarMeasurement.channels_count = uLidarSegment.LidarLasersSegments.Num(); // cLidarMeasurement.channels_count = uLidarSegment.LidarLasersSegments.Num();
cLidarMeasurementData.points_count_by_channel = MakeUnique<uint32_t[]>(cLidarMeasurement.channels_count); // cLidarMeasurementData.points_count_by_channel = MakeUnique<uint32_t[]>(cLidarMeasurement.channels_count);
size_t total_points = 0; // size_t total_points = 0;
for(int i=0; i<cLidarMeasurement.channels_count; i++) // for(int i=0; i<cLidarMeasurement.channels_count; i++)
{ // {
size_t points_count = uLidarSegment.LidarLasersSegments[0].Points.Num(); // size_t points_count = uLidarSegment.LidarLasersSegments[0].Points.Num();
cLidarMeasurementData.points_count_by_channel[i] = points_count; // cLidarMeasurementData.points_count_by_channel[i] = points_count;
total_points += points_count; // total_points += points_count;
} // }
cLidarMeasurementData.points = MakeUnique<double[]>(3 * total_points); // cLidarMeasurementData.points = MakeUnique<double[]>(3 * total_points);
size_t points_filled = 0; // size_t points_filled = 0;
for(int i=0; i<cLidarMeasurement.channels_count; i++) // for(int i=0; i<cLidarMeasurement.channels_count; i++)
{ // {
size_t points_count = cLidarMeasurementData.points_count_by_channel[i]; // size_t points_count = cLidarMeasurementData.points_count_by_channel[i];
auto& laser_points = uLidarSegment.LidarLasersSegments[i].Points; // auto& laser_points = uLidarSegment.LidarLasersSegments[i].Points;
for(int pi=0; pi<points_count; pi++) // for(int pi=0; pi<points_count; pi++)
{ // {
cLidarMeasurementData.points[3 * (pi + points_filled)] = laser_points[pi].X; // cLidarMeasurementData.points[3 * (pi + points_filled)] = laser_points[pi].X;
cLidarMeasurementData.points[3 * (pi + points_filled) + 1] = laser_points[pi].Y; // cLidarMeasurementData.points[3 * (pi + points_filled) + 1] = laser_points[pi].Y;
cLidarMeasurementData.points[3 * (pi + points_filled) + 2] = laser_points[pi].Z; // cLidarMeasurementData.points[3 * (pi + points_filled) + 2] = laser_points[pi].Z;
} // }
points_filled += points_count; // points_filled += points_count;
} // }
cLidarMeasurement.points_count_by_channel = cLidarMeasurementData.points_count_by_channel.Get(); // cLidarMeasurement.points_count_by_channel = cLidarMeasurementData.points_count_by_channel.Get();
cLidarMeasurement.data = cLidarMeasurementData.points.Get(); // cLidarMeasurement.data = cLidarMeasurementData.points.Get();
#ifdef CARLA_SERVER_EXTRA_LOG // #ifdef CARLA_SERVER_EXTRA_LOG
{ // {
const auto Size = uImage.BitMap.Num(); // const auto Size = uImage.BitMap.Num();
UE_LOG(LogCarlaServer, Log, TEXT("Sending lidar measurement %d x %d"), uLidarSegment.LidarLasersSegments.Num(), uLidarSegment.LidarLasersSegments[0].Points.Num()); // UE_LOG(LogCarlaServer, Log, TEXT("Sending lidar measurement %d x %d"), uLidarSegment.LidarLasersSegments.Num(), uLidarSegment.LidarLasersSegments[0].Points.Num());
} // }
} else { // } else {
UE_LOG(LogCarlaServer, Warning, TEXT("Sending empty lidar measurement")); // UE_LOG(LogCarlaServer, Warning, TEXT("Sending empty lidar measurement"));
#endif // CARLA_SERVER_EXTRA_LOG // #endif // CARLA_SERVER_EXTRA_LOG
} // }
} // }
static void SetBoxSpeedAndType(carla_agent &values, const ACharacter *Walker) static void SetBoxSpeedAndType(carla_agent &values, const ACharacter *Walker)
{ {
@ -393,29 +393,5 @@ CarlaServer::ErrorCode CarlaServer::SendMeasurements(
UE_LOG(LogCarlaServer, Log, TEXT("Sending data of %d agents"), values.number_of_non_player_agents); UE_LOG(LogCarlaServer, Log, TEXT("Sending data of %d agents"), values.number_of_non_player_agents);
#endif // CARLA_SERVER_EXTRA_LOG #endif // CARLA_SERVER_EXTRA_LOG
// Images. return ParseErrorCode(carla_write_measurements(Server, values));
const auto NumberOfImages = PlayerState.GetNumberOfImages();
TUniquePtr<carla_image[]> images;
if (NumberOfImages > 0) {
images = MakeUnique<carla_image[]>(NumberOfImages);
for (auto i = 0; i < NumberOfImages; ++i) {
Set(images[i], PlayerState.GetImages()[i]);
}
}
// Lidars.
auto NumberOfLidarMeasurements = PlayerState.GetNumberOfLidarsMeasurements();
TUniquePtr<carla_lidar_measurement[]> lidar_measurements;
TUniquePtr<carla_lidar_measurement_data[]> lidar_measurements_data;
if (NumberOfLidarMeasurements > 0) {
lidar_measurements = MakeUnique<carla_lidar_measurement[]>(NumberOfLidarMeasurements);
lidar_measurements_data = MakeUnique<carla_lidar_measurement_data[]>(NumberOfLidarMeasurements);
for (auto i = 0; i < NumberOfLidarMeasurements; ++i) {
Set(lidar_measurements[i], PlayerState.GetLidarSegments()[i], lidar_measurements_data[i]);
}
}
return ParseErrorCode(carla_write_measurements(
Server, values, images.Get(), lidar_measurements.Get(),
NumberOfImages, NumberOfLidarMeasurements));
} }

View File

@ -56,33 +56,6 @@ void ACarlaVehicleController::Possess(APawn *aPawn)
// -- AActor ------------------------------------------------------------------- // -- AActor -------------------------------------------------------------------
// ============================================================================= // =============================================================================
void ACarlaVehicleController::BeginPlay()
{
Super::BeginPlay();
if (CarlaPlayerState != nullptr) {
CarlaPlayerState->Images.Empty();
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.SizeY = Camera->GetImageSizeY();
Image.FOVAngle = Camera->GetFOVAngle();
Image.PostProcessEffect = Camera->GetPostProcessEffect();
}
}
// Lidars
const auto NumberOfLidars = SceneCaptureLidars.Num();
if (NumberOfLidars > 0) {
CarlaPlayerState->LidarSegments.AddDefaulted(NumberOfLidars);
}
}
}
void ACarlaVehicleController::Tick(float DeltaTime) void ACarlaVehicleController::Tick(float DeltaTime)
{ {
Super::Tick(DeltaTime); Super::Tick(DeltaTime);
@ -104,66 +77,9 @@ void ACarlaVehicleController::Tick(float DeltaTime)
CarlaPlayerState->SpeedLimit = GetSpeedLimit(); CarlaPlayerState->SpeedLimit = GetSpeedLimit();
CarlaPlayerState->TrafficLightState = GetTrafficLightState(); CarlaPlayerState->TrafficLightState = GetTrafficLightState();
IntersectPlayerWithRoadMap(); IntersectPlayerWithRoadMap();
const auto NumberOfCameras = SceneCaptureCameras.Num();
check(NumberOfCameras == CarlaPlayerState->Images.Num());
for (auto i = 0; i < NumberOfCameras; ++i) {
auto &Image = CarlaPlayerState->Images[i];
if (!SceneCaptureCameras[i]->ReadPixels(Image.BitMap)) {
Image.BitMap.Empty();
}
}
// Capture lidars
const auto NumberOfLidars = SceneCaptureLidars.Num();
check(NumberOfLidars == CarlaPlayerState->LidarSegments.Num());
for (auto i = 0; i < NumberOfLidars; ++i) {
auto &LidarSegment = CarlaPlayerState->LidarSegments[i];
SceneCaptureLidars[i]->ReadPoints(DeltaTime, LidarSegment);
}
} }
} }
// =============================================================================
// -- Scene capture ------------------------------------------------------------
// =============================================================================
void ACarlaVehicleController::AddSceneCaptureCamera(
const FCameraDescription &Description,
const FCameraPostProcessParameters *OverridePostProcessParameters)
{
auto Camera = GetWorld()->SpawnActor<ASceneCaptureCamera>(Description.Position, Description.Rotation);
if (OverridePostProcessParameters != nullptr) {
Camera->Set(Description, *OverridePostProcessParameters);
} else {
Camera->Set(Description);
}
Camera->AttachToActor(GetPawn(), FAttachmentTransformRules::KeepRelativeTransform);
Camera->SetOwner(GetPawn());
AddTickPrerequisiteActor(Camera);
SceneCaptureCameras.Add(Camera);
UE_LOG(
LogCarla,
Log,
TEXT("Created capture camera %d with postprocess \"%s\""),
SceneCaptureCameras.Num() - 1,
*PostProcessEffect::ToString(Camera->GetPostProcessEffect()));
}
void ACarlaVehicleController::AddSceneCaptureLidar(
const FLidarDescription &Description)
{
auto Lidar = GetWorld()->SpawnActor<ALidar>(Description.Position, Description.Rotation);
Lidar->Set(Description);
Lidar->AttachToActor(GetPawn(), FAttachmentTransformRules::KeepRelativeTransform);
Lidar->SetOwner(GetPawn());
AddTickPrerequisiteActor(Lidar);
SceneCaptureLidars.Add(Lidar);
UE_LOG(
LogCarla,
Log,
TEXT("Created lidar %d"),
SceneCaptureLidars.Num() - 1);
}
// ============================================================================= // =============================================================================
// -- Events ------------------------------------------------------------------- // -- Events -------------------------------------------------------------------
// ============================================================================= // =============================================================================

View File

@ -11,10 +11,11 @@
class ACarlaHUD; class ACarlaHUD;
class ACarlaPlayerState; class ACarlaPlayerState;
class ASceneCaptureCamera;
class ALidar; class ALidar;
struct FCameraDescription; class ASceneCaptureCamera;
struct FLidarDescription; class UCameraDescription;
class ULidarDescription;
struct FCameraPostProcessParameters;
/// The CARLA player controller. /// The CARLA player controller.
UCLASS() UCLASS()
@ -48,8 +49,6 @@ public:
/// @{ /// @{
public: public:
virtual void BeginPlay() override;
virtual void Tick(float DeltaTime) override; virtual void Tick(float DeltaTime) override;
/// @} /// @}
@ -76,20 +75,6 @@ public:
return *CarlaPlayerState; return *CarlaPlayerState;
} }
/// @}
// ===========================================================================
/// @name Scene Capture
// ===========================================================================
/// @{
public:
void AddSceneCaptureCamera(
const FCameraDescription &CameraDescription,
const FCameraPostProcessParameters *OverridePostProcessParameters);
void AddSceneCaptureLidar(
const FLidarDescription &LidarDescription);
/// @} /// @}
// =========================================================================== // ===========================================================================
/// @name Events /// @name Events
@ -119,12 +104,6 @@ private:
// =========================================================================== // ===========================================================================
private: private:
UPROPERTY()
TArray<ASceneCaptureCamera *> SceneCaptureCameras;
UPROPERTY()
TArray<ALidar *> SceneCaptureLidars;
// Cast for quick access to the custom player state. // Cast for quick access to the custom player state.
UPROPERTY() UPROPERTY()
ACarlaPlayerState *CarlaPlayerState; ACarlaPlayerState *CarlaPlayerState;

View File

@ -22,7 +22,7 @@ ALidar::ALidar(const FObjectInitializer& ObjectInitializer) :
CreateLasers(); CreateLasers();
} }
void ALidar::Set(const FLidarDescription &LidarDescription) void ALidar::Set(const ULidarDescription &LidarDescription)
{ {
Channels = LidarDescription.Channels; Channels = LidarDescription.Channels;
Range = LidarDescription.Range; Range = LidarDescription.Range;

View File

@ -18,7 +18,7 @@ public:
// Sets default values for this actor's properties // Sets default values for this actor's properties
ALidar(const FObjectInitializer& ObjectInitializer); ALidar(const FObjectInitializer& ObjectInitializer);
void Set(const FLidarDescription &LidarDescription); void Set(const ULidarDescription &LidarDescription);
protected: protected:
// Called when the game starts or when spawned // Called when the game starts or when spawned

View File

@ -155,29 +155,26 @@ void ASceneCaptureCamera::SetTargetGamma(const float TargetGamma)
CaptureRenderTarget->TargetGamma = TargetGamma; CaptureRenderTarget->TargetGamma = TargetGamma;
} }
void ASceneCaptureCamera::Set(const FCameraDescription &CameraDescription) void ASceneCaptureCamera::Set(const UCameraDescription &CameraDescription)
{ {
/// @todo What to do with OverridePostProcessParameters?
// if (CameraDescription.OverridePostProcessParameters != nullptr) {
// auto Override = *CameraDescription.OverridePostProcessParameters;
// auto &PostProcessSettings = CaptureComponent2D->PostProcessSettings;
// PostProcessSettings.bOverride_AutoExposureMethod = true;
// PostProcessSettings.AutoExposureMethod = Override.AutoExposureMethod;
// PostProcessSettings.bOverride_AutoExposureMinBrightness = true;
// PostProcessSettings.AutoExposureMinBrightness = Override.AutoExposureMinBrightness;
// PostProcessSettings.bOverride_AutoExposureMaxBrightness = true;
// PostProcessSettings.AutoExposureMaxBrightness = Override.AutoExposureMaxBrightness;
// PostProcessSettings.bOverride_AutoExposureBias = true;
// PostProcessSettings.AutoExposureBias = Override.AutoExposureBias;
// }
SetImageSize(CameraDescription.ImageSizeX, CameraDescription.ImageSizeY); SetImageSize(CameraDescription.ImageSizeX, CameraDescription.ImageSizeY);
SetPostProcessEffect(CameraDescription.PostProcessEffect); SetPostProcessEffect(CameraDescription.PostProcessEffect);
SetFOVAngle(CameraDescription.FOVAngle); SetFOVAngle(CameraDescription.FOVAngle);
} }
void ASceneCaptureCamera::Set(
const FCameraDescription &CameraDescription,
const FCameraPostProcessParameters &OverridePostProcessParameters)
{
auto &PostProcessSettings = CaptureComponent2D->PostProcessSettings;
PostProcessSettings.bOverride_AutoExposureMethod = true;
PostProcessSettings.AutoExposureMethod = OverridePostProcessParameters.AutoExposureMethod;
PostProcessSettings.bOverride_AutoExposureMinBrightness = true;
PostProcessSettings.AutoExposureMinBrightness = OverridePostProcessParameters.AutoExposureMinBrightness;
PostProcessSettings.bOverride_AutoExposureMaxBrightness = true;
PostProcessSettings.AutoExposureMaxBrightness = OverridePostProcessParameters.AutoExposureMaxBrightness;
PostProcessSettings.bOverride_AutoExposureBias = true;
PostProcessSettings.AutoExposureBias = OverridePostProcessParameters.AutoExposureBias;
Set(CameraDescription);
}
bool ASceneCaptureCamera::ReadPixels(TArray<FColor> &BitMap) const bool ASceneCaptureCamera::ReadPixels(TArray<FColor> &BitMap) const
{ {
FTextureRenderTargetResource* RTResource = CaptureRenderTarget->GameThread_GetRenderTargetResource(); FTextureRenderTargetResource* RTResource = CaptureRenderTarget->GameThread_GetRenderTargetResource();

View File

@ -60,11 +60,7 @@ public:
void SetTargetGamma(float TargetGamma); void SetTargetGamma(float TargetGamma);
void Set(const FCameraDescription &CameraDescription); void Set(const UCameraDescription &CameraDescription);
void Set(
const FCameraDescription &CameraDescription,
const FCameraPostProcessParameters &OverridePostProcessParameters);
bool ReadPixels(TArray<FColor> &BitMap) const; bool ReadPixels(TArray<FColor> &BitMap) const;

View File

@ -7,6 +7,20 @@
#include "Carla.h" #include "Carla.h"
#include "Sensor.h" #include "Sensor.h"
ASensor::ASensor(const FObjectInitializer& ObjectInitializer) : static uint32 GetNextSensorId()
Super(ObjectInitializer) {
{} static uint32 COUNT = 0u;
return ++COUNT;
}
ASensor::ASensor(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer),
Id(GetNextSensorId()) {}
void ASensor::AttachToActor(AActor *Actor)
{
check(Actor != nullptr);
Super::AttachToActor(Actor, FAttachmentTransformRules::KeepRelativeTransform);
SetOwner(Actor);
Actor->AddTickPrerequisiteActor(this);
}

View File

@ -18,4 +18,29 @@ class CARLA_API ASensor : public AActor
public: public:
ASensor(const FObjectInitializer& ObjectInitializer); ASensor(const FObjectInitializer& ObjectInitializer);
uint32 GetId() const
{
return Id;
}
void SetName(FString InName)
{
Name = InName;
}
const FString &GetName() const
{
return Name;
}
void AttachToActor(AActor *Actor);
private:
UPROPERTY(VisibleAnywhere)
uint32 Id;
UPROPERTY(VisibleAnywhere)
FString Name;
}; };

View File

@ -0,0 +1,54 @@
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include "Carla.h"
#include "SensorFactory.h"
#include "Lidar.h"
#include "SceneCaptureCamera.h"
#include "Settings/CameraDescription.h"
#include "Settings/LidarDescription.h"
ASensor *FSensorFactory::Make(
const FString &Name,
const USensorDescription &Description,
UWorld &World)
{
FSensorFactory Visitor(World);
Description.AcceptVisitor(Visitor);
check(Visitor.Sensor != nullptr);
Visitor.Sensor->SetName(Name);
return Visitor.Sensor;
}
FSensorFactory::FSensorFactory(UWorld &World) : World(World) {}
void FSensorFactory::Visit(const UCameraDescription &Description)
{
auto Camera = World.SpawnActor<ASceneCaptureCamera>(Description.Position, Description.Rotation);
Camera->Set(Description);
UE_LOG(
LogCarla,
Log,
TEXT("Created Capture Camera %d with postprocess \"%s\""),
Camera->GetId(),
*PostProcessEffect::ToString(Camera->GetPostProcessEffect()));
Sensor = Camera;
}
void FSensorFactory::Visit(const ULidarDescription &Description)
{
auto Lidar = World.SpawnActor<ALidar>(Description.Position, Description.Rotation);
Lidar->Set(Description);
UE_LOG(
LogCarla,
Log,
TEXT("Created LiDAR %d"),
Lidar->GetId());
Sensor = Lidar;
}

View File

@ -0,0 +1,34 @@
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include "Settings/SensorDescriptionVisitor.h"
class ASensor;
class UWorld;
class FSensorFactory : private ISensorDescriptionVisitor
{
public:
static ASensor *Make(
const FString &Name,
const USensorDescription &Description,
UWorld &World);
private:
FSensorFactory(UWorld &World);
virtual void Visit(const UCameraDescription &) final;
virtual void Visit(const ULidarDescription &) final;
UWorld &World;
ASensor *Sensor = nullptr;
};

View File

@ -7,12 +7,20 @@
#pragma once #pragma once
#include "PostProcessEffect.h" #include "PostProcessEffect.h"
#include "SensorDescription.h"
#include "CameraDescription.generated.h" #include "CameraDescription.generated.h"
USTRUCT() UCLASS()
struct FCameraDescription class UCameraDescription : public USensorDescription
{ {
GENERATED_USTRUCT_BODY() GENERATED_BODY()
public:
virtual void AcceptVisitor(ISensorDescriptionVisitor &Visitor) const final
{
Visitor.Visit(*this);
}
/** X size in pixels of the captured image. */ /** X size in pixels of the captured image. */
UPROPERTY(Category = "Camera Description", EditDefaultsOnly, meta=(ClampMin = "1")) UPROPERTY(Category = "Camera Description", EditDefaultsOnly, meta=(ClampMin = "1"))
@ -22,14 +30,6 @@ struct FCameraDescription
UPROPERTY(Category = "Camera Description", EditDefaultsOnly, meta=(ClampMin = "1")) UPROPERTY(Category = "Camera Description", EditDefaultsOnly, meta=(ClampMin = "1"))
uint32 ImageSizeY = 512u; 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. */ /** Post-process effect to be applied to the captured image. */
UPROPERTY(Category = "Camera Description", EditDefaultsOnly) UPROPERTY(Category = "Camera Description", EditDefaultsOnly)
EPostProcessEffect PostProcessEffect = EPostProcessEffect::SceneFinal; EPostProcessEffect PostProcessEffect = EPostProcessEffect::SceneFinal;

View File

@ -5,12 +5,14 @@
// For a copy, see <https://opensource.org/licenses/MIT>. // For a copy, see <https://opensource.org/licenses/MIT>.
#include "Carla.h" #include "Carla.h"
#include "CarlaSettings.h"
#include "CommandLine.h" #include "CommandLine.h"
#include "UnrealMathUtility.h" #include "UnrealMathUtility.h"
#include "DynamicWeather.h" #include "DynamicWeather.h"
#include "Settings/CarlaSettings.h" #include "Settings/CameraDescription.h"
#include "Settings/LidarDescription.h"
#include "Util/IniFile.h" #include "Util/IniFile.h"
// INI file sections. // INI file sections.
@ -56,7 +58,7 @@ public:
static void GetCameraDescription( static void GetCameraDescription(
const MyIniFile &ConfigFile, const MyIniFile &ConfigFile,
const TCHAR* Section, const TCHAR* Section,
FCameraDescription &Camera) UCameraDescription &Camera)
{ {
ConfigFile.GetInt(Section, TEXT("ImageSizeX"), Camera.ImageSizeX); ConfigFile.GetInt(Section, TEXT("ImageSizeX"), Camera.ImageSizeX);
ConfigFile.GetInt(Section, TEXT("ImageSizeY"), Camera.ImageSizeY); ConfigFile.GetInt(Section, TEXT("ImageSizeY"), Camera.ImageSizeY);
@ -70,14 +72,14 @@ static void GetCameraDescription(
ConfigFile.GetPostProcessEffect(Section, TEXT("PostProcessing"), Camera.PostProcessEffect); ConfigFile.GetPostProcessEffect(Section, TEXT("PostProcessing"), Camera.PostProcessEffect);
} }
static void ValidateCameraDescription(FCameraDescription &Camera) static void ValidateCameraDescription(UCameraDescription &Camera)
{ {
FMath::Clamp(Camera.FOVAngle, 0.001f, 360.0f); FMath::Clamp(Camera.FOVAngle, 0.001f, 360.0f);
Camera.ImageSizeX = (Camera.ImageSizeX == 0u ? 720u : Camera.ImageSizeX); Camera.ImageSizeX = (Camera.ImageSizeX == 0u ? 720u : Camera.ImageSizeX);
Camera.ImageSizeY = (Camera.ImageSizeY == 0u ? 512u : Camera.ImageSizeY); Camera.ImageSizeY = (Camera.ImageSizeY == 0u ? 512u : Camera.ImageSizeY);
} }
static bool RequestedSemanticSegmentation(const FCameraDescription &Camera) static bool RequestedSemanticSegmentation(const UCameraDescription &Camera)
{ {
return (Camera.PostProcessEffect == EPostProcessEffect::SemanticSegmentation); return (Camera.PostProcessEffect == EPostProcessEffect::SemanticSegmentation);
} }
@ -85,7 +87,7 @@ static bool RequestedSemanticSegmentation(const FCameraDescription &Camera)
static void GetLidarDescription( static void GetLidarDescription(
const MyIniFile &ConfigFile, const MyIniFile &ConfigFile,
const TCHAR* Section, const TCHAR* Section,
FLidarDescription &Lidar) ULidarDescription &Lidar)
{ {
ConfigFile.GetInt(Section, TEXT("LidarPositionX"), Lidar.Position.X); ConfigFile.GetInt(Section, TEXT("LidarPositionX"), Lidar.Position.X);
ConfigFile.GetInt(Section, TEXT("LidarPositionY"), Lidar.Position.Y); ConfigFile.GetInt(Section, TEXT("LidarPositionY"), Lidar.Position.Y);
@ -129,8 +131,9 @@ static void LoadSettingsFromConfig(
TArray<FString> CameraNames; TArray<FString> CameraNames;
Cameras.ParseIntoArray(CameraNames, TEXT(","), true); Cameras.ParseIntoArray(CameraNames, TEXT(","), true);
for (FString &Name : CameraNames) { for (FString &Name : CameraNames) {
FCameraDescription &Camera = Settings.CameraDescriptions.FindOrAdd(Name); auto *Camera = NewObject<UCameraDescription>(&Settings);
GetCameraDescription(ConfigFile, S_CARLA_SCENECAPTURE, Camera); check(Camera != nullptr);
GetCameraDescription(ConfigFile, S_CARLA_SCENECAPTURE, *Camera);
TArray<FString> SubSections; TArray<FString> SubSections;
Name.ParseIntoArray(SubSections, TEXT("/"), true); Name.ParseIntoArray(SubSections, TEXT("/"), true);
@ -139,11 +142,12 @@ static void LoadSettingsFromConfig(
for (FString &SubSection : SubSections) { for (FString &SubSection : SubSections) {
Section += TEXT("/"); Section += TEXT("/");
Section += SubSection; Section += SubSection;
GetCameraDescription(ConfigFile, *Section, Camera); GetCameraDescription(ConfigFile, *Section, *Camera);
} }
ValidateCameraDescription(Camera); ValidateCameraDescription(*Camera);
Settings.bSemanticSegmentationEnabled |= RequestedSemanticSegmentation(Camera); Settings.bSemanticSegmentationEnabled |= RequestedSemanticSegmentation(*Camera);
Settings.SensorDescriptions.Add(Name, Camera);
} }
// Lidars. // Lidars.
FString Lidars; FString Lidars;
@ -151,8 +155,9 @@ static void LoadSettingsFromConfig(
TArray<FString> LidarNames; TArray<FString> LidarNames;
Lidars.ParseIntoArray(LidarNames, TEXT(","), true); Lidars.ParseIntoArray(LidarNames, TEXT(","), true);
for (FString &Name : LidarNames) { for (FString &Name : LidarNames) {
FLidarDescription &Lidar = Settings.LidarDescriptions.FindOrAdd(Name); auto *Lidar = NewObject<ULidarDescription>(&Settings);
GetLidarDescription(ConfigFile, S_CARLA_SCENECAPTURE, Lidar); check(Lidar != nullptr);
GetLidarDescription(ConfigFile, S_CARLA_SCENECAPTURE, *Lidar);
TArray<FString> SubSections; TArray<FString> SubSections;
Name.ParseIntoArray(SubSections, TEXT("/"), true); Name.ParseIntoArray(SubSections, TEXT("/"), true);
@ -161,8 +166,10 @@ static void LoadSettingsFromConfig(
for (FString &SubSection : SubSections) { for (FString &SubSection : SubSections) {
Section += TEXT("/"); Section += TEXT("/");
Section += SubSection; Section += SubSection;
GetLidarDescription(ConfigFile, *Section, Lidar); GetLidarDescription(ConfigFile, *Section, *Lidar);
} }
Settings.SensorDescriptions.Add(Name, Lidar);
} }
} }
@ -213,8 +220,7 @@ void UCarlaSettings::LoadSettings()
void UCarlaSettings::LoadSettingsFromString(const FString &INIFileContents) void UCarlaSettings::LoadSettingsFromString(const FString &INIFileContents)
{ {
UE_LOG(LogCarla, Log, TEXT("Loading CARLA settings from string")); UE_LOG(LogCarla, Log, TEXT("Loading CARLA settings from string"));
ResetCameraDescriptions(); ResetSensorDescriptions();
ResetLidarDescriptions();
MyIniFile ConfigFile; MyIniFile ConfigFile;
ConfigFile.ProcessInputFileContents(INIFileContents); ConfigFile.ProcessInputFileContents(INIFileContents);
constexpr bool bLoadCarlaServerSection = false; constexpr bool bLoadCarlaServerSection = false;
@ -260,23 +266,24 @@ void UCarlaSettings::LogSettings() const
UE_LOG(LogCarla, Log, TEXT(" * %d - %s"), i, *WeatherDescriptions[i].Name); UE_LOG(LogCarla, Log, TEXT(" * %d - %s"), i, *WeatherDescriptions[i].Name);
} }
UE_LOG(LogCarla, Log, TEXT("[%s]"), S_CARLA_SCENECAPTURE); UE_LOG(LogCarla, Log, TEXT("[%s]"), S_CARLA_SCENECAPTURE);
UE_LOG(LogCarla, Log, TEXT("Added %d cameras."), CameraDescriptions.Num()); UE_LOG(LogCarla, Log, TEXT("Added %d sensors."), SensorDescriptions.Num());
UE_LOG(LogCarla, Log, TEXT("Semantic Segmentation = %s"), EnabledDisabled(bSemanticSegmentationEnabled)); UE_LOG(LogCarla, Log, TEXT("Semantic Segmentation = %s"), EnabledDisabled(bSemanticSegmentationEnabled));
for (auto &Item : CameraDescriptions) { /// @todo Log sensors
UE_LOG(LogCarla, Log, TEXT("[%s/%s]"), S_CARLA_SCENECAPTURE, *Item.Key); // for (auto &Item : CameraDescriptions) {
UE_LOG(LogCarla, Log, TEXT("Image Size = %dx%d"), Item.Value.ImageSizeX, Item.Value.ImageSizeY); // UE_LOG(LogCarla, Log, TEXT("[%s/%s]"), S_CARLA_SCENECAPTURE, *Item.Key);
UE_LOG(LogCarla, Log, TEXT("FOV = %f"), Item.Value.FOVAngle); // UE_LOG(LogCarla, Log, TEXT("Image Size = %dx%d"), Item.Value.ImageSizeX, Item.Value.ImageSizeY);
UE_LOG(LogCarla, Log, TEXT("Camera Position = (%s)"), *Item.Value.Position.ToString()); // UE_LOG(LogCarla, Log, TEXT("FOV = %f"), Item.Value.FOVAngle);
UE_LOG(LogCarla, Log, TEXT("Camera Rotation = (%s)"), *Item.Value.Rotation.ToString()); // UE_LOG(LogCarla, Log, TEXT("Camera Position = (%s)"), *Item.Value.Position.ToString());
UE_LOG(LogCarla, Log, TEXT("Post-Processing = %s"), *PostProcessEffect::ToString(Item.Value.PostProcessEffect)); // UE_LOG(LogCarla, Log, TEXT("Camera Rotation = (%s)"), *Item.Value.Rotation.ToString());
} // UE_LOG(LogCarla, Log, TEXT("Post-Processing = %s"), *PostProcessEffect::ToString(Item.Value.PostProcessEffect));
UE_LOG(LogCarla, Log, TEXT("Added %d lidars."), LidarDescriptions.Num()); // }
for (auto &Item : LidarDescriptions) { // UE_LOG(LogCarla, Log, TEXT("Added %d lidars."), LidarDescriptions.Num());
UE_LOG(LogCarla, Log, TEXT("[%s/%s]"), S_CARLA_SCENECAPTURE, *Item.Key); // for (auto &Item : LidarDescriptions) {
UE_LOG(LogCarla, Log, TEXT("Lidar params = ch %f range %f pts %f"), Item.Value.Channels, Item.Value.Range, Item.Value.PointsPerSecond); // UE_LOG(LogCarla, Log, TEXT("[%s/%s]"), S_CARLA_SCENECAPTURE, *Item.Key);
UE_LOG(LogCarla, Log, TEXT("Lidar Position = (%s)"), *Item.Value.Position.ToString()); // UE_LOG(LogCarla, Log, TEXT("Lidar params = ch %f range %f pts %f"), Item.Value.Channels, Item.Value.Range, Item.Value.PointsPerSecond);
UE_LOG(LogCarla, Log, TEXT("Lidar Rotation = (%s)"), *Item.Value.Rotation.ToString()); // UE_LOG(LogCarla, Log, TEXT("Lidar Position = (%s)"), *Item.Value.Position.ToString());
} // UE_LOG(LogCarla, Log, TEXT("Lidar Rotation = (%s)"), *Item.Value.Rotation.ToString());
// }
UE_LOG(LogCarla, Log, TEXT("================================================================================")); UE_LOG(LogCarla, Log, TEXT("================================================================================"));
} }
@ -304,23 +311,17 @@ const FWeatherDescription &UCarlaSettings::GetWeatherDescriptionByIndex(int32 In
return WeatherDescriptions[Index]; return WeatherDescriptions[Index];
} }
void UCarlaSettings::ResetCameraDescriptions() void UCarlaSettings::ResetSensorDescriptions()
{ {
CameraDescriptions.Empty(); SensorDescriptions.Empty();
bSemanticSegmentationEnabled = false; bSemanticSegmentationEnabled = false;
} }
void UCarlaSettings::ResetLidarDescriptions()
{
LidarDescriptions.Empty();
}
void UCarlaSettings::LoadSettingsFromFile(const FString &FilePath, const bool bLogOnFailure) void UCarlaSettings::LoadSettingsFromFile(const FString &FilePath, const bool bLogOnFailure)
{ {
if (FPaths::FileExists(FilePath)) { if (FPaths::FileExists(FilePath)) {
UE_LOG(LogCarla, Log, TEXT("Loading CARLA settings from \"%s\""), *FilePath); UE_LOG(LogCarla, Log, TEXT("Loading CARLA settings from \"%s\""), *FilePath);
ResetCameraDescriptions(); ResetSensorDescriptions();
ResetLidarDescriptions();
const MyIniFile ConfigFile(FilePath); const MyIniFile ConfigFile(FilePath);
constexpr bool bLoadCarlaServerSection = true; constexpr bool bLoadCarlaServerSection = true;
LoadSettingsFromConfig(ConfigFile, *this, bLoadCarlaServerSection); LoadSettingsFromConfig(ConfigFile, *this, bLoadCarlaServerSection);

View File

@ -6,13 +6,13 @@
#pragma once #pragma once
#include "CameraDescription.h"
#include "WeatherDescription.h" #include "WeatherDescription.h"
#include "LidarDescription.h"
#include "UObject/NoExportTypes.h" #include "UObject/NoExportTypes.h"
#include "CarlaSettings.generated.h" #include "CarlaSettings.generated.h"
class USensorDescription;
/// Global settings for CARLA. /// Global settings for CARLA.
UCLASS() UCLASS()
class CARLA_API UCarlaSettings : public UObject class CARLA_API UCarlaSettings : public UObject
@ -57,9 +57,7 @@ private:
void LoadSettingsFromFile(const FString &FilePath, bool bLogOnFailure); void LoadSettingsFromFile(const FString &FilePath, bool bLogOnFailure);
void ResetCameraDescriptions(); void ResetSensorDescriptions();
void ResetLidarDescriptions();
/** File name of the settings file used to load this settings. Empty if none used. */ /** File name of the settings file used to load this settings. Empty if none used. */
UPROPERTY(Category = "CARLA Settings|Debug", VisibleAnywhere) UPROPERTY(Category = "CARLA Settings|Debug", VisibleAnywhere)
@ -130,25 +128,21 @@ public:
/// @} /// @}
// =========================================================================== // ===========================================================================
/// @name Scene Capture /// @name Sensors
// =========================================================================== // ===========================================================================
/// @{ /// @{
public: public:
/** Descriptions of the cameras to be attached to the player. */ /** Descriptions of the cameras to be attached to the player. */
UPROPERTY(Category = "Scene Capture", VisibleAnywhere) UPROPERTY(Category = "Sensors", VisibleAnywhere)
TMap<FString, FCameraDescription> CameraDescriptions; TMap<FString, USensorDescription *> SensorDescriptions;
/** Whether semantic segmentation should be activated. The mechanisms for /** Whether semantic segmentation should be activated. The mechanisms for
* semantic segmentation impose some performance penalties even if it is not * semantic segmentation impose some performance penalties even if it is not
* used, we only enable it if necessary. * used, we only enable it if necessary.
*/ */
UPROPERTY(Category = "Scene Capture", VisibleAnywhere) UPROPERTY(Category = "Sensors", VisibleAnywhere)
bool bSemanticSegmentationEnabled = false; bool bSemanticSegmentationEnabled = false;
/** Descriptions of the lidars to be attached to the player. */
UPROPERTY(Category = "Scene Capture", VisibleAnywhere)
TMap<FString, FLidarDescription> LidarDescriptions;
/// @} /// @}
}; };

View File

@ -2,12 +2,20 @@
#pragma once #pragma once
#include "SensorDescription.h"
#include "LidarDescription.generated.h" #include "LidarDescription.generated.h"
USTRUCT() UCLASS()
struct FLidarDescription class ULidarDescription : public USensorDescription
{ {
GENERATED_USTRUCT_BODY() GENERATED_BODY()
public:
virtual void AcceptVisitor(ISensorDescriptionVisitor &Visitor) const final
{
Visitor.Visit(*this);
}
/** Number of lasers */ /** Number of lasers */
UPROPERTY(EditDefaultsOnly, Category = "Lidar Description") UPROPERTY(EditDefaultsOnly, Category = "Lidar Description")
@ -26,28 +34,20 @@ struct FLidarDescription
float RotationFrequency = 10; float RotationFrequency = 10;
/** /**
Upper laser angle, counts from horizontal, * Upper laser angle, counts from horizontal, positive values means above
positive values means above horizontal line * horizontal line
*/ */
UPROPERTY(EditDefaultsOnly, Category = "Lidar Description") UPROPERTY(EditDefaultsOnly, Category = "Lidar Description")
float UpperFovLimit = 10; float UpperFovLimit = 10;
/** /**
Lower laser angle, counts from horizontal, * Lower laser angle, counts from horizontal, negative values means under
negative values means under horizontal line * horizontal line
*/ */
UPROPERTY(EditDefaultsOnly, Category = "Lidar Description") UPROPERTY(EditDefaultsOnly, Category = "Lidar Description")
float LowerFovLimit = -30; float LowerFovLimit = -30;
/** wether to show debug points of laser hits in simulator */ /** wether to show debug points of laser hits in simulator */
UPROPERTY(EditDefaultsOnly, Category = "Lidar Description") UPROPERTY(EditDefaultsOnly, Category = "Lidar Description")
bool ShowDebugPoints = false; bool ShowDebugPoints = false;
/** Position relative to the player. */
UPROPERTY(Category = "Lidar Description", EditDefaultsOnly)
FVector Position = {0.0f, 0.0f, 250.0f};
/** Rotation relative to the player. */
UPROPERTY(Category = "Lidar Description", EditDefaultsOnly)
FRotator Rotation = {0.0f, 0.0f, 0.0f};
}; };

View File

@ -0,0 +1,28 @@
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include "SensorDescriptionVisitor.h"
#include "SensorDescription.generated.h"
UCLASS(Abstract)
class USensorDescription : public UObject
{
GENERATED_BODY()
public:
virtual void AcceptVisitor(ISensorDescriptionVisitor &Visitor) const {}
/** Position relative to the player. */
UPROPERTY(Category = "Sensor Description", EditDefaultsOnly)
FVector Position = {170.0f, 0.0f, 150.0f};
/** Rotation relative to the player. */
UPROPERTY(Category = "Sensor Description", EditDefaultsOnly)
FRotator Rotation = {0.0f, 0.0f, 0.0f};
};

View File

@ -0,0 +1,19 @@
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
class UCameraDescription;
class ULidarDescription;
class ISensorDescriptionVisitor
{
public:
virtual void Visit(const UCameraDescription &) = 0;
virtual void Visit(const ULidarDescription &) = 0;
};