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

View File

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

View File

@ -184,46 +184,6 @@ public:
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 --------------------------------------------------------------
@ -301,10 +261,4 @@ private:
UPROPERTY(VisibleAnywhere)
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());
}
static void Set(carla_image &cImage, const FCapturedImage &uImage)
{
if (uImage.BitMap.Num() > 0) {
cImage.width = uImage.SizeX;
cImage.height = uImage.SizeY;
cImage.type = PostProcessEffect::ToUInt(uImage.PostProcessEffect);
cImage.fov = uImage.FOVAngle;
cImage.data = &uImage.BitMap.GetData()->DWColor();
// static void Set(carla_image &cImage, const FCapturedImage &uImage)
// {
// if (uImage.BitMap.Num() > 0) {
// cImage.width = uImage.SizeX;
// cImage.height = uImage.SizeY;
// cImage.type = PostProcessEffect::ToUInt(uImage.PostProcessEffect);
// cImage.fov = uImage.FOVAngle;
// cImage.data = &uImage.BitMap.GetData()->DWColor();
#ifdef CARLA_SERVER_EXTRA_LOG
{
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);
}
} else {
UE_LOG(LogCarlaServer, Warning, TEXT("Sending empty image"));
#endif // CARLA_SERVER_EXTRA_LOG
}
}
// #ifdef CARLA_SERVER_EXTRA_LOG
// {
// 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);
// }
// } else {
// UE_LOG(LogCarlaServer, Warning, TEXT("Sending empty image"));
// #endif // CARLA_SERVER_EXTRA_LOG
// }
// }
struct carla_lidar_measurement_data {
TUniquePtr<uint32_t[]> points_count_by_channel;
TUniquePtr<double[]> points;
};
// struct carla_lidar_measurement_data {
// TUniquePtr<uint32_t[]> points_count_by_channel;
// TUniquePtr<double[]> points;
// };
static void Set(
carla_lidar_measurement &cLidarMeasurement,
const FCapturedLidarSegment &uLidarSegment,
carla_lidar_measurement_data &cLidarMeasurementData)
{
// static void Set(
// carla_lidar_measurement &cLidarMeasurement,
// const FCapturedLidarSegment &uLidarSegment,
// carla_lidar_measurement_data &cLidarMeasurementData)
// {
if (uLidarSegment.LidarLasersSegments.Num() > 0) {
// if (uLidarSegment.LidarLasersSegments.Num() > 0) {
cLidarMeasurement.horizontal_angle = uLidarSegment.HorizontalAngle;
cLidarMeasurement.channels_count = uLidarSegment.LidarLasersSegments.Num();
// cLidarMeasurement.horizontal_angle = uLidarSegment.HorizontalAngle;
// cLidarMeasurement.channels_count = uLidarSegment.LidarLasersSegments.Num();
cLidarMeasurementData.points_count_by_channel = MakeUnique<uint32_t[]>(cLidarMeasurement.channels_count);
size_t total_points = 0;
for(int i=0; i<cLidarMeasurement.channels_count; i++)
{
size_t points_count = uLidarSegment.LidarLasersSegments[0].Points.Num();
cLidarMeasurementData.points_count_by_channel[i] = points_count;
total_points += points_count;
}
cLidarMeasurementData.points = MakeUnique<double[]>(3 * total_points);
size_t points_filled = 0;
for(int i=0; i<cLidarMeasurement.channels_count; i++)
{
size_t points_count = cLidarMeasurementData.points_count_by_channel[i];
auto& laser_points = uLidarSegment.LidarLasersSegments[i].Points;
for(int pi=0; pi<points_count; pi++)
{
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) + 2] = laser_points[pi].Z;
}
points_filled += points_count;
}
// cLidarMeasurementData.points_count_by_channel = MakeUnique<uint32_t[]>(cLidarMeasurement.channels_count);
// size_t total_points = 0;
// for(int i=0; i<cLidarMeasurement.channels_count; i++)
// {
// size_t points_count = uLidarSegment.LidarLasersSegments[0].Points.Num();
// cLidarMeasurementData.points_count_by_channel[i] = points_count;
// total_points += points_count;
// }
// cLidarMeasurementData.points = MakeUnique<double[]>(3 * total_points);
// size_t points_filled = 0;
// for(int i=0; i<cLidarMeasurement.channels_count; i++)
// {
// size_t points_count = cLidarMeasurementData.points_count_by_channel[i];
// auto& laser_points = uLidarSegment.LidarLasersSegments[i].Points;
// for(int pi=0; pi<points_count; pi++)
// {
// 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) + 2] = laser_points[pi].Z;
// }
// points_filled += points_count;
// }
cLidarMeasurement.points_count_by_channel = cLidarMeasurementData.points_count_by_channel.Get();
cLidarMeasurement.data = cLidarMeasurementData.points.Get();
// cLidarMeasurement.points_count_by_channel = cLidarMeasurementData.points_count_by_channel.Get();
// cLidarMeasurement.data = cLidarMeasurementData.points.Get();
#ifdef CARLA_SERVER_EXTRA_LOG
{
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());
}
} else {
UE_LOG(LogCarlaServer, Warning, TEXT("Sending empty lidar measurement"));
#endif // CARLA_SERVER_EXTRA_LOG
}
}
// #ifdef CARLA_SERVER_EXTRA_LOG
// {
// 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());
// }
// } else {
// UE_LOG(LogCarlaServer, Warning, TEXT("Sending empty lidar measurement"));
// #endif // CARLA_SERVER_EXTRA_LOG
// }
// }
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);
#endif // CARLA_SERVER_EXTRA_LOG
// Images.
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));
return ParseErrorCode(carla_write_measurements(Server, values));
}

View File

@ -56,33 +56,6 @@ void ACarlaVehicleController::Possess(APawn *aPawn)
// -- 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)
{
Super::Tick(DeltaTime);
@ -104,66 +77,9 @@ void ACarlaVehicleController::Tick(float DeltaTime)
CarlaPlayerState->SpeedLimit = GetSpeedLimit();
CarlaPlayerState->TrafficLightState = GetTrafficLightState();
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 -------------------------------------------------------------------
// =============================================================================

View File

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

View File

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

View File

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

View File

@ -155,29 +155,26 @@ void ASceneCaptureCamera::SetTargetGamma(const float 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);
SetPostProcessEffect(CameraDescription.PostProcessEffect);
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
{
FTextureRenderTargetResource* RTResource = CaptureRenderTarget->GameThread_GetRenderTargetResource();

View File

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

View File

@ -7,6 +7,20 @@
#include "Carla.h"
#include "Sensor.h"
ASensor::ASensor(const FObjectInitializer& ObjectInitializer) :
Super(ObjectInitializer)
{}
static uint32 GetNextSensorId()
{
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:
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
#include "PostProcessEffect.h"
#include "SensorDescription.h"
#include "CameraDescription.generated.h"
USTRUCT()
struct FCameraDescription
UCLASS()
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. */
UPROPERTY(Category = "Camera Description", EditDefaultsOnly, meta=(ClampMin = "1"))
@ -22,14 +30,6 @@ struct FCameraDescription
UPROPERTY(Category = "Camera Description", EditDefaultsOnly, meta=(ClampMin = "1"))
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

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

View File

@ -6,13 +6,13 @@
#pragma once
#include "CameraDescription.h"
#include "WeatherDescription.h"
#include "LidarDescription.h"
#include "UObject/NoExportTypes.h"
#include "CarlaSettings.generated.h"
class USensorDescription;
/// Global settings for CARLA.
UCLASS()
class CARLA_API UCarlaSettings : public UObject
@ -57,9 +57,7 @@ private:
void LoadSettingsFromFile(const FString &FilePath, bool bLogOnFailure);
void ResetCameraDescriptions();
void ResetLidarDescriptions();
void ResetSensorDescriptions();
/** File name of the settings file used to load this settings. Empty if none used. */
UPROPERTY(Category = "CARLA Settings|Debug", VisibleAnywhere)
@ -130,25 +128,21 @@ public:
/// @}
// ===========================================================================
/// @name Scene Capture
/// @name Sensors
// ===========================================================================
/// @{
public:
/** Descriptions of the cameras to be attached to the player. */
UPROPERTY(Category = "Scene Capture", VisibleAnywhere)
TMap<FString, FCameraDescription> CameraDescriptions;
UPROPERTY(Category = "Sensors", VisibleAnywhere)
TMap<FString, USensorDescription *> SensorDescriptions;
/** Whether semantic segmentation should be activated. The mechanisms for
* semantic segmentation impose some performance penalties even if it is not
* used, we only enable it if necessary.
*/
UPROPERTY(Category = "Scene Capture", VisibleAnywhere)
UPROPERTY(Category = "Sensors", VisibleAnywhere)
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
#include "SensorDescription.h"
#include "LidarDescription.generated.h"
USTRUCT()
struct FLidarDescription
UCLASS()
class ULidarDescription : public USensorDescription
{
GENERATED_USTRUCT_BODY()
GENERATED_BODY()
public:
virtual void AcceptVisitor(ISensorDescriptionVisitor &Visitor) const final
{
Visitor.Visit(*this);
}
/** Number of lasers */
UPROPERTY(EditDefaultsOnly, Category = "Lidar Description")
@ -26,28 +34,20 @@ struct FLidarDescription
float RotationFrequency = 10;
/**
Upper laser angle, counts from horizontal,
positive values means above horizontal line
*/
* Upper laser angle, counts from horizontal, positive values means above
* horizontal line
*/
UPROPERTY(EditDefaultsOnly, Category = "Lidar Description")
float UpperFovLimit = 10;
/**
Lower laser angle, counts from horizontal,
negative values means under horizontal line
*/
* Lower laser angle, counts from horizontal, negative values means under
* horizontal line
*/
UPROPERTY(EditDefaultsOnly, Category = "Lidar Description")
float LowerFovLimit = -30;
/** wether to show debug points of laser hits in simulator */
UPROPERTY(EditDefaultsOnly, Category = "Lidar Description")
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;
};