diff --git a/common/autoware_lanelet2_utility/README.md b/common/autoware_lanelet2_utility/README.md index 89de145ba..2c2955a3f 100644 --- a/common/autoware_lanelet2_utility/README.md +++ b/common/autoware_lanelet2_utility/README.md @@ -2,29 +2,153 @@ ## Nomenclature -This package aims to strictly define the meaning of several words To disambiguate the documentation and API's scope. In the table below, `codespace` words are given specific meanings when used in API and API description. _italic_ words are emphasized to indicate that it refers to social common sense which often comes with ambiguity. To help clarify the meaning, illustration is provided. "Lanelet" refers to the entity of a`lanelet::Lanelet` object in order to distinguish with the word "lane" used in social customs. `A` and `B` stands for Lanelets objects. - -| Word | Meaning | Illustration | -| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `driving` | The vehicle position belongs to the designated Lanelet. | In each map, green Lanelet are the `driving` lanes of the vehicle.
![driving](./media/nomenclature/driving.drawio.svg) | -| `boundary`,
`entry`,
`exit` | The `boundary` of a Lanelet refers to the left or right Linestring. | ![boundary_entry_exit](./media/nomenclature/boundary_entry_exit.drawio.svg) | -| `adjacent` | If A is `adjacent` to B, A and B share a common `boundary` with same direction either on the left or right side. | In each map, orange Lanelet is `adjacent` to green Lanelet.
![adjacent](./media/nomenclature/adjacent.drawio.svg) | -| `same_direction` | Lanelet A and Lanelet B are `same_direction` if A and B are directly or indirectly `adjacent` to each other. | In each map, orange Lanelets are `same_dirction` as green Lanelet.
![same_direction](./media/nomenclature/same_direction.drawio.svg) | -| `bundle` | A `bundle` refers to a transitive closure set of Lanelets which are `same_direction` to each other. | The enclosed sets of Lanelets are `bundle`s.
![bundle](./media/nomenclature/bundle.drawio.svg) | -| `opposite` | If A is `opposite` to B, A and B share a common `boundary` with opposite direction. | In the first map, green Lanelet and orange Lanelet are `opposite` to each other.
In the second map, two red Lanelets are not `opposite` relation because they do not share a common LineString.
![opposite](./media/nomenclature/opposite.drawio.svg) | -| `opposite_direction` | If A and B are `opposite_direction`, the bundle of A and B are directly `opposite` to each other. | In the each map, green Lanelet and orange Lanelet are `opposite_direction` becauase their `bundle`s(enclosed in dotted line) are `opposite` relation.
![opposite_direction](./media/nomenclature/opposite_direction.drawio.svg) | -| `connected` | A is `connected` to(from) B if and only if the `exit`(`entry`) of A is identical to the `entry`(`exit`) of B. | A is connected to B, and B is connected from A.
![connected](./media/nomenclature/connected.drawio.svg) | -| `following` | The `following` Lanelets of A is the list of Lanelets to which A is `connected`. | In each map, orange Lanelets are the `following` of green Lanelet.
![following](./media/nomenclature/following.drawio.svg) | -| `previous` | The `previous` Lanelets of A is the list of Lanelets from which A is `connected`. | In each map, orange Lanelets are the `previous` of green Lanelet.
![previous](./media/nomenclature/previous.drawio.svg) | -| `conflicting` | A is `conflicting` with B if A and B are geometrically intersecting. | | -| `merging` | A is said to be `merging` Lanelet of B if and only if A is `conflicting` with B and both A and B are connected to a common Lanelet. | In each map, one of the orange Lanelet is a `mergin` Lanelet of the other orange Lanelet.
![merging](./media/nomenclature/merging.drawio.svg) | -| `sibling` | The designated Lanelets are refered to as `sibling` if all of them are `connected` from a common Lanelet. | In each map, orange Lanelets are `sibling`s.
![sibling](./media/nomenclature/sibling.drawio.svg) | -| `oncoming` | TBD | TBD | -| `upcoming` | TBD | TBD | -| `sequence` | `sequence` is a list of Lanelets whose each element is `connected from` or `adjacent to` the previous element. | ![sequence](./media/nomenclature/sequence.drawio.svg) | +This package aims to strictly define the meaning of several words to clarify the documentation and API's scope. In the table below, `codespace` words are given specific meanings when used in the API and API description. _italic_ words are emphasized to indicate that it refers to social common sense which often comes with ambiguity. To help disambiguate the meaning, illustration is provided. "Lanelet" refers to the entity of a`lanelet::ConstLanelet` object in order to distinguish with the word "lane" used in social customs. `A` and `B` stands for some Lanelets objects. + +| Word | Meaning | Illustration | +| :-------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| `driving` | The vehicle position belongs to the designated Lanelet. | In each map, green Lanelet are the `driving` lanes of the vehicle.
![driving](./media/nomenclature/driving.drawio.svg) | +| `boundary`,
`entry`,
`exit` | The `boundary` of a Lanelet refers to the left or right Linestring. | ![boundary_entry_exit](./media/nomenclature/boundary_entry_exit.drawio.svg) | +| `adjacent` | If A is `adjacent` to B, A and B share a common `boundary` with same direction either on the left or right side. | In each map, orange Lanelet is `adjacent` to green Lanelet.
![adjacent](./media/nomenclature/adjacent.drawio.svg) | +| `same_direction` | Lanelet A and Lanelet B are `same_direction` if A and B are directly or indirectly `adjacent` to each other. | In each map, orange Lanelets are `same_direction` as green Lanelet.
![same_direction](./media/nomenclature/same_direction.drawio.svg) | +| `bundle` | A `bundle` refers to a transitive closure set of Lanelets which are `same_direction` to each other. | The enclosed sets of Lanelets are `bundle`s.
![bundle](./media/nomenclature/bundle.drawio.svg) | +| `opposite` | If A is `opposite` to B, A and B share a common `boundary` with opposite direction. | In the first map, green Lanelet and orange Lanelet are `opposite` to each other.
In the second map, two red Lanelets are not `opposite` relation because they do not share a common LineString.
![opposite](./media/nomenclature/opposite.drawio.svg) | +| `opposite_direction` | If A and B are `opposite_direction`, the `bundle` of A and B are directly `opposite` to each other. | In the each map, green Lanelet and orange Lanelet are `opposite_direction` because their `bundle`s(enclosed in dotted line) are `opposite` relation.
![opposite_direction](./media/nomenclature/opposite_direction.drawio.svg) | +| `connected` | A is `connected` to(from) B if and only if the `exit`(`entry`) of A is identical to the `entry`(`exit`) of B. | A is connected to B, and B is connected from A.
![connected](./media/nomenclature/connected.drawio.svg) | +| `following` | The `following` Lanelets of A is the list of Lanelets to which A is `connected`. | In each map, orange Lanelets are the `following` of green Lanelet.
![following](./media/nomenclature/following.drawio.svg) | +| `previous` | The `previous` Lanelets of A is the list of Lanelets from which A is `connected`. | In each map, orange Lanelets are the `previous` of green Lanelet.
![previous](./media/nomenclature/previous.drawio.svg) | +| `conflicting` | A is `conflicting` with B if A and B are geometrically intersecting. | | +| `merging` | A is said to be `merging` Lanelet of B if and only if A is `conflicting` with B and both A and B are connected to a common Lanelet. | In each map, one of the orange Lanelet is a `merging` Lanelet of the other orange Lanelet.
![merging](./media/nomenclature/merging.drawio.svg) | +| `sibling` | The designated Lanelets are referred to as `sibling` if all of them are `connected` from a common Lanelet. | In each map, orange Lanelets are `sibling`s.
![sibling](./media/nomenclature/sibling.drawio.svg) | +| `oncoming` | TBD | TBD | +| `upcoming` | TBD | TBD | +| `sequence` | `sequence` is a list of Lanelets whose each element is `connected from` or `adjacent to` the previous element. | ![sequence](./media/nomenclature/sequence.drawio.svg) | ## API description +| Header | function | description | average computational complexity | illustration | +| :----------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `` | `is_road_lane` | | $O(1)$ | | +| | `is_shoulder_lane` | | $O(1)$ | | +| | `is_bicycle_lane` | | $O(1)$ | | +| `` | `left_lanelet` | This function ignores the permission of lane change. Also it ignores `shoulder` and `bicycle` Lanelet. | $O(1)$ | In the first map, the green Lanelet is the `left_lanelet` of the orange Lanelet.
In the second and third map, the `left_lanelet` of the orange Lanelet is `null`.
![left_lanelet](./media/api/left_lanelet.drawio.svg) | +| | `right_lanelet` | same as above `left_lanelet` | $O(1)$ | | +| | `left_opposite_lanelet` | same as below `right_opposite_lanelet` | $O(1)$
see [`findUsage`](./#complexity-of-findusage) for detail | | +| | `right_opposite_lanelet` | | $O(1)$
see [`findUsage`](./#complexity-of-findusage) for detail | In the first and second map, the green Lanelet is the `right_opposite_lanelet` of the orange Lanelet.
In the third map, the `right_opposite_lanelet` of the orange Lanelet is `null`.
![right_opposite_lanelet](./media/api/right_opposite_lanelet.drawio.svg) | +| | `leftmost_lanelet` | | $O(W)$ where $W$ is the size of the `bundle`. | In the first and second map, the green Lanelet is the `leftmost_lanelet` of the orange Lanelet.
In the third map, the `leftmost_lanelet` of the orange Lanelet is `null`.
![leftmost_lanelet](./media/api/leftmost_lanelet.drawio.svg) | +| | `rightmost_lanelet` | | $O(W)$ where $W$ is the size of the `bundle`. | In the first map, the green Lanelet is the `rightmost_lanelet` of the orange Lanelet.
In the second and third map, the `rightmost_lanelet` of the orange Lanelet is `null`.
![rightmost_lanelet](./media/api/rightmost_lanelet.drawio.svg) | +| | `left_lanelets` | The input Lanelet is not included in the output. | $O(W)$ where $W$ is the size of the `bundle`. | In the first map, the green Lanelete are the `left_lanelets` of the orange Lanelet.
In the second and third map, `left_lanelets` of the orange Lanelet is empty.
![left_lanelets](./media/api/left_lanelets.drawio.svg) | +| | `right_lanelets` | same as above `left_lanelets`. | $O(W)$ where $W$ is the size of the `bundle.` | In the first map, the green Lanelets are the `right_lanelets` of the orange Lanelet.
In the second and third map, `right_lanelets` of the orange Lanelet is empty.
![right_lanelets](./media/api/right_lanelets.drawio.svg) | + +### complexity of `findUsage` + +The readers should be noted that following description is implementation dependent. + +- [LaneletMap.h](https://github.com/fzi-forschungszentrum-informatik/Lanelet2/blob/d9320cf66698004cd5e57988ac001e02e73e2e40/lanelet2_core/include/lanelet2_core/LaneletMap.h) +- [LaneletMap.cpp](https://github.com/fzi-forschungszentrum-informatik/Lanelet2/blob/d9320cf66698004cd5e57988ac001e02e73e2e40/lanelet2_core/src/LaneletMap.cpp) + +Lanelet map primitives(like `Lanelet`, `Area`, `RegulatoryElement`) are stored in several `PrimitiveLayer` objects according to their types as shown below. + +```cpp title="lanelet2_core/LaneletMap.h#L375-L438" +class LaneletMap : public LaneletMapLayers { + public: + using LaneletMapLayers::LaneletMapLayers; + <...> +}; +``` + +```cpp title="lanelet2_core/LaneletMap.h#L313-L359" +class LaneletMapLayers { + <...> + LaneletLayer laneletLayer; //!< access to the lanelets within this map + AreaLayer areaLayer; //!< access to areas + RegulatoryElementLayer regulatoryElementLayer; //!< access to regElems + PolygonLayer polygonLayer; //!< access to the polygons + LineStringLayer lineStringLayer; //!< access to the lineStrings + PointLayer pointLayer; //!< access to the points +}; +``` + +```cpp title="lanelet2_core/LaneletMap.h#L285-L303" +class LaneletLayer : public PrimitiveLayer { + public: + using PrimitiveLayer::findUsages; + LaneletLayer() = default; + ~LaneletLayer() = default; + LaneletLayer(const LaneletLayer&) = delete; + LaneletLayer operator=(LaneletLayer&) = delete; + Lanelets findUsages(const RegulatoryElementConstPtr& regElem); + ConstLanelets findUsages(const RegulatoryElementConstPtr& regElem) const; + <...> +}; +``` + +Each `PrimitiveLayer` owns a field named `tree_` that contains a lookup table named `usage` of type `UsageLookup`, + +```cpp title="lanelet2_core/LaneletMap.h#L38-L253" +template +class PrimitiveLayer { + public: + <...> + /** + * @brief finds usages of an owned type within this layer + * + * This is the non-const version to find usages of a primitive in a layer. + */ + std::vector findUsages(const traits::ConstPrimitiveType>& primitive); + <...> + struct Tree; + // NOLINTNEXTLINE + std::unique_ptr tree_; //!< Hides boost trees from you/the compiler +``` + +```cpp title="lanelet2_core/src/LaneletMap.cpp#L277-L308" +template +struct PrimitiveLayer::Tree { + using TreeNode = std::pair; + using RTree = bgi::rtree>; + static TreeNode treeNode(const T& elem) { return {geometry::boundingBox2d(to2D(elem)), elem}; } + <...> + RTree rTree; + UsageLookup usage; +}; +``` + +and `UsageLookup` contains reference relation between different types as `std::unordered_multimap`. + +```cpp title="lanelet2_core/src/LaneletMap.cpp#L259-L270" +template <> +struct UsageLookup { + void add(Lanelet ll) { + ownedLookup.insert(std::make_pair(ll.leftBound(), ll)); + ownedLookup.insert(std::make_pair(ll.rightBound(), ll)); + for (const auto& elem : ll.regulatoryElements()) { + regElemLookup.insert(std::make_pair(elem, ll)); + } + } + std::unordered_multimap ownedLookup; + std::unordered_multimap regElemLookup; +}; +``` + +Thus the complexity of `findUsage` function is equal to that of `std::unordered_multimap::equal_range` + +```cpp title="lanelet2_core/src/LaneletMap.cpp#L419-L424" +template +std::vector::ConstPrimitiveT> PrimitiveLayer::findUsages( + const traits::ConstPrimitiveType::PrimitiveT>>& primitive) const { + return forEachMatchInMultiMap::PrimitiveT>>( + tree_->usage.ownedLookup, primitive, [](const auto& elem) { return traits::toConst(elem.second); }); +} +``` + +```cpp title="lanelet2_core/src/LaneletMap.cpp#L165-L169" +template +std::vector forEachMatchInMultiMap(const MapT& map, const KeyT& key, Func&& f) { + auto range = map.equal_range(key); + return utils::transform(range.first, range.second, f); +} +``` + ## How to craft test map On the VMB, create the map in local projector(or convert it to local projector from MGRS projector) and save the file as ``. Next, select the point to use as (0.0, 0.0) and pass its `` and run diff --git a/common/autoware_lanelet2_utility/include/autoware_lanelet2_utility/kind.hpp b/common/autoware_lanelet2_utility/include/autoware_lanelet2_utility/kind.hpp index 1d5225ff4..974a5623d 100644 --- a/common/autoware_lanelet2_utility/include/autoware_lanelet2_utility/kind.hpp +++ b/common/autoware_lanelet2_utility/include/autoware_lanelet2_utility/kind.hpp @@ -19,9 +19,6 @@ namespace autoware::lanelet2_utility { - -inline namespace kind -{ static constexpr const char * k_road_lane_type = "road"; static constexpr const char * k_shoulder_lane_type = "road_shoulder"; static constexpr const char * k_bicycle_lane_type = "bicycle_lane"; @@ -58,10 +55,8 @@ bool is_shoulder_lane(const lanelet::ConstLanelet & lanelet); /** * @brief check if the given lanelet type has "bicycle_lane" subtype * @param [in] lanelet input lanelet - * @return if the lanelet is bicicye_lane or not + * @return if the lanelet is bicycle_lane or not */ bool is_bicycle_lane(const lanelet::ConstLanelet & lanelet); -} // namespace kind - } // namespace autoware::lanelet2_utility #endif // AUTOWARE_LANELET2_UTILITY__KIND_HPP_ diff --git a/common/autoware_lanelet2_utility/include/autoware_lanelet2_utility/topology.hpp b/common/autoware_lanelet2_utility/include/autoware_lanelet2_utility/topology.hpp new file mode 100644 index 000000000..e94154e89 --- /dev/null +++ b/common/autoware_lanelet2_utility/include/autoware_lanelet2_utility/topology.hpp @@ -0,0 +1,149 @@ +// Copyright 2025 TIER IV, Inc. +// +// 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 AUTOWARE_LANELET2_UTILITY__TOPOLOGY_HPP_ +#define AUTOWARE_LANELET2_UTILITY__TOPOLOGY_HPP_ + +#include +#include + +#include +#include + +namespace autoware::lanelet2_utility +{ +/** + * @brief get the left adjacent and same_direction lanelet on the routing graph if exists regardless + * of lane change permission + * @param [in] lanelet input lanelet + * @param [in] routing_graph routing_graph containing `lanelet` + * @return optional of left adjacent lanelet(nullopt if there is no such adjacent lanelet) + */ +std::optional left_lanelet( + const lanelet::ConstLanelet & lanelet, + const lanelet::routing::RoutingGraphConstPtr routing_graph); + +/** + * @brief get the right adjacent and same_direction lanelet on the routing graph if exists + * @param [in] lanelet input lanelet + * @param [in] routing_graph routing_graph containing `lanelet` + * @return optional of right adjacent lanelet(nullopt if there is no such adjacent lanelet) + */ +std::optional right_lanelet( + const lanelet::ConstLanelet & lanelet, + const lanelet::routing::RoutingGraphConstPtr routing_graph); + +/** + * @brief get the left adjacent and opposite_direction lanelet on the routing graph if exists + * @param [in] lanelet input lanelet + * @param [in] routing_graph routing_graph containing `lanelet` + * @return optional of the left opposite lanelet(nullopt if there is not such opposite lanelet) + */ +std::optional left_opposite_lanelet( + const lanelet::ConstLanelet & lanelet, + const lanelet::routing::RoutingGraphConstPtr routing_graph); + +/** + * @brief get the right adjacent and opposite_direction lanelet on the routing graph if exists + * @param [in] lanelet input lanelet + * @param [in] routing_graph routing_graph containing `lanelet` + * @return optional of the right opposite lanelet(nullopt if there is no such opposite lanelet) + */ +std::optional right_opposite_lanelet( + const lanelet::ConstLanelet & lanelet, + const lanelet::routing::RoutingGraphConstPtr routing_graph); + +/** + * @brief get the leftmost same_direction lanelet if exists + * @param [in] lanelet input lanelet + * @param [in] routing_graph routing_graph containing `lanelet` + * @return optional of such lanelet(nullopt if there is no such adjacent lanelet) + */ +std::optional leftmost_lanelet( + const lanelet::ConstLanelet & lanelet, + const lanelet::routing::RoutingGraphConstPtr routing_graph); + +std::optional rightmost_lanelet( + const lanelet::ConstLanelet & lanelet, + const lanelet::routing::RoutingGraphConstPtr routing_graph); + +/** + * @brief get the left lanelets which are adjacent to `lanelet` + * @param [in] lanelet input lanelet + * @param [in] routing_graph routing_graph containing `lanelet` + * @param [in] include_opposite flag if opposite_direction lanelet is included + * @param [in] invert_opposite_lanelet flag if the opposite lanelet in the output is `.inverted()` + * or not + * @return the list of lanelets excluding `lanelet` which is ordered in the *hopping* number from + * `lanelet` + */ +lanelet::ConstLanelets left_lanelets( + const lanelet::ConstLanelet & lanelet, const lanelet::routing::RoutingGraphConstPtr routing_graph, + const bool include_opposite = false, const bool invert_opposite_lane = false); + +/** + * @brief get the right lanelets which are adjacent to `lanelet` + * @param [in] lanelet input lanelet + * @param [in] routing_graph routing_graph containing `lanelet` + * @param [in] include_opposite flag if opposite_direction lanelet is included + * @param [in] invert_opposite_lanelet flag if the opposite lanelet in the output is `.inverted()` + * or not + * @return the list of lanelets excluding `lanelet` which is ordered in the *hopping* number from + * `lanelet` + */ +lanelet::ConstLanelets right_lanelets( + const lanelet::ConstLanelet & lanelet, const lanelet::routing::RoutingGraphConstPtr routing_graph, + const bool include_opposite = false, const bool invert_opposite_lane = false); + +/** + * @brief get the following lanelets + * @param [in] lanelet input lanelet + * @param [in] routing_graph routing_graph containing `lanelet` + * @return the following lanelets + */ +lanelet::ConstLanelets following_lanelets( + const lanelet::ConstLanelet & lanelet, + const lanelet::routing::RoutingGraphConstPtr routing_graph); + +/** + * @brief get the previous lanelets + * @param [in] lanelet input lanelet + * @param [in] routing_graph routing_graph containing `lanelet` + * @return the previous lanelets + */ +lanelet::ConstLanelets previous_lanelets( + const lanelet::ConstLanelet & lanelet, + const lanelet::routing::RoutingGraphConstPtr routing_graph); + +/** + * @brief get the sibling lanelets + * @param [in] lanelet input lanelet + * @param [in] routing_graph routing_graph containing `lanelet` + * @return the sibling lanelets + */ +lanelet::ConstLanelets sibling_lanelets( + const lanelet::ConstLanelet & lanelet, + const lanelet::routing::RoutingGraphConstPtr routing_graph); + +/** + * @brief get Lanelet instances of the designated ids + * @param [in] lanelet input lanelet + * @param [in] routing_graph routing_graph containing `lanelet` + * @return the list of Lanelets in the same order as `ids` + */ +lanelet::ConstLanelets from_ids( + const lanelet::LaneletMapConstPtr lanelet_map_ptr, const std::vector & ids); +} // namespace autoware::lanelet2_utility + +#endif // AUTOWARE_LANELET2_UTILITY__TOPOLOGY_HPP_ diff --git a/common/autoware_lanelet2_utility/media/api/left_lanelet.drawio.svg b/common/autoware_lanelet2_utility/media/api/left_lanelet.drawio.svg new file mode 100644 index 000000000..4d61a038c --- /dev/null +++ b/common/autoware_lanelet2_utility/media/api/left_lanelet.drawio.svg @@ -0,0 +1,648 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + shoulder lane + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bicycle lane + + + + + + +
+
+
+ + (1) + +
+
+
+
+ (1) +
+
+ + + + +
+
+
+ + (2) + +
+
+
+
+ (2) +
+
+ + + + +
+
+
+ + (3) + +
+
+
+
+ (3) +
+
+
+ + + + Text is not SVG - cannot display + + +
diff --git a/common/autoware_lanelet2_utility/media/api/left_lanelets.drawio.svg b/common/autoware_lanelet2_utility/media/api/left_lanelets.drawio.svg new file mode 100644 index 000000000..64edd454c --- /dev/null +++ b/common/autoware_lanelet2_utility/media/api/left_lanelets.drawio.svg @@ -0,0 +1,672 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + shoulder lane + + + + + + + bicycle lane + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ 2 +
+
+
+
+ 2 +
+
+ + + + +
+
+
+ + (3) + +
+
+
+
+ (3) +
+
+ + + + +
+
+
+ + (1) + +
+
+
+
+ (1) +
+
+ + + + +
+
+
+ + (2) + +
+
+
+
+ (2) +
+
+ + + + + +
+
+
+ 1 +
+
+
+
+ 1 +
+
+
+ + + + Text is not SVG - cannot display + + +
diff --git a/common/autoware_lanelet2_utility/media/api/leftmost_lanelet.drawio.svg b/common/autoware_lanelet2_utility/media/api/leftmost_lanelet.drawio.svg new file mode 100644 index 000000000..3b046687e --- /dev/null +++ b/common/autoware_lanelet2_utility/media/api/leftmost_lanelet.drawio.svg @@ -0,0 +1,629 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + shoulder lane + + + + + + + bicycle lane + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + (1) + +
+
+
+
+ (1) +
+
+ + + + +
+
+
+ + (2) + +
+
+
+
+ (2) +
+
+ + + + +
+
+
+ + (3) + +
+
+
+
+ (3) +
+
+
+ + + + Text is not SVG - cannot display + + +
diff --git a/common/autoware_lanelet2_utility/media/api/right_lanelets.drawio.svg b/common/autoware_lanelet2_utility/media/api/right_lanelets.drawio.svg new file mode 100644 index 000000000..9d6b78f37 --- /dev/null +++ b/common/autoware_lanelet2_utility/media/api/right_lanelets.drawio.svg @@ -0,0 +1,470 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bicycle lane + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ 2 +
+
+
+
+ 2 +
+
+ + + + +
+
+
+ + (1) + +
+
+
+
+ (1) +
+
+ + + + +
+
+
+ + (2) + +
+
+
+
+ (2) +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + (3) + +
+
+
+
+ (3) +
+
+ + + + +
+
+
+ 1 +
+
+
+
+ 1 +
+
+
+ + + + Text is not SVG - cannot display + + +
diff --git a/common/autoware_lanelet2_utility/media/api/right_opposite_lanelet.drawio.svg b/common/autoware_lanelet2_utility/media/api/right_opposite_lanelet.drawio.svg new file mode 100644 index 000000000..98c63bf58 --- /dev/null +++ b/common/autoware_lanelet2_utility/media/api/right_opposite_lanelet.drawio.svg @@ -0,0 +1,640 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + shoulder lane + + + + + + + bicycle lane + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + (1) + +
+
+
+
+ (1) +
+
+ + + + +
+
+
+ + (2) + +
+
+
+
+ (2) +
+
+ + + + +
+
+
+ + (3) + +
+
+
+
+ (3) +
+
+
+ + + + Text is not SVG - cannot display + + +
diff --git a/common/autoware_lanelet2_utility/media/api/rightmost_lanelet.drawio.svg b/common/autoware_lanelet2_utility/media/api/rightmost_lanelet.drawio.svg new file mode 100644 index 000000000..02bece1c1 --- /dev/null +++ b/common/autoware_lanelet2_utility/media/api/rightmost_lanelet.drawio.svg @@ -0,0 +1,435 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bicycle lane + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + (1) + +
+
+
+
+ (1) +
+
+ + + + +
+
+
+ + (2) + +
+
+
+
+ (2) +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + (3) + +
+
+
+
+ (3) +
+
+
+ + + + Text is not SVG - cannot display + + +
diff --git a/common/autoware_lanelet2_utility/src/kind.cpp b/common/autoware_lanelet2_utility/src/kind.cpp index 12a6e98e1..d369a22ef 100644 --- a/common/autoware_lanelet2_utility/src/kind.cpp +++ b/common/autoware_lanelet2_utility/src/kind.cpp @@ -18,9 +18,6 @@ namespace autoware::lanelet2_utility { - -inline namespace kind -{ bool is_road_lane(const lanelet::ConstLanelet & lanelet) { return strcmp(lanelet.attributeOr(lanelet::AttributeName::Subtype, "none"), k_road_lane_type) == @@ -38,5 +35,4 @@ bool is_bicycle_lane(const lanelet::ConstLanelet & lanelet) return strcmp( lanelet.attributeOr(lanelet::AttributeName::Subtype, "none"), k_bicycle_lane_type) == 0; } -} // namespace kind } // namespace autoware::lanelet2_utility diff --git a/common/autoware_lanelet2_utility/src/topology.cpp b/common/autoware_lanelet2_utility/src/topology.cpp new file mode 100644 index 000000000..6569999cc --- /dev/null +++ b/common/autoware_lanelet2_utility/src/topology.cpp @@ -0,0 +1,70 @@ +// Copyright 2025 TIER IV, Inc. +// +// 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 + +#include +#include + +#include + +namespace autoware::lanelet2_utility +{ +std::optional left_lanelet( + const lanelet::ConstLanelet & lanelet, + const lanelet::routing::RoutingGraphConstPtr routing_graph); + +std::optional right_lanelet( + const lanelet::ConstLanelet & lanelet, + const lanelet::routing::RoutingGraphConstPtr routing_graph); + +std::optional left_opposite_lanelet( + const lanelet::ConstLanelet & lanelet, + const lanelet::routing::RoutingGraphConstPtr routing_graph); + +std::optional right_opposite_lanelet( + const lanelet::ConstLanelet & lanelet, + const lanelet::routing::RoutingGraphConstPtr routing_graph); + +std::optional leftmost_lanelet( + const lanelet::ConstLanelet & lanelet, + const lanelet::routing::RoutingGraphConstPtr routing_graph); + +std::optional rightmost_lanelet( + const lanelet::ConstLanelet & lanelet, + const lanelet::routing::RoutingGraphConstPtr routing_graph); + +lanelet::ConstLanelets left_lanelets( + const lanelet::ConstLanelet & lanelet, const lanelet::routing::RoutingGraphConstPtr routing_graph, + const bool include_opposite, const bool invert_opposite_lane); + +lanelet::ConstLanelets right_lanelets( + const lanelet::ConstLanelet & lanelet, const lanelet::routing::RoutingGraphConstPtr routing_graph, + const bool include_opposite, const bool invert_opposite_lane); + +lanelet::ConstLanelets following_lanelets( + const lanelet::ConstLanelet & lanelet, + const lanelet::routing::RoutingGraphConstPtr routing_graph); + +lanelet::ConstLanelets previous_lanelets( + const lanelet::ConstLanelet & lanelet, + const lanelet::routing::RoutingGraphConstPtr routing_graph); + +lanelet::ConstLanelets sibling_lanelets( + const lanelet::ConstLanelet & lanelet, + const lanelet::routing::RoutingGraphConstPtr routing_graph); + +lanelet::ConstLanelets from_ids( + const lanelet::LaneletMapConstPtr lanelet_map_ptr, const std::vector & ids); +} // namespace autoware::lanelet2_utility