Fix: TrafficAreaAction Center Point Limitation
Center Point Limitation in Entity Spawning
Context
TrafficAreaAction spawns entities on a TrafficArea, usually composed of one more lanes. Before spawning, this action checks for entities that are on those lanes to compute SpawnZones that avoid spawning on top of these entities. Previously, it only considered entities whose center position lied on the TrafficArea lanes. This caused the issue seen below. A long bus whose center is on Road 0 (not part of the TrafficArea), but whose front lies on Road 1 (part of the TrafficArea) could result in an entity being spawned in an overlapping position.
gt-gen-core fix
A TrafficAreaAction is parsed by openscenario1engine which queries for entities and instructs gt-gen-core how to spawn entities. Here is a view of the execution-flow:
TrafficAreaAction::PerformInitialSpawing() [openscenario1_engine: TrafficAreaAction_impl.cpp]
→ SpawnSpace::Spawn() [openscenario1_engine: SpawnSpace.cpp]
→ Transform(trafficAreas_, ToSpawnZones{}) → SpawnZones(area) [openscenario1_engine: SpawnZone.cpp]
→ SpawnZone{stream} → GetObstacles(stream) [openscenario1_engine: Obstacle.cpp]
→ stream.GetEntity(SearchDirection, start, end) [gt-gen-core: traffic_area_stream.h]
→ TrafficAreaStream<D>::GetEntity(...) [gt-gen-core: traffic_area_stream.h]
→ TrafficAreaLane::GetEntities(all_entities) [gt-gen-core: lane.cpp]
→ TrafficAreaLane::IsOnLane [gt-gen-core: lane.h]IsOnLane fix
The first issue lies in TrafficAreaLane::IsOnLane which finds entities on the specific TrafficAreaLane, but uses the pre-computed GetAssignedLaneIds vector which only considers entity's center-position to assign them to lanes. Changing the lane assignment can cause issues in other components that also use this vector. For this reason, we can instead add a fallback that checks for geometrical overlap when lane assignment fails. The newly added function is called OverlapsGeometrically.
TrafficAreaStream::Convert implementation
After the previous fix, the unimplemented TrafficAreaStream<D>::Convert started being invoked. Therefore it had to be implemented. This method essentially performs a set of geometrical operations to convert a Global Pose (position & orientation) into a pose in a coordinate system local to the TrafficArea.
