diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.cpp index 178b6c2b8..0a57d66cb 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.cpp @@ -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(); - } - - GameInstance = Cast(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(); + TrafficLightManager->InitializeTrafficLights(); + } + else + { + ATrafficLightManager* TrafficLightManager = Cast(TrafficLightManagerActor); + TrafficLightManager->InitializeTrafficLights(); + } + Episode->InitializeAtBeginPlay(); GameInstance->NotifyBeginEpisode(*Episode); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/WorldObserver.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/WorldObserver.cpp index 58c47b1fb..2225f796e 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/WorldObserver.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/WorldObserver.cpp @@ -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(); } diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightBase.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightBase.cpp index c6c717ea1..6749b5541 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightBase.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightBase.cpp @@ -40,87 +40,15 @@ static ETrafficSignState ToTrafficSignState(ETrafficLightState State) ATrafficLightBase::ATrafficLightBase(const FObjectInitializer &ObjectInitializer) : Super(ObjectInitializer) { - PrimaryActorTick.bCanEverTick = true; + PrimaryActorTick.bCanEverTick = false; TrafficLightComponent = CreateDefaultSubobject(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(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) diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightBase.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightBase.h index 36cb19c9e..ece39c02e 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightBase.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightBase.h @@ -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 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; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightController.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightController.cpp index 2cc4dc09d..6d03bea64 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightController.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightController.cpp @@ -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 &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; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightController.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightController.h index c802c29e3..2a07b6fd9 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightController.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightController.h @@ -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 &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; + }; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightGroup.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightGroup.cpp index 4fa2fc3d3..9ea854899 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightGroup.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightGroup.cpp @@ -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 diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightGroup.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightGroup.h index bd3bf22a3..8b0a5110f 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightGroup.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightGroup.h @@ -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 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(); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightManager.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightManager.cpp index 9108b74c8..3a1f4b2a2 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightManager.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightManager.cpp @@ -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; } diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightManager.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightManager.h index 304ec62bc..569b6cce7 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightManager.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Traffic/TrafficLightManager.h @@ -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: