diff --git a/map/autoware_lanelet2_map_validator/CMakeLists.txt b/map/autoware_lanelet2_map_validator/CMakeLists.txt index 36776605..3d5e1789 100644 --- a/map/autoware_lanelet2_map_validator/CMakeLists.txt +++ b/map/autoware_lanelet2_map_validator/CMakeLists.txt @@ -31,6 +31,11 @@ target_link_libraries(autoware_lanelet2_map_validator autoware_lanelet2_map_validator_lib ) +install(PROGRAMS + template/create_new_validator.py + DESTINATION lib/${PROJECT_NAME} +) + if(BUILD_TESTING) file(GLOB_RECURSE test_src "test/src/test_*.cpp") ament_auto_add_library(autoware_lanelet2_map_validator_test_lib ${test_src}) diff --git a/map/autoware_lanelet2_map_validator/docs/how_to_contribute.md b/map/autoware_lanelet2_map_validator/docs/how_to_contribute.md index 8f097c10..6689b2ee 100644 --- a/map/autoware_lanelet2_map_validator/docs/how_to_contribute.md +++ b/map/autoware_lanelet2_map_validator/docs/how_to_contribute.md @@ -37,7 +37,51 @@ This section is aimed at contributors who want to add their own validators. If y -Contributors are encouraged to make their validators by following the class structure shown in [`validator_template.cpp`](https://github.com/autowarefoundation/autoware_tools/blob/main/map/autoware_lanelet2_map_validator/src/validators/validator_template.cpp) and [`validator_template.hpp`](https://github.com/autowarefoundation/autoware_tools/blob/main/map/autoware_lanelet2_map_validator/src/validators/validator_template.hpp). Looking at other implementations may also be helpful. +Contributors are encouraged to make their validators by following the class structure shown in [`validator_template.cpp`](https://github.com/autowarefoundation/autoware_tools/blob/main/map/autoware_lanelet2_map_validator/template/validator_template.cpp) and [`validator_template.hpp`](https://github.com/autowarefoundation/autoware_tools/blob/main/map/autoware_lanelet2_map_validator/template/validator_template.hpp). + +#### `create_new_validator.py` may be useful + +You can use the script [`create_new_validator.py`](https://github.com/autowarefoundation/autoware_tools/blob/main/map/autoware_lanelet2_map_validator/template/create_new_validator.py) to generate the required files below. + +- Source codes (cpp and hpp) +- Test code (cpp) +- Document file (md) + +You can use this by the command like this example: + +```shell +create_new_validator.py \ +--base_directory ./ \ +--category_name traffic_light \ +--code_name traffic_light_facing \ +--class_name TrafficLightFacingValidator \ +--validator_name mapping.traffic_light.correct_facing \ +--check_function_name check_traffic_light_facing +``` + +OR + +```shell +ros2 run autoware_lanelet2_map_validator create_new_validator.py \ +--base_directory ./ \ +--category_name traffic_light \ +--code_name traffic_light_facing \ +--class_name TrafficLightFacingValidator \ +--validator_name mapping.traffic_light.correct_facing \ +--check_function_name check_traffic_light_facing +``` + +All arguments are required. + +- `--base_directory`: The directory to the `autoware_lanelet2_map_validator` package. +- `--category_name`: The category (like lanelet, traffic_light...) where your validator belongs to. Look [Design Concept](#design-concept) to see the list of categories. +- `--code_name`: The name for the files. The source code names will be like `.cpp` and `` +- `--class_name`: The base class name of your validator which will be defined in your new header file. +- `--validator_name`: The name of the validator which will be displayed when `autoware_lanelet2_map_validator` is executed with a `--print` option. The naming rules are explained in [Restrictions for validator class implementation](#restrictions-for-validator-class-implementation). +- `--check_function_name`: The main function name of your validator which will be defined in your header file, and its implementation will be written in the cpp source file. + +It may be quicker to recognize what this script do by trying the command out. +If you feel typing these arguments exhausting, you can overwrite the `default` value in the python script, but do not forget not to commit those changes. #### Restrictions for path structure diff --git a/map/autoware_lanelet2_map_validator/template/create_new_validator.py b/map/autoware_lanelet2_map_validator/template/create_new_validator.py new file mode 100755 index 00000000..da64764e --- /dev/null +++ b/map/autoware_lanelet2_map_validator/template/create_new_validator.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 + +# Copyright 2024 TIER IV, Inc. All rights reserved. +# +# 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. + +import argparse +import os +import shutil + + +def create_files( + base_directory, category_name, code_name, class_name, validator_name, check_function_name +): + # Define directories + template_directory = os.path.join(base_directory, "template") + src_directory = os.path.join(base_directory, "src/validators", category_name) + include_directory = os.path.join( + base_directory, "src/include/lanelet2_map_validator/validators", category_name + ) + docs_directory = os.path.join(base_directory, "docs", category_name) + test_directory = os.path.join(base_directory, "test/src", category_name) + + # Define source and destination file paths + cpp_template = os.path.join(template_directory, "validator_template.cpp") + hpp_template = os.path.join(template_directory, "validator_template.hpp") + test_template = os.path.join(template_directory, "test_validator_template.cpp") + docs_template = os.path.join(template_directory, "validator_template.md") + cpp_new = os.path.join(src_directory, f"{code_name}.cpp") + print("Create " + cpp_new) + hpp_new = os.path.join(include_directory, f"{code_name}.hpp") + print("Create " + hpp_new) + test_new = os.path.join(test_directory, f"test_{code_name}.cpp") + print("Create " + test_new) + docs_new = os.path.join(docs_directory, f"{code_name}.md") + print("Create " + docs_new) + + # Copy template files + shutil.copy(cpp_template, cpp_new) + shutil.copy(hpp_template, hpp_new) + shutil.copy(test_template, test_new) + shutil.copy(docs_template, docs_new) + + # This is only for documents!! + with open(docs_new, "r") as file: + content = file.read() + content = content.replace("validator_template", code_name) + with open(docs_new, "w") as file: + file.write(content) + + # Replace class name in the new files + for file_path in [cpp_new, hpp_new, test_new, docs_new]: + with open(file_path, "r") as file: + content = file.read() + # Replace the class name + content = content.replace("ValidatorTemplate", class_name) + content = content.replace("mapping.validator.template", validator_name) + content = content.replace("checkFunction", check_function_name) + content = content.replace( + "validator_template.hpp", + "lanelet2_map_validator/validators/" + category_name + "/" + code_name + ".hpp", + ) + content = content.replace( + "MAP__AUTOWARE_LANELET2_MAP_VALIDATOR__TEMPLATE__VALIDATOR_TEMPLATE_HPP_", + "LANELET2_MAP_VALIDATOR__VALIDATORS__" + + category_name.upper() + + "__" + + code_name.upper() + + "_HPP_", + ) + with open(file_path, "w") as file: + file.write(content) + + +if __name__ == "__main__": + # Arguments + parser = argparse.ArgumentParser(description="Generate files for a new validator.") + parser.add_argument( + "--base_directory", default="./", help="Path to the autoware_lanelet2_map_validator package" + ) + parser.add_argument( + "--category_name", default="enter_category", help="Category name of the validator" + ) + parser.add_argument( + "--code_name", + default="enter_code_name", + help="Code name for the validator files (e.g. code_name.cpp, code_name.hpp)", + ) + parser.add_argument( + "--class_name", default="EnterClassNameValidator", help="Class name for the validator" + ) + parser.add_argument( + "--validator_name", + default="mapping.category.something", + help="Full validator name (e. g. mapping.category.something)", + ) + parser.add_argument( + "--check_function_name", + default="enter_function_name", + help="Check function name for the validator", + ) + + args = parser.parse_args() + + # User-defined parameters + directory_path = args.base_directory # Replace with package directory path + category_name = args.category_name + code_name = args.code_name + class_name = args.class_name + validator_name = args.validator_name + check_function_name = args.check_function_name + + create_files( + directory_path, category_name, code_name, class_name, validator_name, check_function_name + ) + print("Process complete.") diff --git a/map/autoware_lanelet2_map_validator/template/test_validator_template.cpp b/map/autoware_lanelet2_map_validator/template/test_validator_template.cpp new file mode 100644 index 00000000..23a4000a --- /dev/null +++ b/map/autoware_lanelet2_map_validator/template/test_validator_template.cpp @@ -0,0 +1,48 @@ +// 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 "map_validation_tester.hpp" +#include "validator_template.hpp" + +#include +#include + +#include + +class TestValidatorTemplate : public MapValidationTester +{ +private: +}; + +TEST_F(TestValidatorTemplate, ValidatorAvailability) // NOLINT for gtest +{ + std::string expected_validator_name = lanelet::autoware::validation::ValidatorTemplate::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(TestValidatorTemplate, SampleMap) // NOLINT for gtest +{ + load_target_map("sample_map.osm"); + + lanelet::autoware::validation::ValidatorTemplate checker; + const auto & issues = checker(*map_); + + EXPECT_EQ(issues.size(), 0); +} diff --git a/map/autoware_lanelet2_map_validator/src/validators/validator_template.cpp b/map/autoware_lanelet2_map_validator/template/validator_template.cpp similarity index 77% rename from map/autoware_lanelet2_map_validator/src/validators/validator_template.cpp rename to map/autoware_lanelet2_map_validator/template/validator_template.cpp index c444a046..5ed7ad65 100644 --- a/map/autoware_lanelet2_map_validator/src/validators/validator_template.cpp +++ b/map/autoware_lanelet2_map_validator/template/validator_template.cpp @@ -14,6 +14,8 @@ #include "validator_template.hpp" +#include "lanelet2_map_validator/utils.hpp" + namespace lanelet::autoware::validation { namespace @@ -25,7 +27,15 @@ lanelet::validation::Issues ValidatorTemplate::operator()(const lanelet::Lanelet { lanelet::validation::Issues issues; - // Remove this line and write down how to append issues + lanelet::autoware::validation::appendIssues(issues, checkFunction(map)); + + return issues; +} + +lanelet::validation::Issues ValidatorTemplate::checkFunction(const lanelet::LaneletMap & map) +{ + lanelet::validation::Issues issues; + (void)map; return issues; diff --git a/map/autoware_lanelet2_map_validator/src/validators/validator_template.hpp b/map/autoware_lanelet2_map_validator/template/validator_template.hpp similarity index 76% rename from map/autoware_lanelet2_map_validator/src/validators/validator_template.hpp rename to map/autoware_lanelet2_map_validator/template/validator_template.hpp index 1b4507ab..25b37e25 100644 --- a/map/autoware_lanelet2_map_validator/src/validators/validator_template.hpp +++ b/map/autoware_lanelet2_map_validator/template/validator_template.hpp @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef VALIDATORS__VALIDATOR_TEMPLATE_HPP_ -#define VALIDATORS__VALIDATOR_TEMPLATE_HPP_ +#ifndef MAP__AUTOWARE_LANELET2_MAP_VALIDATOR__TEMPLATE__VALIDATOR_TEMPLATE_HPP_ +#define MAP__AUTOWARE_LANELET2_MAP_VALIDATOR__TEMPLATE__VALIDATOR_TEMPLATE_HPP_ #include #include @@ -29,7 +29,8 @@ class ValidatorTemplate : public lanelet::validation::MapValidator lanelet::validation::Issues operator()(const lanelet::LaneletMap & map) override; private: + lanelet::validation::Issues checkFunction(const lanelet::LaneletMap & map); }; } // namespace lanelet::autoware::validation -#endif // VALIDATORS__VALIDATOR_TEMPLATE_HPP_ +#endif // MAP__AUTOWARE_LANELET2_MAP_VALIDATOR__TEMPLATE__VALIDATOR_TEMPLATE_HPP_ diff --git a/map/autoware_lanelet2_map_validator/template/validator_template.md b/map/autoware_lanelet2_map_validator/template/validator_template.md new file mode 100644 index 00000000..5e5f81ab --- /dev/null +++ b/map/autoware_lanelet2_map_validator/template/validator_template.md @@ -0,0 +1,18 @@ +# validator_template + +## Validator name + +mapping.validator.template + +## Feature + +Feature explanation here. + +| Issue Code | Message | Severity | Description | Approach | +| ---------- | ------- | -------- | ----------- | -------- | +| | | | | | + +## Related source codes + +- validator_template.cpp +- validator_template.hpp