Skip to content

Generate CARLA blueprints dynamically#401

Open
lola831 wants to merge 7 commits intoBerkeleyLearnVerify:mainfrom
lola831:dynamic-carla-blueprints
Open

Generate CARLA blueprints dynamically#401
lola831 wants to merge 7 commits intoBerkeleyLearnVerify:mainfrom
lola831:dynamic-carla-blueprints

Conversation

@lola831
Copy link
Collaborator

@lola831 lola831 commented Oct 21, 2025

Description

This PR generates CARLA blueprints dynamically (per CARLA version).

-snapshot_blueprints.py: connects to CARLA, collects blueprint IDs and bounding-box dimensions for the running server version, categorizes them for Scenic, and writes tools/carla/snapshots/blueprints_<VERSION>.json.

-make_blueprints.py: reads all snapshot JSONs, sorts/normalizes them, and regenerates src/scenic/simulators/carla/blueprints.py.

-Generated blueprints.py: selects the best-matching snapshot for the installed CARLA version and exposes ids, dims, and helper functions.

-Handles versions that lack certain categories (e.g., CARLA 0.10.0 has no bicycles).

-Uses measured dimensions when available; otherwise falls back to defaults.

-Adds vanModels and busModels categories based on CARLA’s base_type.

Issue Link

N/A

Checklist

  • I have tested the changes locally via pytest and/or other means
  • I have added or updated relevant documentation
  • I have autoformatted the code with black and isort
  • I have added test cases (if applicable)

Additional Notes

N/A

@lola831 lola831 requested a review from dfremont October 21, 2025 14:56
@codecov
Copy link

codecov bot commented Oct 21, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.65%. Comparing base (cbc265d) to head (f6a139a).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #401      +/-   ##
==========================================
- Coverage   89.70%   89.65%   -0.06%     
==========================================
  Files          48       48              
  Lines       13190    13190              
==========================================
- Hits        11832    11825       -7     
- Misses       1358     1365       +7     

see 5 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated docstrings for width/length/height as suggested.

dims = _pick(_DIMS, _CARLA_VER)


def any_in(category):
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 this name is confusing. How about something like blueprintsInCategory?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Renamed to blueprintsInCategory

"""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.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated the Car and Pedestrian docstrings to reflect the new blueprintsInCategory

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.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Re-added the category lists (bicycleModels, etc.) to the blueprints module for backwards compatibility, and kept the new lookup helper.

def load_versions():
files = list(SNAPSHOT_DIR.glob(SNAPSHOT_PATTERN))
if not files:
raise SystemExit("No input JSONs found.")
Copy link
Collaborator

Choose a reason for hiding this comment

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

This looks odd to me. I'd just use sys.exit(), which does the same thing.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Changed this to use sys.exit().

for jf in files:
obj = json.loads(jf.read_text(encoding="utf-8"))
ver = str(obj["server_version"])
entries.append((ver, {"ids": obj.get("ids", {}), "dims": obj.get("dims", {})}))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why the get()s here? Aren't the files malformed if either key is missing?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good point. These snapshot files should always include both "ids" and "dims" so I switched to direct indexing instead of get().

"dims": dims,
}
out_path = SNAPSHOT_DIR / f"blueprints_{server_version}.json"
with open(out_path, "w", encoding="utf-8") as f:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since these will sit around every time someone clones the repo, let's compress them (if we need to inspect the files for debugging, it's easy enough to double-click on them). You can just use gzip.open here and in make_blueprints.py.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Snapshots are now written and read via gzip.open (blueprints_*.json.gz).

Copy link
Collaborator

@dfremont dfremont left a comment

Choose a reason for hiding this comment

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

Looks good in general. Besides some minor comments above, my only suggestion is that since blueprints.py is now very long and difficult to read, let's try splitting it into two files. The non-autogenerated part can stay in blueprints.py, but let's move the giant _IDS and _DIMS dictionaries into a separate _blueprintData.py module and then do from _blueprintData import _IDS, _DIMS. The make_blueprints.py script can then just generate _blueprintData.py.

@lola831
Copy link
Collaborator Author

lola831 commented Mar 5, 2026

@dfremont Thanks for the review. I split out _IDS / _DIMS into _blueprintData.py and left helpers in blueprints.py as suggested. Also addressed all the other review comments in the latest commits.

@lola831 lola831 requested a review from Eric-Vin March 5, 2026 01:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants