Fixed error that caused traffic light actors to be missing in client side.

This commit is contained in:
Axel1092 2020-07-08 14:32:55 +02:00 committed by Axel1092
parent 4d46387eb8
commit 4f1851be3f
10 changed files with 90 additions and 255 deletions

View File

@ -68,12 +68,6 @@ void ACarlaGameModeBase::InitGame(
auto World = GetWorld();
check(World != nullptr);
AActor* TrafficLightManagerActor = UGameplayStatics::GetActorOfClass(World, ATrafficLightManager::StaticClass());
if(TrafficLightManagerActor == nullptr) {
World->SpawnActor<ATrafficLightManager>();
}
GameInstance = Cast<UCarlaGameInstance>(GetGameInstance());
checkf(
GameInstance != nullptr,
@ -130,6 +124,18 @@ void ACarlaGameModeBase::BeginPlay()
TaggerDelegate->SetSemanticSegmentationEnabled();
}
AActor* TrafficLightManagerActor = UGameplayStatics::GetActorOfClass(GetWorld(), ATrafficLightManager::StaticClass());
if(TrafficLightManagerActor == nullptr)
{
ATrafficLightManager* TrafficLightManager = GetWorld()->SpawnActor<ATrafficLightManager>();
TrafficLightManager->InitializeTrafficLights();
}
else
{
ATrafficLightManager* TrafficLightManager = Cast<ATrafficLightManager>(TrafficLightManagerActor);
TrafficLightManager->InitializeTrafficLights();
}
Episode->InitializeAtBeginPlay();
GameInstance->NotifyBeginEpisode(*Episode);

View File

@ -117,7 +117,7 @@ static auto FWorldObserver_GetActorState(const FActorView &View, const FActorReg
state.traffic_light_data.green_time = Controller->GetGreenTime();
state.traffic_light_data.yellow_time = Controller->GetYellowTime();
state.traffic_light_data.red_time = Controller->GetRedTime();
state.traffic_light_data.elapsed_time = Group->GetElapsedTime();
state.traffic_light_data.elapsed_time = Controller->GetElapsedTime();
state.traffic_light_data.time_is_frozen = Group->IsFrozen();
state.traffic_light_data.pole_index = TrafficLight->GetPoleIndex();
}

View File

@ -40,87 +40,15 @@ static ETrafficSignState ToTrafficSignState(ETrafficLightState State)
ATrafficLightBase::ATrafficLightBase(const FObjectInitializer &ObjectInitializer)
: Super(ObjectInitializer)
{
PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.bCanEverTick = false;
TrafficLightComponent = CreateDefaultSubobject<UTrafficLightComponent>(TEXT("TrafficLightComponent"));
if(TrafficLightComponent && RootComponent)
{
TrafficLightComponent->SetupAttachment(RootComponent);
}
SetTrafficSignState(ETrafficSignState::TrafficLightGreen);
}
void ATrafficLightBase::OnConstruction(const FTransform &Transform)
{
Super::OnConstruction(Transform);
SetTrafficLightState(State);
}
void ATrafficLightBase::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
if (TimeIsFrozen || TrafficLightComponent)
{
return;
}
auto* Episode = UCarlaStatics::GetCurrentEpisode(GetWorld());
if (Episode)
{
auto* Replayer = Episode->GetReplayer();
if (Replayer)
{
if(Replayer->IsEnabled())
{
return;
}
}
}
ElapsedTime += DeltaSeconds;
float ChangeTime;
switch (State)
{
case ETrafficLightState::Red:
ChangeTime = RedTime;
break;
case ETrafficLightState::Yellow:
ChangeTime = YellowTime;
break;
case ETrafficLightState::Green:
ChangeTime = GreenTime;
break;
default:
UE_LOG(LogCarla, Error, TEXT("Invalid traffic light state!"));
SetTrafficLightState(ETrafficLightState::Red);
return;
}
if (ElapsedTime > ChangeTime)
{
// Freeze if part of a group and about to turn red
if (GroupTrafficLights.Num() > 0 && State == ETrafficLightState::Yellow)
{
SetTimeIsFrozen(true);
}
SwitchTrafficLightState();
}
}
#if WITH_EDITOR
void ATrafficLightBase::PostEditChangeProperty(FPropertyChangedEvent &Event)
{
Super::PostEditChangeProperty(Event);
const FName PropertyName = (Event.Property != nullptr ? Event.Property->GetFName() : NAME_None);
if (PropertyName == GET_MEMBER_NAME_CHECKED(ATrafficLightBase, State))
{
SetTrafficLightState(State);
}
}
#endif // WITH_EDITOR
ETrafficLightState ATrafficLightBase::GetTrafficLightState() const
{
if (TrafficLightComponent)
@ -129,7 +57,7 @@ ETrafficLightState ATrafficLightBase::GetTrafficLightState() const
}
else
{
return State;
return ETrafficLightState::Red;
}
}
@ -139,48 +67,7 @@ void ATrafficLightBase::SetTrafficLightState(const ETrafficLightState InState)
{
TrafficLightComponent->SetLightState(InState);
}
else
{
ElapsedTime = 0.0f;
State = InState;
SetTrafficSignState(ToTrafficSignState(State));
for (auto Controller : Vehicles)
{
if (Controller != nullptr)
{
Controller->SetTrafficLightState(State);
if (State == ETrafficLightState::Green)
{
Controller->SetTrafficLight(nullptr);
}
}
}
if (State == ETrafficLightState::Green)
{
Vehicles.Empty();
}
}
OnTrafficLightStateChanged(State);
}
void ATrafficLightBase::SwitchTrafficLightState()
{
switch (State)
{
case ETrafficLightState::Red:
SetTrafficLightState(ETrafficLightState::Green);
break;
case ETrafficLightState::Yellow:
SetTrafficLightState(ETrafficLightState::Red);
break;
case ETrafficLightState::Green:
SetTrafficLightState(ETrafficLightState::Yellow);
break;
default:
UE_LOG(LogCarla, Error, TEXT("Invalid traffic light state!"));
SetTrafficLightState(ETrafficLightState::Red);
break;
}
// OnTrafficLightStateChanged(State);
}
void ATrafficLightBase::NotifyWheeledVehicle(ACarlaWheeledVehicle *Vehicle)
@ -190,8 +77,8 @@ void ATrafficLightBase::NotifyWheeledVehicle(ACarlaWheeledVehicle *Vehicle)
auto Controller = Cast<AWheeledVehicleAIController>(Vehicle->GetController());
if (Controller != nullptr)
{
Controller->SetTrafficLightState(State);
if (State != ETrafficLightState::Green)
Controller->SetTrafficLightState(GetTrafficLightState());
if (GetTrafficLightState() != ETrafficLightState::Green)
{
Vehicles.Add(Controller);
Controller->SetTrafficLight(this);
@ -221,11 +108,6 @@ void ATrafficLightBase::SetGreenTime(float InGreenTime)
TrafficLightComponent->GetController();
check(TrafficLightController)
TrafficLightController->SetGreenTime(InGreenTime);
}
else
{
GreenTime = InGreenTime;
}
}
@ -239,7 +121,7 @@ float ATrafficLightBase::GetGreenTime() const
}
else
{
return GreenTime;
return 0;
}
}
@ -252,10 +134,6 @@ void ATrafficLightBase::SetYellowTime(float InYellowTime)
check(TrafficLightController)
TrafficLightController->SetYellowTime(InYellowTime);
}
else
{
YellowTime = InYellowTime;
}
}
float ATrafficLightBase::GetYellowTime() const
@ -268,7 +146,7 @@ float ATrafficLightBase::GetYellowTime() const
}
else
{
return YellowTime;
return 0;
}
}
@ -281,10 +159,6 @@ void ATrafficLightBase::SetRedTime(float InRedTime)
check(TrafficLightController)
TrafficLightController->SetRedTime(InRedTime);
}
else
{
RedTime = InRedTime;
}
}
float ATrafficLightBase::GetRedTime() const
@ -297,7 +171,7 @@ float ATrafficLightBase::GetRedTime() const
}
else
{
return RedTime;
return 0;
}
}
@ -305,13 +179,13 @@ float ATrafficLightBase::GetElapsedTime() const
{
if (TrafficLightComponent)
{
auto* Group = TrafficLightComponent->GetGroup();
check(Group);
return Group->GetElapsedTime();
auto* Controller = TrafficLightComponent->GetController();
check(Controller);
return Controller->GetElapsedTime();
}
else
{
return ElapsedTime;
return 0;
}
}
@ -319,13 +193,9 @@ void ATrafficLightBase::SetElapsedTime(float InElapsedTime)
{
if (TrafficLightComponent)
{
auto* Group = TrafficLightComponent->GetGroup();
check(Group);
return Group->SetElapsedTime(InElapsedTime);
}
else
{
ElapsedTime = InElapsedTime;
auto* Controller = TrafficLightComponent->GetController();
check(Controller);
return Controller->SetElapsedTime(InElapsedTime);
}
}
@ -335,14 +205,6 @@ void ATrafficLightBase::SetTimeIsFrozen(bool InTimeIsFrozen)
{
TrafficLightComponent->SetFrozenGroup(InTimeIsFrozen);
}
else
{
TimeIsFrozen = InTimeIsFrozen;
if (!TimeIsFrozen)
{
ElapsedTime = 0.0f;
}
}
}
bool ATrafficLightBase::GetTimeIsFrozen() const
@ -353,7 +215,7 @@ bool ATrafficLightBase::GetTimeIsFrozen() const
check(Group);
return Group->IsFrozen();
}
return TimeIsFrozen;
return false;
}
void ATrafficLightBase::SetPoleIndex(int InPoleIndex)

View File

@ -26,29 +26,12 @@ public:
ATrafficLightBase(const FObjectInitializer &ObjectInitializer);
virtual void Tick(float DeltaSeconds) override;
protected:
virtual void OnConstruction(const FTransform &Transform) override;
#if WITH_EDITOR
virtual void PostEditChangeProperty(FPropertyChangedEvent &PropertyChangedEvent) override;
#endif // WITH_EDITOR
public:
UFUNCTION(Category = "Traffic Light", BlueprintCallable)
ETrafficLightState GetTrafficLightState() const;
UFUNCTION(Category = "Traffic Light", BlueprintCallable)
void SetTrafficLightState(ETrafficLightState State);
/// Loop over traffic light states.
UFUNCTION(Category = "Traffic Light", BlueprintCallable)
void SwitchTrafficLightState();
UFUNCTION(Category = "Traffic Light", BlueprintCallable)
void NotifyWheeledVehicle(ACarlaWheeledVehicle *Vehicle);
@ -112,27 +95,9 @@ protected:
private:
UPROPERTY(Category = "Traffic Light", EditAnywhere)
ETrafficLightState State = ETrafficLightState::Red;
UPROPERTY(Category = "Traffic Light", VisibleAnywhere)
TArray<AWheeledVehicleAIController *> Vehicles;
UPROPERTY(Category = "Traffic Light", EditAnywhere)
float GreenTime = 10.0f;
UPROPERTY(Category = "Traffic Light", EditAnywhere)
float YellowTime = 2.0f;
UPROPERTY(Category = "Traffic Light", EditAnywhere)
float RedTime = 7.0f;
UPROPERTY(Category = "Traffic Light", VisibleAnywhere)
float ElapsedTime = 0.0f;
UPROPERTY(Category = "Traffic Light", EditAnywhere)
bool TimeIsFrozen = false;
UPROPERTY(Category = "Traffic Light", VisibleAnywhere)
int PoleIndex = 0;

View File

@ -29,6 +29,29 @@ float UTrafficLightController::NextState()
return GetCurrentState().Time;
}
bool UTrafficLightController::AdvanceTimeAndCycleFinished(float DeltaTime)
{
ElapsedTime += DeltaTime;
if(ElapsedTime > GetCurrentState().Time)
{
ElapsedTime = 0;
if (IsCycleFinished())
{
return true;
}
NextState();
}
return false;
}
void UTrafficLightController::StartCycle()
{
ElapsedTime = 0;
CurrentState = 0;
SetTrafficLightsState(GetCurrentState().State);
}
const TArray<UTrafficLightComponent *> &UTrafficLightController::GetTrafficLights()
{
return TrafficLights;
@ -82,6 +105,7 @@ void UTrafficLightController::ResetState()
{
CurrentState = (LightStates.Num() - 1);
SetTrafficLightsState(GetCurrentState().State);
ElapsedTime = 0;
}
void UTrafficLightController::SetYellowTime(float NewTime)
@ -137,6 +161,16 @@ float UTrafficLightController::GetStateTime(const ETrafficLightState State) cons
return 0.0f;
}
float UTrafficLightController::GetElapsedTime() const
{
return ElapsedTime;
}
void UTrafficLightController::SetElapsedTime(float InElapsedTime)
{
ElapsedTime = InElapsedTime;
}
void UTrafficLightController::SetGroup(ATrafficLightGroup* Group)
{
TrafficLightGroup = Group;

View File

@ -50,6 +50,13 @@ public:
UFUNCTION(Category = "Traffic Controller", BlueprintCallable)
float NextState();
// Advances the counter of the controller and returns true if The cicle is finished
UFUNCTION(Category = "Traffic Controller", BlueprintCallable)
bool AdvanceTimeAndCycleFinished(float DeltaTime);
UFUNCTION(Category = "Traffic Controller", BlueprintCallable)
void StartCycle();
UFUNCTION(Category = "Traffic Controller", BlueprintPure)
const TArray<UTrafficLightComponent *> &GetTrafficLights();
@ -98,6 +105,12 @@ public:
UFUNCTION(Category = "Traffic Controller", BlueprintCallable)
float GetRedTime() const;
UFUNCTION(Category = "Traffic Controller", BlueprintCallable)
float GetElapsedTime() const;
UFUNCTION(Category = "Traffic Controller", BlueprintCallable)
void SetElapsedTime(float InElapsedTime);
void SetGroup(ATrafficLightGroup* Group);
ATrafficLightGroup* GetGroup();
@ -133,4 +146,8 @@ private:
// Sequence within junction (unused for now)
UPROPERTY(Category = "Traffic Controller", EditAnywhere)
int Sequence = 0;
UPROPERTY()
float ElapsedTime = 0;
};

View File

@ -35,25 +35,8 @@ void ATrafficLightGroup::ResetGroup()
Controller->ResetState();
}
CurrentController = 0;
if(Controllers.Num() > 0)
{
Timer = Controllers[CurrentController]->NextState();
}
else
{
Timer = 0.0f;
}
CurrentStateTimer = Timer;
}
float ATrafficLightGroup::GetElapsedTime() const
{
return (CurrentStateTimer - Timer);
}
void ATrafficLightGroup::SetElapsedTime(float ElapsedTime)
{
Timer = CurrentStateTimer - ElapsedTime;
UTrafficLightController* controller = Controllers[CurrentController];
controller->StartCycle();
}
// Called every frame
@ -61,6 +44,7 @@ void ATrafficLightGroup::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// Do not update if the replayer is replaying
auto* Episode = UCarlaStatics::GetCurrentEpisode(GetWorld());
if (Episode)
{
@ -79,34 +63,18 @@ void ATrafficLightGroup::Tick(float DeltaTime)
return;
}
Timer -= DeltaTime;
if(Timer <= 0 && Controllers.Num())
{
NextCycleStep();
}
}
void ATrafficLightGroup::NextCycleStep()
{
UTrafficLightController* controller = Controllers[CurrentController];
if (controller->IsCycleFinished())
if (controller->AdvanceTimeAndCycleFinished(DeltaTime))
{
NextController();
}
else
{
Timer = controller->NextState();
CurrentStateTimer = Timer;
}
}
void ATrafficLightGroup::NextController()
{
CurrentController = (CurrentController + 1) % Controllers.Num();
UTrafficLightController* controller = Controllers[CurrentController];
Timer = controller->NextState();
CurrentStateTimer = Timer;
controller->StartCycle();
}
int ATrafficLightGroup::GetJunctionId() const

View File

@ -43,12 +43,6 @@ public:
UFUNCTION(Category = "Traffic Group", BlueprintCallable)
void ResetGroup();
UFUNCTION(Category = "Traffic Group", BlueprintCallable)
float GetElapsedTime() const;
UFUNCTION(Category = "Traffic Group", BlueprintCallable)
void SetElapsedTime(float ElapsedTime);
UFUNCTION(Category = "Traffic Group", BlueprintCallable)
void AddController(UTrafficLightController* Controller);
@ -66,18 +60,9 @@ private:
UPROPERTY(Category = "Traffic Group", EditAnywhere)
TArray<UTrafficLightController*> Controllers;
UPROPERTY(Category = "Traffic Group", VisibleAnywhere)
float Timer = 0.0f;
UPROPERTY(Category = "Traffic Group", VisibleAnywhere)
float CurrentStateTimer = 0.0f;
UPROPERTY(Category = "Traffic Group", VisibleAnywhere)
int CurrentController = 0;
UFUNCTION()
void NextCycleStep();
UFUNCTION()
void NextController();

View File

@ -238,14 +238,13 @@ void ATrafficLightManager::MatchTrafficLightActorsWithOpenDriveSignals()
}
}
// Called when the game starts
void ATrafficLightManager::BeginPlay()
void ATrafficLightManager::InitializeTrafficLights()
{
Super::BeginPlay();
// Should not run in empty maps
if (!GetMap())
{
carla::log_warning("Coud not generate traffic lights: missing map.");
return;
}

View File

@ -47,9 +47,8 @@ public:
UFUNCTION(CallInEditor)
void MatchTrafficLightActorsWithOpenDriveSignals();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Called when the game starts by the gamemode
void InitializeTrafficLights();
private: