Skip to content

Commit

Permalink
Release 2024.3
Browse files Browse the repository at this point in the history
  • Loading branch information
smaierhofer committed Dec 20, 2024
2 parents 1bee014 + 1c25035 commit 98d3145
Show file tree
Hide file tree
Showing 41 changed files with 3,199 additions and 3,534 deletions.
11 changes: 7 additions & 4 deletions .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-13, windows-latest] # we use macos-13 since FedericoCarboni/setup-ffmpeg@v3 has problems with macos-latest -> update to macos-latest as soon problem is fixed in ffmpeg action
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
os: [ubuntu-latest, macos-13, macos-latest, windows-latest]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
steps :
- uses : actions/checkout@v4
- uses : FedericoCarboni/setup-ffmpeg@v3
- name : Setup FFmpeg (with retries)
uses : ./actions/setup-ffmpeg
with :
github-token : ${{ secrets.GITHUB_TOKEN }}
- name : Set up Python
uses : actions/setup-python@v4
with :
Expand All @@ -32,4 +35,4 @@ jobs:
- name : Execute tests
run : |
poetry run coverage run tests/run_tests.py
poetry run coverage report -m || true
poetry run coverage report -m || true
15 changes: 8 additions & 7 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ stages:
- deploy

default:
image: python:3.12
image: python:3.13
before_script:
- pip install poetry
- poetry config virtualenvs.in-project true
Expand Down Expand Up @@ -36,7 +36,7 @@ build_and_test_python:
stage: test
parallel :
matrix :
- PYTHON_VERSIONS : [ "3.9", "3.10", "3.11" ]
- PYTHON_VERSIONS : [ "3.9", "3.10", "3.11", "3.12" ]
script:
- *run-test-with-coverage
needs: []
Expand All @@ -48,13 +48,13 @@ build_and_test_python_arm:
stage: test
parallel :
matrix :
- PYTHON_VERSIONS : [ "3.9", "3.10", "3.11", "3.12" ]
- PYTHON_VERSIONS : [ "3.9", "3.10", "3.11", "3.12", "3.13" ]
script:
- *run-test-with-coverage
needs: []

build_and_test_python_3_12:
image: python:3.12
build_and_test_python_3_13:
image: python:3.13
stage: test
script:
- *run-test-with-coverage
Expand All @@ -73,7 +73,7 @@ build_and_update_packages_arm:
stage: test
parallel :
matrix :
- PYTHON_VERSIONS : [ "3.9", "3.10", "3.11", "3.12" ]
- PYTHON_VERSIONS : [ "3.9", "3.10", "3.11", "3.12", "3.13" ]
script:
- poetry update
- poetry install
Expand All @@ -84,7 +84,7 @@ build_and_update_packages_debian:
stage: test
parallel :
matrix :
- PYTHON_VERSIONS : [ "3.9", "3.10", "3.11", "3.12" ]
- PYTHON_VERSIONS : [ "3.9", "3.10", "3.11", "3.12", "3.13" ]
script:
- poetry update
- poetry install
Expand All @@ -103,6 +103,7 @@ build_doc:

validate_tutorials:
stage: test
image : python:3.12 # needs to be updated when cvxpy supports python 3.13
script:
- poetry install --with tutorials
- pytest --nbval-lax ./tutorials/
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## [2024.3] - 2024-12-20
### Added
- New Australia and US traffic signs
- New lanelet type: `restricted_area`
- `LaneletNetwork.create_from_lanelet_network` now also includes intersections
- Support for Python 3.13
- TR2 cost function enum value

### Fixed
- `DynamicObstacle` cannot be hashed if some optional attributes are missing
- `TrafficLightCycle` does not invalidate cached cycle init timesteps after modification

## [2024.2] - 2024-07-22

### Added
Expand Down
22 changes: 3 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ Learn more about the scenario specification [here](https://gitlab.lrz.de/tum-cps
The commonroad-io package provides methods to read, write, and visualize CommonRoad scenarios and planning problems. Furthermore, it can be used as a framework for implementing motion planning algorithms to solve CommonRoad Benchmarks and is the basis for other tools of the CommonRoad Framework.
With commonroad-io, those solutions can be written to xml-files for uploading them on [commonroad.in.tum.de](https://commonroad.in.tum.de/).

commonroad-io 2024.2 is compatible with CommonRoad scenarios in version 2020a and supports reading 2018b scenarios.
This commonroad-io version is compatible with CommonRoad scenarios in version 2020a and supports reading 2018b scenarios.

The software is written in Python and tested on Linux for the Python 3.9, 3.10, 3.11 and 3.12.
The software is written in Python and tested on Linux for the Python 3.9, 3.10, 3.11, 3.12, and 3.13.


## Documentation
Expand Down Expand Up @@ -80,23 +80,7 @@ Alternatively, clone from our gitlab repository::
and add the folder commonroad-io to your Python environment.

## Changelog
Compared to version 2024.1, the following features have been added or changed:

### Added
- Github actions for ubuntu, windows, and macOS
- Gitlab runner for arm64 ubuntu
- Support for reading xml and protobuf byte streams
- Support for numpy `>=2.0`
- Adjustable zorder for dynamic obstacle & lanelet visualization

### Fixed
- AreaBorder can have multiple adjacent lanelets
- Performance regression for occupancy_set lookups in TrajectoryPrediction
- Matplotlib `>=3.9.0` support

### Removed
- Support for Python 3.8

A detailed overview about the changes in each version is provided in the [Changelog](https://github.com/CommonRoad/commonroad-io/blob/master/CHANGELOG.md).

## Authors
Contribution (in alphabetic order by last name): Yannick Ballnath, Behtarin Ferdousi, Luis Gressenbuch, Moritz Klischat,
Expand Down
32 changes: 32 additions & 0 deletions actions/setup-ffmpeg/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: 'Setup FFmpeg with retries'
description: 'Installs FFmpeg with retry logic'
inputs:
github-token:
description: 'GitHub Token (required by "FedericoCarboni/setup-ffmpeg@v3")'
required: true

runs:
using: 'composite'
steps:
- name: Setup FFmpeg
id: attempt1
continue-on-error: true
uses: FedericoCarboni/setup-ffmpeg@v3
with:
github-token: ${{ inputs.github-token }}

- name: Setup FFmpeg (retry 2)
if: ${{ steps.attempt1.outcome == 'failure' }}
id: attempt2
continue-on-error: true
uses: FedericoCarboni/setup-ffmpeg@v3
with:
github-token: ${{ inputs.github-token }}

- name: Setup FFmpeg (retry 3)
if: ${{ steps.attempt2.outcome == 'failure' }}
id: attempt3
continue-on-error: true
uses: FedericoCarboni/setup-ffmpeg@v3
with:
github-token: ${{ inputs.github-token }}
1 change: 1 addition & 0 deletions commonroad/common/common_lanelet.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class LaneletType(enum.Enum):
BORDER = "border"
PARKING = "parking"
RESTRICTED = "restricted" # cars not allowed, e.g., special lanes for busses
RESTRICTED_AREA = "restricted_area" # area where vehicles are not allowed; usually the area is indicated by diagonal line markings, e.g., German traffic sign ID 298
UNKNOWN = "unknown"


Expand Down
1 change: 1 addition & 0 deletions commonroad/common/solution.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class CostFunction(Enum):
SM3 = 5
MW1 = 6
TR1 = 7
TR2 = 8


@unique
Expand Down
52 changes: 47 additions & 5 deletions commonroad/scenario/lanelet.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
)
from commonroad.geometry.shape import Circle, Polygon, Rectangle, Shape, ShapeGroup
from commonroad.scenario.area import Area
from commonroad.scenario.intersection import Intersection
from commonroad.scenario.intersection import Intersection, IntersectionIncomingElement
from commonroad.scenario.obstacle import Obstacle
from commonroad.scenario.state import TraceState
from commonroad.scenario.traffic_light import TrafficLight
Expand Down Expand Up @@ -1484,7 +1484,7 @@ def create_from_lanelet_network(
traffic_sign_ids = set()
traffic_light_ids = set()
area_ids = set()
lanelets = set()
lanelet_ids = set()

for la in lanelet_network.lanelets:
if (
Expand All @@ -1494,14 +1494,56 @@ def create_from_lanelet_network(
):
continue

lanelets.add(la)
lanelet_ids.add(la.lanelet_id)

for sign_id in la.traffic_signs:
traffic_sign_ids.add(sign_id)
for light_id in la.traffic_lights:
traffic_light_ids.add(light_id)
for area_id in la.adjacent_areas:
area_ids.add(area_id)

# In contrast to the other objects, intersections need some special processing:
# Some lanelets might be excluded from the new lanelet network, but those lanelets could
# be referenced as incomings, successors or crossings. Therfore, new intersections
# are created here, which only reference lanelets that are also in the new lanelet network
for old_intersection in lanelet_network.intersections:
new_incomings = list()
for old_incoming in old_intersection.incomings:
new_incoming_lanelets = old_incoming.incoming_lanelets.intersection(lanelet_ids)
if len(new_incoming_lanelets) == 0:
continue

new_successors_right = old_incoming.successors_right.intersection(lanelet_ids)
new_successors_left = old_incoming.successors_left.intersection(lanelet_ids)
new_successors_straight = old_incoming.successors_straight.intersection(lanelet_ids)

if len(new_successors_left) + len(new_successors_straight) + len(new_successors_right) < 1:
continue

new_incoming = IntersectionIncomingElement(
incoming_id=old_incoming.incoming_id,
incoming_lanelets=new_incoming_lanelets,
successors_right=new_successors_right,
successors_straight=new_successors_straight,
successors_left=new_successors_left,
left_of=old_incoming.left_of,
)
new_incomings.append(new_incoming)

if len(new_incomings) == 0:
continue

new_crossings = set()
for crossing in old_intersection.crossings:
if crossing in lanelet_ids:
new_crossings.add(crossing)

new_intersection = Intersection(
intersection_id=old_intersection.intersection_id, incomings=new_incomings, crossings=new_crossings
)
new_lanelet_network.add_intersection(new_intersection)

for sign_id in traffic_sign_ids:
new_lanelet_network.add_traffic_sign(copy.deepcopy(lanelet_network.find_traffic_sign_by_id(sign_id)), set())
for light_id in traffic_light_ids:
Expand All @@ -1510,8 +1552,8 @@ def create_from_lanelet_network(
)
for area_id in area_ids:
new_lanelet_network.add_area(copy.deepcopy(lanelet_network.find_area_by_id(area_id)), set())
for la in lanelets:
new_lanelet_network.add_lanelet(copy.deepcopy(la), rtree=False)
for lanelet_id in lanelet_ids:
new_lanelet_network.add_lanelet(copy.deepcopy(lanelet_network.find_lanelet_by_id(lanelet_id)), rtree=False)

if cleanup_ids:
new_lanelet_network.cleanup_lanelet_references()
Expand Down
18 changes: 14 additions & 4 deletions commonroad/scenario/obstacle.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,17 +145,24 @@ def __eq__(self, other):
return obstacle_eq

def __hash__(self):
initial_center_lanelet_ids = (
None if self.initial_center_lanelet_ids is None else frozenset(self.initial_center_lanelet_ids)
)
initial_shape_lanelet_ids = (
None if self.initial_shape_lanelet_ids is None else frozenset(self.initial_shape_lanelet_ids)
)
signal_series = None if self.signal_series is None else frozenset(self.signal_series)
return hash(
(
self._obstacle_id,
self._obstacle_role,
self._obstacle_type,
self._obstacle_shape,
self._initial_state,
frozenset(self.initial_center_lanelet_ids),
frozenset(self.initial_shape_lanelet_ids),
initial_center_lanelet_ids,
initial_shape_lanelet_ids,
self._initial_signal_state,
tuple(self.signal_series),
signal_series,
)
)

Expand Down Expand Up @@ -538,12 +545,15 @@ def __hash__(self):
if self.shape_lanelet_ids_history is None
else tuple(frozenset(value) for value in self.shape_lanelet_ids_history)
)
meta_information_series = (
None if self._meta_information_series is None else tuple(self._meta_information_series)
)

return hash(
(
self._prediction,
self._initial_meta_information_state,
tuple(self._meta_information_series),
meta_information_series,
self._external_dataset_id,
tuple(self.history),
tuple(self.signal_history),
Expand Down
6 changes: 6 additions & 0 deletions commonroad/scenario/traffic_light.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ def cycle_elements(self) -> Union[None, List[TrafficLightCycleElement]]:
@cycle_elements.setter
def cycle_elements(self, cycle_elements: Union[None, List[TrafficLightCycleElement]]):
self._cycle_elements = cycle_elements
# Invalidate cached attribute which was calculated based on the previous cycle elements
if hasattr(self, "_cycle_init_timesteps"):
del self._cycle_init_timesteps

@property
def time_offset(self) -> int:
Expand All @@ -152,6 +155,9 @@ def time_offset(self) -> int:
@time_offset.setter
def time_offset(self, time_offset: int):
self._time_offset = time_offset
# Invalidate cached attribute which was calculated based on the previous time offset
if hasattr(self, "_cycle_init_timesteps"):
del self._cycle_init_timesteps

@property
def active(self) -> bool:
Expand Down
Loading

0 comments on commit 98d3145

Please sign in to comment.