From 9b495781e8879bb14298ff276531b706303e5464 Mon Sep 17 00:00:00 2001 From: Fabian Immel Date: Mon, 28 Oct 2024 17:06:19 +0100 Subject: [PATCH] Imported upstream version '1.2.2' of 'upstream' --- .github/conan_dockerfile/Dockerfile | 37 ++-- .github/workflows/cd.yaml | 37 +++- .github/workflows/ci.yaml | 8 +- README.md | 11 +- conanfile.py | 179 ++++++++++++++---- docs/cp_docu_files.sh | 37 ++++ docs/requirements.txt | 2 + lanelet2/CHANGELOG.rst | 3 + lanelet2/package.xml | 2 +- lanelet2_core/CHANGELOG.rst | 8 + lanelet2_core/README.md | 2 +- lanelet2_core/doc/RegulatoryElementTagging.md | 2 +- .../lanelet2_core/geometry/LineString.h | 12 ++ .../lanelet2_core/geometry/impl/LineString.h | 8 +- lanelet2_core/package.xml | 2 +- lanelet2_core/test/test_linestring.cpp | 6 + lanelet2_examples/CHANGELOG.rst | 6 + lanelet2_examples/README.md | 4 +- lanelet2_examples/package.xml | 2 +- lanelet2_examples/scripts/tutorial.py | 10 +- lanelet2_io/CHANGELOG.rst | 5 + lanelet2_io/README.md | 4 +- lanelet2_io/package.xml | 2 +- lanelet2_maps/CHANGELOG.rst | 5 + lanelet2_maps/josm/laneletpresets.xml | 2 +- lanelet2_maps/package.xml | 2 +- lanelet2_matching/CHANGELOG.rst | 3 + lanelet2_matching/package.xml | 2 +- lanelet2_projection/CHANGELOG.rst | 5 + .../include/lanelet2_projection/Geocentric.h | 3 + lanelet2_projection/package.xml | 2 +- lanelet2_python/CHANGELOG.rst | 22 ++- lanelet2_python/README.md | 2 +- lanelet2_python/package.xml | 2 +- lanelet2_python/python_api/core.cpp | 14 +- lanelet2_python/python_api/geometry.cpp | 23 ++- lanelet2_python/python_api/routing.cpp | 2 +- lanelet2_python/scripts/print_ids.py | 2 +- lanelet2_python/setup.py.template | 30 ++- lanelet2_routing/CHANGELOG.rst | 6 + lanelet2_routing/README.md | 2 +- lanelet2_routing/package.xml | 2 +- lanelet2_routing/src/Route.cpp | 6 +- lanelet2_traffic_rules/CHANGELOG.rst | 5 + lanelet2_traffic_rules/README.md | 2 +- lanelet2_traffic_rules/package.xml | 2 +- lanelet2_validation/CHANGELOG.rst | 3 + lanelet2_validation/package.xml | 2 +- mkdocs.yml | 29 +++ 49 files changed, 449 insertions(+), 120 deletions(-) create mode 100755 docs/cp_docu_files.sh create mode 100644 docs/requirements.txt create mode 100644 mkdocs.yml diff --git a/.github/conan_dockerfile/Dockerfile b/.github/conan_dockerfile/Dockerfile index d8d38c7e..c4393f77 100644 --- a/.github/conan_dockerfile/Dockerfile +++ b/.github/conan_dockerfile/Dockerfile @@ -11,10 +11,11 @@ RUN sudo -E apt-get update \ libncursesw5-dev xz-utils libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev # setup python environment -ARG PY_VERSION=3.8 -RUN pyenv install -s $PY_VERSION \ +ARG PY_VERSION=3.12 +RUN pyenv update \ + && pyenv install -s $PY_VERSION \ && pyenv global $PY_VERSION -RUN pip install "conan==1.59.0" catkin_pkg numpy wheel auditwheel cmake +RUN pip install "conan~=2.8.0" catkin_pkg "numpy<2.0" wheel auditwheel cmake # install patchelf RUN wget https://github.com/NixOS/patchelf/releases/download/0.17.2/patchelf-0.17.2-x86_64.tar.gz \ @@ -22,10 +23,6 @@ RUN wget https://github.com/NixOS/patchelf/releases/download/0.17.2/patchelf-0.1 && sudo -E ln -s $HOME/bin/patchelf /bin/patchelf \ && patchelf --version -# setup conan for python dependencies via bincrafters remote -RUN conan remote add bincrafters https://bincrafters.jfrog.io/artifactory/api/conan/public-conan \ - && conan config set general.revisions_enabled=1 - FROM lanelet2_conan_deps as lanelet2_conan_src @@ -38,28 +35,18 @@ FROM lanelet2_conan_src as lanelet2_conan # compile ARG CONAN_ARGS="" +ARG PLATFORM="manylinux_2_31_x86_64" WORKDIR /home/conan/src/lanelet2 -RUN conan create . lanelet2/stable --build=missing ${CONAN_ARGS} \ - && export LANELET2_VERSION=$(conan inspect . --raw version) \ - && echo "Lanelet2 version: $LANELET2_VERSION" \ - && conan install lanelet2/$LANELET2_VERSION@lanelet2/stable --build=missing -g virtualenv +RUN conan profile detect \ + && conan create . --format=json --build=missing -o "&:build_wheel=True" -o "&:platform=${PLATFORM}" ${CONAN_ARGS} > conaninfo.json + +# obtain wheel FROM lanelet2_conan as lanelet2_conan_with_pip_wheel SHELL ["/bin/bash", "-c"] WORKDIR /home/conan -RUN source /home/conan/src/lanelet2/activate.sh \ - && LANELET2_PACKAGE_DIR=$(python -c "import lanelet2; from pathlib import Path; print(Path(lanelet2.__file__).parent)") \ - && cp -r $LANELET2_PACKAGE_DIR . -RUN export LANELET2_VERSION=$(conan inspect ./src/lanelet2 --raw version) \ - && echo "Lanelet2 version: $LANELET2_VERSION" \ - && sed 's/{{ version }}/'"$LANELET2_VERSION"'/' /home/conan/src/lanelet2/lanelet2_python/setup.py.template > /home/conan/setup.py - -ARG PLATFORM="manylinux_2_31_x86_64" -RUN source /home/conan/src/lanelet2/activate.sh \ - && pip wheel -w broken-dist/ . \ - && auditwheel repair -w dist/ --plat ${PLATFORM} broken-dist/*.whl +RUN LANELET2_PACKAGE_DIR=$(python3 -c "import json; f=open('src/lanelet2/conaninfo.json'); data=json.load(f); ll2=next(d for d in data['graph']['nodes'].values() if 'lanelet2' in d['ref']); print(f'{ll2[\"package_folder\"]}/wheel')") \ + && cp -r $LANELET2_PACKAGE_DIR dist # to extract the wheel manually run: -# $ docker run -it -v /path/to/some/local/folder:/dist /bin/bash -# then inside the container: -# $ sudo cp dist/lanelet2-<...>.whl /dist/. +# $ docker run --rm -v /path/to/some/local/folder:/dist /bin/bash -c 'sudo cp dist/lanelet2-<...>.whl /dist/.' \ No newline at end of file diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index 95ae7fb3..027d6128 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -19,19 +19,18 @@ jobs: python-version: ["3.8", "3.9", "3.10", "3.11"] include: - python-version: "3.8" - boost-version: "1.75.0" platform-version: manylinux_2_27_x86_64 image-version: conanio/gcc7:latest - python-version: "3.9" - boost-version: "1.75.0" platform-version: manylinux_2_27_x86_64 image-version: conanio/gcc7:latest - python-version: "3.10" - boost-version: "1.81.0" platform-version: manylinux_2_31_x86_64 image-version: conanio/gcc10:latest - python-version: "3.11" - boost-version: "1.81.0" + platform-version: manylinux_2_31_x86_64 + image-version: conanio/gcc10:latest + - python-version: "3.12" platform-version: manylinux_2_31_x86_64 image-version: conanio/gcc10:latest runs-on: ubuntu-latest @@ -52,7 +51,6 @@ jobs: FROM=${{ matrix.image-version }} PY_VERSION=${{ matrix.python-version }} PLATFORM=${{ matrix.platform-version }} - CONAN_ARGS=--require-override=boost/${{ matrix.boost-version }} - name: Create output directory run: mkdir -p ${{ github.workspace }}/output @@ -82,8 +80,8 @@ jobs: strategy: matrix: # test only on currently supported version - python-version: ["3.8", "3.9", "3.10", "3.11"] - os: ["ubuntu-22.04", "ubuntu-20.04"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + os: ["ubuntu-20.04", "ubuntu-22.04", "ubuntu-24.04"] runs-on: ${{ matrix.os }} steps: - name: Restore wheel @@ -95,8 +93,13 @@ jobs: uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} + - name: Install wheel 24.04 + # use dist/ directory as package source instead of pypi.org + if: ${{ matrix.os == 'ubuntu-24.04' }} + run: pip install lanelet2 --break-system-packages --no-index --find-links dist/ - name: Install wheel # use dist/ directory as package source instead of pypi.org + if: ${{ matrix.os != 'ubuntu-24.04' }} run: pip install lanelet2 --no-index --find-links dist/ - name: Test wheel run: python -c "import lanelet2; assert lanelet2.core.Point2d(0, 0, 0) is not None" @@ -122,3 +125,23 @@ jobs: uses: pypa/gh-action-pypi-publish@release/v1 with: password: ${{ secrets.PYPI_API_TOKEN }} + + deploy-pages: + runs-on: ubuntu-22.04 + if: github.ref == 'refs/heads/master' + concurrency: deploy-${{ github.ref }} + steps: + - uses: actions/checkout@v2 + + - name: set up python + uses: actions/setup-python@v2 + with: + python-version: 3.7 + + - name: set up env + run: python -m pip install -r docs/requirements.txt + + - name: copy docs to docs folder + run: bash docs/cp_docu_files.sh + + - run: mkdocs gh-deploy --force diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index be918adb..46567d0e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -187,19 +187,18 @@ jobs: python-version: ["3.8", "3.9", "3.10", "3.11"] include: - python-version: "3.8" - boost-version: "1.75.0" platform-version: manylinux_2_27_x86_64 image-version: conanio/gcc7:latest - python-version: "3.9" - boost-version: "1.75.0" platform-version: manylinux_2_27_x86_64 image-version: conanio/gcc7:latest - python-version: "3.10" - boost-version: "1.81.0" platform-version: manylinux_2_31_x86_64 image-version: conanio/gcc10:latest - python-version: "3.11" - boost-version: "1.81.0" + platform-version: manylinux_2_31_x86_64 + image-version: conanio/gcc10:latest + - python-version: "3.12" platform-version: manylinux_2_31_x86_64 image-version: conanio/gcc10:latest runs-on: ubuntu-latest @@ -220,4 +219,3 @@ jobs: FROM=${{ matrix.image-version }} PY_VERSION=${{ matrix.python-version }} PLATFORM=${{ matrix.platform-version }} - CONAN_ARGS=--require-override=boost/${{ matrix.boost-version }} diff --git a/README.md b/README.md index 5f24b528..92604f6b 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,8 @@ You can find more documentation in the individual packages and in doxygen commen - If you are interested in Lanelet2's **projections**, you will find more [here](lanelet2_projection/doc/Map_Projections_Coordinate_Systems.md). - To get more information on how to create valid maps, see [here](lanelet2_maps/README.md). +You can also find the documentation at this [link](https://fzi-forschungszentrum-informatik.github.io/Lanelet2). + ## Installation ### Within ROS @@ -134,26 +136,23 @@ catkin build If unsure, see the [Dockerfile](Dockerfile) or the [travis build log](https://travis-ci.org/fzi-forschungszentrum-informatik/Lanelet2). It shows the full installation process, with subsequent build and test based on a docker image with a clean Ubuntu installation. ### Manual, experimental installation using conan +**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: ```bash pip install conan catkin_pkg numpy -conan remote add bincrafters https://bincrafters.jfrog.io/artifactory/api/conan/public-conan # required for python bindings -conan config set general.revisions_enabled=1 # requried to use bincrafters remote git clone https://github.com/fzi-forschungszentrum-informatik/lanelet2.git cd lanelet2 ``` From here, just use the default conan build/install procedure, e.g.: ```bash -conan source . -conan create . lanelet2/stable --build=missing +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: +To be able to use the python bindings, you have to make conan export the PYTHONPATH for lanelet2 after `conan create`: ```bash -conan install lanelet2/0.0.0@lanelet2/stable --build=missing -g virtualenv # replace 0.0.0 with the version shown by conan source activate.sh python -c "import lanelet2" # or whatever you want to do source deactivate.sh diff --git a/conanfile.py b/conanfile.py index 0160043b..edf3ec92 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,30 +1,52 @@ import os import sys import xml.etree.ElementTree as ET -from conans import ConanFile, CMake, tools from distutils.sysconfig import get_python_lib +from io import StringIO +from pathlib import Path -find_mrt_cmake=""" +from conan import ConanFile +from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout +from conan.tools.files import copy + +find_mrt_cmake = """ set(mrt_cmake_modules_FOUND True) include(${CMAKE_CURRENT_LIST_DIR}/mrt_cmake_modules-extras.cmake) """ -cmake_lists=""" +cmake_lists = """ cmake_minimum_required(VERSION 3.5) project(lanelet2) if(POLICY CMP0079) cmake_policy(SET CMP0079 NEW) # allows to do target_link_libraries on targets from subdirs endif() set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}) -set(BoostPython_FOUND Yes) -include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) -conan_basic_setup(SKIP_STD) +# mrt_cmake_modules inofficially support conan, but only conan1. So we have to set these: +set(CONAN_PACKAGE_NAME lanelet2) +macro(conan_define_targets) + add_library(${PROJECT_NAME}_conan_deps INTERFACE) + target_include_directories(${PROJECT_NAME}_conan_deps INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include) + set(CONAN_TARGETS ${PROJECT_NAME}_conan_deps) +endmacro() # hint to gtest set(GOOGLETEST_VERSION 1.0.0) set(MRT_GTEST_DIR ${CMAKE_CURRENT_LIST_DIR}) enable_testing() +# find thirdparty +find_package(mrt_cmake_modules REQUIRED) +find_package(Boost REQUIRED) +find_package(BoostPython REQUIRED) +find_package(GeographicLib REQUIRED) +find_package(Eigen3 REQUIRED) +find_package(pugixml REQUIRED) +add_library(conan INTERFACE IMPORTED) +set_target_properties( + conan + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${BoostPython_INCLUDE_DIRS}") +target_link_libraries(conan INTERFACE ${BoostPython_LIBRARIES} boost::boost pugixml::pugixml GeographicLib::GeographicLib Eigen3::Eigen) + # declare dependencies include_directories(lanelet2_core/include lanelet2_io/include lanelet2_projection/include lanelet2_traffic_rules/include lanelet2_routing/include lanelet2_validation/include) @@ -39,6 +61,7 @@ add_subdirectory(lanelet2_maps) add_subdirectory(lanelet2_matching) # declare dependencies +target_link_libraries(lanelet2_core PUBLIC conan) target_link_libraries(lanelet2_io PUBLIC lanelet2_core) target_link_libraries(lanelet2_projection PUBLIC lanelet2_core) target_link_libraries(lanelet2_traffic_rules PUBLIC lanelet2_core) @@ -49,30 +72,46 @@ target_link_libraries(lanelet2_python_compiler_flags INTERFACE lanelet2_core lanelet2_io lanelet2_routing lanelet2_traffic_rules lanelet2_projection lanelet2_matching) """ + def read_version(): - package = ET.parse('lanelet2_core/package.xml') - return package.find('version').text + package = ET.parse("lanelet2_core/package.xml") + return package.find("version").text + def get_py_version(): return "{}.{}".format(sys.version_info.major, sys.version_info.minor) -def get_py_exec(): - return "python3" if sys.version_info.major == 3 else "python" class Lanelet2Conan(ConanFile): name = "lanelet2" version = read_version() settings = "os", "compiler", "build_type", "arch" - generators = "cmake" license = "BSD" url = "https://github.com/fzi-forschungszentrum-informatik/lanelet2" description = "Map handling framework for automated driving" - options = {"shared": [True, False], "fPIC": [True]} - default_options = {"shared": True, "fPIC": True, "boost:shared": True, "boost:python_version": get_py_version(), "boost:without_python": False, "python_dev_config:python": get_py_exec()} + options = { + "shared": [True, False], + "fPIC": [True], + "python": ["ANY"], + "build_wheel": [True, False], + "platform": ["ANY"], + } + generators = "CMakeDeps", "VirtualRunEnv" + default_options = { + "shared": True, + "fPIC": True, + "build_wheel": False, + "python": sys.executable, + "platform": "manylinux_2_31_x86_64", + "boost/*:shared": True, + "boost/*:python_version": get_py_version(), + "boost/*:without_python": False, + } + + virtualrunenv = True requires = ( - "python_dev_config/0.6@bincrafters/stable", - "boost/[>=1.75.0 <=1.81.0]", + "boost/1.81.0" if sys.version_info.minor > 9 else "boost/1.75.0", "eigen/3.4.0", "geographiclib/1.52", "pugixml/1.13", @@ -82,31 +121,63 @@ class Lanelet2Conan(ConanFile): exports = "lanelet2_core/package.xml" proj_list = [ - 'lanelet2_core', - 'lanelet2_io', - 'lanelet2_matching', - 'lanelet2_projection', - 'lanelet2_traffic_rules', - 'lanelet2_routing', - 'lanelet2_validation' + "lanelet2_core", + "lanelet2_io", + "lanelet2_matching", + "lanelet2_projection", + "lanelet2_traffic_rules", + "lanelet2_routing", + "lanelet2_validation", ] + def layout(self): + cmake_layout(self) + + def generate(self): + # This generates "conan_toolchain.cmake" in self.generators_folder + tc = CMakeToolchain(self) + output = StringIO() + py_exec = str(self.options.python) + output = StringIO() + self.run( + "{0} -c \"from sys import *; print('%d.%d' % (version_info[0],version_info[1]))\"".format( + py_exec + ), + stdout=output, + ) + py_version = output.getvalue().strip() + tc.variables["PYTHON_VERSION"] = py_version + tc.variables["PYTHON_EXECUTABLE"] = py_exec + tc.variables["MRT_CMAKE_ENV"] = "sh env PYTHONPATH=" + py_exec + tc.generate() + self._set_env(self.runenv) + def _configure_cmake(self): cmake = CMake(self) - cmake.definitions["PYTHON_VERSION"] = get_py_version() - cmake.definitions["MRT_CMAKE_ENV"] = "sh;env;PYTHONPATH=" + os.path.join(self.package_folder, self._pythonpath()) - cmake.configure() + mrt_env = "sh;env;PYTHONPATH=" + os.path.join( + self.package_folder, self._pythonpath() + ) + cmake.configure( + variables={"PYTHON_VERSION": get_py_version(), "MRT_CMAKE_ENV": mrt_env} + ) return cmake def _pythonpath(self): - return os.path.relpath(get_python_lib(prefix=self.package_folder), start=self.package_folder) + return os.path.relpath( + get_python_lib(prefix=self.package_folder), start=self.package_folder + ) def source(self): if not os.path.exists("mrt_cmake_modules"): self.run("git clone https://github.com/KIT-MRT/mrt_cmake_modules.git") mrt_cmake_dir = os.path.join(os.getcwd(), "mrt_cmake_modules") with open("mrt_cmake_modules/cmake/mrt_cmake_modules-extras.cmake.in") as f: - extras = f.read().replace("@DEVELSPACE@", "True").replace("@PROJECT_SOURCE_DIR@", mrt_cmake_dir).replace("@CMAKE_CURRENT_SOURCE_DIR@", mrt_cmake_dir) + extras = ( + f.read() + .replace("@DEVELSPACE@", "True") + .replace("@PROJECT_SOURCE_DIR@", mrt_cmake_dir) + .replace("@CMAKE_CURRENT_SOURCE_DIR@", mrt_cmake_dir) + ) with open("mrt_cmake_modules-extras.cmake", "w") as f: f.write(extras) with open("Findmrt_cmake_modules.cmake", "w") as f: @@ -117,22 +188,52 @@ def source(self): self.run("git clone https://github.com/google/googletest.git") def build(self): - cmake = self._configure_cmake() + cmake = CMake(self) + cmake.configure() cmake.build() - cmake.test() # not working as long as the pythonpath is not adapted first - cmake.install() + cmake.test( + cli_args=["-v"] + ) # not working as long as the pythonpath is not adapted first + if self.options.build_wheel: + with ( + Path(self.source_folder) / "lanelet2_python" / "setup.py.template" + ).open() as f: + setup_template = f.read() + setup_py = setup_template.replace("{{ version }}", self.version) + with (Path(self.build_folder) / "setup.py").open("w") as f: + f.write(setup_py) def package(self): - cmake = self._configure_cmake() + cmake = CMake(self) cmake.install() + if self.options.build_wheel: + whl_tmp = os.path.join(self.package_folder, "wheel-incomplete") + whl_out = os.path.join(self.package_folder, "wheel") + copy(self, "setup.py", self.build_folder, whl_tmp) + copy( + self, + "*", + os.path.join(self.package_folder, self._pythonpath()), + whl_tmp, + ) + self.run(f"pip wheel -w {whl_tmp} {whl_tmp}") + self.run( + f"export LD_LIBRARY_PATH={os.path.join(self.package_folder, self.cpp_info.libdir)}:$LD_LIBRARY_PATH && auditwheel repair -w {whl_out} --plat {self.options.platform} {whl_tmp}/*.whl", + scope="conanrun", + ) + + def _set_env(self, env_info): + if not self.package_folder: + return + execs = ("lanelet2_examples", "lanelet2_validation", "lanelet2_python") + env_info.define_path( + "PYTHONPATH", os.path.join(self.package_folder, self._pythonpath()) + ) + for libname in execs: + env_info.append_path( + "PATH", os.path.join(self.package_folder, "lib", libname) + ) def package_info(self): self.cpp_info.libs = list(reversed(self.proj_list)) - libpath = os.path.join(self.package_folder, "lib") - boost_libpaths = self.deps_cpp_info["boost"].lib_paths - execs = ("lanelet2_examples", "lanelet2_validation", "lanelet2_python") - binpaths = [os.path.join(self.package_folder, "lib", libname) for libname in execs] - self.env_info.PYTHONPATH.append(os.path.join(self.package_folder, self._pythonpath())) - self.env_info.LD_LIBRARY_PATH += [libpath] + boost_libpaths - self.env_info.DYLD_LIBRARY_PATH += [libpath] + boost_libpaths - self.env_info.PATH += binpaths + self._set_env(self.runenv_info) diff --git a/docs/cp_docu_files.sh b/docs/cp_docu_files.sh new file mode 100755 index 00000000..668cb85e --- /dev/null +++ b/docs/cp_docu_files.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# Destination directory (docs folder) +dest_dir="docs/" + +# Ensure the destination directory exists +lanelet2_core_dir="lanelet2_core" +lanelet2_examples_dir="lanelet2_examples" +lanelet2_io_dir="lanelet2_io" +lanelet2_maps_dir="lanelet2_maps" +lanelet2_matching_dir="lanelet2_matching" +lanelet2_projection_dir="lanelet2_projection" +lanelet2_python_dir="lanelet2_python" +lanelet2_routing_dir="lanelet2_routing" +lanelet2_traffic_rules_dir="lanelet2_traffic_rules" +lanelet2_validation_dir="lanelet2_validation" + +cp "README.md" "$dest_dir/index.md" + +cp "$lanelet2_core_dir/README.md" "$dest_dir/lanelet2_core.md" +cp -r "$lanelet2_core_dir/doc" "$dest_dir/lanelet2_core" + +cp "$lanelet2_examples_dir/README.md" "$dest_dir/lanelet2_examples.md" +cp "$lanelet2_io_dir/README.md" "$dest_dir/lanelet2_io.md" +cp "$lanelet2_maps_dir/README.md" "$dest_dir/lanelet2_maps.md" +cp "$lanelet2_matching_dir/README.md" "$dest_dir/lanelet2_matching.md" +cp "$lanelet2_projection_dir/README.md" "$dest_dir/lanelet2_projection.md" +cp -r "$lanelet2_projection_dir/doc" "$dest_dir/lanelet2_projection" +cp "$lanelet2_python_dir/README.md" "$dest_dir/lanelet2_python.md" + +cp "$lanelet2_routing_dir/README.md" "$dest_dir/lanelet2_routing.md" +cp -r "$lanelet2_routing_dir/doc" "$dest_dir/lanelet2_routing" + +cp "$lanelet2_traffic_rules_dir/README.md" "$dest_dir/lanelet2_traffic_rules.md" +cp "$lanelet2_validation_dir/README.md" "$dest_dir/lanelet2_validation.md" + +echo "Documentation files copied to the docs folder." diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000..29b84636 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +mkdocs == 1.2.3 +jinja2==3.0.3 \ No newline at end of file diff --git a/lanelet2/CHANGELOG.rst b/lanelet2/CHANGELOG.rst index 708c02f8..0b9f6849 100644 --- a/lanelet2/CHANGELOG.rst +++ b/lanelet2/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package lanelet2 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +1.2.2 (2024-10-25) +------------------ + 1.2.1 (2023-05-10) ------------------ diff --git a/lanelet2/package.xml b/lanelet2/package.xml index 2b6583b3..b8932de7 100644 --- a/lanelet2/package.xml +++ b/lanelet2/package.xml @@ -2,7 +2,7 @@ lanelet2 - 1.2.1 + 1.2.2 Meta-package for lanelet2 BSD diff --git a/lanelet2_core/CHANGELOG.rst b/lanelet2_core/CHANGELOG.rst index 64929e69..ebbcb034 100644 --- a/lanelet2_core/CHANGELOG.rst +++ b/lanelet2_core/CHANGELOG.rst @@ -2,6 +2,14 @@ Changelog for package lanelet2_core ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +1.2.2 (2024-10-25) +------------------ +* Implement signed curvature (`#355 `_) +* Build documentation with mkdocs (`#321 `_) +* Update RegulatoryElementTagging.md (`#316 `_) +* Remove unused local typedefs (`#312 `_) +* Contributors: DavUhll, Johannes Schmitz, Kosuke Takeuchi, johannes-fischer + 1.2.1 (2023-05-10) ------------------ * Update thirdparty deps, rework projected point, enable python 3.10/3.11 (`#300 `_) diff --git a/lanelet2_core/README.md b/lanelet2_core/README.md index 4d96cb4e..7da004fa 100644 --- a/lanelet2_core/README.md +++ b/lanelet2_core/README.md @@ -6,7 +6,7 @@ This package contains the core library of Lanelet2: - The [basic primitives](doc/LaneletPrimitives.md), including LaneletMap - [Geometry functions](doc/GeometryPrimer.md) -For usage examples, please refer to the [lanelet2_examples](../lanelet2_examples/README.md) package. +For usage examples, please refer to the [lanelet2_examples](https://github.com/fzi-forschungszentrum-informatik/Lanelet2/tree/master/lanelet2_examples/README.md) package. ## Debugging diff --git a/lanelet2_core/doc/RegulatoryElementTagging.md b/lanelet2_core/doc/RegulatoryElementTagging.md index 4c1eef9d..05644def 100644 --- a/lanelet2_core/doc/RegulatoryElementTagging.md +++ b/lanelet2_core/doc/RegulatoryElementTagging.md @@ -40,7 +40,7 @@ The most common roles that are used across all regulatory elements are: ### Traffic Sign -A traffic sign generically expresses a restriction that is expressed by a traffic sign. The *refers* part refers to traffic signs that form the rule. The *cancels* parameter then refers to traffic signs that mark the end of the restriction expressed by the sign (e.g. the end of no-overtaking section). The *ref_line* and *cancel_line* parameters can then be used to define the exact start and end points of the rule. The LineStrings referenced by that must not have an intersection with the referencing lanelet or Area. If they do, the rule is valid from/to this intersection point. If not, the rule is valid for the whole lanelet/area. +A traffic sign generically expresses a restriction that is expressed by a traffic sign. The *refers* part refers to traffic signs that form the rule. The *cancels* parameter then refers to traffic signs that mark the end of the restriction expressed by the sign (e.g. the end of no-overtaking section). The *ref_line* and *cancel_line* parameters can then be used to define the exact start and end points of the rule. The LineStrings referenced by that do not necessarily need to have an intersection with the referencing lanelet or Area. If they do, the rule is valid from/to this intersection point. If not, the rule is valid for the whole lanelet/area. ### Speed Limit diff --git a/lanelet2_core/include/lanelet2_core/geometry/LineString.h b/lanelet2_core/include/lanelet2_core/geometry/LineString.h index 8bc7e656..0b929e75 100644 --- a/lanelet2_core/include/lanelet2_core/geometry/LineString.h +++ b/lanelet2_core/include/lanelet2_core/geometry/LineString.h @@ -110,6 +110,18 @@ double signedDistance(const LineString2dT& lineString, const BasicPoint2d& p); template double curvature2d(const Point2dT& p1, const Point2dT& p2, const Point2dT& p3); +/** + * Calculate the signed curvature value given 3 consecutive points. + * The signed curvature value is positive if the consecutive points describe a left turn, negative otherwise. + * + * @param p1, p2, p3 are the points + * @return curvature value. + * + * If any 2 of the 3 points duplicate, return infinity. + */ +template +double signedCurvature2d(const Point2dT& p1, const Point2dT& p2, const Point2dT& p3); + /** * * @brief Transform a point to the coordinates of the linestring diff --git a/lanelet2_core/include/lanelet2_core/geometry/impl/LineString.h b/lanelet2_core/include/lanelet2_core/geometry/impl/LineString.h index 47e0abf0..a6461cfc 100644 --- a/lanelet2_core/include/lanelet2_core/geometry/impl/LineString.h +++ b/lanelet2_core/include/lanelet2_core/geometry/impl/LineString.h @@ -127,7 +127,6 @@ BasicPoint3d project(const CompoundHybridLineString3d& lineString, const BasicPo template std::pair>> signedDistanceImpl(const LineStringT lineString, const PointT& p) { - using BasicPoint = PointT; const auto basicP = utils::toBasicPoint(p); const auto nextSegment = closestSegment(lineString, basicP); const auto projPoint = lanelet::geometry::project(utils::toBasicSegment(nextSegment), basicP); @@ -704,6 +703,11 @@ double signedDistance(const LineString2dT& lineString, const BasicPoint2d& p) { template double curvature2d(const Point2dT& p1, const Point2dT& p2, const Point2dT& p3) { + return std::fabs(signedCurvature2d(p1, p2, p3)); +} + +template +double signedCurvature2d(const Point2dT& p1, const Point2dT& p2, const Point2dT& p3) { // see https://en.wikipedia.org/wiki/Menger_curvature#Definition const double area = 0.5 * ((p2.x() - p1.x()) * (p3.y() - p1.y()) - (p2.y() - p1.y()) * (p3.x() - p1.x())); const double side1 = distance(p1, p2); @@ -713,7 +717,7 @@ double curvature2d(const Point2dT& p1, const Point2dT& p2, const Point2dT& p3) { if (product < 1e-20) { return std::numeric_limits::infinity(); } - return std::fabs(4 * area / product); + return 4 * area / product; } template diff --git a/lanelet2_core/package.xml b/lanelet2_core/package.xml index 911c8c52..221d68fa 100644 --- a/lanelet2_core/package.xml +++ b/lanelet2_core/package.xml @@ -2,7 +2,7 @@ lanelet2_core - 1.2.1 + 1.2.2 Lanelet2 core module BSD diff --git a/lanelet2_core/test/test_linestring.cpp b/lanelet2_core/test/test_linestring.cpp index b8242ee2..7ef3d7c9 100644 --- a/lanelet2_core/test/test_linestring.cpp +++ b/lanelet2_core/test/test_linestring.cpp @@ -413,6 +413,12 @@ TYPED_TEST(AllLineStringsTest, segmentsInverse) { // NOLINT TYPED_TEST(TwoDPointsTest, checkCurvature) { EXPECT_DOUBLE_EQ(1., geometry::curvature2d(this->p1, this->p2, this->p3)); EXPECT_DOUBLE_EQ(std::numeric_limits::infinity(), geometry::curvature2d(this->p1, this->p2, this->p4)); + EXPECT_DOUBLE_EQ(1., geometry::curvature2d(this->p3, this->p2, this->p1)); + EXPECT_DOUBLE_EQ(std::numeric_limits::infinity(), geometry::curvature2d(this->p3, this->p2, this->p4)); + EXPECT_DOUBLE_EQ(1., geometry::signedCurvature2d(this->p1, this->p2, this->p3)); + EXPECT_DOUBLE_EQ(std::numeric_limits::infinity(), geometry::signedCurvature2d(this->p1, this->p2, this->p4)); + EXPECT_DOUBLE_EQ(-1., geometry::signedCurvature2d(this->p3, this->p2, this->p1)); + EXPECT_DOUBLE_EQ(std::numeric_limits::infinity(), geometry::signedCurvature2d(this->p3, this->p2, this->p4)); } TYPED_TEST(TwoDLineStringsTest, signedDistance) { // NOLINT diff --git a/lanelet2_examples/CHANGELOG.rst b/lanelet2_examples/CHANGELOG.rst index e70fe505..9b21d5c1 100644 --- a/lanelet2_examples/CHANGELOG.rst +++ b/lanelet2_examples/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package lanelet2_examples ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +1.2.2 (2024-10-25) +------------------ +* Build documentation with mkdocs (`#321 `_) +* Fix `#324 `_: exception thrown when using GeocentricProjector (`#325 `_) +* Contributors: DavUhll, Michał Antkiewicz + 1.2.1 (2023-05-10) ------------------ diff --git a/lanelet2_examples/README.md b/lanelet2_examples/README.md index f3ca3b1d..6cae22df 100644 --- a/lanelet2_examples/README.md +++ b/lanelet2_examples/README.md @@ -2,7 +2,7 @@ This package contains executable usage examples for people who would like to know how to work with a lanelet2 map. Simply look at the code in the individual lessons. They are equipped with lots of explaining comments. You can also build and run them to see them in action. -The examples are divided into individual lessons that help you step by step to understand lanelet2. Simply look [here](src) for an overview on the C++ tutorials. +The examples are divided into individual lessons that help you step by step to understand lanelet2. Simply look [here](https://github.com/fzi-forschungszentrum-informatik/Lanelet2/tree/master/lanelet2_examples/src) for an overview on the C++ tutorials. -The python tutorials are shorter and demonstrate the similarity of the interface. They can be found [here](scripts/tutorial.py). +The python tutorials are shorter and demonstrate the similarity of the interface. They can be found [here](https://github.com/fzi-forschungszentrum-informatik/Lanelet2/tree/master/lanelet2_examples/scripts/tutorial.py). diff --git a/lanelet2_examples/package.xml b/lanelet2_examples/package.xml index 310c0ea9..60fb1380 100644 --- a/lanelet2_examples/package.xml +++ b/lanelet2_examples/package.xml @@ -2,7 +2,7 @@ lanelet2_examples - 1.2.1 + 1.2.2 Examples for working with Lanelet2 BSD diff --git a/lanelet2_examples/scripts/tutorial.py b/lanelet2_examples/scripts/tutorial.py index 68aea514..d9ee2f38 100755 --- a/lanelet2_examples/scripts/tutorial.py +++ b/lanelet2_examples/scripts/tutorial.py @@ -178,7 +178,7 @@ def part4reading_and_writing(): assert not write_errors ## 3. Write using the default spherical mercator projector at the giver origin - ## This was the default projection in Lanelet1 + ## This was the default projection in Lanelet1. Use is not recommended. lanelet2.io.write(path, map, lanelet2.io.Origin(49, 8.4)) ## 4. Write using the given projector and override the default values of the optional parameters for JOSM @@ -193,6 +193,14 @@ def part4reading_and_writing(): assert not load_errors assert loadedMap.laneletLayer.exists(lanelet.id) + ## GeocentricProjector: the origin is the centre of the Earth + gc_projector = GeocentricProjector() + write_errors = lanelet2.io.writeRobust(path, map, gc_projector) + assert not write_errors + loadedMap, load_errors = lanelet2.io.loadRobust(path, gc_projector) + assert not load_errors + assert loadedMap.laneletLayer.exists(lanelet.id) + def part5traffic_rules(): # this is just as you would expect diff --git a/lanelet2_io/CHANGELOG.rst b/lanelet2_io/CHANGELOG.rst index 728139f6..bb2934f8 100644 --- a/lanelet2_io/CHANGELOG.rst +++ b/lanelet2_io/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package lanelet2_io ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +1.2.2 (2024-10-25) +------------------ +* Build documentation with mkdocs (`#321 `_) +* Contributors: DavUhll + 1.2.1 (2023-05-10) ------------------ diff --git a/lanelet2_io/README.md b/lanelet2_io/README.md index f6f293d1..81f3b160 100644 --- a/lanelet2_io/README.md +++ b/lanelet2_io/README.md @@ -5,7 +5,7 @@ IO Module for parsing and writing LaneletMaps. It contains a various reader/writer functions for different formats. Which format will be used is determined the extension of the given filename. If a writer/parser is registered for this extension, it will be chosen automatically. Currently available IO modules are: -- **OSM (.osm)** writes/loads specialized lanelet maps from OpenStreetMap html files. See [maps module](../lanelet2_maps/README.md) for a primer on this. +- **OSM (.osm)** writes/loads specialized lanelet maps from OpenStreetMap html files. See [maps module](https://github.com/fzi-forschungszentrum-informatik/Lanelet2/tree/master/lanelet2_maps/README.md) for a primer on this. - **Binary (.bin)** writes/loads the map to/from an internal bin format. Very efficient for writing and reading but not human-readable @@ -14,7 +14,7 @@ Most IO modules require a projection from WGS84 (lat/lon) to a local metric coor The origin should be as close to where the map is as possible. -For an overview on projections, have a look at the [projection module](../lanelet2_projection/README.md). +For an overview on projections, have a look at the [projection module](https://github.com/fzi-forschungszentrum-informatik/Lanelet2/tree/master/lanelet2_projection/README.md). ## Usage diff --git a/lanelet2_io/package.xml b/lanelet2_io/package.xml index ac5b3d47..678b8670 100644 --- a/lanelet2_io/package.xml +++ b/lanelet2_io/package.xml @@ -2,7 +2,7 @@ lanelet2_io - 1.2.1 + 1.2.2 Parser/Writer module for lanelet2 BSD diff --git a/lanelet2_maps/CHANGELOG.rst b/lanelet2_maps/CHANGELOG.rst index aa6484c3..30baaa1f 100644 --- a/lanelet2_maps/CHANGELOG.rst +++ b/lanelet2_maps/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package lanelet2_maps ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +1.2.2 (2024-10-25) +------------------ +* bugfix speed limit preset in laneletpresets.xml (`#318 `_) +* Contributors: R-Fehler + 1.2.1 (2023-05-10) ------------------ diff --git a/lanelet2_maps/josm/laneletpresets.xml b/lanelet2_maps/josm/laneletpresets.xml index a07f5f8d..0b4aca99 100644 --- a/lanelet2_maps/josm/laneletpresets.xml +++ b/lanelet2_maps/josm/laneletpresets.xml @@ -271,7 +271,7 @@ - + diff --git a/lanelet2_maps/package.xml b/lanelet2_maps/package.xml index 907f78fb..faab23b1 100644 --- a/lanelet2_maps/package.xml +++ b/lanelet2_maps/package.xml @@ -2,7 +2,7 @@ lanelet2_maps - 1.2.1 + 1.2.2 Example maps in the lanelet2-format BSD diff --git a/lanelet2_matching/CHANGELOG.rst b/lanelet2_matching/CHANGELOG.rst index 5f28d895..0ef414ae 100644 --- a/lanelet2_matching/CHANGELOG.rst +++ b/lanelet2_matching/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package lanelet2_matching ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +1.2.2 (2024-10-25) +------------------ + 1.2.1 (2023-05-10) ------------------ diff --git a/lanelet2_matching/package.xml b/lanelet2_matching/package.xml index 7668c526..e8a488eb 100644 --- a/lanelet2_matching/package.xml +++ b/lanelet2_matching/package.xml @@ -2,7 +2,7 @@ lanelet2_matching - 1.2.1 + 1.2.2 Library to match objects to lanelets BSD diff --git a/lanelet2_projection/CHANGELOG.rst b/lanelet2_projection/CHANGELOG.rst index 18dba275..13e3fac8 100644 --- a/lanelet2_projection/CHANGELOG.rst +++ b/lanelet2_projection/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package lanelet2_projection ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +1.2.2 (2024-10-25) +------------------ +* Fix `#324 `_: exception thrown when using GeocentricProjector (`#325 `_) +* Contributors: Michał Antkiewicz + 1.2.1 (2023-05-10) ------------------ diff --git a/lanelet2_projection/include/lanelet2_projection/Geocentric.h b/lanelet2_projection/include/lanelet2_projection/Geocentric.h index 33808e00..93737efb 100644 --- a/lanelet2_projection/include/lanelet2_projection/Geocentric.h +++ b/lanelet2_projection/include/lanelet2_projection/Geocentric.h @@ -6,6 +6,9 @@ namespace projection { class GeocentricProjector : public Projector { public: + // initialize the origin so that it's not the default one which causes + // IOHandler::handleDefaultProjector to throw an exception + GeocentricProjector() : Projector{Origin({90.0, 0.0, -6356752.3})} {} BasicPoint3d forward(const GPSPoint& gps) const override; GPSPoint reverse(const BasicPoint3d& enu) const override; }; diff --git a/lanelet2_projection/package.xml b/lanelet2_projection/package.xml index 6a24333f..ac7588d8 100644 --- a/lanelet2_projection/package.xml +++ b/lanelet2_projection/package.xml @@ -2,7 +2,7 @@ lanelet2_projection - 1.2.1 + 1.2.2 Lanelet2 projection library for lat/lon to local x/y conversion BSD diff --git a/lanelet2_python/CHANGELOG.rst b/lanelet2_python/CHANGELOG.rst index 193a4378..aaf3b0b3 100644 --- a/lanelet2_python/CHANGELOG.rst +++ b/lanelet2_python/CHANGELOG.rst @@ -2,13 +2,33 @@ Changelog for package lanelet2_python ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +1.2.2 (2024-10-25) +------------------ +* Update print_ids.py to Python3 (`#357 `_) +* Implement signed curvature (`#355 `_) +* Migrate conanfile to conan2 (`#364 `_) +* Add missing argument in RoutingGraph.routingRelation python interface (`#349 `_) + Co-authored-by: poggenhans +* Add/fix python repr interface for 2d lines/points (`#348 `_) + * Add/fix python repr interface for 2d lines/points + * Remove whitespace + --------- + Co-authored-by: poggenhans +* Improve ArcCoordinates interface (`#351 `_) + * improve python interface for ArcCoordinates + Co-authored-by: poggenhans +* Added missing to_python converter for ConstWeakLanelet (`#331 `_) + Co-authored-by: Julian Brandes +* Build documentation with mkdocs (`#321 `_) +* Contributors: DavUhll, Julian, R-Fehler, johannes-fischer, poggenhans + 1.2.1 (2023-05-10) ------------------ * Improve python core module (`#293 `_) Improve lanelet2.core python wrappers add docstrings, named arguments and __repr_\_ methods to core primitives in python, fix bugs and add more initialization options --------- - Co-authored-by: Fabian Poggenhans + Co-authored-by: Fabian Poggenhans * Add readme to PyPi package description and fix readme icons (`#283 `_) * Build lanelet2 wheel and publish in GH release and PyPI (`#278 `_) * Contributors: Jan Rudolph, immel-f, poggenhans diff --git a/lanelet2_python/README.md b/lanelet2_python/README.md index 91741b0b..86f79318 100644 --- a/lanelet2_python/README.md +++ b/lanelet2_python/README.md @@ -15,4 +15,4 @@ for elem in map.laneletLayer: elem.attributes["participant:vehicle"] = "no" ``` -For more usage examples refer to our [example package](../lanelet2_examples/README.md). +For more usage examples refer to our [example package](https://github.com/fzi-forschungszentrum-informatik/Lanelet2/tree/master/lanelet2_examples/README.md). diff --git a/lanelet2_python/package.xml b/lanelet2_python/package.xml index 57d6d3ed..68f1d2c9 100644 --- a/lanelet2_python/package.xml +++ b/lanelet2_python/package.xml @@ -2,7 +2,7 @@ lanelet2_python - 1.2.1 + 1.2.2 Python bindings for lanelet2 BSD diff --git a/lanelet2_python/python_api/core.cpp b/lanelet2_python/python_api/core.cpp index 6c0bb7eb..54faea85 100644 --- a/lanelet2_python/python_api/core.cpp +++ b/lanelet2_python/python_api/core.cpp @@ -152,6 +152,12 @@ struct ConstLaneletOrAreaToObject { } }; +struct ConstWeakLaneletToObject { + static PyObject* convert(const lanelet::ConstWeakLanelet& v) { + return incref(object(v.lock()).ptr()); + } +}; + template struct MapItem { using K = typename T::key_type; @@ -658,6 +664,8 @@ BOOST_PYTHON_MODULE(PYTHON_API_MODULE_NAME) { // NOLINT to_python_converter(); to_python_converter(); to_python_converter(); + to_python_converter(); + implicitly_convertible(); implicitly_convertible(); implicitly_convertible(); @@ -692,6 +700,8 @@ BOOST_PYTHON_MODULE(PYTHON_API_MODULE_NAME) { // NOLINT .def(IsConstPrimitive()) .add_property("x", getXWrapper, "x coordinate") .add_property("y", getYWrapper, "y coordinate") + .def( + "__repr__", +[](const ConstPoint2d& p) { return makeRepr("ConstPoint2d", p.id(), p.x(), p.y(), repr(p.attributes())); }) .def("basicPoint", &ConstPoint2d::basicPoint, return_internal_reference<>(), "Returns a plain 2D point primitive (no ID, no attributes) for efficient geometry operations"); class_>( @@ -788,8 +798,8 @@ BOOST_PYTHON_MODULE(PYTHON_API_MODULE_NAME) { // NOLINT "returned in reversed order") .def( "__repr__", - +[](const ConstLineString3d& ls) { - return makeRepr("LineString3d", ls.id(), repr(list(ls)), repr(ls.attributes())); + +[](const LineString2d& ls) { + return makeRepr("LineString2d", ls.id(), repr(list(ls)), repr(ls.attributes())); }) .def(IsLineString()); diff --git a/lanelet2_python/python_api/geometry.cpp b/lanelet2_python/python_api/geometry.cpp index 1ac82147..d4bf866a 100644 --- a/lanelet2_python/python_api/geometry.cpp +++ b/lanelet2_python/python_api/geometry.cpp @@ -288,9 +288,28 @@ BOOST_PYTHON_MODULE(PYTHON_API_MODULE_NAME) { // NOLINT def("area", boost::geometry::area); def("area", boost::geometry::area); - class_("ArcCoordinates", "Coordinates along an arc", init<>()) + def("curvature2d", lg::curvature2d); + def("curvature2d", lg::curvature2d); + + def("signedCurvature2d", lg::signedCurvature2d); + def("signedCurvature2d", lg::signedCurvature2d); + + class_("ArcCoordinates", "Coordinates along an arc", no_init) + .def("__init__", make_constructor( + +[](double length, double distance) { + return std::make_shared(ArcCoordinates{length, distance}); + }, + default_call_policies(), + (arg("length") = 0., arg("distance") = 0.))) .def_readwrite("length", &ArcCoordinates::length, "length along arc") - .def_readwrite("distance", &ArcCoordinates::distance, "signed distance to arc (left is positive"); + .def_readwrite("distance", &ArcCoordinates::distance, "signed distance to arc (left is positive") + .def( + "__eq__", +[](const ArcCoordinates& ac1, + const ArcCoordinates& ac2) { return ac1.length == ac2.length && ac1.distance == ac2.distance; }) + .def( + "__repr__", +[](const ArcCoordinates& ac) { + return "ArcCoordinates(" + std::to_string(ac.length) + ", " + std::to_string(ac.distance) + ")"; + }); def("toArcCoordinates", lg::toArcCoordinates, "Project a point into arc coordinates of the linestring"); diff --git a/lanelet2_python/python_api/routing.cpp b/lanelet2_python/python_api/routing.cpp index ddfef5d2..f159a242 100644 --- a/lanelet2_python/python_api/routing.cpp +++ b/lanelet2_python/python_api/routing.cpp @@ -193,7 +193,7 @@ BOOST_PYTHON_MODULE(PYTHON_API_MODULE_NAME) { // NOLINT "shortest path between 'start' and 'end' using intermediate points", (arg("start"), arg("via"), arg("end"), arg("routingCostId") = 0, arg("withLaneChanges") = true)) .def("routingRelation", &RoutingGraph::routingRelation, "relation between two lanelets excluding 'conflicting'", - (arg("from"), arg("to"))) + (arg("from"), arg("to"), arg("includeConflicting") = false)) .def("following", &RoutingGraph::following, "lanelets that can be reached from this lanelet", lltAndLc) .def("followingRelations", &RoutingGraph::followingRelations, "relations to following lanelets", lltAndLc) .def("previous", &RoutingGraph::previous, "previous lanelets of this lanelet", lltAndLc) diff --git a/lanelet2_python/scripts/print_ids.py b/lanelet2_python/scripts/print_ids.py index d2435f9b..dca9c491 100755 --- a/lanelet2_python/scripts/print_ids.py +++ b/lanelet2_python/scripts/print_ids.py @@ -21,7 +21,7 @@ def print_layer(layer, layerName): layers = {"Points": map.pointLayer, "Line Strings": map.lineStringLayer, "Polygons": map.polygonLayer, "Lanelets": map.laneletLayer, "Areas": map.areaLayer, "Regulatory Elements": map.regulatoryElementLayer} -for layer_name, layer in layers.iteritems(): +for layer_name, layer in layers.items(): if not args.has_id: print_layer(layer, layer_name) else: diff --git a/lanelet2_python/setup.py.template b/lanelet2_python/setup.py.template index d5d2b7e7..57effa9c 100644 --- a/lanelet2_python/setup.py.template +++ b/lanelet2_python/setup.py.template @@ -11,22 +11,44 @@ DESCRIPTION = "Map handling framework for automated driving." MAINTAINER = "Fabian Immel" MAINTAINER_EMAIL = "fabian.immel@kit.edu" URL = "https://github.com/fzi-forschungszentrum-informatik/Lanelet2" -LICENSE = "BSD" DOWNLOAD_URL = "https://github.com/fzi-forschungszentrum-informatik/Lanelet2/releases/tag/{{ version }}" VERSION = "{{ version }}" -this_directory = Path(__file__).parent -long_description = (this_directory /"src" / "lanelet2" / "README.md").read_text() +long_description = """ +Lanelet2 is a C++-based framework 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** +""" + +classifiers = [ + "Development Status :: 5 - Production/Stable", + "License :: OSI Approved :: BSD License", + "Operating System :: Unix", + "Programming Language :: Python :: 3", + "Programming Language :: C++", +] + class ExtModules(list): def __bool__(self): return True setup(name=DISTNAME, + classifiers=classifiers, description=DESCRIPTION, maintainer=MAINTAINER, maintainer_email=MAINTAINER_EMAIL, url=URL, - license=LICENSE, download_url=DOWNLOAD_URL, version=VERSION, packages=["lanelet2"], diff --git a/lanelet2_routing/CHANGELOG.rst b/lanelet2_routing/CHANGELOG.rst index 65bd9323..86cdfbbe 100644 --- a/lanelet2_routing/CHANGELOG.rst +++ b/lanelet2_routing/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package lanelet2_routing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +1.2.2 (2024-10-25) +------------------ +* Prevent unintended modification of graph in lanelet::routing::Route (`#352 `_) +* Build documentation with mkdocs (`#321 `_) +* Contributors: DavUhll, poggenhans + 1.2.1 (2023-05-10) ------------------ * Update thirdparty deps, rework projected point, enable python 3.10/3.11 (`#300 `_) diff --git a/lanelet2_routing/README.md b/lanelet2_routing/README.md index c971680c..b6a3f6f7 100644 --- a/lanelet2_routing/README.md +++ b/lanelet2_routing/README.md @@ -19,7 +19,7 @@ The needed components to create a routing graph are: * **You can easily plug in your own routing cost calculation** * *Influences the prefered path* -**Traffic Rules for a Specific Participant** (see [lanelet2_traffic_rules](../lanelet2_traffic_rules/README.md)) +**Traffic Rules for a Specific Participant** (see [lanelet2_traffic_rules](https://github.com/fzi-forschungszentrum-informatik/Lanelet2/tree/master/lanelet2_traffic_rules/README.md)) * Determines which lanelets/areas are passable * *Influences the possible paths* diff --git a/lanelet2_routing/package.xml b/lanelet2_routing/package.xml index 54f2152f..58a316bc 100644 --- a/lanelet2_routing/package.xml +++ b/lanelet2_routing/package.xml @@ -2,7 +2,7 @@ lanelet2_routing - 1.2.1 + 1.2.2 Routing module for lanelet2 BSD diff --git a/lanelet2_routing/src/Route.cpp b/lanelet2_routing/src/Route.cpp index a17adede..380affdd 100644 --- a/lanelet2_routing/src/Route.cpp +++ b/lanelet2_routing/src/Route.cpp @@ -192,7 +192,7 @@ double Route::length2d() const { size_t Route::numLanes() const { std::set lanes; - auto& g = graph_->get(); + const auto& g = graph_->get(); for (auto v : g.vertex_set()) { lanes.emplace(g[v].laneId); } @@ -342,7 +342,7 @@ ConstLaneletOrAreas Route::conflictingInMap(const ConstLanelet& lanelet) const { } ConstLaneletOrAreas lanelet::routing::Route::allConflictingInMap() const { - auto& g = graph_->get(); + const auto& g = graph_->get(); return utils::concatenateRange(g.vertex_set(), [&](auto v) { auto& conf = g[v].conflictingInMap; return std::make_pair(std::begin(conf), std::end(conf)); @@ -369,7 +369,7 @@ Route::Errors Route::checkValidity(bool throwOnError) const { } } // Check if all relations are back and forth - auto g = graph_->get(); + const auto& g = graph_->get(); auto edges = boost::edges(g); std::for_each(edges.first, edges.second, [&](internal::RouteGraph::Edge e) { // get reverse edge diff --git a/lanelet2_traffic_rules/CHANGELOG.rst b/lanelet2_traffic_rules/CHANGELOG.rst index 2f2d1ccb..5ab5092d 100644 --- a/lanelet2_traffic_rules/CHANGELOG.rst +++ b/lanelet2_traffic_rules/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package lanelet2_traffic_rules ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +1.2.2 (2024-10-25) +------------------ +* Build documentation with mkdocs (`#321 `_) +* Contributors: DavUhll + 1.2.1 (2023-05-10) ------------------ diff --git a/lanelet2_traffic_rules/README.md b/lanelet2_traffic_rules/README.md index ed6a488d..9b730ede 100644 --- a/lanelet2_traffic_rules/README.md +++ b/lanelet2_traffic_rules/README.md @@ -18,7 +18,7 @@ lanelet::traffic_rules::SpeedLimitInformation speedLimit = trafficRulesPtr->spee This package offers the abstract `TrafficRules` class that is used as an interface to interpret the data in the map. It provides information whether a lanelet is usable/drivable, where lane changes are possible and what the speed limits are. -Derived from this is the abstract `GenericTrafficRules` class that implements the traffic rules based on the [tagging specification](../lanelet2_core/doc). This class can then be derived to create traffic rules for individual countries and participants. This is especially important for the speed limits and interpreting country specific traffic signs. +Derived from this is the abstract `GenericTrafficRules` class that implements the traffic rules based on the [tagging specification](https://github.com/fzi-forschungszentrum-informatik/Lanelet2/tree/master/lanelet2_core/doc). This class can then be derived to create traffic rules for individual countries and participants. This is especially important for the speed limits and interpreting country specific traffic signs. After registering this class using `RegisterTrafficRules`, Lanelet2 is able to create instances of this traffic rule using the `TrafficRuleFactory`. diff --git a/lanelet2_traffic_rules/package.xml b/lanelet2_traffic_rules/package.xml index 258b37ee..7efee1c2 100644 --- a/lanelet2_traffic_rules/package.xml +++ b/lanelet2_traffic_rules/package.xml @@ -2,7 +2,7 @@ lanelet2_traffic_rules - 1.2.1 + 1.2.2 Package for interpreting traffic rules in a lanelet map BSD diff --git a/lanelet2_validation/CHANGELOG.rst b/lanelet2_validation/CHANGELOG.rst index b78e04e1..7d68273c 100644 --- a/lanelet2_validation/CHANGELOG.rst +++ b/lanelet2_validation/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package lanelet2_validation ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +1.2.2 (2024-10-25) +------------------ + 1.2.1 (2023-05-10) ------------------ diff --git a/lanelet2_validation/package.xml b/lanelet2_validation/package.xml index 6ec41574..4484939a 100644 --- a/lanelet2_validation/package.xml +++ b/lanelet2_validation/package.xml @@ -2,7 +2,7 @@ lanelet2_validation - 1.2.1 + 1.2.2 Package for sanitizing lanelet maps BSD diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 00000000..edf27172 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,29 @@ +site_name: Lanelet2 +repo_url: https://github.com/fzi-forschungszentrum-informatik/Lanelet2 +docs_dir: docs +edit_uri: 'edit/master/docs/' +theme: readthedocs + +nav: +- Home: 'index.md' +- lanelet2_core: 'lanelet2_core.md' +- lanelet2_examples: 'lanelet2_examples.md' +- lanelet2_io: 'lanelet2_io.md' +- lanelet2_maps: 'lanelet2_maps.md' +- lanelet2_matching: 'lanelet2_matching.md' +- lanelet2_projection: 'lanelet2_projection.md' +- lanelet2_python: 'lanelet2_python.md' +- lanelet2_routing: 'lanelet2_routing.md' +- lanelet2_traffic_rules: 'lanelet2_traffic_rules.md' +- lanelet2_validation: 'lanelet2_validation.md' + +- Detailed Documentation: + - 'Architecture': 'lanelet2_core/Architecture.md' + - 'GeometryPrimer': 'lanelet2_core/GeometryPrimer.md' + - 'Lanelet1Compability': 'lanelet2_core/Lanelet1Compability.md' + - 'LaneletAndAreaTagging': 'lanelet2_core/LaneletAndAreaTagging.md' + - 'LaneletPrimitives': 'lanelet2_core/LaneletPrimitives.md' + - 'LinestringTagging': 'lanelet2_core/LinestringTagging.md' + - 'RegulatoryElementTagging': 'lanelet2_core/RegulatoryElementTagging.md' + - 'Map_Projections_Coordinate_Systems': 'lanelet2_projection/Map_Projections_Coordinate_Systems.md' +