multimodalart's picture
multimodalart HF Staff
prep stage
1811aab verified
Raw History Blame Contribute Delete
4.42 kB
"""Background traffic and the scene description saved for the coarse proxy."""
from __future__ import annotations
import math
from dataclasses import dataclass, field
import carla
# level bounding boxes exported for the coarse proxy: CARLA label -> CWM class
STATIC_LABELS = {"Buildings": 0, "Walls": 0, "Fences": 0, "Poles": 0, "TrafficLight": 0, "TrafficSigns": 0,
"Static": 0, "Dynamic": 0, "Bridge": 0, "GuardRail": 0, "Vegetation": 5, "Water": 2}
SCENE_RADIUS_M = 300.0
@dataclass
class Traffic:
actors: list = field(default_factory=list)
controllers: list = field(default_factory=list)
vehicles: list = field(default_factory=list)
walkers: list = field(default_factory=list)
def spawn_traffic(world, bp, rng, n_vehicles: int, n_walkers: int) -> Traffic:
"""Parked vehicles (physics off: no traffic manager, it segfaults libcarla on some nodes, and a
static street is what a revisit dataset wants) and AI-driven background pedestrians."""
t = Traffic()
spawns = world.get_map().get_spawn_points()
rng.shuffle(spawns)
vbps = [b for b in bp.filter("vehicle.*") if int(b.get_attribute("number_of_wheels")) == 4]
for sp in spawns[:n_vehicles]:
v = world.try_spawn_actor(rng.choice(vbps), sp)
if v:
v.set_simulate_physics(False)
t.actors.append(v)
t.vehicles.append(v)
wbps = bp.filter("walker.pedestrian.*")
ctrl_bp = bp.find("controller.ai.walker")
for _ in range(n_walkers):
loc = world.get_random_location_from_navigation()
if loc is None:
continue
w = world.try_spawn_actor(rng.choice(wbps), carla.Transform(loc + carla.Location(z=1.0)))
if w:
t.actors.append(w)
t.walkers.append(w)
t.controllers.append(world.spawn_actor(ctrl_bp, carla.Transform(), w))
world.tick()
for c in t.controllers:
c.start()
c.go_to_location(world.get_random_location_from_navigation())
c.set_max_speed(1.0 + rng.random() * 0.6)
return t
def adult_walkers(bp):
return [b for b in bp.filter("walker.pedestrian.*")
if not (b.has_attribute("age") and b.get_attribute("age").as_str() == "child")]
def frame_record(hero, walkers) -> dict:
"""Per-frame scene state for the coarse proxy: protagonist bones, background walker poses."""
bones = {bt.name: [round(bt.world.location.x, 3), round(bt.world.location.y, 3), round(bt.world.location.z, 3)]
for bt in hero.get_bones().bone_transforms}
others = []
for w in walkers:
wt = w.get_transform()
others.append([round(wt.location.x, 2), round(wt.location.y, 2), round(wt.location.z, 2), round(wt.rotation.yaw, 1)])
return dict(bones=bones, walkers=others)
def scene_static(world, centre, hidden, vehicles) -> dict:
"""Level boxes, driving-lane waypoints and parked vehicles within SCENE_RADIUS_M of `centre`.
Objects switched off for the walk (`hidden`: their box centres) are left out."""
L = carla.CityObjectLabel
cx, cy = centre
boxes = []
for name, cls in STATIC_LABELS.items():
if not hasattr(L, name):
continue
for bb in world.get_level_bbs(getattr(L, name)):
if math.hypot(bb.location.x - cx, bb.location.y - cy) > SCENE_RADIUS_M:
continue
if any(abs(bb.location.x - h[0]) < 0.05 and abs(bb.location.y - h[1]) < 0.05
and abs(bb.location.z - h[2]) < 0.05 for h in hidden):
continue
boxes.append(dict(cls=cls, label=name, c=[bb.location.x, bb.location.y, bb.location.z],
e=[bb.extent.x, bb.extent.y, bb.extent.z],
r=[bb.rotation.pitch, bb.rotation.yaw, bb.rotation.roll]))
lanes = []
for w in world.get_map().generate_waypoints(2.0):
p = w.transform.location
if math.hypot(p.x - cx, p.y - cy) <= SCENE_RADIUS_M:
lanes.append([p.x, p.y, p.z, w.transform.rotation.yaw, w.lane_width])
vboxes = []
for v in vehicles:
bb, vt = v.bounding_box, v.get_transform()
c = vt.transform(bb.location)
vboxes.append(dict(c=[c.x, c.y, c.z], e=[bb.extent.x, bb.extent.y, bb.extent.z],
r=[vt.rotation.pitch, vt.rotation.yaw, vt.rotation.roll]))
return dict(boxes=boxes, lanes=lanes, vehicles=vboxes)