From 1ccfdf1ffe2ca89502ecccf3c1a25742ebdffaf5 Mon Sep 17 00:00:00 2001 From: Mamoru Sobue Date: Wed, 25 Dec 2024 12:02:48 +0900 Subject: [PATCH] feat(autoware_lanelet_map_validator): add dangling reference checker to non existing intersection_area (#177) Signed-off-by: Mamoru Sobue --- .../CMakeLists.txt | 1 + map/autoware_lanelet2_map_validator/README.md | 2 +- .../autoware_requirement_set.json | 8 + .../intersection_area_dangling_reference.md | 27 + .../intersection_area_dangling_reference.hpp | 51 + .../intersection_area_dangling_reference.cpp | 91 + ...ersection_area_with_dangling_reference.osm | 2988 +++++++++++++++++ ...t_intersection_area_dangling_reference.cpp | 63 + 8 files changed, 3230 insertions(+), 1 deletion(-) create mode 100644 map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_dangling_reference.md create mode 100644 map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validators/intersection/intersection_area_dangling_reference.hpp create mode 100644 map/autoware_lanelet2_map_validator/src/validators/intersection/intersection_area_dangling_reference.cpp create mode 100644 map/autoware_lanelet2_map_validator/test/data/map/intersection/intersection_area_with_dangling_reference.osm create mode 100644 map/autoware_lanelet2_map_validator/test/src/test_intersection_area_dangling_reference.cpp diff --git a/map/autoware_lanelet2_map_validator/CMakeLists.txt b/map/autoware_lanelet2_map_validator/CMakeLists.txt index 691821ee..80af8e75 100644 --- a/map/autoware_lanelet2_map_validator/CMakeLists.txt +++ b/map/autoware_lanelet2_map_validator/CMakeLists.txt @@ -67,6 +67,7 @@ if(BUILD_TESTING) add_validation_test(missing_referrers_for_traffic_lights) add_validation_test(intersection_area_validity) add_validation_test(intersection_area_segment_type) + add_validation_test(intersection_area_dangling_reference) endif() ament_auto_package( diff --git a/map/autoware_lanelet2_map_validator/README.md b/map/autoware_lanelet2_map_validator/README.md index e78ff02a..f1b2833f 100644 --- a/map/autoware_lanelet2_map_validator/README.md +++ b/map/autoware_lanelet2_map_validator/README.md @@ -319,7 +319,7 @@ The "Validators" column will be blank if it hasn't be implemented. | vm-01-19 | Walkway | | | vm-02-01 | Stop line alignment | (Not detectable) | | vm-02-02 | Stop sign | [mapping.stop_line.missing_regulatory_elements](./docs/stop_line/missing_regulatory_elements_for_stop_lines.md) | -| vm-03-01 | Intersection criteria | | +| vm-03-01 | Intersection criteria | [mapping.intersection.intersection_area_dangling_reference](./docs/intersection/intersection_area_dangling_reference.md) | | vm-03-02 | Lanelet's turn direction and virtual | | | vm-03-03 | Lanelet width in the intersection | | | vm-03-04 | Lanelet creation in the intersection | | diff --git a/map/autoware_lanelet2_map_validator/autoware_requirement_set.json b/map/autoware_lanelet2_map_validator/autoware_requirement_set.json index 74185b48..4b8566f7 100644 --- a/map/autoware_lanelet2_map_validator/autoware_requirement_set.json +++ b/map/autoware_lanelet2_map_validator/autoware_requirement_set.json @@ -8,6 +8,14 @@ } ] }, + { + "id": "vm-03-01", + "validators": [ + { + "name": "mapping.intersection.intersection_area_dangling_reference" + } + ] + }, { "id": "vm-03-08", "validators": [ diff --git a/map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_dangling_reference.md b/map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_dangling_reference.md new file mode 100644 index 00000000..ab77f8e6 --- /dev/null +++ b/map/autoware_lanelet2_map_validator/docs/intersection/intersection_area_dangling_reference.md @@ -0,0 +1,27 @@ +# intersection_area_dangling_reference + +## Validator name + +mapping.intersection.intersection_area_dangling_reference + +## Feature + +This validator checks whether each intersection lanelet(namely the lanelet with `turn_direction` property) has reference to existing `intersection_area` polygon. Such invalid case occurs when an intersection_area is deleted but its referrers are not updated. + +This is achieved by the following procedure. + +1. Obtain the set of `intersection_area` polygon IDs +2. Check if intersection lanelet has "intersection_area" key and its value is contained in the above IDs + +The validator outputs the following issue with the corresponding ID of the primitive. + +| Issue Code | Message | Severity | Primitive | Description | Approach | +| -------------------------------------------------- | --------------------------------------------------------------------------------------- | -------- | --------- | -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | +| Intersection.IntersectionAreaDanglingReference-001 | "Dangling reference to non-existing intersection area of ID \ is detected" | Error | Lanelet | The reported lanelet will cause a runtime error when attempting to look up the non-existent intersection_area. | Go to the reported lanelet and delete "intersection_area" key entry. | + +### Supplementary information + +## Related source codes + +- intersection_area_dangling_reference.hpp +- intersection_area_dangling_reference.cpp diff --git a/map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validators/intersection/intersection_area_dangling_reference.hpp b/map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validators/intersection/intersection_area_dangling_reference.hpp new file mode 100644 index 00000000..f9a24c28 --- /dev/null +++ b/map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validators/intersection/intersection_area_dangling_reference.hpp @@ -0,0 +1,51 @@ +// Copyright 2024 Autoware Foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef LANELET2_MAP_VALIDATOR__VALIDATORS__INTERSECTION__INTERSECTION_AREA_DANGLING_REFERENCE_HPP_ // NOLINT +#define LANELET2_MAP_VALIDATOR__VALIDATORS__INTERSECTION__INTERSECTION_AREA_DANGLING_REFERENCE_HPP_ // NOLINT + +#include +#include + +#include +#include + +namespace lanelet::autoware::validation +{ +class IntersectionAreaDanglingReferenceValidator : public lanelet::validation::MapValidator +{ +public: + constexpr static const char * name() + { + return "mapping.intersection.intersection_area_dangling_reference"; + } + + lanelet::validation::Issues operator()(const lanelet::LaneletMap & map) override; + +private: + /** + * @brief queries all intersection lanelets and check if their "intersection_area" custom KEY + * entry has existing id as VALUE + * + * @param map + * @return lanelet::validation::Issues + */ + lanelet::validation::Issues check_intersection_area_dangling_reference( + const lanelet::LaneletMap & map); +}; +} // namespace lanelet::autoware::validation + +// clang-format off +#endif // LANELET2_MAP_VALIDATOR__VALIDATORS__INTERSECTION__INTERSECTION_AREA_DANGLING_REFERENCE_HPP_ // NOLINT +// clang-format on diff --git a/map/autoware_lanelet2_map_validator/src/validators/intersection/intersection_area_dangling_reference.cpp b/map/autoware_lanelet2_map_validator/src/validators/intersection/intersection_area_dangling_reference.cpp new file mode 100644 index 00000000..a3cbeb19 --- /dev/null +++ b/map/autoware_lanelet2_map_validator/src/validators/intersection/intersection_area_dangling_reference.cpp @@ -0,0 +1,91 @@ +// Copyright 2024 Autoware Foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "lanelet2_map_validator/validators/intersection/intersection_area_dangling_reference.hpp" + +#include "lanelet2_map_validator/utils.hpp" + +#include + +#include +#include +#include +#include + +namespace lanelet::autoware::validation +{ + +namespace +{ +lanelet::validation::RegisterMapValidator reg; +} // namespace + +lanelet::validation::Issues IntersectionAreaDanglingReferenceValidator::operator()( + const lanelet::LaneletMap & map) +{ + lanelet::validation::Issues issues; + + lanelet::autoware::validation::appendIssues( + issues, check_intersection_area_dangling_reference(map)); + + return issues; +} + +lanelet::validation::Issues +IntersectionAreaDanglingReferenceValidator::check_intersection_area_dangling_reference( + const lanelet::LaneletMap & map) +{ + // returns the VALUE of intersection_area key + auto is_intersection_with_area = [](const auto & lanelet) -> std::optional { + if (lanelet.attributeOr("turn_direction", "none") == std::string("none")) { + return std::nullopt; + } + + const std::string id_str = lanelet.attributeOr("intersection_area", "none"); + if (id_str == std::string("none")) { + return std::nullopt; + } + + const auto id = static_cast(std::atoi(id_str.c_str())); + return id; + }; + + std::unordered_set intersection_area_ids; + for (const auto & area : map.polygonLayer) { + if ( + area.attributeOr(lanelet::AttributeName::Type, "none") == std::string("intersection_area")) { + intersection_area_ids.emplace(area.id()); + } + } + + lanelet::validation::Issues issues; + for (const auto & lanelet : map.laneletLayer) { + if (const auto id_opt = is_intersection_with_area(lanelet); id_opt) { + const auto id = id_opt.value(); + if (intersection_area_ids.find(id) == intersection_area_ids.end()) { + issues.emplace_back( + lanelet::validation::Severity::Error, lanelet::validation::Primitive::Lanelet, + lanelet.id(), + append_issue_code_prefix( + this->name(), 1, + "Dangling reference to non-existing intersection area of ID " + std::to_string(id) + + " is detected")); + } + } + } + + return issues; +} + +} // namespace lanelet::autoware::validation diff --git a/map/autoware_lanelet2_map_validator/test/data/map/intersection/intersection_area_with_dangling_reference.osm b/map/autoware_lanelet2_map_validator/test/data/map/intersection/intersection_area_with_dangling_reference.osm new file mode 100644 index 00000000..ccb148db --- /dev/null +++ b/map/autoware_lanelet2_map_validator/test/data/map/intersection/intersection_area_with_dangling_reference.osm @@ -0,0 +1,2988 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/map/autoware_lanelet2_map_validator/test/src/test_intersection_area_dangling_reference.cpp b/map/autoware_lanelet2_map_validator/test/src/test_intersection_area_dangling_reference.cpp new file mode 100644 index 00000000..bd81497d --- /dev/null +++ b/map/autoware_lanelet2_map_validator/test/src/test_intersection_area_dangling_reference.cpp @@ -0,0 +1,63 @@ +// Copyright 2024 Autoware Foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "lanelet2_map_validator/validators/intersection/intersection_area_dangling_reference.hpp" +#include "map_validation_tester.hpp" + +#include +#include + +#include + +class TestIntersectionAreaDanglingReference : public MapValidationTester +{ +}; + +TEST_F(TestIntersectionAreaDanglingReference, ValidatorAvailability) // NOLINT for gtest +{ + std::string expected_validator_name = + lanelet::autoware::validation::IntersectionAreaDanglingReferenceValidator::name(); + + lanelet::validation::Strings validators = + lanelet::validation::availabeChecks(expected_validator_name); // cspell:disable-line + + const uint32_t expected_validator_num = 1; + EXPECT_EQ(expected_validator_num, validators.size()); + EXPECT_EQ(expected_validator_name, validators[0]); +} + +TEST_F(TestIntersectionAreaDanglingReference, ValidateDanglingReference) // NOLINT for gtest +{ + load_target_map("intersection/intersection_area_with_dangling_reference.osm"); + lanelet::autoware::validation::IntersectionAreaDanglingReferenceValidator checker; + const auto & issues = checker(*map_); + + EXPECT_EQ(issues.size(), 1); + EXPECT_EQ(issues[0].id, 53); + EXPECT_EQ(issues[0].severity, lanelet::validation::Severity::Error); + EXPECT_EQ(issues[0].primitive, lanelet::validation::Primitive::Lanelet); + EXPECT_EQ( + issues[0].message, + "[Intersection.IntersectionAreaDanglingReference-001] Dangling " + "reference to non-existing intersection area of ID 777 is detected"); +} + +TEST_F(TestIntersectionAreaDanglingReference, ValidIntersectionArea) // NOLINT for gtest +{ + load_target_map("intersection/basic_intersection_area.osm"); + lanelet::autoware::validation::IntersectionAreaDanglingReferenceValidator checker; + const auto & issues = checker(*map_); + + EXPECT_EQ(issues.size(), 0); +}