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