Merge branch 'dev' into xisco
This commit is contained in:
commit
e4d55e3464
13
CHANGELOG.md
13
CHANGELOG.md
|
@ -1,3 +1,16 @@
|
|||
## CARLA 0.3.0
|
||||
|
||||
* Added basic dynamic weather functionality.
|
||||
- Weather and sun light can be changed during game.
|
||||
- Presets stored in config file CarlaWeather.ini.
|
||||
* Add basic functionality to spawn pedestrians.
|
||||
* Split road meshes for intersections and turns for better precission of the road map.
|
||||
* Better debug for road map.
|
||||
* Implemented collision count for other cars and pedestrians.
|
||||
* Command line argument -carla-settings now accepts relative paths.
|
||||
* Improved performance when semantic segmentation is disabled.
|
||||
* Improved tagger system.
|
||||
|
||||
## CARLA 0.2.4
|
||||
|
||||
* Fixed serialization of road map resulting in a huge map size.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"FileVersion": 3,
|
||||
"Version": 1,
|
||||
"VersionName": "0.2.4",
|
||||
"VersionName": "0.3.0",
|
||||
"FriendlyName": "CARLA",
|
||||
"Description": "",
|
||||
"Category": "Science",
|
||||
|
|
|
@ -14,6 +14,14 @@ WorldPort=2000
|
|||
WritePort=2001
|
||||
ReadPort=2002
|
||||
|
||||
[CARLA/LevelSettings]
|
||||
; Number of NPC vehicles to be spawned into the level.
|
||||
NumberOfVehicles=5
|
||||
; Number of NPC pedestrians to be spawned into the level.
|
||||
NumberOfPedestrians=15
|
||||
; Index of the weather presets to use. If negative, weather won't be changed.
|
||||
WeatherId=-1
|
||||
|
||||
[CARLA/SceneCapture]
|
||||
; Names of the scene capture cameras to attach to the player, each of them
|
||||
; should be defined in its own subsection.
|
||||
|
|
|
@ -20,3 +20,32 @@ following
|
|||
[/Script/Engine.RendererSettings]
|
||||
r.CustomDepth=3
|
||||
```
|
||||
|
||||
Weather presets
|
||||
---------------
|
||||
|
||||
To change the weather and sun light, set `WeatherId` in CarlaSettings.ini
|
||||
from the following
|
||||
|
||||
* 0 - Default
|
||||
* 1 - ClearNoon
|
||||
* 2 - CloudyNoon
|
||||
* 3 - WetNoon
|
||||
* 4 - WetCloudyNoon
|
||||
* 5 - MidRainyNoon
|
||||
* 6 - HardRainNoon
|
||||
* 7 - SoftRainNoon
|
||||
* 8 - ClearSunset
|
||||
* 9 - CloudySunset
|
||||
* 10 - WetSunset
|
||||
* 11 - WetCloudySunset
|
||||
* 12 - MidRainSunset
|
||||
* 13 - HardRainSunset
|
||||
* 14 - SoftRainSunset
|
||||
|
||||
E.g., to choose the weather to be hard-rain at noon, add to CarlaSettings.ini
|
||||
|
||||
```
|
||||
[CARLA/LevelSettings]
|
||||
WeatherId=6
|
||||
```
|
||||
|
|
|
@ -5,9 +5,25 @@
|
|||
#include "Engine/TargetPoint.h"
|
||||
#include "WalkerSpawnPoint.generated.h"
|
||||
|
||||
/// Used to set spawner locations for walkers in the level.
|
||||
UCLASS()
|
||||
class CARLA_API AWalkerSpawnPoint : public ATargetPoint
|
||||
/// Base class for spawner locations for walkers.
|
||||
UCLASS(Abstract)
|
||||
class CARLA_API AWalkerSpawnPointBase : public ATargetPoint
|
||||
{
|
||||
GENERATED_BODY()
|
||||
};
|
||||
|
||||
/// Used to set spawner locations for walkers in the level. These positions will
|
||||
/// be used solely to spawn walkers at begin play.
|
||||
UCLASS()
|
||||
class CARLA_API AWalkerStartSpawnPoint : public AWalkerSpawnPointBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
};
|
||||
|
||||
/// Used to set spawner locations for walkers in the level. These positions will
|
||||
/// be used as spawn points as well as destination points for walkers.
|
||||
UCLASS()
|
||||
class CARLA_API AWalkerSpawnPoint : public AWalkerSpawnPointBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
};
|
||||
|
|
|
@ -14,9 +14,24 @@
|
|||
// -- Static local methods -----------------------------------------------------
|
||||
// =============================================================================
|
||||
|
||||
static bool WalkerIsValid(ACharacter *Walker)
|
||||
{
|
||||
return ((Walker != nullptr) && !Walker->IsPendingKill());
|
||||
}
|
||||
|
||||
static AWalkerAIController *GetController(ACharacter *Walker)
|
||||
{
|
||||
return (Walker != nullptr ? Cast<AWalkerAIController>(Walker->GetController()) : nullptr);
|
||||
return (WalkerIsValid(Walker) ? Cast<AWalkerAIController>(Walker->GetController()) : nullptr);
|
||||
}
|
||||
|
||||
static float GetDistance(const FVector &Location0, const FVector &Location1)
|
||||
{
|
||||
return FMath::Abs((Location0 - Location1).Size());
|
||||
}
|
||||
|
||||
static float GetDistance(const AActor &Actor0, const AActor &Actor1)
|
||||
{
|
||||
return GetDistance(Actor0.GetActorLocation(), Actor1.GetActorLocation());
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
@ -39,6 +54,8 @@ void AWalkerSpawnerBase::BeginPlay()
|
|||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
NumberOfWalkers = FMath::Max(0, NumberOfWalkers);
|
||||
|
||||
// Allocate space for walkers.
|
||||
Walkers.Reserve(NumberOfWalkers);
|
||||
|
||||
|
@ -50,14 +67,32 @@ void AWalkerSpawnerBase::BeginPlay()
|
|||
}
|
||||
|
||||
// Find spawn points present in level.
|
||||
for (TActorIterator<AWalkerSpawnPoint> It(GetWorld()); It; ++It) {
|
||||
SpawnPoints.Add(*It);
|
||||
TArray<AWalkerSpawnPointBase *> BeginSpawnPoints;
|
||||
for (TActorIterator<AWalkerSpawnPointBase> It(GetWorld()); It; ++It) {
|
||||
BeginSpawnPoints.Add(*It);
|
||||
AWalkerSpawnPoint *SpawnPoint = Cast<AWalkerSpawnPoint>(*It);
|
||||
if (SpawnPoint != nullptr) {
|
||||
SpawnPoints.Add(SpawnPoint);
|
||||
}
|
||||
}
|
||||
UE_LOG(LogCarla, Log, TEXT("Found %d positions for spawning walkers"), SpawnPoints.Num());
|
||||
UE_LOG(LogCarla, Log, TEXT("Found %d positions for spawning walkers at begin play."), BeginSpawnPoints.Num());
|
||||
UE_LOG(LogCarla, Log, TEXT("Found %d positions for spawning walkers during game play."), SpawnPoints.Num());
|
||||
|
||||
if (SpawnPoints.Num() < 2) {
|
||||
bSpawnWalkers = false;
|
||||
UE_LOG(LogCarla, Error, TEXT("We don't have enough spawn points for walkers!"));
|
||||
} else if (BeginSpawnPoints.Num() < NumberOfWalkers) {
|
||||
UE_LOG(LogCarla, Warning, TEXT("Requested %d walkers, but we only have %d spawn points. Some will fail to spawn."), NumberOfWalkers, BeginSpawnPoints.Num());
|
||||
}
|
||||
|
||||
if (bSpawnWalkers) {
|
||||
uint32 Count = 0u;
|
||||
for (auto i = 0; i < NumberOfWalkers; ++i) {
|
||||
if (TryToSpawnWalkerAt(*BeginSpawnPoints[i % BeginSpawnPoints.Num()])) {
|
||||
++Count;
|
||||
}
|
||||
}
|
||||
UE_LOG(LogCarla, Log, TEXT("Spawned %d walkers at begin play."), Count);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,21 +100,39 @@ void AWalkerSpawnerBase::Tick(float DeltaTime)
|
|||
{
|
||||
Super::Tick(DeltaTime);
|
||||
|
||||
if (bSpawnWalkers && (NumberOfWalkers > Walkers.Num())) {
|
||||
if (bSpawnWalkers && (NumberOfWalkers > GetCurrentNumberOfWalkers())) {
|
||||
// Try to spawn one walker.
|
||||
TryToSpawnRandomWalker();
|
||||
TryToSpawnWalkerAt(GetRandomSpawnPoint());
|
||||
}
|
||||
|
||||
if (WalkersBlackList.Num() > 0) {
|
||||
// If still stuck in the black list, just kill it.
|
||||
const int32 Index = (++CurrentIndexToCheck % WalkersBlackList.Num());
|
||||
auto Walker = WalkersBlackList[Index];
|
||||
auto Controller = GetController(Walker);
|
||||
if ((Controller == nullptr) ||
|
||||
(Controller->GetMoveStatus() != EPathFollowingStatus::Moving)) {
|
||||
WalkersBlackList.RemoveAtSwap(Index);
|
||||
if (Walker != nullptr) {
|
||||
Walker->Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Walkers.Num() > 0) {
|
||||
// Check one walker and kill it if necessary.
|
||||
// Check one walker, if fails black-list it or kill it.
|
||||
const int32 Index = (++CurrentIndexToCheck % Walkers.Num());
|
||||
auto Walker = Walkers[Index];
|
||||
auto Controller = GetController(Walker);
|
||||
if ((Controller == nullptr) || (Controller->GetMoveStatus() != EPathFollowingStatus::Moving)) {
|
||||
if (Controller == nullptr) {
|
||||
Walkers.RemoveAtSwap(Index);
|
||||
if (Walker != nullptr) {
|
||||
Walker->Destroy();
|
||||
}
|
||||
} else if (Controller->GetMoveStatus() != EPathFollowingStatus::Moving) {
|
||||
TrySetDestination(*Walker);
|
||||
WalkersBlackList.Add(Walker);
|
||||
Walkers.RemoveAtSwap(Index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,45 +151,64 @@ void AWalkerSpawnerBase::SetNumberOfWalkers(const int32 Count)
|
|||
}
|
||||
}
|
||||
|
||||
void AWalkerSpawnerBase::TryToSpawnRandomWalker()
|
||||
const AWalkerSpawnPointBase &AWalkerSpawnerBase::GetRandomSpawnPoint() const
|
||||
{
|
||||
auto SpawnPoint = GetRandomSpawnPoint();
|
||||
auto DestinationPoint = GetRandomSpawnPoint();
|
||||
if ((SpawnPoint != nullptr) && (DestinationPoint != nullptr)) {
|
||||
const auto StraightDistance =
|
||||
DestinationPoint->GetActorLocation() -
|
||||
SpawnPoint->GetActorLocation();
|
||||
if (StraightDistance.Size() >= MinimumWalkDistance) {
|
||||
SpawnWalkerAtSpawnPoint(*SpawnPoint, DestinationPoint->GetActorLocation());
|
||||
}
|
||||
} else {
|
||||
UE_LOG(LogCarla, Error, TEXT("Unable to find spawn point"));
|
||||
}
|
||||
check(SpawnPoints.Num() > 0);
|
||||
return *SpawnPoints[RandomStream.RandRange(0, SpawnPoints.Num() - 1)];
|
||||
}
|
||||
|
||||
void AWalkerSpawnerBase::SpawnWalkerAtSpawnPoint(
|
||||
const AWalkerSpawnPoint &SpawnPoint,
|
||||
const FVector &Destination)
|
||||
bool AWalkerSpawnerBase::TryGetValidDestination(const FVector &Origin, FVector &Destination) const
|
||||
{
|
||||
const auto &DestinationPoint = GetRandomSpawnPoint();
|
||||
Destination = DestinationPoint.GetActorLocation();
|
||||
return (GetDistance(Origin, Destination) >= MinimumWalkDistance);
|
||||
}
|
||||
|
||||
bool AWalkerSpawnerBase::TryToSpawnWalkerAt(const AWalkerSpawnPointBase &SpawnPoint)
|
||||
{
|
||||
// Try find destination.
|
||||
FVector Destination;
|
||||
if (!TryGetValidDestination(SpawnPoint.GetActorLocation(), Destination)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Spawn walker.
|
||||
ACharacter *Walker;
|
||||
SpawnWalker(SpawnPoint.GetActorTransform(), Walker);
|
||||
if ((Walker != nullptr) && !Walker->IsPendingKill()) {
|
||||
Walker->AIControllerClass = AWalkerAIController::StaticClass();
|
||||
Walker->SpawnDefaultController();
|
||||
auto Controller = GetController(Walker);
|
||||
if (Controller != nullptr) { // Sometimes fails...
|
||||
Controller->MoveToLocation(Destination);
|
||||
Walkers.Add(Walker);
|
||||
} else {
|
||||
UE_LOG(LogCarla, Error, TEXT("Something went wrong creating the controller for the new walker"));
|
||||
Walker->Destroy();
|
||||
}
|
||||
if (!WalkerIsValid(Walker)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Assign controller.
|
||||
Walker->AIControllerClass = AWalkerAIController::StaticClass();
|
||||
Walker->SpawnDefaultController();
|
||||
auto Controller = GetController(Walker);
|
||||
if (Controller == nullptr) { // Sometimes fails...
|
||||
UE_LOG(LogCarla, Error, TEXT("Something went wrong creating the controller for the new walker"));
|
||||
Walker->Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add walker and set destination.
|
||||
Walkers.Add(Walker);
|
||||
Controller->MoveToLocation(Destination);
|
||||
return true;
|
||||
}
|
||||
|
||||
AWalkerSpawnPoint *AWalkerSpawnerBase::GetRandomSpawnPoint() const
|
||||
bool AWalkerSpawnerBase::TrySetDestination(ACharacter &Walker) const
|
||||
{
|
||||
return (SpawnPoints.Num() > 0 ?
|
||||
SpawnPoints[RandomStream.RandRange(0, SpawnPoints.Num() - 1)] :
|
||||
nullptr);
|
||||
// Try to retrieve controller.
|
||||
auto Controller = GetController(&Walker);
|
||||
if (Controller == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try find destination.
|
||||
FVector Destination;
|
||||
if (!TryGetValidDestination(Walker.GetActorLocation(), Destination)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Controller->MoveToLocation(Destination);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "WalkerSpawnerBase.generated.h"
|
||||
|
||||
class AWalkerSpawnPoint;
|
||||
class AWalkerSpawnPointBase;
|
||||
class UBoxComponent;
|
||||
|
||||
/// Base class for spawning walkers. Implement SpawnWalker in derived
|
||||
|
@ -64,13 +65,20 @@ public:
|
|||
|
||||
void SetNumberOfWalkers(int32 Count);
|
||||
|
||||
int32 GetCurrentNumberOfWalkers() const
|
||||
{
|
||||
return Walkers.Num() + WalkersBlackList.Num();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void TryToSpawnRandomWalker();
|
||||
const AWalkerSpawnPointBase &GetRandomSpawnPoint() const;
|
||||
|
||||
void SpawnWalkerAtSpawnPoint(const AWalkerSpawnPoint &SpawnPoint, const FVector &Destination);
|
||||
bool TryGetValidDestination(const FVector &Origin, FVector &Destination) const;
|
||||
|
||||
AWalkerSpawnPoint *GetRandomSpawnPoint() const;
|
||||
bool TryToSpawnWalkerAt(const AWalkerSpawnPointBase &SpawnPoint);
|
||||
|
||||
bool TrySetDestination(ACharacter &Walker) const;
|
||||
|
||||
/// @}
|
||||
|
||||
|
@ -105,5 +113,8 @@ private:
|
|||
UPROPERTY(Category = "Walker Spawner", VisibleAnywhere, AdvancedDisplay)
|
||||
TArray<ACharacter *> Walkers;
|
||||
|
||||
UPROPERTY(Category = "Walker Spawner", VisibleAnywhere, AdvancedDisplay)
|
||||
TArray<ACharacter *> WalkersBlackList;
|
||||
|
||||
uint32 CurrentIndexToCheck = 0u;
|
||||
};
|
||||
|
|
|
@ -12,7 +12,7 @@ DECLARE_LOG_CATEGORY_EXTERN(LogCarla, Log, All);
|
|||
DECLARE_LOG_CATEGORY_EXTERN(LogCarlaServer, Log, All);
|
||||
|
||||
// Options to compile with extra debug options.
|
||||
#ifdef WITH_EDITOR
|
||||
#if WITH_EDITOR
|
||||
// #define CARLA_ROAD_GENERATOR_EXTRA_LOG /// @todo #1 Crashes in Linux.
|
||||
// #define CARLA_SERVER_EXTRA_LOG
|
||||
// #define CARLA_TAGGER_EXTRA_LOG
|
||||
|
|
|
@ -276,7 +276,7 @@ void ACityMapGenerator::GenerateRoadMap()
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_EDITOR
|
||||
#if WITH_EDITOR
|
||||
RoadMap->Log();
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
|
@ -286,7 +286,7 @@ void ACityMapGenerator::GenerateRoadMap()
|
|||
RoadMap->SaveAsPNG(FilePath);
|
||||
}
|
||||
|
||||
#ifdef WITH_EDITOR
|
||||
#if WITH_EDITOR
|
||||
RoadMap->DrawDebugPixelsToLevel(GetWorld(), !bDrawDebugPixelsToLevel);
|
||||
#endif // WITH_EDITOR
|
||||
}
|
||||
|
|
|
@ -71,7 +71,17 @@ ADynamicWeather::ADynamicWeather(const FObjectInitializer& ObjectInitializer)
|
|||
void ADynamicWeather::OnConstruction(const FTransform &Transform)
|
||||
{
|
||||
Super::OnConstruction(Transform);
|
||||
#if WITH_EDITOR
|
||||
Update();
|
||||
#endif // WITH_EDITOR
|
||||
}
|
||||
|
||||
void ADynamicWeather::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
#if WITH_EDITOR
|
||||
Update();
|
||||
#endif // WITH_EDITOR
|
||||
}
|
||||
|
||||
#if WITH_EDITOR
|
||||
|
@ -82,6 +92,9 @@ void ADynamicWeather::PostEditChangeProperty(FPropertyChangedEvent &Event)
|
|||
const FName PropertyName = (Event.Property != NULL ? Event.Property->GetFName() : NAME_None);
|
||||
if (PropertyName == GET_MEMBER_NAME_CHECKED(ADynamicWeather, Weather)) {
|
||||
Update();
|
||||
} else if ((PropertyName == GET_MEMBER_NAME_CHECKED(ADynamicWeather, bSaveToConfigFile)) ||
|
||||
(PropertyName == GET_MEMBER_NAME_CHECKED(ADynamicWeather, bLoadFromConfigFile))) {
|
||||
// Do nothing.
|
||||
} else {
|
||||
AdjustSunPositionBasedOnActorRotation();
|
||||
}
|
||||
|
@ -97,6 +110,7 @@ void ADynamicWeather::PostEditChangeProperty(FPropertyChangedEvent &Event)
|
|||
bLoadFromConfigFile = false;
|
||||
if (LoadFromConfigFile()) {
|
||||
UE_LOG(LogCarla, Log, TEXT("Weather \"%s\" loaded from config file"), *Weather.Name);
|
||||
Update();
|
||||
} else {
|
||||
UE_LOG(LogCarla, Error, TEXT("Error loading weather from config file"));
|
||||
}
|
||||
|
@ -123,16 +137,6 @@ FVector ADynamicWeather::GetSunDirection() const
|
|||
return - SphericalCoords.SphericalToUnitCartesian();
|
||||
}
|
||||
|
||||
void ADynamicWeather::Update()
|
||||
{
|
||||
// Modify this actor's rotation according to Sun position.
|
||||
if (!SetActorRotation(FQuat(GetSunDirection().Rotation()), ETeleportType::None)) {
|
||||
UE_LOG(LogCarla, Warning, TEXT("Unable to rotate actor"));
|
||||
}
|
||||
|
||||
RefreshWeather();
|
||||
}
|
||||
|
||||
void ADynamicWeather::AdjustSunPositionBasedOnActorRotation()
|
||||
{
|
||||
const FVector Direction = - GetActorQuat().GetForwardVector();
|
||||
|
@ -143,6 +147,18 @@ void ADynamicWeather::AdjustSunPositionBasedOnActorRotation()
|
|||
|
||||
#if WITH_EDITOR
|
||||
|
||||
void ADynamicWeather::Update()
|
||||
{
|
||||
// Modify this actor's rotation according to Sun position.
|
||||
if (!SetActorRotation(FQuat(GetSunDirection().Rotation()), ETeleportType::None)) {
|
||||
UE_LOG(LogCarla, Warning, TEXT("Unable to rotate actor"));
|
||||
}
|
||||
|
||||
if (bRefreshAutomatically) {
|
||||
RefreshWeather();
|
||||
}
|
||||
}
|
||||
|
||||
bool ADynamicWeather::LoadFromConfigFile()
|
||||
{
|
||||
FString FileName;
|
||||
|
|
|
@ -22,6 +22,8 @@ public:
|
|||
|
||||
virtual void OnConstruction(const FTransform &Transform) override;
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
|
||||
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
|
||||
|
@ -49,12 +51,12 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
void Update();
|
||||
|
||||
void AdjustSunPositionBasedOnActorRotation();
|
||||
|
||||
#if WITH_EDITOR
|
||||
|
||||
void Update();
|
||||
|
||||
bool LoadFromConfigFile();
|
||||
|
||||
bool SaveToConfigFile() const;
|
||||
|
@ -66,9 +68,17 @@ private:
|
|||
UPROPERTY()
|
||||
UArrowComponent *ArrowComponent;
|
||||
|
||||
/** If true, the weather is refreshed on construction and at begin play.
|
||||
* Useful for editing the weather (Editor only).
|
||||
*/
|
||||
UPROPERTY(Category = "Weather Description", EditAnywhere)
|
||||
bool bRefreshAutomatically = false;
|
||||
|
||||
/** Load the section with the currently set name. */
|
||||
UPROPERTY(Category = "Weather Description", EditAnywhere)
|
||||
bool bLoadFromConfigFile = false;
|
||||
|
||||
/** Save current settings to disk. */
|
||||
UPROPERTY(Category = "Weather Description", EditAnywhere)
|
||||
bool bSaveToConfigFile = false;
|
||||
|
||||
|
|
|
@ -16,7 +16,8 @@ UCarlaGameInstance::UCarlaGameInstance() {
|
|||
|
||||
UCarlaGameInstance::~UCarlaGameInstance() {}
|
||||
|
||||
void UCarlaGameInstance::InitializeGameControllerIfNotPresent()
|
||||
void UCarlaGameInstance::InitializeGameControllerIfNotPresent(
|
||||
const FMockGameControllerSettings &MockControllerSettings)
|
||||
{
|
||||
if (GameController == nullptr) {
|
||||
if (CarlaSettings->bUseNetworking) {
|
||||
|
@ -25,8 +26,8 @@ void UCarlaGameInstance::InitializeGameControllerIfNotPresent()
|
|||
CarlaSettings->WritePort,
|
||||
CarlaSettings->ReadPort);
|
||||
} else {
|
||||
GameController = MakeUnique<MockGameController>();
|
||||
UE_LOG(LogCarla, Warning, TEXT("Using mock CARLA controller"));
|
||||
GameController = MakeUnique<MockGameController>(MockControllerSettings);
|
||||
UE_LOG(LogCarla, Log, TEXT("Using mock CARLA controller"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "CarlaGameInstance.generated.h"
|
||||
|
||||
class UCarlaSettings;
|
||||
struct FMockGameControllerSettings;
|
||||
|
||||
/// The game instance contains elements that must be kept alive in between
|
||||
/// levels. It is instantiate once per game.
|
||||
|
@ -21,7 +22,8 @@ public:
|
|||
|
||||
~UCarlaGameInstance();
|
||||
|
||||
void InitializeGameControllerIfNotPresent();
|
||||
void InitializeGameControllerIfNotPresent(
|
||||
const FMockGameControllerSettings &MockControllerSettings);
|
||||
|
||||
CarlaGameControllerBase &GetGameController()
|
||||
{
|
||||
|
|
|
@ -23,6 +23,7 @@ ACarlaGameModeBase::ACarlaGameModeBase(const FObjectInitializer& ObjectInitializ
|
|||
{
|
||||
PrimaryActorTick.bCanEverTick = true;
|
||||
PrimaryActorTick.TickGroup = TG_PrePhysics;
|
||||
bAllowTickBeforeBeginPlay = false;
|
||||
|
||||
PlayerControllerClass = ACarlaVehicleController::StaticClass();
|
||||
GameStateClass = ACarlaGameState::StaticClass();
|
||||
|
@ -43,7 +44,7 @@ void ACarlaGameModeBase::InitGame(
|
|||
checkf(
|
||||
GameInstance != nullptr,
|
||||
TEXT("GameInstance is not a UCarlaGameInstance, did you forget to set it in the project settings?"));
|
||||
GameInstance->InitializeGameControllerIfNotPresent();
|
||||
GameInstance->InitializeGameControllerIfNotPresent(MockGameControllerSettings);
|
||||
GameController = &GameInstance->GetGameController();
|
||||
GameController->Initialize(GameInstance->GetCarlaSettings());
|
||||
GameInstance->GetCarlaSettings().LogSettings();
|
||||
|
@ -98,14 +99,21 @@ void ACarlaGameModeBase::BeginPlay()
|
|||
|
||||
// Change weather.
|
||||
if (DynamicWeather != nullptr) {
|
||||
const auto &Weather = CarlaSettings.GetActiveWeatherDescription();
|
||||
UE_LOG(LogCarla, Log, TEXT("Changing weather settings to \"%s\""), *Weather.Name);
|
||||
DynamicWeather->SetWeatherDescription(Weather);
|
||||
const auto *Weather = CarlaSettings.GetActiveWeatherDescription();
|
||||
if (Weather != nullptr) {
|
||||
UE_LOG(LogCarla, Log, TEXT("Changing weather settings to \"%s\""), *Weather->Name);
|
||||
DynamicWeather->SetWeatherDescription(*Weather);
|
||||
DynamicWeather->RefreshWeather();
|
||||
}
|
||||
} else {
|
||||
UE_LOG(LogCarla, Error, TEXT("Missing dynamic weather actor!"));
|
||||
}
|
||||
|
||||
// Setup walkers.
|
||||
if (WalkerSpawner != nullptr) {
|
||||
WalkerSpawner->SetNumberOfWalkers(CarlaSettings.NumberOfPedestrians);
|
||||
} else {
|
||||
UE_LOG(LogCarla, Error, TEXT("Missing walker spawner actor!"));
|
||||
}
|
||||
|
||||
GameController->BeginPlay();
|
||||
|
@ -164,7 +172,7 @@ APlayerStart *ACarlaGameModeBase::FindUnOccupiedStartPoints(
|
|||
if (!GetWorld()->EncroachingBlockingGeometry(PawnToFit, ActorLocation, ActorRotation)) {
|
||||
UnOccupiedStartPoints.Add(PlayerStart);
|
||||
}
|
||||
#ifdef WITH_EDITOR
|
||||
#if WITH_EDITOR
|
||||
else if (GetWorld()->FindTeleportSpot(PawnToFit, ActorLocation, ActorRotation)) {
|
||||
UE_LOG(
|
||||
LogCarla,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "AI/WalkerSpawnerBase.h"
|
||||
#include "CarlaGameControllerBase.h"
|
||||
#include "DynamicWeather.h"
|
||||
#include "MockGameControllerSettings.h"
|
||||
#include "CarlaGameModeBase.generated.h"
|
||||
|
||||
class APlayerStart;
|
||||
|
@ -15,7 +16,7 @@ class UTaggerDelegate;
|
|||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
UCLASS(HideCategories=(ActorTick))
|
||||
class CARLA_API ACarlaGameModeBase : public AGameModeBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
@ -34,6 +35,10 @@ public:
|
|||
|
||||
protected:
|
||||
|
||||
/** Used only when networking is disabled. */
|
||||
UPROPERTY(Category = "Mock CARLA Controller", EditAnywhere, BlueprintReadOnly, meta = (ExposeFunctionCategories = "Mock CARLA Controller"))
|
||||
FMockGameControllerSettings MockGameControllerSettings;
|
||||
|
||||
/** The class of DynamicWeather to spawn. */
|
||||
UPROPERTY(Category = "CARLA Classes", EditAnywhere, BlueprintReadOnly)
|
||||
TSubclassOf<ADynamicWeather> DynamicWeatherClass;
|
||||
|
|
|
@ -90,9 +90,9 @@ static void LoadSettingsFromFile(const FString &FileName, UCarlaSettings &Settin
|
|||
Settings.WeatherDescriptions.Empty();
|
||||
ADynamicWeather::LoadWeatherDescriptionsFromFile(Settings.WeatherDescriptions);
|
||||
check(Settings.WeatherDescriptions.Num() > 0);
|
||||
if (static_cast<int32>(Settings.WeatherId) >= Settings.WeatherDescriptions.Num()) {
|
||||
if (Settings.WeatherId >= Settings.WeatherDescriptions.Num()) {
|
||||
UE_LOG(LogCarla, Error, TEXT("Provided weather id %d cannot be found"), Settings.WeatherId);
|
||||
Settings.WeatherId = 0u;
|
||||
Settings.WeatherId = -1;
|
||||
}
|
||||
// SceneCapture.
|
||||
FString Cameras;
|
||||
|
|
|
@ -22,9 +22,12 @@ public:
|
|||
/** Log settings values. */
|
||||
void LogSettings() const;
|
||||
|
||||
const FWeatherDescription &GetActiveWeatherDescription() const
|
||||
const FWeatherDescription *GetActiveWeatherDescription() const
|
||||
{
|
||||
return WeatherDescriptions[WeatherId];
|
||||
if ((WeatherId >= 0) && (WeatherId < WeatherDescriptions.Num())) {
|
||||
return &WeatherDescriptions[WeatherId];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -70,9 +73,9 @@ public:
|
|||
UPROPERTY(Category = "Level Settings", EditDefaultsOnly)
|
||||
uint32 NumberOfPedestrians = 15u;
|
||||
|
||||
/** Index of the weather setting to use. */
|
||||
/** Index of the weather setting to use. If negative, weather won't be changed. */
|
||||
UPROPERTY(Category = "Level Settings", EditDefaultsOnly)
|
||||
uint32 WeatherId = 0;
|
||||
int32 WeatherId = -1;
|
||||
|
||||
/** Available weather settings. */
|
||||
UPROPERTY(Category = "Level Settings", EditDefaultsOnly)
|
||||
|
|
|
@ -3,15 +3,46 @@
|
|||
#include "Carla.h"
|
||||
#include "MockGameController.h"
|
||||
|
||||
void MockGameController::Initialize(UCarlaSettings & /*CarlaSettings*/)
|
||||
{
|
||||
MockGameController::MockGameController(const FMockGameControllerSettings &InSettings) :
|
||||
Settings(InSettings) {}
|
||||
|
||||
void MockGameController::Initialize(UCarlaSettings & CarlaSettings)
|
||||
{
|
||||
#if WITH_EDITOR
|
||||
if (Settings.bOverrideCarlaSettings) {
|
||||
CarlaSettings.NumberOfVehicles = Settings.NumberOfVehicles;
|
||||
CarlaSettings.NumberOfPedestrians = Settings.NumberOfPedestrians;
|
||||
CarlaSettings.WeatherId = Settings.WeatherId;
|
||||
}
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
if (Settings.bChangeWeatherOnBeginPlay && (CarlaSettings.WeatherDescriptions.Num() > 0)) {
|
||||
static uint32 StaticIndex = 0u;
|
||||
CarlaSettings.WeatherId = StaticIndex % CarlaSettings.WeatherDescriptions.Num();
|
||||
++StaticIndex;
|
||||
}
|
||||
|
||||
#if WITH_EDITOR
|
||||
if (Settings.bForceEnableSemanticSegmentation) {
|
||||
CarlaSettings.bSemanticSegmentationEnabled = true;
|
||||
}
|
||||
#endif // WITH_EDITOR
|
||||
}
|
||||
|
||||
APlayerStart *MockGameController::ChoosePlayerStart(
|
||||
const TArray<APlayerStart *> &AvailableStartSpots)
|
||||
{
|
||||
return AvailableStartSpots[FMath::RandRange(0, AvailableStartSpots.Num() - 1)];
|
||||
check(AvailableStartSpots.Num() > 0);
|
||||
uint32 Index;
|
||||
if (Settings.bRandomPlayerStart) {
|
||||
Index = FMath::RandRange(0, AvailableStartSpots.Num() - 1);
|
||||
} else {
|
||||
static uint32 StaticIndex = 0u;
|
||||
Index = StaticIndex % AvailableStartSpots.Num();
|
||||
++StaticIndex;
|
||||
}
|
||||
UE_LOG(LogCarla, Log, TEXT("Spawning player at player start %d/%d"), Index, AvailableStartSpots.Num());
|
||||
return AvailableStartSpots[Index];
|
||||
}
|
||||
|
||||
void MockGameController::RegisterPlayer(AController &NewPlayer)
|
||||
|
|
|
@ -3,12 +3,15 @@
|
|||
#pragma once
|
||||
|
||||
#include "CarlaGameControllerBase.h"
|
||||
#include "MockGameControllerSettings.h"
|
||||
|
||||
/// Mocks the CARLA game controller class for testing purposes.
|
||||
class CARLA_API MockGameController : public CarlaGameControllerBase
|
||||
{
|
||||
public:
|
||||
|
||||
explicit MockGameController(const FMockGameControllerSettings &Settings);
|
||||
|
||||
virtual void Initialize(UCarlaSettings &CarlaSettings) override;
|
||||
|
||||
virtual APlayerStart *ChoosePlayerStart(const TArray<APlayerStart *> &AvailableStartSpots) override;
|
||||
|
@ -18,4 +21,8 @@ public:
|
|||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void Tick(float DeltaSeconds) override;
|
||||
|
||||
private:
|
||||
|
||||
FMockGameControllerSettings Settings;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
// CARLA, Copyright (C) 2017 Computer Vision Center (CVC)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "MockGameControllerSettings.generated.h"
|
||||
|
||||
USTRUCT(BlueprintType)
|
||||
struct FMockGameControllerSettings
|
||||
{
|
||||
GENERATED_USTRUCT_BODY()
|
||||
|
||||
/** If true, weather will be changed every time we start the level.
|
||||
*
|
||||
* Has precedence over options in "Override CARLA Settings".
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, Category = "Mock CARLA Controller")
|
||||
bool bChangeWeatherOnBeginPlay = true;
|
||||
|
||||
/** If true, a random player start position will be chosen every time we start the level. */
|
||||
UPROPERTY(EditAnywhere, Category = "Mock CARLA Controller")
|
||||
bool bRandomPlayerStart = true;
|
||||
|
||||
/** If true, semantic segmentation will be always enabled even if no camera needs it. */
|
||||
UPROPERTY(EditAnywhere, Category = "Mock CARLA Controller")
|
||||
bool bForceEnableSemanticSegmentation = false;
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
|
||||
/** Override available settings in CARLA Settings (Editor only). */
|
||||
UPROPERTY(EditAnywhere, Category = "Mock CARLA Controller", meta = (DisplayName = "Override CARLA Settings"))
|
||||
bool bOverrideCarlaSettings = false;
|
||||
|
||||
/** Number of NPC vehicles to be spawned into the level. */
|
||||
UPROPERTY(EditAnywhere, Category = "Mock CARLA Controller", meta = (EditCondition = "bOverrideCarlaSettings", ClampMin = 0))
|
||||
int32 NumberOfVehicles = 5;
|
||||
|
||||
/** Number of NPC pedestrians to be spawned into the level. */
|
||||
UPROPERTY(EditAnywhere, Category = "Mock CARLA Controller", meta = (EditCondition = "bOverrideCarlaSettings", ClampMin = 0))
|
||||
int32 NumberOfPedestrians = 15;
|
||||
|
||||
/** Index of the weather setting to use. If negative, weather won't be changed. */
|
||||
UPROPERTY(EditAnywhere, Category = "Mock CARLA Controller", meta = (EditCondition = "bOverrideCarlaSettings"))
|
||||
int32 WeatherId = -1;
|
||||
|
||||
#endif // WITH_EDITORONLY_DATA
|
||||
};
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "HighResScreenshot.h"
|
||||
|
||||
#ifdef WITH_EDITOR
|
||||
#if WITH_EDITOR
|
||||
#include "DrawDebugHelpers.h"
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
|
@ -261,7 +261,7 @@ bool URoadMap::SaveAsPNG(const FString &Path) const
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef WITH_EDITOR
|
||||
#if WITH_EDITOR
|
||||
|
||||
void URoadMap::Log() const
|
||||
{
|
||||
|
|
|
@ -141,7 +141,7 @@ public:
|
|||
/// Save the current map as PNG with the pixel data encoded as color.
|
||||
bool SaveAsPNG(const FString &Path) const;
|
||||
|
||||
#ifdef WITH_EDITOR
|
||||
#if WITH_EDITOR
|
||||
|
||||
/// Log status of the map to the console.
|
||||
void Log() const;
|
||||
|
|
Loading…
Reference in New Issue