Skip to content

Commit

Permalink
feat(lanelet2_map_validator): add validator to check whether intersec…
Browse files Browse the repository at this point in the history
…tion lanelets have valid turn_direction tags (#186)

* Added validator which checks the "turn_direction" tag in intersection_areas

Signed-off-by: TaikiYamada4 <taiki.yamada@tier4.jp>

* Added test code for mapping.intersection.turn_direction_tagging

Signed-off-by: TaikiYamada4 <taiki.yamada@tier4.jp>

* Added document for mapping.intersection.turn_direction_tagging

Signed-off-by: TaikiYamada4 <taiki.yamada@tier4.jp>

* Added mapping.intersection.turn_direction_tagging to autoware_requirement_set.json

Signed-off-by: TaikiYamada4 <taiki.yamada@tier4.jp>

* Fixed spelling errors

Signed-off-by: TaikiYamada4 <taiki.yamada@tier4.jp>

* Removed crosswalk boundaries from test map

Signed-off-by: TaikiYamada4 <taiki.yamada@tier4.jp>

---------

Signed-off-by: TaikiYamada4 <taiki.yamada@tier4.jp>
  • Loading branch information
TaikiYamada4 authored Jan 14, 2025
1 parent efcedc2 commit 6883c3d
Show file tree
Hide file tree
Showing 7 changed files with 6,039 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@
}
]
},
{
"id": "vm-03-02",
"validators": [
{
"name": "mapping.intersection.turn_direction_tagging"
}
]
},
{
"id": "vm-03-08",
"validators": [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# turn_direction_tagging

## Validator name

mapping.intersection.turn_direction_tagging

## Feature

This validator checks whether lanelets inside the `intersection_area` polygon have a `turn_direction` tag and it is set to "straight", "left", or "right".

The validator will output the following issues with the corresponding primitive ID.

| Issue Code | Message | Severity | Primitive | Description | Approach |
| ------------------------------------- | ---------------------------------------------------- | -------- | --------- | ------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Intersection.TurnDirectionTagging-001 | "This lanelet is missing a turn_direction tag." | Error | Lanelet | Lanelets at intersections must have a `turn_direction` tag but this lanelet doesn't have it. | Set a `turn_direction` tag to the lanelet with a value of `straight`, `left` or `right`. This tells the vehicle whether to use the blinkers or not at intersections. |
| Intersection.TurnDirectionTagging-002 | "Invalid turn_direction tag <INVALID_TAG> is found." | Error | Lanelet | The `turn_direction` tag of this lanelet is set to <INVALID_TAG> while it has to be `straight`, `left` or `right`. | Fix the tag value to `straight`, `left` or `right`. |

## Related source codes

- turn_direction_tagging.cpp
- turn_direction_tagging.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2025 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__TURN_DIRECTION_TAGGING_HPP_ // NOLINT
#define LANELET2_MAP_VALIDATOR__VALIDATORS__INTERSECTION__TURN_DIRECTION_TAGGING_HPP_ // NOLINT

#include <lanelet2_validation/Validation.h>
#include <lanelet2_validation/ValidatorFactory.h>

namespace lanelet::autoware::validation
{
class IntersectionTurnDirectionTaggingValidator : public lanelet::validation::MapValidator
{
public:
constexpr static const char * name() { return "mapping.intersection.turn_direction_tagging"; }

lanelet::validation::Issues operator()(const lanelet::LaneletMap & map) override;

private:
lanelet::validation::Issues checkTurnDirectionTagging(const lanelet::LaneletMap & map);
bool lanelet_is_within_intersection_area2d(
const lanelet::BasicPolygon2d & intersection_area2d, const lanelet::ConstLanelet & lanelet);
};
} // namespace lanelet::autoware::validation

// clang-format off
#endif // LANELET2_MAP_VALIDATOR__VALIDATORS__INTERSECTION__TURN_DIRECTION_TAGGING_HPP_ // NOLINT
// clang-format on
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright 2025 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/turn_direction_tagging.hpp"

#include "lanelet2_map_validator/utils.hpp"

#include <boost/geometry/geometry.hpp>

#include <lanelet2_core/LaneletMap.h>
#include <lanelet2_core/geometry/Polygon.h>
#include <lanelet2_core/primitives/BoundingBox.h>
#include <lanelet2_core/primitives/Polygon.h>

#include <set>
#include <string>

namespace lanelet::autoware::validation
{
namespace
{
lanelet::validation::RegisterMapValidator<IntersectionTurnDirectionTaggingValidator> reg;
}

lanelet::validation::Issues IntersectionTurnDirectionTaggingValidator::operator()(
const lanelet::LaneletMap & map)
{
lanelet::validation::Issues issues;

lanelet::autoware::validation::appendIssues(issues, checkTurnDirectionTagging(map));

return issues;
}

lanelet::validation::Issues IntersectionTurnDirectionTaggingValidator::checkTurnDirectionTagging(
const lanelet::LaneletMap & map)
{
lanelet::validation::Issues issues;
const std::set<std::string> direction_set = {"left", "straight", "right"};

for (const lanelet::ConstPolygon3d & polygon3d : map.polygonLayer) {
if (
!polygon3d.hasAttribute(lanelet::AttributeName::Type) ||
polygon3d.attribute(lanelet::AttributeName::Type).value() != "intersection_area") {
continue;
}

lanelet::BasicPolygon2d intersection_area2d = lanelet::traits::toBasicPolygon2d(polygon3d);
lanelet::BoundingBox2d bbox2d = lanelet::geometry::boundingBox2d(intersection_area2d);
lanelet::ConstLanelets nearby_lanelets = map.laneletLayer.search(bbox2d);

for (const auto & lane : nearby_lanelets) {
// Skip lanelets that are not roads and not inside the intersection_area
if (
!lane.hasAttribute(lanelet::AttributeName::Subtype) ||
lane.attribute(lanelet::AttributeName::Subtype).value() !=
lanelet::AttributeValueString::Road) {
continue;
}
if (!lanelet_is_within_intersection_area2d(intersection_area2d, lane)) {
continue;
}

if (!lane.hasAttribute("turn_direction")) {
issues.emplace_back(
lanelet::validation::Severity::Error, lanelet::validation::Primitive::Lanelet, lane.id(),
append_issue_code_prefix(
this->name(), 1, "This lanelet is missing a turn_direction tag."));
continue;
}

std::string turn_direction = lane.attribute("turn_direction").value();
if (direction_set.find(turn_direction) == direction_set.end()) {
issues.emplace_back(
lanelet::validation::Severity::Error, lanelet::validation::Primitive::Lanelet, lane.id(),
append_issue_code_prefix(
this->name(), 2, "Invalid turn_direction tag \"" + turn_direction + "\" is found."));
}
}
}

return issues;
}

bool IntersectionTurnDirectionTaggingValidator::lanelet_is_within_intersection_area2d(
const lanelet::BasicPolygon2d & intersection_area2d, const lanelet::ConstLanelet & lanelet)
{
for (const auto & left_point : lanelet.leftBound2d()) {
if (!boost::geometry::covered_by(left_point.basicPoint(), intersection_area2d)) {
return false;
}
}
for (const auto & right_point : lanelet.rightBound2d()) {
if (!boost::geometry::covered_by(right_point.basicPoint(), intersection_area2d)) {
return false;
}
}
return true;
}

} // namespace lanelet::autoware::validation
Loading

0 comments on commit 6883c3d

Please sign in to comment.