Browse Source

feat: scenario-centric migration for Town10HD_Opt

- Updated braking, cutin, and obstacle scenarios with class-held constants
- Added deterministic ego_spawn_point (Showcase P2) for all scenarios
- Added 0.5m Z-lift to NPC spawns to prevent ground clipping in Town10
- Refactored showcase.py to use the new standardized ego_spawn_point property
1843_integration
RUSHIL AMBARISH KADU 2 months ago
parent
commit
c5f2eeb42b
  1. 24
      scenarios/braking.py
  2. 25
      scenarios/cutin.py
  3. 13
      scenarios/obstacle.py
  4. 8
      scenarios/showcase.py

24
scenarios/braking.py

@ -15,7 +15,6 @@ import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import carla
import config
from scenarios.base import ScenarioBase
@ -29,9 +28,9 @@ class BrakingScenario(ScenarioBase):
Frame BRAKE_FRAME+ : Lead vehicle applies emergency stop.
"""
LEAD_DISTANCE_M = getattr(config, "SCENARIO_LEAD_DISTANCE", 25)
BRAKE_FRAME = getattr(config, "SCENARIO_BRAKE_FRAME", 80)
CRUISE_SPEED = 30 # km/h, set via TM percentage of speed limit
LEAD_DISTANCE_M = 25 # metres ahead of ego for lead vehicle
BRAKE_FRAME = 80 # frame on which the lead vehicle emergency-brakes
CRUISE_SPEED = 30 # km/h, set via TM percentage of speed limit
def __init__(self):
super().__init__()
@ -46,6 +45,11 @@ class BrakingScenario(ScenarioBase):
def name(self) -> str:
return "braking"
@property
def ego_spawn_point(self):
# Using the known-working Town10 intersection point
return carla.Transform(carla.Location(x=107.412, y=45.309, z=0.5), carla.Rotation(yaw=-87.7))
def setup(self, world, ego_vehicle, traffic_manager) -> None:
self._world = world
self._ego = ego_vehicle
@ -67,11 +71,15 @@ class BrakingScenario(ScenarioBase):
"Ensure ego is on a driveable lane."
)
self._lead_vehicle = world.try_spawn_actor(lead_bp, spawn_wp.transform)
# Lift actor slightly to avoid ground clipping
spawn_transform = spawn_wp.transform
spawn_transform.location.z += 0.5
self._lead_vehicle = world.try_spawn_actor(lead_bp, spawn_transform)
if self._lead_vehicle is None:
raise RuntimeError(
"[BrakingScenario] Failed to spawn lead vehicle at waypoint "
f"{spawn_wp.transform.location}. Spot may be occupied."
f"{spawn_transform.location}. Spot may be occupied."
)
self._actors.append(self._lead_vehicle)
@ -90,7 +98,7 @@ class BrakingScenario(ScenarioBase):
)
def step(self, frame_count: int, ego_vehicle, pbar=None) -> None:
if frame == self.BRAKE_FRAME and not self._braked:
if frame_count == self.BRAKE_FRAME and not self._braked:
if self._lead_vehicle and self._lead_vehicle.is_alive:
# Disengage TM autopilot and apply full brake
self._lead_vehicle.set_autopilot(False)
@ -100,7 +108,7 @@ class BrakingScenario(ScenarioBase):
control.hand_brake = True
self._lead_vehicle.apply_control(control)
self._braked = True
print(f"[{self.name}] EMERGENCY BRAKE applied at frame {frame}.")
print(f"[{self.name}] EMERGENCY BRAKE applied at frame {frame_count}.")
def cleanup(self) -> None:
self._destroy_actors()

25
scenarios/cutin.py

@ -13,7 +13,6 @@ import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import config
from scenarios.base import ScenarioBase
@ -27,9 +26,9 @@ class CutInScenario(ScenarioBase):
Frame CUTIN_FRAME+ : TM forced lane change into ego lane.
"""
NPC_DISTANCE_M = getattr(config, "SCENARIO_CUTIN_DISTANCE", 15)
CUTIN_FRAME = getattr(config, "SCENARIO_CUTIN_FRAME", 60)
LANE_OFFSET = -1 # -1 = left lane, 1 = right lane
NPC_DISTANCE_M = 15 # metres ahead of ego for NPC in adjacent lane
CUTIN_FRAME = 60 # frame on which NPC is forced to change lane
LANE_OFFSET = -1 # -1 = left lane, 1 = right lane
def __init__(self):
super().__init__()
@ -44,6 +43,12 @@ class CutInScenario(ScenarioBase):
def name(self) -> str:
return "cutin"
@property
def ego_spawn_point(self):
# Working Town10 intersection point (Southbound)
import carla
return carla.Transform(carla.Location(x=107.412, y=45.309, z=0.5), carla.Rotation(yaw=-87.7))
def setup(self, world, ego_vehicle, traffic_manager) -> None:
self._world = world
self._ego = ego_vehicle
@ -66,11 +71,15 @@ class CutInScenario(ScenarioBase):
"Try a map with multiple lanes."
)
self._npc = world.try_spawn_actor(npc_bp, spawn_wp.transform)
# Lift actor slightly to avoid ground clipping
spawn_transform = spawn_wp.transform
spawn_transform.location.z += 0.5
self._npc = world.try_spawn_actor(npc_bp, spawn_transform)
if self._npc is None:
raise RuntimeError(
"[CutInScenario] Failed to spawn NPC at "
f"{spawn_wp.transform.location}. Spot may be occupied."
f"{spawn_transform.location}. Spot may be occupied."
)
self._actors.append(self._npc)
@ -85,13 +94,13 @@ class CutInScenario(ScenarioBase):
)
def step(self, frame_count: int, ego_vehicle, pbar=None) -> None:
if frame == self.CUTIN_FRAME and not self._cut_triggered:
if frame_count == self.CUTIN_FRAME and not self._cut_triggered:
if self._npc and self._npc.is_alive:
# force_lane_change: True = left, False = right
force_left = (self.LANE_OFFSET < 0)
self._tm.force_lane_change(self._npc, force_left)
self._cut_triggered = True
print(f"[{self.name}] Lane change triggered at frame {frame}.")
print(f"[{self.name}] Lane change triggered at frame {frame_count}.")
def cleanup(self) -> None:
self._destroy_actors()

13
scenarios/obstacle.py

@ -13,7 +13,6 @@ import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import config
from scenarios.base import ScenarioBase
@ -25,11 +24,9 @@ class ObstacleScenario(ScenarioBase):
autopilot and must navigate around or brake for the obstacle.
"""
OBSTACLE_DISTANCE_M = getattr(config, "SCENARIO_OBSTACLE_DISTANCE", 30)
OBSTACLE_DISTANCE_M = 30 # metres ahead of ego for static prop
# CARLA blueprint name for the static prop
PROP_BLUEPRINT = getattr(
config, "SCENARIO_OBSTACLE_PROP", "static.prop.trafficcone01"
)
PROP_BLUEPRINT = "static.prop.trafficcone01"
def __init__(self):
super().__init__()
@ -43,6 +40,12 @@ class ObstacleScenario(ScenarioBase):
def name(self) -> str:
return "obstacle"
@property
def ego_spawn_point(self):
# Working Town10 intersection point (Southbound)
import carla
return carla.Transform(carla.Location(x=107.412, y=45.309, z=0.5), carla.Rotation(yaw=-87.7))
def setup(self, world, ego_vehicle, traffic_manager) -> None:
self._world = world
self._ego = ego_vehicle

8
scenarios/showcase.py

@ -16,6 +16,11 @@ class ShowcaseScenario(ScenarioBase):
def name(self):
return "showcase"
@property
def ego_spawn_point(self):
# Working Town10 intersection point (Southbound)
return carla.Transform(carla.Location(x=107.412, y=45.309, z=0.5), carla.Rotation(yaw=-87.7))
def setup(self, world, ego_vehicle, traffic_manager) -> None:
"""
Step 11: Deep Intersection Guidance for Ego.
@ -38,8 +43,7 @@ class ShowcaseScenario(ScenarioBase):
self.EGO_MID = carla.Location(x=107.412, y=32.0, z=0.5)
self._ego_reached_mid = False
# 1. Setup Ego
self._ego.set_transform(self.P2)
# 1. Setup Ego (Already spawned at ego_spawn_point by main.py)
self._ego.set_autopilot(False)
# 2. Spawn NPC

Loading…
Cancel
Save