404
+ +Page not found
+ + +diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/404.html b/404.html new file mode 100644 index 00000000..5e64f1cb --- /dev/null +++ b/404.html @@ -0,0 +1,186 @@ + + + +
+ + + + + + + +Page not found
+ + +Lanelet2 is a C++ library for handling map data in the context of automated driving. It is designed to utilize high-definition map data in order to efficiently handle the challenges posed to a vehicle in complex traffic scenarios. Flexibility and extensibility are some of the core principles to handle the upcoming challenges of future maps.
+Features: +- 2D and 3D support +- Consistent modification: if one point is modified, all owning objects see the change +- Supports lane changes, routing through areas, etc. +- Separated routing for pedestrians, vehicles, bikes, etc. +- Many customization points to add new traffic rules, routing costs, parsers, etc. +- Simple convenience functions for common tasks when handling maps +- Accurate Projection between the lat/lon geographic world and local metric coordinates +- IO Interface for reading and writing e.g. osm data formats (this does not mean it can deal with osm maps) +- Python bindings for the whole C++ interface +- Boost Geometry support for all thinkable kinds of geometry calculations on map primitives +- Released under the BSD 3-Clause license +- Support for ROS1, ROS2, Docker and Conan (see instructions below)
+ +Lanelet2 is the successor of the old liblanelet that was developed in 2013. If you know Lanelet1, you might be interested in reading this.
+You can find more documentation in the individual packages and in doxygen comments. Here is an overview on the most important topics: +- Here is more information on the basic primitives that make up a Lanelet2 map. +- Read here for a primer on the software architecture of lanelet2. +- There is also some documentation on the geometry calculations you can do with lanelet2 primitives. +- If you are interested in Lanelet2's projections, you will find more here. +- To get more information on how to create valid maps, see here.
+You can also find the documentation at this link.
+Lanelet2 has been released for ROS. Just install ros-[distribution]-lanelet2
, e.g.:
sudo apt install ros-noetic-lanelet2
+
+Outside of ROS, Lanelet2 can be installed from PyPI. Note that currently only Python 3.8-3.11 linux builds are available and that Python 3.10+ is only supported for recent linux distributions such as Ubuntu 20.04+.
+pip install lanelet2
+
+If you receive the error
+ERROR: Could not find a version that satisfies the requirement lanelet2 (from versions: none)
+ERROR: No matching distribution found for lanelet2
+
+during installation, even when using e.g. python 3.9 or 3.8 on a somewhat recent linux such as Ubuntu 18.04 or newer, your pip version is probably too old, +as e.g. the pip version that comes with apt on Ubuntu 20.04 (20.0.2) is not recent enough for the provided package.
+In this case you need to simply update pip with
+pip3 install -U pip
+
+There is a Docker container from which you can test things out:
+docker build -t lanelet2 . # builds a docker image named "lanelet2"
+docker run -it --rm lanelet2:latest /bin/bash # starts the docker image
+python -c "import lanelet2" # quick check to see everything is fine
+
+The docker image contains a link to your local lanelet2, so you can work and see changes (almost) at the same time. Work with two screens, one local and one on docker. Make your code changes locally, then run again catkin build
on docker to recompile the code (update python modules).
In case you want to build it in your own way (without the above Docker image) use these instructions.
+Lanelet2 relies mainly on Catkin for building and is targeted towards Linux.
+At least C++14 is required.
+Besides Catkin, the dependencies are
+* Boost
(from 1.58)
+* eigen3
+* mrt_cmake_modules
, a CMake helper library
+* pugixml
(for lanelet2_io)
+* boost-python, python2 or python3
(for lanelet2_python)
+* geographiclib
(for lanelet2_projection)
+* rosbash
(for lanelet2_examples)
For Ubuntu, the steps are the following:
+* Set up ROS, and install at least rospack
, catkin
and mrt_cmake_modules
(e.g. ros-melodic-rospack
, ros-melodic-catkin
, ros-melodic-mrt-cmake-modules
):
sudo apt-get install ros-melodic-rospack ros-melodic-catkin ros-melodic-mrt-cmake-modules
+
+sudo apt-get install libboost-dev libeigen3-dev libgeographic-dev libpugixml-dev libpython-dev libboost-python-dev python-catkin-tools
+
+On 16.04 and below, mrt_cmake_modules
is not available in ROS and you have to clone it into your workspace (git clone https://github.com/KIT-MRT/mrt_cmake_modules.git
).
As usual with Catkin, after you have sourced the ros installation, you have to create a workspace and clone all required packages there. Then you can build.
+source /opt/ros/$ROS_DISTRO/setup.bash
+mkdir catkin_ws && cd catkin_ws && mkdir src
+catkin init
+catkin config --cmake-args -DCMAKE_BUILD_TYPE=RelWithDebInfo # build in release mode (or whatever you prefer)
+cd src
+git clone https://github.com/fzi-forschungszentrum-informatik/lanelet2.git
+cd ..
+catkin build
+
+If unsure, see the Dockerfile or the travis build log. It shows the full installation process, with subsequent build and test based on a docker image with a clean Ubuntu installation.
+Note: Updated instructions for conan2! +For non-catkin users, we also offer a conan based install process. Its experimental and might not work on all platforms, especially Windows. +Since conan handles installing all C++ dependencies, all you need is a cloned repository, conan itself and a few python dependencies:
+pip install conan catkin_pkg numpy
+git clone https://github.com/fzi-forschungszentrum-informatik/lanelet2.git
+cd lanelet2
+
+From here, just use the default conan build/install procedure, e.g.:
+conan create . --build=missing
+
+Different from the conan defaults, we build lanelet2 and boost as shared libraries, because otherwise the lanelet2's plugin mechanisms as well as boost::python will fail. E.g. loading maps will not be possible and the python API will not be usable.
+To be able to use the python bindings, you have to make conan export the PYTHONPATH for lanelet2 after conan create
:
source activate.sh
+python -c "import lanelet2" # or whatever you want to do
+source deactivate.sh
+
+The python bindings are build for your default python installation by default (which currently is python2 on most systems). To build for python3 instead of python2, create a python3 virtualenv before initializing the workspace with catkin init
. The command python
should point to python3
.
After catkin init
run catkin config --cmake-args -DCMAKE_BUILD_TYPE=RelWithDebInfo -DPYTHON_VERSION=3.6
to make sure that the correct python version is used. Then build and use as usual.
Note: With bionic and beyond, the apt package python3-catkin-tools
conflicts with ROS melodic and should not be used. Use either the python2 version or use pip to install the python3 version.
Examples and common use cases in both C++ and Python can be found here.
+If you are using Lanelet2 for scientific research, we would be pleased if you would cite our publication:
+@inproceedings{poggenhans2018lanelet2,
+ title = {Lanelet2: A High-Definition Map Framework for the Future of Automated Driving},
+ author = {Poggenhans, Fabian and Pauls, Jan-Hendrik and Janosovits, Johannes and Orf, Stefan and Naumann, Maximilian and Kuhnt, Florian and Mayr, Matthias},
+ booktitle = {Proc.\ IEEE Intell.\ Trans.\ Syst.\ Conf.},
+ year = {2018},
+ address = {Hawaii, USA},
+ owner = {poggenhans},
+ month = {November},
+ Url={http://www.mrt.kit.edu/z/publ/download/2018/Poggenhans2018Lanelet2.pdf}
+}
+
+
+ This file describes the technical architecture of Lanelet2. For information on the representation of Lanelet2 and its primitives, please read first here.
+In Lanelet2, everything that has an ID is unique across the whole map. Because multiple primitives can reference the same element, it is not possible to duplicate/copy the information of a Lanelet primitive. If that was possible, modifying the information would leave the map in an invalid state, because other elements that reference it would not be notified of the change.
+To solve this issue, Lanelet2's primitive do not actually store data. Instead, they hold a pointer to the real, uncopyable data object. This means they only provide a view on the underlying map data. This means that Lanelet2 primitives can be copied without regret, because all copies still point to the same underlying data object. If the data is modified through one of the primtives, all other copies can observe the change.
+This results in some interesting properties. Firstly, primitives can be copied extremely fast, because only the pointer is copied, not the data. Secondly, this means that we can provide different views on the data. One example is that we can give you a 2D view and a 3D view on the data, e.g. a Point2d that returns x and y coordinates but not the z coordinate. You can convert this point back to Point3d without losing information, because in the underlying data, the z-coordinate was always there. Linestrings behave similar. A LineString3d
returns Point3d
, a LineString2d
gives you Point2d
.
We can also easily invert Linestrings and Lanelets with this technique. An inverted Linestring simply returns the underlying data in reversed order. You will not even notice it is inverted, because it still behaves in the same way as a non-inverted one. The effort of creating the inverted Linestring is - you guessed it - just the effort of copying a pointer!
+Like this we can make sure that modifying the map is always consistent. All primitives will observe the change. However, there are two exceptions to this, and they are related to caching: The centerline of a Lanelet is calculated based on the left and right bound at the time it was first requested. If the points of a left or right bound were modified, the Lanelet does not notice the change and returns the outdated centerline. You have to reset the centerline of the Lanelet yourself. The second issue is within the LaneletMap
container. It holds some precalculated tree structures to efficiently query closest points or usages of a point. If one of the points is modified, the query will still run on the old tree structure. So the general message is: When you plan to modify the map, know what you are doing!
Since Lanelet2's primitives, especially Lanelets represent an atomic section of the map, it is often important to compose these atomic parts together to create compound objects. These compound primitives behave in the same way as the primitives they are composed of, but internally access the primitive's data. This is also driven by the pointer-based concept introduced above: The compound objects simply hold a list of pointers instead of a single one. As an example, you can compose multiple Linestring3d
to one CompoundLineString3d
. It behaves like a single Linestring, gives you its size()
in points and access to the individual points while still internally accessing the data of the actual Linestrings. You can also compose polygons from Linestrings, LaneletSet
from Lanelets, and so on.
Since modifying the map can make cached data invalid, and since modifications affect the whole map, Lanelet2 offers some protection against unwanted modification. This is related to const correctness: If an object is passed to a function as const
, not only the data of the object itself is immutable, but also the data derived from it and all the copies that you make.
E.g., if a function accepts a Linestring as ConstLinestring3d
, its data is guaranteed to be immutable. If you access a point of the Linestring, you get a ConstPoint3d
, that allows you to access its data, but not modify it. It is not possible to convert a ConstPoint3d
back to a Point3d
. This means, if you call a function that accepts a const LineString3d
or even a ConstLineString3d
, it is guaranteed that your map data will not be modified.
We are aware of the fact that roads can be very different in different countries and different places. Some things can be hard to squeeze into the typical map format. Also, the requirements on the map can be very different. To account for this, we tried to make Lanelet2 as flexible as possible by adding customization points where you can plugin your customized solution. Also the modularity of Lanelet2 aims to make it as simple as possible to add new functionality in the future.
+Part of the flexibility concept is that the tags that are used on objects can be extended without any limits. This way you can easily add more specific information to your maps that you are missing. New, custom regulatory elements can be added to account for difficult traffic situations. Also Lanelet2 can be extended for different countries and different road participants by adding new TrafficRules
objects which are used by Lanelet2 to interpret the map data. New parsers and writers for new map formats can be added and registered while still using the same good old load
/write
function.
Lanelet2's objects are meant to be directly usable for geometry calculations. They are all registered with boost::geometry, meaning the follwing is easily possible: double d = boost::geometry::distance(laneletPoint1, laneletPoint2)
. If laneletPoint1/2 is a 2D point, you will get the result in 2D, else in 3D.
However, there are limitations to this that originate from the fact that the ConstCorrectness concept and boost::geometry do not play well with each other, because boost::geometry gets confused by the different point types used when things are used in a const and a non-const context. If you want to know more how to solve this problem and avoid pages and pages of compiler errors from boost's feared template code, read our Geometry Primer on this.
+If you don't know Lanelet2's basic primitives yet, better read here first!
+Here, we want to introduce the basic terms and objects that you will be confronted with when using Lanelet2 and how they interact:
+* Primitive any Lanelet2 primitive and their derivates (Lanelet
, ConstLanelet
, LineString2d
, etc)
+* LaneletMap a LaneletMap
is the basic storage container for primitives. It is separated in layers, one for each primitive type and offers different ways to access its data (by a BoundingBox
, by ID, by nearest point, etc). It does not provide routing functionality.
+* TrafficRules a traffic rules object interprets the map. E.g., it reports if a Lanelet isPassable
, or if lane changes are possible between two Lanelets. A traffic rule object interprets the map from the perspective of one road participant type. A vehicle TrafficRule
object will therefore give completely different results on a specific Lanelet than a pedestrian TrafficRule
object.
+* RoutingCost these classes are used by the routing graph to determine costs when driving from one Lanelet/area to another one. It could be by travelled distance, by travel time but there are no limits for more advanced routing cost functions. You can also choose the cost of lane changes so that routes with few, preferably long lane changes are preferred.
+* RoutingGraph a routing graph is built from a LaneletMap
, TrafficRules
and RoutingCost
objects. One routing graph is only for one single participant: The one that the TrafficRules
belong to. With the routing graph, you can make all kinds of queries to determine where you or someone else can go/drive.
+* Route a route is something returned by the graph when you query a route from A to B. It contains a structure of all the Lanelets that you can use along the way with the lowest routing cost, including all possible lane changes.
+* LaneletPath or Path in general is a sequence of Lanelets returned by the RoutingGraph that are directly adjacent and have the lowest routing cost to the destination. "Adjacent" means that they can also be connected by a lane change, not only by following the Lanelet in a straight direction.
+* LaneletSequence a list of directly succeeding Lanelets that can be reached without lane changes. A LaneletSequence is the special case of a LaneletPath where no lane change is necessary.
+* Projector projectors are used by the IO module to convert between maps that store date in the WGS84 (lat/lon) format and the local coordinates used by Lanelet2. There are many different projections that all have different properties, so you should choose the one that fits best to you. If in doubt, use UTM.