27 PrimaryActorTick.bCanEverTick =
false;
28 SceneComponent = CreateDefaultSubobject<USceneComponent>(TEXT(
"RootComponent"));
32 static ConstructorHelpers::FClassFinder<AActor> TrafficLightFinder(
33 TEXT(
"/Game/Carla/Blueprints/TrafficLight/BP_TLOpenDrive" ) );
34 if (TrafficLightFinder.Succeeded())
36 TSubclassOf<AActor> Model = TrafficLightFinder.Class;
40 static ConstructorHelpers::FClassFinder<AActor> StopFinder(
41 TEXT(
"/Game/Carla/Static/TrafficSign/BP_Stop" ) );
42 if (StopFinder.Succeeded())
44 TSubclassOf<AActor> StopSignModel = StopFinder.Class;
48 static ConstructorHelpers::FClassFinder<AActor> YieldFinder(
49 TEXT(
"/Game/Carla/Static/TrafficSign/BP_Yield" ) );
50 if (YieldFinder.Succeeded())
52 TSubclassOf<AActor> YieldSignModel = YieldFinder.Class;
56 static ConstructorHelpers::FClassFinder<AActor> SpeedLimit30Finder(
57 TEXT(
"/Game/Carla/Static/TrafficSign/BP_SpeedLimit30" ) );
58 if (SpeedLimit30Finder.Succeeded())
60 TSubclassOf<AActor> SpeedLimitModel = SpeedLimit30Finder.Class;
63 static ConstructorHelpers::FClassFinder<AActor> SpeedLimit40Finder(
64 TEXT(
"/Game/Carla/Static/TrafficSign/BP_SpeedLimit40" ) );
65 if (SpeedLimit40Finder.Succeeded())
67 TSubclassOf<AActor> SpeedLimitModel = SpeedLimit40Finder.Class;
70 static ConstructorHelpers::FClassFinder<AActor> SpeedLimit50Finder(
71 TEXT(
"/Game/Carla/Static/TrafficSign/BP_SpeedLimit50" ) );
72 if (SpeedLimit50Finder.Succeeded())
74 TSubclassOf<AActor> SpeedLimitModel = SpeedLimit50Finder.Class;
77 static ConstructorHelpers::FClassFinder<AActor> SpeedLimit60Finder(
78 TEXT(
"/Game/Carla/Static/TrafficSign/BP_SpeedLimit60" ) );
79 if (SpeedLimit60Finder.Succeeded())
81 TSubclassOf<AActor> SpeedLimitModel = SpeedLimit60Finder.Class;
84 static ConstructorHelpers::FClassFinder<AActor> SpeedLimit70Finder(
85 TEXT(
"/Game/Carla/Static/TrafficSign/BP_SpeedLimit70" ) );
86 if (SpeedLimit70Finder.Succeeded())
88 TSubclassOf<AActor> SpeedLimitModel = SpeedLimit70Finder.Class;
91 static ConstructorHelpers::FClassFinder<AActor> SpeedLimit80Finder(
92 TEXT(
"/Game/Carla/Static/TrafficSign/BP_SpeedLimit80" ) );
93 if (SpeedLimit80Finder.Succeeded())
95 TSubclassOf<AActor> SpeedLimitModel = SpeedLimit80Finder.Class;
98 static ConstructorHelpers::FClassFinder<AActor> SpeedLimit90Finder(
99 TEXT(
"/Game/Carla/Static/TrafficSign/BP_SpeedLimit90" ) );
100 if (SpeedLimit90Finder.Succeeded())
102 TSubclassOf<AActor> SpeedLimitModel = SpeedLimit90Finder.Class;
105 static ConstructorHelpers::FClassFinder<AActor> SpeedLimit100Finder(
106 TEXT(
"/Game/Carla/Static/TrafficSign/BP_SpeedLimit100" ) );
107 if (SpeedLimit100Finder.Succeeded())
109 TSubclassOf<AActor> SpeedLimitModel = SpeedLimit100Finder.Class;
112 static ConstructorHelpers::FClassFinder<AActor> SpeedLimit110Finder(
113 TEXT(
"/Game/Carla/Static/TrafficSign/BP_SpeedLimit110" ) );
114 if (SpeedLimit110Finder.Succeeded())
116 TSubclassOf<AActor> SpeedLimitModel = SpeedLimit110Finder.Class;
119 static ConstructorHelpers::FClassFinder<AActor> SpeedLimit120Finder(
120 TEXT(
"/Game/Carla/Static/TrafficSign/BP_SpeedLimit120" ) );
121 if (SpeedLimit120Finder.Succeeded())
123 TSubclassOf<AActor> SpeedLimitModel = SpeedLimit120Finder.Class;
140 const auto &Signal =
GetMap()->GetSignals().at(SignId);
141 if(Signal->GetControllers().size())
144 auto ControllerId = *(Signal->GetControllers().begin());
147 const auto &Controller =
GetMap()->GetControllers().at(ControllerId);
148 if(Controller->GetJunctions().empty())
150 UE_LOG(LogCarla, Error, TEXT(
"No junctions in controller %d"), *(ControllerId.c_str()) );
154 auto JunctionId = *(Controller->GetJunctions().begin());
159 FActorSpawnParameters SpawnParams;
161 auto * NewTrafficLightGroup =
163 NewTrafficLightGroup->
JunctionId = JunctionId;
171 auto *NewTrafficLightController = NewObject<UTrafficLightController>();
172 NewTrafficLightController->SetControllerId(ControllerId.c_str());
180 FActorSpawnParameters SpawnParams;
182 auto * NewTrafficLightGroup =
185 TrafficGroups.Add(NewTrafficLightGroup->JunctionId, NewTrafficLightGroup);
186 TrafficLightGroup = NewTrafficLightGroup;
188 auto *NewTrafficLightController = NewObject<UTrafficLightController>();
191 NewTrafficLightController->SetRedTime(10);
192 TrafficLightGroup->
GetControllers().Add(NewTrafficLightController);
193 TrafficControllers.Add(NewTrafficLightController->GetControllerId(), NewTrafficLightController);
194 TrafficLightController = NewTrafficLightController;
296 TArray<AActor*> Actors;
297 UGameplayStatics::GetAllActorsOfClass(GetWorld(), ATrafficLightBase::StaticClass(), Actors);
308 TArray<ATrafficLightBase*> TrafficLights;
309 for (
AActor* Actor : Actors)
314 TrafficLight->GetTrafficLightComponent()->SetSignId(
"");
319 if (!TrafficLights.Num())
325 const auto& Signals = Map->GetSignals();
326 const auto& Controllers = Map->GetControllers();
328 for(
const auto& Signal : Signals) {
329 const auto& ODSignal = Signal.second;
330 const FTransform Transform = ODSignal->GetTransform();
331 const FVector Location = Transform.GetLocation();
332 if (ODSignal->GetName() ==
"")
337 float MinDistance = FVector::DistSquaredXY(TrafficLights.Top()->GetActorLocation(), Location);
340 float Distance = FVector::DistSquaredXY(Actor->GetActorLocation(), Location);
341 if (Distance < MinDistance)
343 MinDistance = Distance;
344 ClosestActor = Actor;
349 if (Component->GetSignId() ==
"")
351 Component->SetSignId(carla::rpc::ToFString(ODSignal->GetSignalId()));
355 carla::log_warning(
"Could not find a suitable traffic light for signal", ODSignal->GetSignalId(),
356 "Closest traffic light has id", carla::rpc::FromFString(Component->GetSignId()));
381 if (ClosestTrafficSign)
383 if ((Signal.
GetType() == cr::SignalType::StopSign()) &&
388 else if ((Signal.
GetType() == cr::SignalType::YieldSign()) &&
393 else if (cr::SignalType::IsTrafficLight(Signal.
GetType()))
400 else if (Signal.
GetType() == cr::SignalType::MaximumSpeed())
485 const auto& Signals =
GetMap()->GetSignals();
486 std::unordered_set<std::string> SignalsToSpawn;
487 for(
const auto& ControllerPair :
GetMap()->GetControllers())
489 const auto& Controller = ControllerPair.second;
490 for(
const auto& SignalId : Controller->GetSignals())
492 auto& Signal = Signals.at(SignalId);
493 if (!cr::SignalType::IsTrafficLight(Signal->GetType()))
498 *Signal.get(), GetWorld());
501 UTrafficLightComponent *TrafficLightComponent =
TrafficLight->GetTrafficLightComponent();
502 TrafficLightComponent->SetSignId(SignalId.c_str());
506 SignalsToSpawn.insert(SignalId);
511 for(
const auto& SignalPair : Signals)
513 const auto& SignalId = SignalPair.first;
514 const auto& Signal = SignalPair.second;
515 if(!Signal->GetControllers().size() &&
516 !
GetMap()->IsJunction(Signal->GetRoadId()) &&
518 !SignalsToSpawn.count(SignalId))
521 *Signal.get(), GetWorld());
524 UTrafficLightComponent *TrafficLightComponent =
TrafficLight->GetTrafficLightComponent();
525 TrafficLightComponent->SetSignId(SignalId.c_str());
529 SignalsToSpawn.insert(SignalId);
536 for(
auto &SignalId : SignalsToSpawn)
542 if (Signals.count(SignalId) == 0)
544 UE_LOG(LogCarla, Warning,
545 TEXT(
"Possible OpenDRIVE error, reference to nonexistent signal id: %s"),
546 *carla::rpc::ToFString(SignalId));
549 const auto& Signal = Signals.at(SignalId);
550 auto CarlaTransform = Signal->GetTransform();
551 FTransform SpawnTransform(CarlaTransform);
553 FVector SpawnLocation = SpawnTransform.GetLocation();
554 FRotator SpawnRotation(SpawnTransform.GetRotation());
556 SpawnRotation.Yaw += 90;
558 SpawnRotation.Roll = 0;
559 SpawnRotation.Pitch = 0;
561 FActorSpawnParameters SpawnParams;
562 SpawnParams.Owner =
this;
563 SpawnParams.SpawnCollisionHandlingOverride =
564 ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
574 UTrafficLightComponent *TrafficLightComponent =
TrafficLight->GetTrafficLightComponent();
575 TrafficLightComponent->SetSignId(SignalId.c_str());
577 auto ClosestWaypointToSignal =
578 GetMap()->GetClosestWaypointOnRoad(CarlaTransform.location);
579 if (ClosestWaypointToSignal)
581 auto SignalDistanceToRoad =
582 (
GetMap()->ComputeTransform(ClosestWaypointToSignal.get()).location - CarlaTransform.location).Length();
583 double LaneWidth =
GetMap()->GetLaneWidth(ClosestWaypointToSignal.get());
585 if(SignalDistanceToRoad < LaneWidth * 0.5)
588 TCHAR_TO_UTF8(*TrafficLightComponent->GetSignId()),
589 "overlaps a driving lane. Disabling collision...");
591 TArray<UPrimitiveComponent*> Primitives;
593 for (
auto* Primitive : Primitives)
595 Primitive->SetCollisionProfileName(TEXT(
"NoCollision"));
601 TrafficLightComponent->InitializeSign(
GetMap().get());
610 const auto &Signals =
GetMap()->GetSignals();
611 for (
auto& SignalPair : Signals)
613 auto &Signal = SignalPair.second;
614 FString SignalType = Signal->GetType().c_str();
617 if (ClosestTrafficSign)
619 USignComponent *SignComponent;
623 NewObject<USignComponent>(
629 NewObject<USignComponent>(
632 SignComponent->SetSignId(Signal->GetSignalId().c_str());
633 SignComponent->RegisterComponent();
634 SignComponent->AttachToComponent(
635 ClosestTrafficSign->GetRootComponent(),
636 FAttachmentTransformRules::KeepRelativeTransform);
643 if (Signal->GetName() ==
"Stencil_STOP")
647 auto CarlaTransform = Signal->GetTransform();
648 FTransform SpawnTransform(CarlaTransform);
649 FVector SpawnLocation = SpawnTransform.GetLocation();
650 FRotator SpawnRotation(SpawnTransform.GetRotation());
651 SpawnRotation.Yaw += 90;
653 SpawnRotation.Roll = 0;
654 SpawnRotation.Pitch = 0;
656 FActorSpawnParameters SpawnParams;
657 SpawnParams.Owner =
this;
658 SpawnParams.SpawnCollisionHandlingOverride =
659 ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
667 USignComponent *SignComponent =
669 SignComponent->SetSignId(Signal->GetSignalId().c_str());
670 SignComponent->RegisterComponent();
671 SignComponent->AttachToComponent(
672 TrafficSign->GetRootComponent(),
673 FAttachmentTransformRules::KeepRelativeTransform);
674 SignComponent->InitializeSign(
GetMap().get());
676 auto ClosestWaypointToSignal =
677 GetMap()->GetClosestWaypointOnRoad(CarlaTransform.location);
678 if (ClosestWaypointToSignal)
680 auto SignalDistanceToRoad =
681 (
GetMap()->ComputeTransform(ClosestWaypointToSignal.get()).location - CarlaTransform.location).Length();
682 double LaneWidth =
GetMap()->GetLaneWidth(ClosestWaypointToSignal.get());
684 if(SignalDistanceToRoad < LaneWidth * 0.5)
687 TCHAR_TO_UTF8(*SignComponent->GetSignId()),
688 "overlaps a driving lane. Disabling collision...");
690 TArray<UPrimitiveComponent*> Primitives;
691 TrafficSign->GetComponents(Primitives);
692 for (
auto* Primitive : Primitives)
694 Primitive->SetCollisionProfileName(TEXT(
"NoCollision"));
704 auto CarlaTransform = Signal->GetTransform();
705 FTransform SpawnTransform(CarlaTransform);
706 FVector SpawnLocation = SpawnTransform.GetLocation();
707 FRotator SpawnRotation(SpawnTransform.GetRotation());
708 SpawnRotation.Yaw += 90;
710 SpawnRotation.Roll = 0;
711 SpawnRotation.Pitch = 0;
713 FActorSpawnParameters SpawnParams;
714 SpawnParams.Owner =
this;
715 SpawnParams.SpawnCollisionHandlingOverride =
716 ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
724 USpeedLimitComponent *SignComponent =
725 NewObject<USpeedLimitComponent>(TrafficSign);
726 SignComponent->SetSignId(Signal->GetSignalId().c_str());
727 SignComponent->RegisterComponent();
728 SignComponent->AttachToComponent(
729 TrafficSign->GetRootComponent(),
730 FAttachmentTransformRules::KeepRelativeTransform);
731 SignComponent->InitializeSign(
GetMap().get());
732 SignComponent->SetSpeedLimit(Signal->GetValue());
734 auto ClosestWaypointToSignal =
735 GetMap()->GetClosestWaypointOnRoad(CarlaTransform.location);
736 if (ClosestWaypointToSignal)
738 auto SignalDistanceToRoad =
739 (
GetMap()->ComputeTransform(ClosestWaypointToSignal.get()).location - CarlaTransform.location).Length();
740 double LaneWidth =
GetMap()->GetLaneWidth(ClosestWaypointToSignal.get());
742 if(SignalDistanceToRoad < LaneWidth * 0.5)
745 TCHAR_TO_UTF8(*SignComponent->GetSignId()),
746 "overlaps a driving lane. Disabling collision...");
748 TArray<UPrimitiveComponent*> Primitives;
749 TrafficSign->GetComponents(Primitives);
750 for (
auto* Primitive : Primitives)
752 Primitive->SetCollisionProfileName(TEXT(
"NoCollision"));