CARLA
 
载入中...
搜索中...
未找到
YieldSignComponent.cpp
浏览该文件的文档.
1// Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
8#include "TrafficLightState.h"
9#include <queue>
10
18
19void UYieldSignComponent::InitializeSign(const carla::road::Map &Map)
20{
21
22 const double epsilon = 0.00001;
23
24 auto References = GetAllReferencesToThisSignal(Map);
25
26 for (auto& Reference : References)
27 {
28 auto RoadId = Reference.first;
29 const auto* SignalReference = Reference.second;
30 TSet<carla::road::RoadId> SignalPredecessors;
31 // Yield box
32 for(auto &validity : SignalReference->GetValidities())
33 {
34 for(auto lane : carla::geom::Math::GenerateRange(validity._from_lane, validity._to_lane))
35 {
36 if(lane == 0)
37 continue;
38
39 auto signal_waypoint_optional = Map.GetWaypoint(RoadId, lane, SignalReference->GetS());
40 if (!signal_waypoint_optional) {
41 carla::log_warning("YieldSignComponent::InitializeSignsignal() waypoint seems to be invalid, ignoring. RoadId:", RoadId, " LaneId:", lane, " s:", SignalReference->GetS());
42 continue;
43 }
44 auto signal_waypoint = signal_waypoint_optional.value();
45 if(Map.GetLane(signal_waypoint).GetType() != cr::Lane::LaneType::Driving) {
46 continue;
47 }
48
49 auto box_waypoint = signal_waypoint;
50 // Prevent adding the bounding box inside the intersection
51 if (Map.IsJunction(RoadId)) {
52 auto predecessors = Map.GetPredecessors(box_waypoint);
53 if (predecessors.size() == 1) {
54 auto predecessor = predecessors.front();
55 if (!Map.IsJunction(predecessor.road_id)) {
56 box_waypoint = predecessor;
57 }
58 }
59 }
60
61 // Get 50% of the half size of the width of the lane
62 float BoxWidth = static_cast<float>(
63 0.5f*Map.GetLaneWidth(box_waypoint)*0.5);
64 float BoxLength = 1.5f;
65 float BoxHeight = 1.0f;
66 // Prevent a situation where the road width is 0,
67 // this could happen in a lane that is just appearing
68 BoxWidth = std::max(0.01f, BoxWidth);
69 // Get min and max
70 double LaneLength = Map.GetLane(box_waypoint).GetLength();
71 double LaneDistance = Map.GetLane(box_waypoint).GetDistance();
72 // Safe distance to avoid overlapping the bounding box with the intersection
73 float AdditionalDistance = 1.5f;
74 if(lane < 0)
75 {
76 box_waypoint.s = FMath::Clamp(box_waypoint.s - (BoxLength + AdditionalDistance),
77 LaneDistance + epsilon, LaneDistance + LaneLength - epsilon);
78 }
79 else
80 {
81 box_waypoint.s = FMath::Clamp(box_waypoint.s + (BoxLength + AdditionalDistance),
82 LaneDistance + epsilon, LaneDistance + LaneLength - epsilon);
83 }
84 FTransform BoxTransform = Map.ComputeTransform(box_waypoint);
85 ALargeMapManager* LargeMapManager = UCarlaStatics::GetLargeMapManager(GetWorld());
86 if (LargeMapManager)
87 {
88 BoxTransform = LargeMapManager->GlobalToLocalTransform(BoxTransform);
89 }
90 GenerateYieldBox(BoxTransform, FVector(100*BoxLength, 100*BoxWidth, 100*BoxHeight));
91
92 auto Predecessors = Map.GetPredecessors(signal_waypoint);
93 for(auto &Prev : Predecessors)
94 {
95 if(!SignalPredecessors.Contains(Prev.road_id))
96 {
97 SignalPredecessors.Add(Prev.road_id);
98 }
99 }
100 }
101 }
102
103 //Check boxes
104 if(Map.IsJunction(RoadId))
105 {
106 auto JuncId = Map.GetJunctionId(RoadId);
107 const auto * Junction = Map.GetJunction(JuncId);
108 if(Junction->RoadHasConflicts(RoadId))
109 {
110 const auto &ConflictingRoads = Junction->GetConflictsOfRoad(RoadId);
111 for(const auto &Conflict : ConflictingRoads)
112 {
113 auto Waypoints = Map.GenerateWaypointsInRoad(Conflict);
114 for(auto& Waypoint : Waypoints)
115 {
116 // Skip roads that share the same previous road
117 bool bHasSamePredecessor = false;
118 auto Predecessors = Map.GetPredecessors(Waypoint);
119 for(auto &Prev : Predecessors)
120 {
121 if(SignalPredecessors.Contains(Prev.road_id))
122 {
123 bHasSamePredecessor = true;
124 }
125 }
126 if(bHasSamePredecessor)
127 {
128 continue;
129 }
130
131 if(Map.GetLane(Waypoint).GetType() != cr::Lane::LaneType::Driving)
132 continue;
133
134 // Cover the road within the junction
135 auto CurrentWaypoint = Waypoint;
136 auto NextWaypoint = CurrentWaypoint;
137 float BoxSize = static_cast<float>(
138 0.9*Map.GetLaneWidth(NextWaypoint)/2.0);
139 // Prevent a situation where the road width is 0,
140 // this could happen in a lane that is just appearing
141 BoxSize = std::max(0.01f, BoxSize);
142 float UEBoxSize = 100*BoxSize;
143
144 FTransform BoxTransform = Map.ComputeTransform(NextWaypoint);
145 ALargeMapManager* LargeMapManager = UCarlaStatics::GetLargeMapManager(GetWorld());
146 if (LargeMapManager)
147 {
148 BoxTransform = LargeMapManager->GlobalToLocalTransform(BoxTransform);
149 }
150 GenerateCheckBox(BoxTransform, UEBoxSize);
151
152 while (true)
153 {
154 auto Next = Map.GetNext(NextWaypoint, 2*BoxSize);
155 if (Next.size() != 1)
156 {
157 break;
158 }
159 NextWaypoint = Next.front();
160 if(NextWaypoint.road_id != Waypoint.road_id)
161 {
162 break;
163 }
164 BoxTransform = Map.ComputeTransform(NextWaypoint);
165 if (LargeMapManager)
166 {
167 BoxTransform = LargeMapManager->GlobalToLocalTransform(BoxTransform);
168 }
169 GenerateCheckBox(BoxTransform, UEBoxSize);
170
171 }
172 // Cover the road before the junction
173 // Hard coded anticipation time (boxes placed prior to the junction)
174 double AnticipationTime = 0.1;
175 auto Previous = Map.GetPrevious(Waypoint, 2*BoxSize);
176 std::queue<std::pair<float, carla::road::element::Waypoint>>
177 WaypointQueue;
178 for (auto & Prev : Previous)
179 {
180 WaypointQueue.push({AnticipationTime, Prev});
181 }
182 while (!WaypointQueue.empty())
183 {
184 auto CurrentElement = WaypointQueue.front();
185 WaypointQueue.pop();
186 GenerateCheckBox(Map.ComputeTransform(CurrentElement.second), UEBoxSize);
187
188 float Speed = 40;
189 auto* InfoSpeed = Map.GetLane(CurrentElement.second).GetRoad()->GetInfo<carla::road::element::RoadInfoSpeed>(CurrentElement.second.s);
190 if(InfoSpeed)
191 {
192 Speed = InfoSpeed->GetSpeed();
193 }
194 float RemainingTime = CurrentElement.first - BoxSize/Speed;
195 if(RemainingTime > 0)
196 {
197 Previous = Map.GetPrevious(CurrentElement.second, 2*BoxSize);
198 for (auto & Prev : Previous)
199 {
200 WaypointQueue.push({RemainingTime, Prev});
201 }
202 }
203 }
204 }
205 }
206 }
207 }
208 }
209}
210
211void UYieldSignComponent::GenerateYieldBox(const FTransform BoxTransform,
212 const FVector BoxSize)
213{
214 UBoxComponent* BoxComponent = GenerateTriggerBox(BoxTransform, BoxSize);
215 BoxComponent->OnComponentBeginOverlap.AddDynamic(this, &UYieldSignComponent::OnOverlapBeginYieldEffectBox);
216 BoxComponent->OnComponentEndOverlap.AddDynamic(this, &UYieldSignComponent::OnOverlapEndYieldEffectBox);
217 AddEffectTriggerVolume(BoxComponent);
218}
219
220void UYieldSignComponent::GenerateCheckBox(const FTransform BoxTransform,
221 float BoxSize)
222{
223 UBoxComponent* BoxComponent = GenerateTriggerBox(BoxTransform, BoxSize);
224 BoxComponent->OnComponentBeginOverlap.AddDynamic(this, &UYieldSignComponent::OnOverlapBeginYieldCheckBox);
225 BoxComponent->OnComponentEndOverlap.AddDynamic(this, &UYieldSignComponent::OnOverlapEndYieldCheckBox);
226}
227
228void UYieldSignComponent::GiveWayIfPossible()
229{
230 if (VehiclesToCheck.Num() == 0)
231 {
232 for (auto Vehicle : VehiclesInYield)
233 {
234 AWheeledVehicleAIController* VehicleController =
235 Cast<AWheeledVehicleAIController>(Vehicle->GetController());
236 VehicleController->SetTrafficLightState(ETrafficLightState::Green);
237 }
238 }
239 else
240 {
241 if(VehiclesInYield.Num())
242 {
243 for (auto Vehicle : VehiclesInYield)
244 {
245 AWheeledVehicleAIController* VehicleController =
246 Cast<AWheeledVehicleAIController>(Vehicle->GetController());
247 VehicleController->SetTrafficLightState(ETrafficLightState::Red);
248 }
249 // 0.5 second delay
250 DelayedGiveWay(0.5f);
251 }
252 }
253}
254
255void UYieldSignComponent::DelayedGiveWay(float Delay)
256{
257 FTimerHandle TimerHandler;
258 GetWorld()->GetTimerManager().
259 SetTimer(TimerHandler, this, &UYieldSignComponent::GiveWayIfPossible, Delay);
260}
261
262void UYieldSignComponent::OnOverlapBeginYieldEffectBox(UPrimitiveComponent *OverlappedComp,
263 AActor *OtherActor,
264 UPrimitiveComponent *OtherComp,
265 int32 OtherBodyIndex,
266 bool bFromSweep,
267 const FHitResult &SweepResult)
268{
269 ACarlaWheeledVehicle * Vehicle = Cast<ACarlaWheeledVehicle>(OtherActor);
270 if (Vehicle)
271 {
272 AWheeledVehicleAIController* VehicleController =
273 Cast<AWheeledVehicleAIController>(Vehicle->GetController());
274 if (VehicleController)
275 {
276 VehiclesInYield.Add(Vehicle);
277 RemoveSameVehicleInBothLists();
278 GiveWayIfPossible();
279 }
280 }
281}
282
283void UYieldSignComponent::OnOverlapEndYieldEffectBox(UPrimitiveComponent *OverlappedComp,
284 AActor *OtherActor,
285 UPrimitiveComponent *OtherComp,
286 int32 OtherBodyIndex)
287{
288 ACarlaWheeledVehicle * Vehicle = Cast<ACarlaWheeledVehicle>(OtherActor);
289 if (Vehicle)
290 {
291 VehiclesInYield.Remove(Vehicle);
292 }
293}
294
295void UYieldSignComponent::OnOverlapBeginYieldCheckBox(UPrimitiveComponent *OverlappedComp,
296 AActor *OtherActor,
297 UPrimitiveComponent *OtherComp,
298 int32 OtherBodyIndex,
299 bool bFromSweep,
300 const FHitResult &SweepResult)
301{
302 ACarlaWheeledVehicle * Vehicle = Cast<ACarlaWheeledVehicle>(OtherActor);
303 if (Vehicle)
304 {
305 if(!VehiclesInYield.Contains(Vehicle))
306 {
307 if (!VehiclesToCheck.Contains(Vehicle))
308 {
309 VehiclesToCheck.Add(Vehicle, 0);
310 }
311 VehiclesToCheck[Vehicle]++;
312 }
313 GiveWayIfPossible();
314 }
315}
316
317void UYieldSignComponent::OnOverlapEndYieldCheckBox(UPrimitiveComponent *OverlappedComp,
318 AActor *OtherActor,
319 UPrimitiveComponent *OtherComp,
320 int32 OtherBodyIndex)
321{
322 ACarlaWheeledVehicle * Vehicle = Cast<ACarlaWheeledVehicle>(OtherActor);
323 if (Vehicle)
324 {
325 if(VehiclesToCheck.Contains(Vehicle))
326 {
327 VehiclesToCheck[Vehicle]--;
328 if(VehiclesToCheck[Vehicle] <= 0)
329 {
330 VehiclesToCheck.Remove(Vehicle);
331 }
332 }
333 // 0.5 second delay
334 DelayedGiveWay(0.5);
335 }
336}
337void UYieldSignComponent::RemoveSameVehicleInBothLists()
338{
339 for(auto* Vehicle : VehiclesInYield)
340 {
341 if(VehiclesToCheck.Contains(Vehicle))
342 {
343 VehiclesToCheck.Remove(Vehicle);
344 }
345 }
346}
Base class for CARLA wheeled vehicles.
FTransform GlobalToLocalTransform(const FTransform &InTransform) const
Wheeled vehicle controller with optional AI.
void SetTrafficLightState(ETrafficLightState InTrafficLightState)
Set traffic light state currently affecting this vehicle.
static ALargeMapManager * GetLargeMapManager(const UObject *WorldContextObject)
Road * GetRoad() const
Definition Lane.cpp:29
LaneType GetType() const
Definition Lane.cpp:38
double GetDistance() const
Definition Lane.cpp:46
double GetLength() const
Definition Lane.cpp:51
JuncId GetJunctionId(RoadId road_id) const
Definition road/Map.cpp:298
std::vector< Waypoint > GetPrevious(Waypoint waypoint, double distance) const
Return the list of waypoints at distance in the reversed direction that a vehicle at waypoint could d...
Definition road/Map.cpp:590
bool IsJunction(RoadId road_id) const
Definition road/Map.cpp:302
double GetLaneWidth(Waypoint waypoint) const
Definition road/Map.cpp:285
boost::optional< element::Waypoint > GetWaypoint(const geom::Location &location, int32_t lane_type=static_cast< int32_t >(Lane::LaneType::Driving)) const
Definition road/Map.cpp:212
std::vector< Waypoint > GetNext(Waypoint waypoint, double distance) const
Return the list of waypoints at distance such that a vehicle at waypoint could drive to.
Definition road/Map.cpp:554
Junction * GetJunction(JuncId id)
Definition road/Map.cpp:997
std::vector< Waypoint > GenerateWaypointsInRoad(RoadId road_id, Lane::LaneType lane_type=Lane::LaneType::Driving) const
Generate waypoints at the entry of each lane of the specified road
Definition road/Map.cpp:692
geom::Transform ComputeTransform(Waypoint waypoint) const
Definition road/Map.cpp:273
std::vector< Waypoint > GetPredecessors(Waypoint waypoint) const
Definition road/Map.cpp:536
const Lane & GetLane(Waypoint waypoint) const
========================================================================
Definition road/Map.cpp:834
const T * GetInfo(const double s) const
Definition Road.h:113
carla::SharedPtr< carla::client::Junction > Junction
This file contains definitions of common data structures used in traffic manager.
Definition Carla.cpp:133
static void log_warning(Args &&... args)
Definition Logging.h:96