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

Refactor to use one checker per rule #97

Merged
merged 2 commits into from
Sep 16, 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
34 changes: 28 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ as an application.
pip install asam-qc-opendrive@git+https://github.com/asam-ev/qc-opendrive@main
```

**Note**: To install from different sources, you can replace `@main` with
your desired target. For example, `develop` branch as `@develop`.
**Note:** The above command will install `asam-qc-opendrive` from the `main` branch. If you want to install `asam-qc-opendrive` from another branch or tag, replace `@main` with the desired branch or tag. It is also possible to install from a local directory.

```bash
pip install /home/user/qc-opendrive
```

#### To use as a library

Expand Down Expand Up @@ -163,10 +166,29 @@ An example configuration file for using this Checker Bundle within the ASAM Qual

<CheckerBundle application="xodrBundle">
<Param name="resultFile" value="xodr_bundle_report.xqar" />
<Checker checkerId="semantic_xodr" maxLevel="1" minLevel="3" />
<Checker checkerId="geometry_xodr" maxLevel="1" minLevel="3" />
<Checker checkerId="performance_xodr" maxLevel="1" minLevel="3" />
<Checker checkerId="smoothness_xodr" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_xml_valid_xml_document" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_xml_root_tag_is_opendrive" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_xml_fileheader_is_present" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_xml_version_is_defined" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_xml_valid_schema" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_road_lane_level_true_one_side" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_road_lane_access_no_mix_of_deny_or_allow" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_road_lane_link_lanes_across_lane_sections" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_road_linkage_is_junction_needed" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_road_lane_link_zero_width_at_start" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_road_lane_link_zero_width_at_end" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_road_lane_link_new_lane_appear" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_junctions_connection_connect_road_no_incoming_road" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_junctions_connection_one_connection_element" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_junctions_connection_one_link_to_incoming" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_junctions_connection_start_along_linkage" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_junctions_connection_end_opposite_linkage" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_road_geometry_parampoly3_length_match" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_road_lane_border_overlap_with_inner_lanes" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_road_geometry_parampoly3_arclength_range" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_road_geometry_parampoly3_normalized_range" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_performance_avoid_redundant_info" maxLevel="1" minLevel="3" />
<Checker checkerId="check_asam_xodr_lane_smoothness_contact_point_no_horizontal_gaps" maxLevel="1" minLevel="3" />
</CheckerBundle>

<ReportModule application="TextReport">
Expand Down
118 changes: 109 additions & 9 deletions checker_bundle_doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,144 @@

## Parameters

* InputFile: The path of the input file.
* InputFile

## Checkers

### semantic_xodr
### check_asam_xodr_xml_valid_xml_document

* Description: Evaluates elements in the file and their semantics to guarantee they are in conformity with the standard.
* Description: The input file must be a valid XML document.
* Addressed rules:
* asam.net:xodr:1.0.0:xml.valid_xml_document

### check_asam_xodr_xml_root_tag_is_opendrive

* Description: The root element of a valid XML document must be OpenSCENARIO.
* Addressed rules:
* asam.net:xodr:1.0.0:xml.root_tag_is_opendrive

### check_asam_xodr_xml_fileheader_is_present

* Description: Below the root element a tag with FileHeader must be defined.
* Addressed rules:
* asam.net:xodr:1.0.0:xml.fileheader_is_present

### check_asam_xodr_xml_version_is_defined

* Description: The FileHeader tag must have the attributes revMajor and revMinor and of type unsignedShort.
* Addressed rules:
* asam.net:xodr:1.0.0:xml.version_is_defined

### check_asam_xodr_xml_valid_schema

* Description: Input xml file must be valid according to the schema.
* Addressed rules:
* asam.net:xodr:1.0.0:xml.valid_schema

### check_asam_xodr_road_lane_level_true_one_side

* Description: Check if there is any @Level=False after being True until the lane border.
* Addressed rules:
* asam.net:xodr:1.7.0:road.lane.level_true_one_side

### check_asam_xodr_road_lane_access_no_mix_of_deny_or_allow

* Description: Check if there is mixed content on access rules for the same sOffset on lanes.
* Addressed rules:
* asam.net:xodr:1.7.0:road.lane.access.no_mix_of_deny_or_allow

### check_asam_xodr_road_lane_link_lanes_across_lane_sections

* Description: Lanes that continues across the lane sections shall be connected in both directions.
* Addressed rules:
* asam.net:xodr:1.4.0:road.lane.link.lanes_across_lane_sections

### check_asam_xodr_road_linkage_is_junction_needed

* Description: Two roads shall only be linked directly, if the linkage is clear. If the relationship to successor or predecessor is ambiguous, junctions shall be used.
* Addressed rules:
* asam.net:xodr:1.4.0:road.linkage.is_junction_needed

### check_asam_xodr_road_lane_link_zero_width_at_start

* Description: Lanes that have a width of zero at the beginning of the lane section shall have no predecessor element.
* Addressed rules:
* asam.net:xodr:1.7.0:road.lane.link.zero_width_at_start

### check_asam_xodr_road_lane_link_zero_width_at_end

* Description: Lanes that have a width of zero at the end of the lane section shall have no successor element.
* Addressed rules:
* asam.net:xodr:1.7.0:road.lane.link.zero_width_at_end

### check_asam_xodr_road_lane_link_new_lane_appear

* Description: If a new lane appears besides, only the continuing lane shall be connected to the original lane, not the appearing lane.
* Addressed rules:
* asam.net:xodr:1.4.0:road.lane.link.new_lane_appear

### check_asam_xodr_junctions_connection_connect_road_no_incoming_road

* Description: Connecting roads shall not be incoming roads.
* Addressed rules:
* asam.net:xodr:1.4.0:junctions.connection.connect_road_no_incoming_road

### check_asam_xodr_junctions_connection_one_connection_element

* Description: Each connecting road shall be represented by exactly one element. A connecting road may contain as many lanes as required.
* Addressed rules:
* asam.net:xodr:1.7.0:junctions.connection.one_connection_element

### check_asam_xodr_junctions_connection_one_link_to_incoming

* Description: Each connecting road shall be associated with at most one <connection> element per incoming road. A connecting road shall only have the <laneLink> element for that direction.
* Addressed rules:
* asam.net:xodr:1.8.0:junctions.connection.one_link_to_incoming

### check_asam_xodr_junctions_connection_start_along_linkage

* Description: The value "start" shall be used to indicate that the connecting road runs along the linkage indicated in the element.
* Addressed rules:
* asam.net:xodr:1.7.0:junctions.connection.start_along_linkage

### check_asam_xodr_junctions_connection_end_opposite_linkage

* Description: The value "end" shall be used to indicate that the connectingroad runs along the opposite direction of the linkage indicated in the element.
* Addressed rules:
* asam.net:xodr:1.7.0:junctions.connection.end_opposite_linkage

### geometry_xodr
### check_asam_xodr_road_geometry_parampoly3_length_match

* Description: Evaluates elements in the file and their geometrys to guarantee they are in conformity with the standard.
* Description: The actual curve length, as determined by numerical integration over the parameter range, should match '@Length'.
* Addressed rules:
* asam.net:xodr:1.7.0:road.geometry.parampoly3.length_match

### check_asam_xodr_road_lane_border_overlap_with_inner_lanes

* Description: Lane borders shall not intersect inner lanes.
* Addressed rules:
* asam.net:xodr:1.4.0:road.lane.border.overlap_with_inner_lanes

### check_asam_xodr_road_geometry_parampoly3_arclength_range

* Description: If @prange='arcLength', p shall be chosen in [0, @Length from geometry].
* Addressed rules:
* asam.net:xodr:1.7.0:road.geometry.parampoly3.arclength_range

### check_asam_xodr_road_geometry_parampoly3_normalized_range

* Description: If @prange='normalized', p shall be chosen in [0, 1].
* Addressed rules:
* asam.net:xodr:1.7.0:road.geometry.parampoly3.normalized_range

### performance_xodr
### check_asam_xodr_performance_avoid_redundant_info

* Description: Evaluates elements in the file to guarantee they are optimized.
* Description: Redundant elements should be avoided.
* Addressed rules:
* asam.net:xodr:1.7.0:performance.avoid_redundant_info

### smoothness_xodr
### check_asam_xodr_lane_smoothness_contact_point_no_horizontal_gaps

* Description: Evaluates elements in the file and their geometries to guarantee they are in conformity with the standard definition of smoothness.
* Description: Two connected drivable lanes shall have no horizontal gaps.
* Addressed rules:
* asam.net:xodr:1.7.0:lane_smoothness.contact_point_no_horizontal_gaps
1 change: 1 addition & 0 deletions qc_opendrive/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from . import constants as constants
from . import checks as checks
from . import basic_preconditions as basic_preconditions
6 changes: 4 additions & 2 deletions qc_opendrive/base/models.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
from dataclasses import dataclass
from enum import Enum
from lxml import etree
from typing import Union

from qc_baselib import Configuration, Result


@dataclass
class CheckerData:
input_file_xml_root: etree._ElementTree
xml_file_path: str
input_file_xml_root: Union[None, etree._ElementTree]
config: Configuration
result: Result
schema_version: str
schema_version: Union[None, str]


class LinkageTag(str, Enum):
Expand Down
32 changes: 32 additions & 0 deletions qc_opendrive/base/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1751,3 +1751,35 @@ def get_middle_point_xyz_at_height_zero_from_lane_by_s(

def get_s_offset_from_access(access: etree._ElementTree) -> Union[None, float]:
return to_float(access.get("sOffset"))


def compare_versions(version1: str, version2: str) -> int:
"""Compare two version strings like "X.x.x"
This function is to avoid comparing version string basing on lexicographical order
that could cause problem. E.g.
1.10.0 > 1.2.0 but lexicographical comparison of string would return the opposite

Args:
version1 (str): First string to compare
version2 (str): Second string to compare

Returns:
int: 1 if version1 is bigger than version2. 0 if the version are the same. -1 otherwise
"""
v1_components = list(map(int, version1.split(".")))
v2_components = list(map(int, version2.split(".")))

# Compare each component until one is greater or they are equal
for v1, v2 in zip(v1_components, v2_components):
if v1 < v2:
return -1
elif v1 > v2:
return 1

# If all components are equal, compare based on length
if len(v1_components) < len(v2_components):
return -1
elif len(v1_components) > len(v2_components):
return 1
else:
return 0
16 changes: 16 additions & 0 deletions qc_opendrive/basic_preconditions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from qc_opendrive.checks.basic import (
valid_xml_document,
root_tag_is_opendrive,
fileheader_is_present,
version_is_defined,
)

from qc_opendrive.checks.schema import valid_schema

CHECKER_PRECONDITIONS = {
valid_xml_document.CHECKER_ID,
root_tag_is_opendrive.CHECKER_ID,
fileheader_is_present.CHECKER_ID,
version_is_defined.CHECKER_ID,
valid_schema.CHECKER_ID,
}
2 changes: 0 additions & 2 deletions qc_opendrive/checks/basic/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from . import basic_constants as basic_constants
from . import basic_checker as basic_checker
from . import valid_xml_document as valid_xml_document
from . import root_tag_is_opendrive as root_tag_is_opendrive
from . import fileheader_is_present as fileheader_is_present
Expand Down
67 changes: 0 additions & 67 deletions qc_opendrive/checks/basic/basic_checker.py

This file was deleted.

1 change: 0 additions & 1 deletion qc_opendrive/checks/basic/basic_constants.py

This file was deleted.

Loading