Merge branch 'nestor' into xisco
This commit is contained in:
commit
126194b5fc
|
@ -5,6 +5,7 @@
|
|||
#define LOCTEXT_NAMESPACE "FCarlaModule"
|
||||
|
||||
DEFINE_LOG_CATEGORY(LogCarla);
|
||||
DEFINE_LOG_CATEGORY(LogCarlaServer);
|
||||
|
||||
void FCarlaModule::StartupModule()
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "NonCopyable.h"
|
||||
|
||||
DECLARE_LOG_CATEGORY_EXTERN(LogCarla, Log, All);
|
||||
DECLARE_LOG_CATEGORY_EXTERN(LogCarlaServer, Log, All);
|
||||
|
||||
class FCarlaModule : public IModuleInterface
|
||||
{
|
||||
|
|
|
@ -30,11 +30,11 @@ static inline void Set(carla::Vector2D &cVector, const FVector &uVector)
|
|||
cVector = {uVector.X, uVector.Y};
|
||||
}
|
||||
|
||||
static void Set(std::vector<carla::Color> &cImage, const ASceneCaptureCamera *Camera)
|
||||
static void Set(std::vector<carla::Color> &cImage, const TArray<FColor> &BitMap)
|
||||
{
|
||||
if (Camera != nullptr) {
|
||||
cImage.reserve(Camera->GetImage().Num());
|
||||
for (const auto &color : Camera->GetImage()) {
|
||||
if (BitMap.Num() > 0) {
|
||||
cImage.reserve(BitMap.Num());
|
||||
for (const auto &color : BitMap) {
|
||||
cImage.emplace_back();
|
||||
cImage.back().R = color.R;
|
||||
cImage.back().G = color.G;
|
||||
|
@ -48,89 +48,111 @@ static void Set(std::vector<carla::Color> &cImage, const ASceneCaptureCamera *Ca
|
|||
// -- Other static methods -----------------------------------------------------
|
||||
// =============================================================================
|
||||
|
||||
// Wait for the scene init to be sent, return false if we need to restart the
|
||||
// server.
|
||||
/// @todo At the moment we just ignored what it is sent.
|
||||
static bool ReadSceneInit(carla::CarlaServer &Server)
|
||||
{
|
||||
carla::Mode mode;
|
||||
uint32 scene;
|
||||
UE_LOG(LogCarla, Log, TEXT("Waiting for tryReadSceneInit..."));
|
||||
while (!Server.tryReadSceneInit(mode, scene)) {
|
||||
if (Server.needsRestart())
|
||||
carla::Mode Mode;
|
||||
uint32 Scene;
|
||||
bool Success = false;
|
||||
UE_LOG(LogCarlaServer, Log, TEXT("(tryReadSceneInit) Waiting for client..."));
|
||||
while (!Success) {
|
||||
if (!Server.tryReadSceneInit(Mode, Scene, Success))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Send the available start spots to the client and wait for them to answer.
|
||||
// Return false if the server needs restart.
|
||||
static bool SendAndReadSceneValues(
|
||||
carla::CarlaServer &Server,
|
||||
const TArray<APlayerStart *> &AvailableStartSpots,
|
||||
uint32 &StartIndex)
|
||||
{
|
||||
check(AvailableStartSpots.Num() > 0);
|
||||
|
||||
// Retrieve the location of each player start.
|
||||
carla::Scene_Values sceneValues;
|
||||
sceneValues.possible_positions.reserve(AvailableStartSpots.Num());
|
||||
for (APlayerStart *StartSpot : AvailableStartSpots) {
|
||||
check(StartSpot != nullptr);
|
||||
const FVector &Location = StartSpot->GetActorLocation();
|
||||
UE_LOG(LogCarla, Log, TEXT("Found start position {%f, %f}"), Location.X, Location.Y);
|
||||
sceneValues.possible_positions.push_back({Location.X, Location.Y});
|
||||
}
|
||||
// Send scene values.
|
||||
UE_LOG(LogCarla, Log, TEXT("Send scene values: %d positions"), sceneValues.possible_positions.size());
|
||||
Server.sendSceneValues(sceneValues);
|
||||
// Wait till we receive the answer.
|
||||
// Send the positions.
|
||||
/// @todo At the moment we don't send the cameras' projection matrices.
|
||||
UE_LOG(LogCarlaServer, Log, TEXT("Sending %d available start positions"), sceneValues.possible_positions.size());
|
||||
if (!Server.sendSceneValues(sceneValues))
|
||||
return false;
|
||||
// Wait till we receive an answer.
|
||||
uint32 EndIndex;
|
||||
UE_LOG(LogCarla, Log, TEXT("Waiting for episode start..."));
|
||||
while (!Server.tryReadEpisodeStart(StartIndex, EndIndex)) {
|
||||
if (Server.needsRestart())
|
||||
bool Success = false;
|
||||
UE_LOG(LogCarlaServer, Log, TEXT("(tryReadEpisodeStart) Waiting for client..."));
|
||||
while (!Success) {
|
||||
if (!Server.tryReadEpisodeStart(StartIndex, EndIndex, Success))
|
||||
return false;
|
||||
}
|
||||
UE_LOG(LogCarla, Log, TEXT("Episode start received: %d -> %d"), StartIndex, EndIndex);
|
||||
UE_LOG(LogCarlaServer, Log, TEXT("Episode start received: { StartIndex = %d, EndIndex = %d }"), StartIndex, EndIndex);
|
||||
// Make sure the index is in range.
|
||||
if (StartIndex >= AvailableStartSpots.Num()) {
|
||||
UE_LOG(LogCarla, Warning, TEXT("Received invalid start index, using zero instead"));
|
||||
UE_LOG(
|
||||
LogCarlaServer,
|
||||
Error,
|
||||
TEXT("Requested start position #%d but we only have %d, using first position instead"),
|
||||
StartIndex,
|
||||
AvailableStartSpots.Num());
|
||||
StartIndex = 0u;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void SendReward(
|
||||
static bool SendReward(
|
||||
carla::CarlaServer &Server,
|
||||
const ACarlaPlayerState &PlayerState,
|
||||
const std::array<const ASceneCaptureCamera *, 2u> &Cameras)
|
||||
const ACarlaPlayerState &PlayerState)
|
||||
{
|
||||
carla::Reward_Values reward;
|
||||
reward.timestamp = FMath::RoundHalfToZero(1000.0 * FPlatformTime::Seconds());
|
||||
Set(reward.player_location, PlayerState.GetLocation());
|
||||
Set(reward.player_orientation, PlayerState.GetOrientation());
|
||||
Set(reward.player_acceleration, PlayerState.GetAcceleration());
|
||||
Set(reward.forward_speed, PlayerState.GetForwardSpeed());
|
||||
Set(reward.collision_car, PlayerState.GetCollisionIntensityCars());
|
||||
Set(reward.collision_pedestrian, PlayerState.GetCollisionIntensityPedestrians());
|
||||
Set(reward.collision_general, PlayerState.GetCollisionIntensityOther());
|
||||
// Set(reward.intersect_other_lane, );
|
||||
// Set(reward.intersect_offroad, );
|
||||
if (Cameras[0u] != nullptr) {
|
||||
reward.image_width = Cameras[0u]->GetImageSizeX();
|
||||
reward.image_height = Cameras[0u]->GetImageSizeY();
|
||||
auto reward = std::make_unique<carla::Reward_Values>();
|
||||
reward->timestamp = PlayerState.GetTimeStamp();
|
||||
Set(reward->player_location, PlayerState.GetLocation());
|
||||
Set(reward->player_orientation, PlayerState.GetOrientation());
|
||||
Set(reward->player_acceleration, PlayerState.GetAcceleration());
|
||||
Set(reward->forward_speed, PlayerState.GetForwardSpeed());
|
||||
Set(reward->collision_car, PlayerState.GetCollisionIntensityCars());
|
||||
Set(reward->collision_pedestrian, PlayerState.GetCollisionIntensityPedestrians());
|
||||
Set(reward->collision_general, PlayerState.GetCollisionIntensityOther());
|
||||
Set(reward->intersect_other_lane, PlayerState.GetOtherLaneIntersectionFactor());
|
||||
Set(reward->intersect_offroad, PlayerState.GetOffRoadIntersectionFactor());
|
||||
{ // Add images.
|
||||
using CPS = ACarlaPlayerState;
|
||||
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);
|
||||
}
|
||||
}
|
||||
Set(reward.image_rgb_0, Cameras[0u]);
|
||||
Set(reward.image_rgb_1, Cameras[1u]);
|
||||
// Set(reward.image_depth_0, );
|
||||
// Set(reward.image_depth_1, );
|
||||
UE_LOG(LogCarla, Log, TEXT("Sending reward"));
|
||||
Server.sendReward(reward);
|
||||
UE_LOG(LogCarlaServer, Log, TEXT("Sending reward"));
|
||||
return Server.sendReward(reward.release());
|
||||
}
|
||||
|
||||
static void TryReadControl(carla::CarlaServer &Server, ACarlaVehicleController &Player)
|
||||
static bool TryReadControl(carla::CarlaServer &Server, ACarlaVehicleController &Player)
|
||||
{
|
||||
float steer;
|
||||
float throttle;
|
||||
if (Server.tryReadControl(steer, throttle)) {
|
||||
Player.SetSteeringInput(steer);
|
||||
Player.SetThrottleInput(throttle);
|
||||
UE_LOG(LogCarla, Log, TEXT("Read control: steer = %f, throttle = %f"), steer, throttle);
|
||||
float Steer;
|
||||
float Throttle;
|
||||
bool Success = false;
|
||||
bool bServerNeedsRestart = Server.tryReadControl(Steer, Throttle, Success);
|
||||
if (Success) {
|
||||
check(!bServerNeedsRestart);
|
||||
UE_LOG(LogCarlaServer, Log, TEXT("Read control: { Steer = %f, Throttle = %f }"), Steer, Throttle);
|
||||
Player.SetSteeringInput(Steer);
|
||||
Player.SetThrottleInput(Throttle);
|
||||
}
|
||||
return bServerNeedsRestart;
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
@ -139,26 +161,23 @@ static void TryReadControl(carla::CarlaServer &Server, ACarlaVehicleController &
|
|||
|
||||
CarlaGameController::CarlaGameController() :
|
||||
Server(MakeUnique<carla::CarlaServer>(2001u, 2002u, 2000u)),
|
||||
Player(nullptr),
|
||||
Cameras({{nullptr}}) {}
|
||||
Player(nullptr) {}
|
||||
|
||||
CarlaGameController::~CarlaGameController()
|
||||
{
|
||||
UE_LOG(LogCarla, Log, TEXT("Destroying CarlaGameController..."));
|
||||
UE_LOG(LogCarlaServer, Log, TEXT("Destroying CarlaGameController..."));
|
||||
}
|
||||
|
||||
void CarlaGameController::Initialize()
|
||||
{
|
||||
if (bServerNeedsRestart) {
|
||||
UE_LOG(LogCarla, Log, TEXT("Initializing CarlaServer"));
|
||||
Server->init(1u);
|
||||
if (ReadSceneInit(*Server)) {
|
||||
UE_LOG(LogCarlaServer, Log, TEXT("Initializing CarlaServer"));
|
||||
if (Server->init(1u) && ReadSceneInit(*Server)) {
|
||||
bServerNeedsRestart = false;
|
||||
} else {
|
||||
UE_LOG(LogCarla, Warning, TEXT("Read scene init failed, server needs restart"));
|
||||
UE_LOG(LogCarlaServer, Warning, TEXT("Failed to initialize, server needs restart"));
|
||||
}
|
||||
}
|
||||
Cameras = {{nullptr}};
|
||||
}
|
||||
|
||||
APlayerStart *CarlaGameController::ChoosePlayerStart(
|
||||
|
@ -166,7 +185,7 @@ APlayerStart *CarlaGameController::ChoosePlayerStart(
|
|||
{
|
||||
uint32 StartIndex;
|
||||
if (!SendAndReadSceneValues(*Server, AvailableStartSpots, StartIndex)) {
|
||||
UE_LOG(LogCarla, Warning, TEXT("Read scene values failed, server needs restart"));
|
||||
UE_LOG(LogCarlaServer, Warning, TEXT("Unable to choose start position, server needs restart"));
|
||||
StartIndex = 0u;
|
||||
}
|
||||
return AvailableStartSpots[StartIndex];
|
||||
|
@ -178,48 +197,47 @@ void CarlaGameController::RegisterPlayer(AController &NewPlayer)
|
|||
check(Player != nullptr);
|
||||
}
|
||||
|
||||
void CarlaGameController::RegisterCaptureCamera(const ASceneCaptureCamera &CaptureCamera)
|
||||
{
|
||||
for (auto i = 0u; i < Cameras.size(); ++i) {
|
||||
if (Cameras[i] == nullptr) {
|
||||
Cameras[i] = &CaptureCamera;
|
||||
UE_LOG(LogCarla, Log, TEXT("Registered capture camera %d"), i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
UE_LOG(
|
||||
LogCarla,
|
||||
Warning,
|
||||
TEXT("Attempting to register a camera but already have %d, captures from this camera won't be send"),
|
||||
Cameras.size());
|
||||
}
|
||||
|
||||
void CarlaGameController::BeginPlay()
|
||||
{
|
||||
Server->sendEndReset();
|
||||
if (!bServerNeedsRestart) {
|
||||
UE_LOG(LogCarlaServer, Log, TEXT("Ready to play, notifying client"));
|
||||
if (!Server->sendEndReset()) {
|
||||
bServerNeedsRestart = true;
|
||||
UE_LOG(LogCarlaServer, Warning, TEXT("Unable to send end reset, server needs restart"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CarlaGameController::Tick(float DeltaSeconds)
|
||||
{
|
||||
check(Player != nullptr);
|
||||
if (bServerNeedsRestart || Server->needsRestart()) {
|
||||
RestartLevel(true);
|
||||
return;
|
||||
if (bServerNeedsRestart || Server->needsRestart() || !TickServer()) {
|
||||
UE_LOG(LogCarlaServer, Warning, TEXT("Client disconnected, server needs restart"));
|
||||
bServerNeedsRestart = true;
|
||||
RestartLevel();
|
||||
}
|
||||
|
||||
if (Server->newEpisodeRequested()) {
|
||||
UE_LOG(LogCarla, Log, TEXT("New episode requested"));
|
||||
RestartLevel(false);
|
||||
return;
|
||||
}
|
||||
|
||||
SendReward(*Server, Player->GetPlayerState(), Cameras);
|
||||
TryReadControl(*Server, *Player);
|
||||
}
|
||||
|
||||
void CarlaGameController::RestartLevel(bool ServerNeedsRestart)
|
||||
bool CarlaGameController::TickServer()
|
||||
{
|
||||
UE_LOG(LogCarla, Log, TEXT("Restarting..."));
|
||||
bServerNeedsRestart = ServerNeedsRestart;
|
||||
// Check if the client requested a new episode.
|
||||
bool bNewEpisodeRequested = false;
|
||||
if (!Server->newEpisodeRequested(bNewEpisodeRequested)) {
|
||||
return false;
|
||||
} else if (bNewEpisodeRequested) {
|
||||
UE_LOG(LogCarlaServer, Log, TEXT("New episode requested"));
|
||||
RestartLevel();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Send reward and try to read control.
|
||||
return
|
||||
SendReward(*Server, Player->GetPlayerState()) &&
|
||||
TryReadControl(*Server, *Player);
|
||||
}
|
||||
|
||||
void CarlaGameController::RestartLevel()
|
||||
{
|
||||
UE_LOG(LogCarlaServer, Log, TEXT("Restarting the level..."));
|
||||
Player->RestartLevel();
|
||||
}
|
||||
|
|
|
@ -25,21 +25,20 @@ public:
|
|||
|
||||
virtual void RegisterPlayer(AController &NewPlayer) override;
|
||||
|
||||
virtual void RegisterCaptureCamera(const ASceneCaptureCamera &CaptureCamera) override;
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void Tick(float DeltaSeconds) override;
|
||||
|
||||
private:
|
||||
|
||||
void RestartLevel(bool ServerNeedsRestart);
|
||||
/// Return false if the server needs restart.
|
||||
bool TickServer();
|
||||
|
||||
void RestartLevel();
|
||||
|
||||
TUniquePtr<carla::CarlaServer> Server;
|
||||
|
||||
ACarlaVehicleController *Player;
|
||||
|
||||
std::array<const ASceneCaptureCamera *, 2u> Cameras;
|
||||
|
||||
bool bServerNeedsRestart = true;
|
||||
};
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
class AController;
|
||||
class APlayerStart;
|
||||
class ASceneCaptureCamera;
|
||||
|
||||
/// Base class for a CARLA game controller.
|
||||
class CARLA_API CarlaGameControllerBase
|
||||
|
@ -21,8 +20,6 @@ public:
|
|||
|
||||
virtual void RegisterPlayer(AController &NewPlayer) = 0;
|
||||
|
||||
virtual void RegisterCaptureCamera(const ASceneCaptureCamera &CaptureCamera) = 0;
|
||||
|
||||
virtual void BeginPlay() = 0;
|
||||
|
||||
virtual void Tick(float DeltaSeconds) = 0;
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
|
||||
ACarlaGameMode::ACarlaGameMode() :
|
||||
Super(),
|
||||
GameController(nullptr)
|
||||
GameController(nullptr),
|
||||
PlayerController(nullptr)
|
||||
{
|
||||
PrimaryActorTick.bCanEverTick = true;
|
||||
PrimaryActorTick.TickGroup = TG_PrePhysics;
|
||||
|
@ -79,7 +80,10 @@ void ACarlaGameMode::RegisterCaptureCamera(ASceneCaptureCamera &CaptureCamera)
|
|||
{
|
||||
check(GameController != nullptr);
|
||||
AddTickPrerequisiteActor(&CaptureCamera);
|
||||
GameController->RegisterCaptureCamera(CaptureCamera);
|
||||
ACarlaVehicleController *Player = Cast<ACarlaVehicleController>(PlayerController);
|
||||
if (Player != nullptr) {
|
||||
Player->RegisterCaptureCamera(CaptureCamera);
|
||||
}
|
||||
}
|
||||
|
||||
void ACarlaGameMode::RegisterPlayer(AController &NewPlayer)
|
||||
|
@ -87,6 +91,7 @@ void ACarlaGameMode::RegisterPlayer(AController &NewPlayer)
|
|||
check(GameController != nullptr);
|
||||
AddTickPrerequisiteActor(&NewPlayer);
|
||||
GameController->RegisterPlayer(NewPlayer);
|
||||
PlayerController = &NewPlayer;
|
||||
}
|
||||
|
||||
APlayerStart *ACarlaGameMode::FindUnOccupiedStartPoints(
|
||||
|
|
|
@ -48,4 +48,6 @@ private:
|
|||
TArray<APlayerStart *> &UnOccupiedStartPoints);
|
||||
|
||||
CarlaGameControllerBase *GameController;
|
||||
|
||||
AController *PlayerController;
|
||||
};
|
||||
|
|
|
@ -6,9 +6,14 @@
|
|||
void ACarlaPlayerState::Reset()
|
||||
{
|
||||
Super::Reset();
|
||||
// Reset incremental values.
|
||||
CollisionIntensityCars = 0.0f;
|
||||
CollisionIntensityPedestrians = 0.0f;
|
||||
CollisionIntensityOther = 0.0f;
|
||||
// Invalidate images.
|
||||
for (auto &image : Images) {
|
||||
image = Image(); // Reset.
|
||||
}
|
||||
}
|
||||
|
||||
void ACarlaPlayerState::CopyProperties(APlayerState *PlayerState)
|
||||
|
@ -19,6 +24,7 @@ void ACarlaPlayerState::CopyProperties(APlayerState *PlayerState)
|
|||
ACarlaPlayerState *Other = Cast<ACarlaPlayerState>(PlayerState);
|
||||
if (Other != nullptr)
|
||||
{
|
||||
TimeStamp = Other->TimeStamp;
|
||||
Location = Other->Location;
|
||||
Orientation = Other->Orientation;
|
||||
Acceleration = Other->Acceleration;
|
||||
|
@ -26,6 +32,10 @@ void ACarlaPlayerState::CopyProperties(APlayerState *PlayerState)
|
|||
CollisionIntensityCars = Other->CollisionIntensityCars;
|
||||
CollisionIntensityPedestrians = Other->CollisionIntensityPedestrians;
|
||||
CollisionIntensityOther = Other->CollisionIntensityOther;
|
||||
OtherLaneIntersectionFactor = Other->OtherLaneIntersectionFactor;
|
||||
OffRoadIntersectionFactor = Other->OffRoadIntersectionFactor;
|
||||
Images = Other->Images;
|
||||
UE_LOG(LogCarla, Log, TEXT("Copied properties of ACarlaPlayerState"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,3 +44,8 @@ void ACarlaPlayerState::RegisterCollision(AActor */*Actor*/, FVector NormalImpul
|
|||
{
|
||||
CollisionIntensityOther += NormalImpulse.Size();
|
||||
}
|
||||
|
||||
void ACarlaPlayerState::UpdateTimeStamp()
|
||||
{
|
||||
TimeStamp = FMath::RoundHalfToZero(1000.0 * FPlatformTime::Seconds());
|
||||
}
|
||||
|
|
|
@ -2,24 +2,56 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include "GameFramework/PlayerState.h"
|
||||
#include "CarlaPlayerState.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
/// Current state of the player, updated every frame by ACarlaVehicleController.
|
||||
///
|
||||
/// This class matches the reward that it is sent to the client over the
|
||||
/// network.
|
||||
UCLASS()
|
||||
class CARLA_API ACarlaPlayerState : public APlayerState
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
// ===========================================================================
|
||||
// -- Types ------------------------------------------------------------------
|
||||
// ===========================================================================
|
||||
public:
|
||||
|
||||
enum ImageTag {
|
||||
ImageRGB0,
|
||||
ImageRGB1,
|
||||
ImageDepth0,
|
||||
ImageDepth1,
|
||||
NUMBER_OF_IMAGES
|
||||
};
|
||||
|
||||
struct Image {
|
||||
uint32 SizeX = 0u;
|
||||
uint32 SizeY = 0u;
|
||||
TArray<FColor> BitMap;
|
||||
};
|
||||
|
||||
// ===========================================================================
|
||||
// -- APlayerState -----------------------------------------------------------
|
||||
// ===========================================================================
|
||||
public:
|
||||
|
||||
virtual void Reset() override;
|
||||
|
||||
virtual void CopyProperties(APlayerState *PlayerState) override;
|
||||
|
||||
void RegisterCollision(AActor *Actor, FVector NormalImpulse);
|
||||
// ===========================================================================
|
||||
// -- Getters ----------------------------------------------------------------
|
||||
// ===========================================================================
|
||||
public:
|
||||
|
||||
int32 GetTimeStamp() const
|
||||
{
|
||||
return TimeStamp;
|
||||
}
|
||||
|
||||
const FVector &GetLocation() const
|
||||
{
|
||||
|
@ -56,21 +88,59 @@ public:
|
|||
return CollisionIntensityOther;
|
||||
}
|
||||
|
||||
float GetOtherLaneIntersectionFactor() const
|
||||
{
|
||||
return OtherLaneIntersectionFactor;
|
||||
}
|
||||
|
||||
float GetOffRoadIntersectionFactor() const
|
||||
{
|
||||
return OffRoadIntersectionFactor;
|
||||
}
|
||||
|
||||
const Image &GetImage(ImageTag Tag) const
|
||||
{
|
||||
return Images[Tag];
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// -- Modifiers --------------------------------------------------------------
|
||||
// ===========================================================================
|
||||
private:
|
||||
|
||||
void RegisterCollision(AActor *Actor, FVector NormalImpulse);
|
||||
|
||||
void UpdateTimeStamp();
|
||||
|
||||
// ===========================================================================
|
||||
// -- Private members --------------------------------------------------------
|
||||
// ===========================================================================
|
||||
private:
|
||||
|
||||
friend class ACarlaVehicleController;
|
||||
|
||||
// If you add another variable here, don't forget to copy it inside
|
||||
// CopyProperties if necessary.
|
||||
|
||||
int32 TimeStamp;
|
||||
|
||||
FVector Location;
|
||||
|
||||
FVector Orientation;
|
||||
|
||||
FVector Acceleration;
|
||||
|
||||
float ForwardSpeed;
|
||||
float ForwardSpeed = 0.0f;
|
||||
|
||||
float CollisionIntensityCars = 0.0f;
|
||||
|
||||
float CollisionIntensityPedestrians = 0.0f;
|
||||
|
||||
float CollisionIntensityOther = 0.0f;
|
||||
|
||||
float OtherLaneIntersectionFactor = 0.0f;
|
||||
|
||||
float OffRoadIntersectionFactor = 0.0f;
|
||||
|
||||
std::array<Image, NUMBER_OF_IMAGES> Images;
|
||||
};
|
||||
|
|
|
@ -86,17 +86,36 @@ void ACarlaVehicleController::Possess(APawn *aPawn)
|
|||
}
|
||||
}
|
||||
|
||||
static void ReadCameraPixels(const ASceneCaptureCamera *Camera, ACarlaPlayerState::Image &Image)
|
||||
{
|
||||
if (Camera != nullptr) {
|
||||
if (Camera->ReadPixels(Image.BitMap)) {
|
||||
Image.SizeX = Camera->GetImageSizeX();
|
||||
Image.SizeY = Camera->GetImageSizeY();
|
||||
} else {
|
||||
Image.BitMap.Empty(); // Clears the array.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ACarlaVehicleController::Tick(float DeltaTime)
|
||||
{
|
||||
Super::PlayerTick(DeltaTime);
|
||||
|
||||
if (IsPossessingAVehicle()) {
|
||||
CarlaPlayerState->UpdateTimeStamp();
|
||||
CarlaPlayerState->Location = GetVehicleLocation();
|
||||
const FVector PreviousSpeed = CarlaPlayerState->ForwardSpeed * CarlaPlayerState->Orientation;
|
||||
CarlaPlayerState->Orientation = GetVehicleOrientation();
|
||||
CarlaPlayerState->ForwardSpeed = GetVehicleForwardSpeed();
|
||||
const FVector CurrentSpeed = CarlaPlayerState->ForwardSpeed * CarlaPlayerState->Orientation;
|
||||
CarlaPlayerState->Acceleration = (CurrentSpeed - PreviousSpeed) / DeltaTime;
|
||||
/// @todo Set intersection factors.
|
||||
using CPS = ACarlaPlayerState;
|
||||
ReadCameraPixels(RGBCameras[0u], CarlaPlayerState->Images[CPS::ImageRGB0]);
|
||||
ReadCameraPixels(RGBCameras[1u], CarlaPlayerState->Images[CPS::ImageRGB1]);
|
||||
ReadCameraPixels(DepthCameras[0u], CarlaPlayerState->Images[CPS::ImageDepth0]);
|
||||
ReadCameraPixels(DepthCameras[1u], CarlaPlayerState->Images[CPS::ImageDepth1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,10 +146,34 @@ FVector ACarlaVehicleController::GetVehicleOrientation() const
|
|||
return GetPawn()->GetTransform().GetRotation().GetForwardVector();
|
||||
}
|
||||
|
||||
void ACarlaVehicleController::ResetPlayerState()
|
||||
// =============================================================================
|
||||
// -- Scene capture ------------------------------------------------------------
|
||||
// =============================================================================
|
||||
|
||||
void ACarlaVehicleController::RegisterCaptureCamera(const ASceneCaptureCamera &CaptureCamera)
|
||||
{
|
||||
check(CarlaPlayerState != nullptr);
|
||||
CarlaPlayerState->Reset();
|
||||
const auto Effect = CaptureCamera.GetPostProcessEffect();
|
||||
check((Effect == EPostProcessEffect::None) || (Effect == EPostProcessEffect::Depth))
|
||||
auto &Cameras = (Effect == EPostProcessEffect::None ? RGBCameras : DepthCameras);
|
||||
|
||||
for (auto i = 0u; i < Cameras.size(); ++i) {
|
||||
if (Cameras[i] == nullptr) {
|
||||
Cameras[i] = &CaptureCamera;
|
||||
UE_LOG(
|
||||
LogCarla,
|
||||
Log,
|
||||
TEXT("Registered capture camera %d with postprocess \"%s\""),
|
||||
i,
|
||||
*CaptureCamera.GetPostProcessEffectAsString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
UE_LOG(
|
||||
LogCarla,
|
||||
Warning,
|
||||
TEXT("Attempting to register a capture camera of type \"%d\" but already have %d, captures from this camera won't be sent"),
|
||||
*CaptureCamera.GetPostProcessEffectAsString(),
|
||||
Cameras.size());
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "CarlaVehicleController.generated.h"
|
||||
|
||||
class ACarlaPlayerState;
|
||||
class ASceneCaptureCamera;
|
||||
class UCameraComponent;
|
||||
class USpringArmComponent;
|
||||
class UWheeledVehicleMovementComponent;
|
||||
|
@ -48,6 +49,7 @@ public:
|
|||
/// @name Vehicle pawn info
|
||||
// ===========================================================================
|
||||
/// @{
|
||||
public:
|
||||
|
||||
bool IsPossessingAVehicle() const
|
||||
{
|
||||
|
@ -68,7 +70,14 @@ public:
|
|||
return *CarlaPlayerState;
|
||||
}
|
||||
|
||||
void ResetPlayerState();
|
||||
/// @}
|
||||
// ===========================================================================
|
||||
/// @name Scene Capture
|
||||
// ===========================================================================
|
||||
/// @{
|
||||
public:
|
||||
|
||||
void RegisterCaptureCamera(const ASceneCaptureCamera &CaptureCamera);
|
||||
|
||||
/// @}
|
||||
// ===========================================================================
|
||||
|
@ -166,4 +175,10 @@ private:
|
|||
// Cast for quick access to the custom player state.
|
||||
UPROPERTY()
|
||||
ACarlaPlayerState *CarlaPlayerState;
|
||||
|
||||
using CaptureCameraArray = std::array<const ASceneCaptureCamera *, 2u>;
|
||||
|
||||
CaptureCameraArray RGBCameras;
|
||||
|
||||
CaptureCameraArray DepthCameras;
|
||||
};
|
||||
|
|
|
@ -24,11 +24,6 @@ void MockGameController::RegisterPlayer(AController &NewPlayer)
|
|||
}
|
||||
}
|
||||
|
||||
void MockGameController::RegisterCaptureCamera(const ASceneCaptureCamera &CaptureCamera)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MockGameController::BeginPlay()
|
||||
{
|
||||
|
||||
|
|
|
@ -15,8 +15,6 @@ public:
|
|||
|
||||
virtual void RegisterPlayer(AController &NewPlayer) override;
|
||||
|
||||
virtual void RegisterCaptureCamera(const ASceneCaptureCamera &CaptureCamera) override;
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void Tick(float DeltaSeconds) override;
|
||||
|
|
|
@ -17,9 +17,10 @@
|
|||
ASceneCaptureCamera::ASceneCaptureCamera(const FObjectInitializer& ObjectInitializer) :
|
||||
Super(ObjectInitializer),
|
||||
SizeX(200u),
|
||||
SizeY(200u)
|
||||
SizeY(200u),
|
||||
PostProcessEffect(EPostProcessEffect::None)
|
||||
{
|
||||
PrimaryActorTick.bCanEverTick = true;
|
||||
PrimaryActorTick.bCanEverTick = true; /// @todo Does it need to tick?
|
||||
PrimaryActorTick.TickGroup = TG_PrePhysics;
|
||||
|
||||
MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("CamMesh0"));
|
||||
|
@ -82,14 +83,20 @@ void ASceneCaptureCamera::BeginPlay()
|
|||
GameMode->RegisterCaptureCamera(*this);
|
||||
}
|
||||
|
||||
void ASceneCaptureCamera::Tick(float Delta)
|
||||
FString ASceneCaptureCamera::GetPostProcessEffectAsString() const
|
||||
{
|
||||
const UEnum* ptr = FindObject<UEnum>(ANY_PACKAGE, TEXT("EPostProcessEffect"), true);
|
||||
if(!ptr)
|
||||
return FString("Invalid");
|
||||
return ptr->GetEnumName(static_cast<int32>(PostProcessEffect));
|
||||
}
|
||||
|
||||
bool ASceneCaptureCamera::ReadPixels(TArray<FColor> &BitMap) const
|
||||
{
|
||||
Super::Tick(Delta);
|
||||
// Update the image bitmap.
|
||||
FTextureRenderTargetResource* RTResource = CaptureRenderTarget->GameThread_GetRenderTargetResource();
|
||||
FReadSurfaceDataFlags ReadPixelFlags(RCM_UNorm);
|
||||
ReadPixelFlags.SetLinearToGamma(true);
|
||||
RTResource->ReadPixels(ImageBitMap, ReadPixelFlags);
|
||||
return RTResource->ReadPixels(BitMap, ReadPixelFlags);
|
||||
}
|
||||
|
||||
void ASceneCaptureCamera::UpdateDrawFrustum()
|
||||
|
|
|
@ -15,7 +15,16 @@ class UDrawFrustumComponent;
|
|||
class USceneCaptureComponent2D;
|
||||
class UStaticMeshComponent;
|
||||
|
||||
UCLASS(hidecategories=(Collision, Material, Attachment, Actor))
|
||||
UENUM(BlueprintType)
|
||||
enum class EPostProcessEffect : uint8
|
||||
{
|
||||
None UMETA(DisplayName = "RGB"),
|
||||
Depth UMETA(DisplayName = "Depth Map"),
|
||||
|
||||
SIZE UMETA(Hidden)
|
||||
};
|
||||
|
||||
UCLASS(hidecategories=(Collision, Attachment, Actor))
|
||||
class CARLA_API ASceneCaptureCamera : public AActor
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
@ -32,8 +41,6 @@ public:
|
|||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void Tick(float Delta) override;
|
||||
|
||||
uint32 GetImageSizeX() const
|
||||
{
|
||||
return SizeX;
|
||||
|
@ -44,11 +51,15 @@ public:
|
|||
return SizeY;
|
||||
}
|
||||
|
||||
const TArray<FColor> &GetImage() const
|
||||
EPostProcessEffect GetPostProcessEffect() const
|
||||
{
|
||||
return ImageBitMap;
|
||||
return PostProcessEffect;
|
||||
}
|
||||
|
||||
FString GetPostProcessEffectAsString() const;
|
||||
|
||||
bool ReadPixels(TArray<FColor> &BitMap) const;
|
||||
|
||||
private:
|
||||
|
||||
/// Used to synchronize the DrawFrustumComponent with the
|
||||
|
@ -61,6 +72,9 @@ private:
|
|||
UPROPERTY(Category = SceneCapture, EditAnywhere)
|
||||
uint32 SizeY;
|
||||
|
||||
UPROPERTY(Category = SceneCapture, EditAnywhere)
|
||||
EPostProcessEffect PostProcessEffect;
|
||||
|
||||
/** To display the 3d camera in the editor. */
|
||||
UPROPERTY()
|
||||
class UStaticMeshComponent* MeshComp;
|
||||
|
@ -74,9 +88,6 @@ private:
|
|||
class UTextureRenderTarget2D* CaptureRenderTarget;
|
||||
|
||||
/** Scene capture component. */
|
||||
UPROPERTY(Transient)
|
||||
UPROPERTY(EditAnywhere)
|
||||
class USceneCaptureComponent2D* CaptureComponent2D;
|
||||
|
||||
UPROPERTY()
|
||||
TArray<FColor> ImageBitMap;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue