Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CCB Review: Prepare v1.0.0-rc.1 release candidate #68

Merged
merged 2 commits into from
Oct 24, 2024
Merged
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
373 changes: 373 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

45 changes: 44 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

This project implements the [ASAM OpenScenario XML Checker Bundle](checker_bundle_doc.md).

**Disclaimer**: The current version is a release candidate. The first official release is expected to be in November.

- [asam-qc-openscenarioxml](#asam-qc-openscenarioxml)
- [Installation and usage](#installation-and-usage)
- [Installation using pip](#installation-using-pip)
Expand All @@ -23,11 +25,21 @@ asam-qc-openscenarioxml can be installed using pip or from source.

asam-qc-openscenarioxml can be installed using pip.

**From PyPi**

```bash
pip install asam-qc-openscenarioxml
```

**From GitHub repository**

```bash
pip install asam-qc-openscenarioxml@git+https://github.com/asam-ev/qc-openscenarioxml@main
```

**Note:** The above command will install `asam-qc-openscenarioxml` from the `main` branch. If you want to install `asam-qc-openscenarioxml` from another branch or tag, replace `@main` with the desired branch or tag. It is also possible to install from a local directory.
The above command will install `asam-qc-openscenarioxml` from the `main` branch. If you want to install `asam-qc-openscenarioxml` from another branch or tag, replace `@main` with the desired branch or tag.

**From a local repository**

```bash
pip install /home/user/qc-openscenarioxml
Expand Down Expand Up @@ -208,3 +220,34 @@ You need to have pre-commit installed and install the hooks:
```
pre-commit install
```

**To implement a new checker**

1. Create a new Python module for each checker.
2. Specify the following global variables for the Python module

| Variable | Meaning |
| --- | --- |
| `CHECKER_ID` | The ID of the checker |
| `CHECKER_DESCRIPTION` | The description of the checker |
| `CHECKER_PRECONDITIONS` | A set of other checkers in which if any of them raise an issue, the current checker will be skipped |
| `RULE_UID` | The rule UID of the rule that the checker will check |

3. Implement the checker logic in the following function:

```python
def check_rule(checker_data: models.CheckerData) -> None:
pass
```

1. Register the checker module in the following function in [main.py](qc_openscenario/main.py).

```python
def run_checks(config: Configuration, result: Result) -> None:
...
# Add the following line to register your checker module
execute_checker(your_checker_module, checker_data)
...
```

All the checkers in this checker bundle are implemented in this way. Take a look at some of them before implementing your first checker.
4 changes: 2 additions & 2 deletions checker_bundle_doc.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

# Checker bundle: xoscBundle

* Build version: 0.1.0
* Build version: v1.0.0-rc.1
* Description: OpenScenario checker bundle

## Parameters

* InputFile
* resultFile

## Checkers

Expand Down
2 changes: 1 addition & 1 deletion manifest_templates/windows_xosc_manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"name": "xoscBundle",
"exec_type": "executable",
"module_type": "checker_bundle",
"exec_command": "cd %ASAM_QC_FRAMEWORK_WORKING_DIR% && qc_openscenario -c %ASAM_QC_FRAMEWORK_CONFIG_FILE%"
"exec_command": "cd \"%ASAM_QC_FRAMEWORK_WORKING_DIR%\" && qc_openscenario -c \"%ASAM_QC_FRAMEWORK_CONFIG_FILE%\""
}
]
}
38 changes: 17 additions & 21 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "asam-qc-openscenarioxml"
version = "0.1.0"
version = "1.0.0rc1"
description = "This project implements the OpenScenario Checker for the ASAM Quality Checker project."
authors = ["Danilo Romano <[email protected]>"]
license = "MPL-2.0"
Expand All @@ -12,7 +12,7 @@ packages = [

[tool.poetry.dependencies]
python = "^3.10"
asam-qc-baselib = {git = "https://github.com/asam-ev/qc-baselib-py.git", rev = "develop"}
asam-qc-baselib = "^1.0.0rc1"
lxml = "^5.2.2"

[tool.poetry.group.dev.dependencies]
Expand Down
4 changes: 2 additions & 2 deletions qc_openscenario/checks/data_type_checker/allowed_operators.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging

from dataclasses import dataclass
from typing import Union
from typing import Union, Optional

from lxml import etree

Expand Down Expand Up @@ -47,7 +47,7 @@ class ExpressionMember(enum.IntEnum):
@dataclass
class QueueNode:
element: etree._ElementTree
xpath: Union[str, None]
xpath: Optional[str]


@dataclass
Expand Down
8 changes: 4 additions & 4 deletions qc_openscenario/checks/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from dataclasses import dataclass
from lxml import etree
from typing import Union
from typing import Optional
from enum import Enum

from qc_baselib import Configuration, Result
Expand All @@ -9,11 +9,11 @@
@dataclass
class CheckerData:
xml_file_path: str
input_file_xml_root: Union[None, etree._ElementTree]
input_file_xml_root: Optional[etree._ElementTree]
config: Configuration
result: Result
schema_version: Union[None, str]
xodr_root: Union[None, etree._ElementTree]
schema_version: Optional[str]
xodr_root: Optional[etree._ElementTree]


class AttributeType(Enum):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import logging

from dataclasses import dataclass
from typing import Union
from typing import Optional

from lxml import etree

from qc_baselib import IssueSeverity, StatusType
from qc_baselib import IssueSeverity

from qc_openscenario import constants
from qc_openscenario.checks import utils, models
from qc_openscenario.checks import models

from qc_openscenario import basic_preconditions
from collections import deque, defaultdict
Expand All @@ -22,7 +22,7 @@
@dataclass
class QueueNode:
element: etree._ElementTree
parent_xpath: Union[str, None]
parent_xpath: Optional[str]


@dataclass
Expand Down
15 changes: 9 additions & 6 deletions qc_openscenario/checks/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from lxml import etree
from io import BytesIO
from typing import Union
from typing import Union, Optional
from qc_openscenario.checks import models
import re
import logging
Expand All @@ -17,7 +17,10 @@ def to_float(s):
return None


def get_root_without_default_namespace(path: str) -> etree._ElementTree:
def get_root_without_default_namespace(path: str) -> Optional[etree._ElementTree]:
if not os.path.exists(path):
return None

with open(path, "rb") as raw_file:
xml_string = raw_file.read().decode()

Expand All @@ -27,7 +30,7 @@ def get_root_without_default_namespace(path: str) -> etree._ElementTree:
return etree.parse(BytesIO(xml_string.encode()))


def get_standard_schema_version(root: etree._ElementTree) -> Union[str, None]:
def get_standard_schema_version(root: etree._ElementTree) -> Optional[str]:
header = root.find("FileHeader")
if header is None:
return None
Expand Down Expand Up @@ -104,15 +107,15 @@ def get_parameter_value_from_node(

def get_xodr_road_network(
input_file_path: str, tree: etree._ElementTree
) -> Union[etree._ElementTree, None]:
) -> Optional[etree._ElementTree]:
"""Get parsed xodr tree indicated in the RoadNetwork/LogicFile node of the input tree

Args:
tree (etree._ElementTree): xml document tree that refers to a xodr file

Returns:
Union[etree._ElementTree, None]: the parsed road network tree.
None if the specified nodes in the root or the road network file are not found
Optional[etree._ElementTree]: the parsed road network tree.
None if the specified nodes in the root or the road network file are not found
"""

road_network = tree.find("RoadNetwork")
Expand Down
2 changes: 1 addition & 1 deletion qc_openscenario/constants.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
BUNDLE_NAME = "xoscBundle"
BUNDLE_VERSION = "0.1.0"
BUNDLE_VERSION = "v1.0.0-rc.1"
1 change: 0 additions & 1 deletion qc_openscenario/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,6 @@ def main():
result = Result()
result.register_checker_bundle(
name=constants.BUNDLE_NAME,
build_date=datetime.today().strftime("%Y-%m-%d"),
description="OpenScenario checker bundle",
version=constants.BUNDLE_VERSION,
summary="",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<OpenSCENARIO xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Schema/OpenSCENARIO.xsd">
<FileHeader author="ASAM e.V." date="2021-02-05T18:50:17" description="Simple Overtaker example" revMajor="1" revMinor="3" />
<ParameterDeclarations />
<CatalogLocations />
<RoadNetwork>
<LogicFile filepath="non_existing_file.xodr" />
</RoadNetwork>
<Entities>
<ScenarioObject name="Vehicle 1">
<Vehicle name="Vehicle 1" vehicleCategory="car">
<BoundingBox>
<Center x="1.3" y="0.0" z="0.75" />
<Dimensions width="1.8" length="4.5" height="1.5" />
</BoundingBox>
<Performance maxSpeed="200.0" maxDeceleration="30.0" maxAcceleration="200.0" />
<Axles>
<FrontAxle positionZ="0.4" trackWidth="1.68" positionX="2.98" maxSteering="0.5235987756" wheelDiameter="0.8" />
<RearAxle positionZ="0.4" trackWidth="1.68" positionX="0.0" maxSteering="0.5235987756" wheelDiameter="0.8" />
</Axles>
</Vehicle>
</ScenarioObject>
</Entities>
<Storyboard>
<Init>
<Actions>
<GlobalAction>
<InfrastructureAction>
<TrafficSignalAction>
<TrafficSignalStateAction name="12345" state="on;off;off" />
</TrafficSignalAction>
</InfrastructureAction>
</GlobalAction>
<Private entityRef="Vehicle 1">
<PrivateAction>
<TeleportAction>
<Position>
<WorldPosition x="0.0" y="0.0" />
</Position>
</TeleportAction>
</PrivateAction>
</Private>
</Actions>
</Init>
</Storyboard>
</OpenSCENARIO>
21 changes: 21 additions & 0 deletions tests/test_main_executor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import os
import pytest
import test_utils
from qc_baselib import Result, IssueSeverity, StatusType
from qc_openscenario.checks import basic_checker


def test_non_existing_road_network_file(
monkeypatch,
) -> None:
base_path = "tests/data/non_existing_road_network_file/"
target_file_name = f"non_existing_road_network_file.xosc"
target_file_path = os.path.join(base_path, target_file_name)

test_utils.create_test_config(target_file_path)

test_utils.launch_main(monkeypatch)

# Should have no exception
assert True
test_utils.cleanup_files()