Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4,472 changes: 4,249 additions & 223 deletions src/scenic/simulators/carla/blueprints.py

Large diffs are not rendered by default.

126 changes: 76 additions & 50 deletions src/scenic/simulators/carla/model.scenic
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Global Parameters:
import pathlib
from scenic.domains.driving.model import *

import scenic.simulators.carla.blueprints as blueprints
import scenic.simulators.carla.blueprints as bp
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the old blueprints is more understandable.

from scenic.simulators.carla.behaviors import *
from scenic.simulators.utils.colors import Color

Expand Down Expand Up @@ -122,6 +122,12 @@ class CarlaActor(DrivingObject):
carlaActor (dynamic): Set during simulations to the ``carla.Actor`` representing this
object.
blueprint (str): Identifier of the CARLA blueprint specifying the type of object.
defaultWidth (float): Default width to use if Scenic has no recorded dimensions for this blueprint.
defaultLength (float): Default length to use if Scenic has no recorded dimensions for this blueprint.
defaultHeight (float): Default height to use if Scenic has no recorded dimensions for this blueprint.
width (float): Width for this blueprint; uses Scenic's recorded dimensions when available, otherwise ``defaultWidth``.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
width (float): Width for this blueprint; uses Scenic's recorded dimensions when available, otherwise ``defaultWidth``.
width (float): Width for this object; uses the value from ``blueprint`` when available, otherwise ``defaultWidth``.

Ditto for length and height.

length (float): Length for this blueprint; uses Scenic's recorded dimensions when available, otherwise ``defaultLength``.
height (float): Height for this blueprint; uses Scenic's recorded dimensions when available, otherwise ``defaultHeight``.
rolename (str): Can be used to differentiate specific actors during runtime. Default
value ``None``.
physics (bool): Whether physics is enabled for this object in CARLA. Default true.
Expand All @@ -130,8 +136,13 @@ class CarlaActor(DrivingObject):
"""
carlaActor: None
blueprint: None
defaultWidth: 1
defaultLength: 1
defaultHeight: 1
width: bp.width(self.blueprint, self.defaultWidth)
length: bp.length(self.blueprint, self.defaultLength)
height: bp.height(self.blueprint, self.defaultHeight)
rolename: None
color: None
physics: True
snapToGround: globalParameters.snapToGroundDefault

Expand All @@ -155,7 +166,7 @@ class CarlaActor(DrivingObject):
else:
self.carlaActor.set_velocity(cvel)

class Vehicle(Vehicle, CarlaActor, Steers, _CarlaVehicle):
class Vehicle(CarlaActor, Vehicle, Steers, _CarlaVehicle):
"""Abstract class for steerable vehicles."""

def setThrottle(self, throttle):
Expand All @@ -182,7 +193,10 @@ class Car(Vehicle):
The default ``blueprint`` (see `CarlaActor`) is a uniform distribution over the
blueprints listed in :obj:`scenic.simulators.carla.blueprints.carModels`.
"""
blueprint: Uniform(*blueprints.carModels)
blueprint: Uniform(*bp.any_in("car"))
defaultWidth: 2
defaultLength: 4.5
defaultHeight: 1.5

@property
def isCar(self):
Expand All @@ -192,32 +206,45 @@ class NPCCar(Car): # no distinction between these in CARLA
pass

class Bicycle(Vehicle):
width: 1
length: 2
blueprint: Uniform(*blueprints.bicycleModels)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For backwards compatibility, can we continue to define bicycleModels, etc. in the blueprints module? People might be using them, and they are documented. I think keeping those and also providing the new function to look up by the name of the category would make sense.


blueprint: Uniform(*bp.any_in("bicycle"))
defaultWidth: 1
defaultLength: 2
defaultHeight: 1.5

class Motorcycle(Vehicle):
width: 1
length:2
blueprint: Uniform(*blueprints.motorcycleModels)

blueprint: Uniform(*bp.any_in("motorcycle"))
defaultWidth: 1
defaultLength: 2
defaultHeight: 1.5

class Truck(Vehicle):
width: 3
length: 7
blueprint: Uniform(*blueprints.truckModels)


class Pedestrian(Pedestrian, CarlaActor, Walks, _CarlaPedestrian):
blueprint: Uniform(*bp.any_in("truck"))
defaultWidth: 2.5
defaultLength: 7.5
defaultHeight: 3

class Van(Vehicle):
blueprint: Uniform(*bp.any_in("van"))
defaultWidth: 2
defaultLength: 5
defaultHeight: 2

class Bus(Vehicle):
blueprint: Uniform(*bp.any_in("bus"))
defaultWidth: 4
defaultLength: 10
defaultHeight: 4

class Pedestrian(CarlaActor, Pedestrian, Walks, _CarlaPedestrian):
"""A pedestrian.

The default ``blueprint`` (see `CarlaActor`) is a uniform distribution over the
blueprints listed in :obj:`scenic.simulators.carla.blueprints.walkerModels`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to fix the docstring here, since the location of the blueprints has changed.

"""
width: 0.5
length: 0.5
blueprint: Uniform(*blueprints.walkerModels)
blueprint: Uniform(*bp.any_in("walker"))
defaultWidth: 0.5
defaultLength: 0.5
defaultHeight: 1.5
carlaController: None

def setWalkingDirection(self, heading):
Expand All @@ -238,100 +265,99 @@ class Prop(CarlaActor):
regionContainedIn: road
position: new Point on road
parentOrientation: Range(0, 360) deg
width: 0.5
length: 0.5
defaultWidth: 0.5
defaultLength: 0.5
defaultHeight: 0.5
physics: False

class Trash(Prop):
blueprint: Uniform(*blueprints.trashModels)
blueprint: Uniform(*bp.any_in("trash"))


class Cone(Prop):
blueprint: Uniform(*blueprints.coneModels)
blueprint: Uniform(*bp.any_in("cone"))


class Debris(Prop):
blueprint: Uniform(*blueprints.debrisModels)
blueprint: Uniform(*bp.any_in("debris"))


class VendingMachine(Prop):
blueprint: Uniform(*blueprints.vendingMachineModels)

blueprint: Uniform(*bp.any_in("vendingMachine"))

class Chair(Prop):
blueprint: Uniform(*blueprints.chairModels)

blueprint: Uniform(*bp.any_in("chair"))

class BusStop(Prop):
blueprint: Uniform(*blueprints.busStopModels)
blueprint: Uniform(*bp.any_in("busStop"))


class Advertisement(Prop):
blueprint: Uniform(*blueprints.advertisementModels)
blueprint: Uniform(*bp.any_in("advertisement"))


class Garbage(Prop):
blueprint: Uniform(*blueprints.garbageModels)

blueprint: Uniform(*bp.any_in("garbage"))

class Container(Prop):
blueprint: Uniform(*blueprints.containerModels)
blueprint: Uniform(*bp.any_in("container"))


class Table(Prop):
blueprint: Uniform(*blueprints.tableModels)
blueprint: Uniform(*bp.any_in("table"))


class Barrier(Prop):
blueprint: Uniform(*blueprints.barrierModels)
blueprint: Uniform(*bp.any_in("barrier"))


class PlantPot(Prop):
blueprint: Uniform(*blueprints.plantpotModels)
blueprint: Uniform(*bp.any_in("plantpot"))


class Mailbox(Prop):
blueprint: Uniform(*blueprints.mailboxModels)

blueprint: Uniform(*bp.any_in("mailbox"))

class Gnome(Prop):
blueprint: Uniform(*blueprints.gnomeModels)
blueprint: Uniform(*bp.any_in("gnome"))


class CreasedBox(Prop):
blueprint: Uniform(*blueprints.creasedboxModels)
blueprint: Uniform(*bp.any_in("creasedbox"))


class Case(Prop):
blueprint: Uniform(*blueprints.caseModels)
blueprint: Uniform(*bp.any_in("case"))


class Box(Prop):
blueprint: Uniform(*blueprints.boxModels)
blueprint: Uniform(*bp.any_in("box"))


class Bench(Prop):
blueprint: Uniform(*blueprints.benchModels)
blueprint: Uniform(*bp.any_in("bench"))


class Barrel(Prop):
blueprint: Uniform(*blueprints.barrelModels)
blueprint: Uniform(*bp.any_in("barrel"))


class ATM(Prop):
blueprint: Uniform(*blueprints.atmModels)
blueprint: Uniform(*bp.any_in("atm"))


class Kiosk(Prop):
blueprint: Uniform(*blueprints.kioskModels)
blueprint: Uniform(*bp.any_in("kiosk"))


class IronPlate(Prop):
blueprint: Uniform(*blueprints.ironplateModels)
blueprint: Uniform(*bp.any_in("ironplate"))


class TrafficWarning(Prop):
blueprint: Uniform(*blueprints.trafficwarningModels)
blueprint: Uniform(*bp.any_in("trafficwarning"))


## Utility functions
Expand Down
125 changes: 52 additions & 73 deletions tests/simulators/carla/test_blueprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,92 +7,71 @@

from test_actions import getCarlaSimulator

from scenic.simulators.carla.blueprints import (
advertisementModels,
atmModels,
barrelModels,
barrierModels,
benchModels,
bicycleModels,
boxModels,
busStopModels,
carModels,
caseModels,
chairModels,
coneModels,
containerModels,
creasedboxModels,
debrisModels,
garbageModels,
gnomeModels,
ironplateModels,
kioskModels,
mailboxModels,
motorcycleModels,
plantpotModels,
tableModels,
trafficwarningModels,
trashModels,
truckModels,
vendingMachineModels,
walkerModels,
)
from scenic.simulators.carla import blueprints as bp
from tests.utils import compileScenic, sampleScene

# Map class name -> ids dict key
CATEGORY_TO_CLASS = {
"carModels": "Car",
"bicycleModels": "Bicycle",
"motorcycleModels": "Motorcycle",
"truckModels": "Truck",
"vanModels": "Van",
"busModels": "Bus",
"trashModels": "Trash",
"coneModels": "Cone",
"debrisModels": "Debris",
"vendingMachineModels": "VendingMachine",
"chairModels": "Chair",
"busStopModels": "BusStop",
"advertisementModels": "Advertisement",
"garbageModels": "Garbage",
"containerModels": "Container",
"tableModels": "Table",
"barrierModels": "Barrier",
"plantpotModels": "PlantPot",
"mailboxModels": "Mailbox",
"gnomeModels": "Gnome",
"creasedboxModels": "CreasedBox",
"caseModels": "Case",
"boxModels": "Box",
"benchModels": "Bench",
"barrelModels": "Barrel",
"atmModels": "ATM",
"kioskModels": "Kiosk",
"ironplateModels": "IronPlate",
"trafficwarningModels": "TrafficWarning",
"walkerModels": "Pedestrian",
}

# Build the (modelType, modelName) pairs from bp.ids
PARAMS = [
(model_type, model_name)
for key, model_type in CATEGORY_TO_CLASS.items()
for model_name in bp.ids.get(key, []) # empty lists are fine; they just add no params
]


def model_blueprint(simulator, mapPath, town, modelType, modelName):
code = f"""
param map = r'{mapPath}'
param carla_map = '{town}'
param time_step = 1.0/10
param map = r'{mapPath}'
param carla_map = '{town}'
param time_step = 1.0/10

model scenic.simulators.carla.model
ego = new {modelType} with blueprint '{modelName}'
terminate after 1 steps
"""
model scenic.simulators.carla.model
ego = new {modelType} at (369, -326),
with blueprint '{modelName}',
with regionContainedIn None
terminate after 1 steps
"""
scenario = compileScenic(code, mode2D=True)
scene = sampleScene(scenario)
simulation = simulator.simulate(scene)
obj = simulation.objects[0]
assert obj.blueprint == modelName


model_data = {
"Car": carModels,
"Bicycle": bicycleModels,
"Motorcycle": motorcycleModels,
"Truck": truckModels,
"Trash": trashModels,
"Cone": coneModels,
"Debris": debrisModels,
"VendingMachine": vendingMachineModels,
"Chair": chairModels,
"BusStop": busStopModels,
"Advertisement": advertisementModels,
"Garbage": garbageModels,
"Container": containerModels,
"Table": tableModels,
"Barrier": barrierModels,
"PlantPot": plantpotModels,
"Mailbox": mailboxModels,
"Gnome": gnomeModels,
"CreasedBox": creasedboxModels,
"Case": caseModels,
"Box": boxModels,
"Bench": benchModels,
"Barrel": barrelModels,
"ATM": atmModels,
"Kiosk": kioskModels,
"IronPlate": ironplateModels,
"TrafficWarning": trafficwarningModels,
"Pedestrian": walkerModels,
}


@pytest.mark.parametrize(
"modelType, modelName",
[(type, name) for type, names in model_data.items() for name in names],
)
@pytest.mark.parametrize("modelType, modelName", PARAMS)
def test_model_blueprints(getCarlaSimulator, modelType, modelName):
simulator, town, mapPath = getCarlaSimulator("Town01")
model_blueprint(simulator, mapPath, town, modelType, modelName)
Loading
Loading