├── .github ├── ISSUE_TEMPLATE.md └── workflows │ ├── style.yml │ └── tests.yml ├── .gitignore ├── .pre-commit-config.yaml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── docs ├── Makefile ├── authors.rst ├── conf.py ├── history.rst ├── index.rst ├── installation.rst ├── make.bat ├── readme.rst └── usage.rst ├── map_metrics ├── __init__.py ├── config.py ├── metrics.py └── utils │ ├── __init__.py │ └── orthogonal.py ├── pyproject.toml ├── requirements.txt └── tests ├── data ├── depth │ ├── README.md │ ├── orth_subset │ │ └── orth-0091.npy │ ├── pcs │ │ ├── PC-0071.pcd │ │ ├── PC-0081.pcd │ │ ├── PC-0091.pcd │ │ ├── PC-0101.pcd │ │ ├── PC-0111.pcd │ │ ├── PC-0121.pcd │ │ ├── PC-0131.pcd │ │ ├── PC-0141.pcd │ │ ├── PC-0151.pcd │ │ ├── PC-0161.pcd │ │ ├── PC-0171.pcd │ │ ├── PC-0181.pcd │ │ ├── PC-0191.pcd │ │ ├── PC-0201.pcd │ │ ├── PC-0211.pcd │ │ ├── PC-0221.pcd │ │ ├── PC-0231.pcd │ │ ├── PC-0241.pcd │ │ ├── PC-0251.pcd │ │ ├── PC-0261.pcd │ │ ├── PC-0271.pcd │ │ ├── PC-0281.pcd │ │ ├── PC-0291.pcd │ │ ├── PC-0301.pcd │ │ ├── PC-0311.pcd │ │ ├── PC-0321.pcd │ │ ├── PC-0331.pcd │ │ └── PC-0341.pcd │ └── poses │ │ ├── pose-0071.txt │ │ ├── pose-0081.txt │ │ ├── pose-0091.txt │ │ ├── pose-0101.txt │ │ ├── pose-0111.txt │ │ ├── pose-0121.txt │ │ ├── pose-0131.txt │ │ ├── pose-0141.txt │ │ ├── pose-0151.txt │ │ ├── pose-0161.txt │ │ ├── pose-0171.txt │ │ ├── pose-0181.txt │ │ ├── pose-0191.txt │ │ ├── pose-0201.txt │ │ ├── pose-0211.txt │ │ ├── pose-0221.txt │ │ ├── pose-0231.txt │ │ ├── pose-0241.txt │ │ ├── pose-0251.txt │ │ ├── pose-0261.txt │ │ ├── pose-0271.txt │ │ ├── pose-0281.txt │ │ ├── pose-0291.txt │ │ ├── pose-0301.txt │ │ ├── pose-0311.txt │ │ ├── pose-0321.txt │ │ ├── pose-0331.txt │ │ └── pose-0341.txt └── lidar │ ├── README.md │ ├── pcs │ ├── 000000.bin │ ├── 000001.bin │ ├── 000002.bin │ ├── 000003.bin │ ├── 000004.bin │ ├── 000005.bin │ ├── 000006.bin │ ├── 000007.bin │ ├── 000008.bin │ ├── 000009.bin │ ├── 000010.bin │ ├── 000011.bin │ ├── 000012.bin │ ├── 000013.bin │ ├── 000014.bin │ ├── 000015.bin │ ├── 000016.bin │ ├── 000017.bin │ ├── 000018.bin │ └── 000019.bin │ └── poses.txt ├── test_config.py ├── test_metrics.py └── test_orthogonal.py /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | * Map Metrics version: 2 | * Python version: 3 | * Operating System: 4 | 5 | ### Description 6 | 7 | Describe what you were trying to get done. 8 | Tell us what happened, what went wrong, and what you expected to happen. 9 | 10 | ### What I Did 11 | 12 | ``` 13 | Paste the command(s) you ran and the output. 14 | If there was a crash, please include the traceback here. 15 | ``` 16 | -------------------------------------------------------------------------------- /.github/workflows/style.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: Code style 4 | 5 | # Controls when the workflow will run 6 | on: 7 | # Triggers the workflow on push or pull request events 8 | [ push, pull_request ] 9 | 10 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 11 | jobs: 12 | 13 | # This workflow contains a single job called "style" 14 | style: 15 | 16 | # The type of runner that the job will run on 17 | runs-on: ubuntu-latest 18 | 19 | # A strategy creates a build matrix for your jobs 20 | strategy: 21 | 22 | # You can define a matrix of different job configurations 23 | matrix: 24 | 25 | # Each option you define in the matrix has a key and value 26 | python-version: [ 3.8 ] 27 | 28 | # Steps represent a sequence of tasks that will be executed as part of the job 29 | steps: 30 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 31 | - name: Set up Git repository 32 | uses: actions/checkout@v2 33 | 34 | # Setup Python with version from matrix 35 | - name: Set up Python ${{ matrix.python-version }} 36 | uses: actions/setup-python@v2 37 | with: 38 | python-version: ${{ matrix.python-version }} 39 | 40 | # Install requirements 41 | - name: Install requirements 42 | 43 | # Runs command-line programs using the operating system's shell 44 | run: | 45 | python -m pip install --upgrade pip wheel setuptools 46 | python -m pip install pre-commit black 47 | python -m pip list 48 | 49 | # Install pre-commit from .pre-commit-config.yaml 50 | - name: Install pre-commit 51 | run: | 52 | pre-commit install 53 | 54 | # Run pre-commit on all the files in the repo 55 | - name: Run pre-commit 56 | run: | 57 | pre-commit run --all-files --color always --verbose --show-diff-on-failure 58 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: Check tests 4 | 5 | # Controls when the workflow will run 6 | on: 7 | # Triggers the workflow on push or pull request events 8 | [ push, pull_request ] 9 | 10 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 11 | jobs: 12 | 13 | # This workflow contains a single job called "style" 14 | build-and-test: 15 | 16 | # The type of runner that the job will run on 17 | runs-on: ${{ matrix.os }} 18 | 19 | # A strategy creates a build matrix for your jobs 20 | strategy: 21 | 22 | # You can define a matrix of different job configurations 23 | matrix: 24 | os: [macos-latest, windows-latest, ubuntu-latest] 25 | 26 | # Each option you define in the matrix has a key and value 27 | python-version: [ 3.8 ] 28 | 29 | # Steps represent a sequence of tasks that will be executed as part of the job 30 | steps: 31 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 32 | - name: Set up Git repository 33 | uses: actions/checkout@v2 34 | 35 | # Setup Python with version from matrix 36 | - name: Set up Python ${{ matrix.python-version }} 37 | uses: actions/setup-python@v2 38 | with: 39 | python-version: ${{ matrix.python-version }} 40 | 41 | # Install requirements 42 | - name: Install requirements 43 | shell: bash 44 | # Runs command-line programs using the operating system's shell 45 | run: | 46 | python -m pip install --upgrade pip wheel setuptools 47 | python -m pip install -r requirements.txt 48 | 49 | # Run tests from /tests directory 50 | - name: Run tests 51 | run: | 52 | python -m pytest 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | poetry.lock 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .coverage 43 | .coverage.* 44 | .cache 45 | nosetests.xml 46 | coverage.xml 47 | *.cover 48 | .hypothesis/ 49 | .pytest_cache/ 50 | 51 | # Translations 52 | *.mo 53 | *.pot 54 | 55 | # Django stuff: 56 | *.log 57 | local_settings.py 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # dotenv 85 | .env 86 | 87 | # virtualenv 88 | .venv 89 | venv/ 90 | ENV/ 91 | 92 | # Spyder project settings 93 | .spyderproject 94 | .spyproject 95 | 96 | # Rope project settings 97 | .ropeproject 98 | 99 | # mkdocs documentation 100 | /site 101 | 102 | # mypy 103 | .mypy_cache/ 104 | 105 | # IDE settings 106 | .vscode/ 107 | .idea/ 108 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/pre-commit-hooks 3 | rev: v3.4.0 4 | hooks: 5 | - id: check-yaml 6 | - id: end-of-file-fixer 7 | - id: trailing-whitespace 8 | - id: requirements-txt-fixer 9 | - repo: https://github.com/psf/black 10 | rev: 21.7b0 11 | hooks: 12 | - id: black 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/CHANGELOG.md -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache Software License 2.0 2 | 3 | Copyright (c) 2022, Skolkovo Institute of Science and Technology (Skoltech) 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # map-metrics 2 | Map metrics toolkit provides a set of metrics **to quantitatively evaluate trajectory quality via estimating 3 | consistency of the map aggregated from point clouds**. 4 | 5 | GPS or Motion Capture systems are not always available in perception systems, or their quality is not enough (GPS on 6 | small-scale distances) for use as ground truth trajectory. Thus, common full-reference trajectory metrics (APE, 7 | RPE, and their modifications) could not be applied to evaluate trajectory quality. When 3D sensing technologies (depth 8 | camera, LiDAR) are available on the perception system, one can alternatively assess trajectory quality -- estimate 9 | the consistency of the map from registered point clouds via the trajectory. 10 | 11 | ## Installation 12 | ```bash 13 | $ pip install map-metrics 14 | ``` 15 | 16 | ## Usage 17 | Run metric algorithms from `map_metrics` on your point cloud data. 18 | 19 | ```python 20 | from map_metrics.metrics import mme 21 | from map_metrics.config import LidarConfig 22 | 23 | result = mme(pointclouds, poses, config=LidarConfig) 24 | ``` 25 | 26 | ## License 27 | License... 28 | 29 | ## Credits 30 | Credits... 31 | 32 | ## Citation 33 | If you use this toolkit or MOM-metric results, please, cite our work: 34 | 35 | @misc{kornilova2021benchmark, 36 | title={Be your own Benchmark: No-Reference Trajectory Metric on Registered Point Clouds}, 37 | author={Anastasiia Kornilova and Gonzalo Ferrer}, 38 | year={2021}, 39 | eprint={2106.11351}, 40 | archivePrefix={arXiv}, 41 | primaryClass={cs.RO} 42 | } 43 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = python -msphinx 7 | SPHINXPROJ = map_metrics 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/authors.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../AUTHORS.rst 2 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # map_metrics documentation build configuration file, created by 4 | # sphinx-quickstart on Fri Jun 9 13:47:02 2017. 5 | # 6 | # This file is execfile()d with the current directory set to its 7 | # containing dir. 8 | # 9 | # Note that not all possible configuration values are present in this 10 | # autogenerated file. 11 | # 12 | # All configuration values have a default; values that are commented out 13 | # serve to show the default. 14 | 15 | # If extensions (or modules to document with autodoc) are in another 16 | # directory, add these directories to sys.path here. If the directory is 17 | # relative to the documentation root, use os.path.abspath to make it 18 | # absolute, like shown here. 19 | # 20 | import os 21 | import sys 22 | 23 | sys.path.insert(0, os.path.abspath("..")) 24 | 25 | import map_metrics 26 | 27 | # -- General configuration --------------------------------------------- 28 | 29 | # If your documentation needs a minimal Sphinx version, state it here. 30 | # 31 | # needs_sphinx = '1.0' 32 | 33 | # Add any Sphinx extension module names here, as strings. They can be 34 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. 35 | extensions = ["sphinx.ext.autodoc", "sphinx.ext.viewcode"] 36 | 37 | # Add any paths that contain templates here, relative to this directory. 38 | templates_path = ["_templates"] 39 | 40 | # The suffix(es) of source filenames. 41 | # You can specify multiple suffix as a list of string: 42 | # 43 | # source_suffix = ['.rst', '.md'] 44 | source_suffix = ".rst" 45 | 46 | # The master toctree document. 47 | master_doc = "index" 48 | 49 | # General information about the project. 50 | project = "Map Metrics" 51 | copyright = "2022, Skoltech" 52 | author = "Anastasiia Kornilova, Arthur Chains" 53 | 54 | # The version info for the project you're documenting, acts as replacement 55 | # for |version| and |release|, also used in various other places throughout 56 | # the built documents. 57 | # 58 | # The short X.Y version. 59 | version = map_metrics.__version__ 60 | # The full version, including alpha/beta/rc tags. 61 | release = map_metrics.__version__ 62 | 63 | # The language for content autogenerated by Sphinx. Refer to documentation 64 | # for a list of supported languages. 65 | # 66 | # This is also used if you do content translation via gettext catalogs. 67 | # Usually you set "language" from the command line for these cases. 68 | language = None 69 | 70 | # List of patterns, relative to source directory, that match files and 71 | # directories to ignore when looking for source files. 72 | # This patterns also effect to html_static_path and html_extra_path 73 | exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] 74 | 75 | # The name of the Pygments (syntax highlighting) style to use. 76 | pygments_style = "sphinx" 77 | 78 | # If true, `todo` and `todoList` produce output, else they produce nothing. 79 | todo_include_todos = False 80 | 81 | 82 | # -- Options for HTML output ------------------------------------------- 83 | 84 | # The theme to use for HTML and HTML Help pages. See the documentation for 85 | # a list of builtin themes. 86 | # 87 | html_theme = "sphinx_rtd_theme" 88 | 89 | # Theme options are theme-specific and customize the look and feel of a 90 | # theme further. For a list of options available for each theme, see the 91 | # documentation. 92 | # 93 | # html_theme_options = {} 94 | 95 | # Add any paths that contain custom static files (such as style sheets) here, 96 | # relative to this directory. They are copied after the builtin static files, 97 | # so a file named "default.css" will overwrite the builtin "default.css". 98 | html_static_path = ["_static"] 99 | 100 | 101 | # -- Options for HTMLHelp output --------------------------------------- 102 | 103 | # Output file base name for HTML help builder. 104 | htmlhelp_basename = "map_metricsdoc" 105 | 106 | 107 | # -- Options for LaTeX output ------------------------------------------ 108 | 109 | latex_elements = { 110 | # The paper size ('letterpaper' or 'a4paper'). 111 | # 112 | # 'papersize': 'letterpaper', 113 | # The font size ('10pt', '11pt' or '12pt'). 114 | # 115 | # 'pointsize': '10pt', 116 | # Additional stuff for the LaTeX preamble. 117 | # 118 | # 'preamble': '', 119 | # Latex figure (float) alignment 120 | # 121 | # 'figure_align': 'htbp', 122 | } 123 | 124 | # Grouping the document tree into LaTeX files. List of tuples 125 | # (source start file, target name, title, author, documentclass 126 | # [howto, manual, or own class]). 127 | latex_documents = [ 128 | ( 129 | master_doc, 130 | "map_metrics.tex", 131 | "Map Metrics Documentation", 132 | "Anastasiia Kornilova", 133 | "manual", 134 | ), 135 | ] 136 | 137 | 138 | # -- Options for manual page output ------------------------------------ 139 | 140 | # One entry per manual page. List of tuples 141 | # (source start file, name, description, authors, manual section). 142 | man_pages = [(master_doc, "map_metrics", "Map Metrics Documentation", [author], 1)] 143 | 144 | 145 | # -- Options for Texinfo output ---------------------------------------- 146 | 147 | # Grouping the document tree into Texinfo files. List of tuples 148 | # (source start file, target name, title, author, 149 | # dir menu entry, description, category) 150 | texinfo_documents = [ 151 | ( 152 | master_doc, 153 | "map_metrics", 154 | "Map Metrics Documentation", 155 | author, 156 | "map_metrics", 157 | "One line description of project.", 158 | "Miscellaneous", 159 | ), 160 | ] 161 | -------------------------------------------------------------------------------- /docs/history.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../HISTORY.rst 2 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | Welcome to Map Metrics's documentation! 2 | ====================================== 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | :caption: Contents: 7 | 8 | readme 9 | installation 10 | usage 11 | authors 12 | history 13 | 14 | Indices and tables 15 | ================== 16 | * :ref:`genindex` 17 | * :ref:`modindex` 18 | * :ref:`search` 19 | -------------------------------------------------------------------------------- /docs/installation.rst: -------------------------------------------------------------------------------- 1 | .. highlight:: shell 2 | 3 | ============ 4 | Installation 5 | ============ 6 | 7 | 8 | Latest release 9 | -------------- 10 | 11 | To install Map Metrics, run this command in your terminal: 12 | 13 | .. code-block:: console 14 | 15 | $ pip install -U pip 16 | $ pip install -U map_metrics 17 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=python -msphinx 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | set SPHINXPROJ=map_metrics 13 | 14 | if "%1" == "" goto help 15 | 16 | %SPHINXBUILD% >NUL 2>NUL 17 | if errorlevel 9009 ( 18 | echo. 19 | echo.The Sphinx module was not found. Make sure you have Sphinx installed, 20 | echo.then set the SPHINXBUILD environment variable to point to the full 21 | echo.path of the 'sphinx-build' executable. Alternatively you may add the 22 | echo.Sphinx directory to PATH. 23 | echo. 24 | echo.If you don't have Sphinx installed, grab it from 25 | echo.http://sphinx-doc.org/ 26 | exit /b 1 27 | ) 28 | 29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 30 | goto end 31 | 32 | :help 33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 34 | 35 | :end 36 | popd 37 | -------------------------------------------------------------------------------- /docs/readme.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../README.rst 2 | -------------------------------------------------------------------------------- /docs/usage.rst: -------------------------------------------------------------------------------- 1 | ===== 2 | Usage 3 | ===== 4 | 5 | To use Map Metrics in a project:: 6 | 7 | import map_metrics 8 | 9 | 10 | Mean Map Entropy (MME) 11 | ---------------------- 12 | 13 | Mean Map Entropy calculcates average entropy of every point vicinity in the aggregated map: 14 | 15 | .. math:: 16 | 17 | h(p_k) = \frac{1}{2}\det \big(2\pi e \Sigma(W(p_k)) \big) 18 | 19 | H(P) = \frac{1}{|P|}\sum_{k=1}^{|P|} h(q_k) 20 | 21 | To use it, provide `pcs` --- a list of point clouds pcs in the form of `open3d.PointCloud` and `Ts` --- a list of 22 | corresponding poses in the trajectory in the form of `4x4` transformation matrices. 23 | 24 | .. code-block:: python 25 | 26 | map_metrics.mme(pcs, Ts) 27 | 28 | 29 | Mean Plane Variance (MPV) 30 | ------------------------- 31 | 32 | Mean Plane Variance calculcates average plane variance of every point vicinity in the aggregated map: 33 | 34 | .. math:: 35 | V(P) = \frac{1}{|P|}\sum_{k=1}^{|P|}v(p_k) = \frac{1}{|P|}\sum_{k=1}^{|P|} \lambda_{min} 36 | 37 | To use it, provide `pcs` --- a list of point clouds pcs in the form of `open3d.PointCloud` and `Ts` --- a list of 38 | corresponding poses in the trajectory in the form of `4x4` transformation matrices. 39 | 40 | .. code-block:: python 41 | 42 | map_metrics.mpv(pcs, Ts) 43 | 44 | 45 | Mutually Orthogonal Metric (MOM) 46 | -------------------------------- 47 | 48 | Mutual Orthogonality is a concept of considering not all points in the map but only ones from mutually orthogonal 49 | surfaces. Mean Plane Variance over those points provides (as described in our paper) correlation with Relative Pose 50 | Error (RPE) --- one of the popular full-reference metrics for trajectories. 51 | 52 | To use it, provide `pcs` --- a list of point clouds pcs in the form of `open3d.PointCloud` and `Ts` --- a list of 53 | corresponding poses in the trajectory in the form of `4x4` transformation matrices. 54 | 55 | .. code-block:: python 56 | 57 | map_metrics.mom(pcs, Ts) 58 | 59 | The default usage of the method assumes extraction of points from mutually orthogonal surfaces during the method 60 | execution and therefore increase calculation time. One can extract those points manually one time for specific set 61 | of point cloud and use it as parameter to calculate MOM faster. 62 | 63 | .. code-block:: python 64 | 65 | orth_list, _, _ = map_metrics.extract_orthogonal_subsets(pcs[0]) 66 | print(map_metrics.orth_mme(pcs, Ts_gt, orth_list=orth_list)) 67 | -------------------------------------------------------------------------------- /map_metrics/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022, Skolkovo Institute of Science and Technology (Skoltech) 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | __author__ = """Anastasiia Kornilova, Arthur Chains""" 15 | __email__ = "anastasiia.kornilova@skoltech.ru" 16 | __version__ = "0.0.4" 17 | 18 | from map_metrics.metrics import * 19 | -------------------------------------------------------------------------------- /map_metrics/config.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022, Skolkovo Institute of Science and Technology (Skoltech) 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | from abc import ABC 15 | 16 | 17 | __all__ = ["BaseConfig", "DepthConfig", "LidarConfig", "CustomConfig"] 18 | 19 | 20 | class BaseConfig(ABC): 21 | """ 22 | Base Config Class 23 | """ 24 | 25 | KNN_RAD = None 26 | MIN_KNN = None 27 | MAX_NN = None 28 | MIN_CLUST_SIZE = None 29 | 30 | 31 | class DepthConfig(BaseConfig): 32 | """ 33 | Config recommended for data obtained from Depth Camera 34 | """ 35 | 36 | KNN_RAD = 0.2 37 | MIN_KNN = 5 38 | MAX_NN = 30 39 | MIN_CLUST_SIZE = 5 40 | 41 | 42 | class LidarConfig(BaseConfig): 43 | """ 44 | Config recommended for data obtained from LiDAR 45 | """ 46 | 47 | KNN_RAD = 1 48 | MIN_KNN = 5 49 | MAX_NN = 30 50 | MIN_CLUST_SIZE = 5 51 | 52 | 53 | class CustomConfig(BaseConfig): 54 | """ 55 | Configurable Config 56 | 57 | Attributes 58 | ---------- 59 | KNN_RAD: float, default=1.0 60 | Estimated radius between a pair of points on the map 61 | The value is given in meters 62 | MIN_KNN: int, default=5 63 | Minimum number of a point neighbors 64 | MAX_NN: int, default=30 65 | At most MAX_NN nearest neighbors that have distances to the anchor point less than a given radius 66 | MIN_CLUST_SIZE: int, default=5 67 | Minimal acceptable cluster size in orthogonal extraction 68 | """ 69 | 70 | def __init__(self, knn_rad=1.0, min_knn=5, max_nn=30, min_clust_size=5): 71 | self.KNN_RAD = knn_rad 72 | self.MIN_KNN = min_knn 73 | self.MAX_NN = max_nn 74 | self.MIN_CLUST_SIZE = min_clust_size 75 | -------------------------------------------------------------------------------- /map_metrics/metrics.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022, Skolkovo Institute of Science and Technology (Skoltech) 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | import copy 15 | import numpy as np 16 | import open3d as o3d 17 | 18 | from typing import Optional, Type, Any, List, Callable 19 | from nptyping import NDArray 20 | 21 | from map_metrics.utils.orthogonal import extract_orthogonal_subsets 22 | from map_metrics.config import BaseConfig, LidarConfig 23 | 24 | __all__ = ["aggregate_map", "mme", "mpv", "mom"] 25 | 26 | 27 | def aggregate_map( 28 | pcs: List[o3d.geometry.PointCloud], ts: List[NDArray[(4, 4), np.float64]] 29 | ) -> o3d.geometry.PointCloud: 30 | """ 31 | Build a map from point clouds with their poses 32 | 33 | Parameters 34 | ---------- 35 | pcs: List[o3d.geometry.PointCloud] 36 | Point Clouds obtained from sensors 37 | ts: List[NDArray[(4, 4), np.float64]] 38 | Transformation matrices list (i.e., Point Cloud poses) 39 | 40 | Returns 41 | ------- 42 | pc_map: o3d.geometry.PointCloud 43 | Map aggregated from point clouds 44 | 45 | Raises 46 | ------ 47 | ValueError 48 | If number of point clouds does not match number of poses 49 | """ 50 | if len(pcs) != len(ts): 51 | raise ValueError("Number of point clouds does not match number of poses") 52 | 53 | ts = [np.linalg.inv(ts[0]) @ T for T in ts] 54 | pc_map = o3d.geometry.PointCloud() 55 | for i, pc in enumerate(pcs): 56 | pc_map += copy.deepcopy(pc).transform(ts[i]) 57 | 58 | return pc_map 59 | 60 | 61 | def _plane_variance(points: NDArray[(Any, 3), np.float64]) -> float: 62 | """ 63 | Compute plane variance of given points 64 | 65 | Parameters 66 | ---------- 67 | points: NDArray[(Any, 3), np.float64] 68 | Point Cloud points 69 | 70 | Returns 71 | ------- 72 | plane_variance: float 73 | Points plane variance 74 | """ 75 | cov = np.cov(points.T) 76 | eigenvalues = np.linalg.eig(cov)[0] 77 | return min(eigenvalues) 78 | 79 | 80 | def _entropy(points: NDArray[(Any, 3), np.float64]) -> Optional[float]: 81 | """ 82 | Compute entropy of given points 83 | 84 | Parameters 85 | ---------- 86 | points: NDArray[(Any, 3), np.float64] 87 | Point Cloud points 88 | 89 | Returns 90 | ------- 91 | entropy: Optional[float] 92 | Points entropy 93 | """ 94 | cov = np.cov(points.T) 95 | det = np.linalg.det(2 * np.pi * np.e * cov) 96 | if det > 0: 97 | return 0.5 * np.log(det) 98 | 99 | return None 100 | 101 | 102 | def _mean_map_metric( 103 | pcs: List[o3d.geometry.PointCloud], 104 | ts: List[NDArray[(4, 4), np.float64]], 105 | config: Type[BaseConfig] = LidarConfig, 106 | alg: Callable = _plane_variance, 107 | ) -> float: 108 | """ 109 | No-reference metric algorithms helper 110 | 111 | Parameters 112 | ---------- 113 | pcs: List[o3d.geometry.PointCloud] 114 | Point Clouds obtained from sensors 115 | ts: List[NDArray[(4, 4), np.float64]] 116 | Transformation matrices list (i.e., Point Cloud poses) 117 | config: BaseConfig 118 | Scene hyperparameters 119 | alg: Callable 120 | Metric algorithm basis (e.g., plane variance, entropy) 121 | Returns 122 | ------- 123 | mean: float 124 | Mean of given metric algorithm values 125 | """ 126 | pc_map = aggregate_map(pcs, ts) 127 | 128 | map_tree = o3d.geometry.KDTreeFlann(pc_map) 129 | points = np.asarray(pc_map.points) 130 | metric = [] 131 | for i in range(points.shape[0]): 132 | point = points[i] 133 | _, idx, _ = map_tree.search_radius_vector_3d(point, config.KNN_RAD) 134 | if len(idx) > config.MIN_KNN: 135 | metric_value = alg(points[idx]) 136 | if metric_value is not None: 137 | metric.append(metric_value) 138 | 139 | return 0.0 if len(metric) == 0 else np.mean(metric) 140 | 141 | 142 | def _orth_mpv( 143 | pcs: List[o3d.geometry.PointCloud], 144 | ts: List[NDArray[(4, 4), np.float64]], 145 | config: Type[BaseConfig] = LidarConfig, 146 | orth_list: List[o3d.geometry.PointCloud] = None, 147 | ): 148 | """ 149 | 150 | Parameters 151 | ---------- 152 | pcs: List[o3d.geometry.PointCloud] 153 | Point Clouds obtained from sensors 154 | ts: List[NDArray[(4, 4), np.float64]] 155 | Transformation matrices list (i.e., Point Cloud poses) 156 | config: BaseConfig 157 | Scene hyperparameters 158 | orth_list: List[o3d.geometry.PointCloud], default=None 159 | List of orthogonal planes of the map 160 | 161 | Returns 162 | ------- 163 | val: float 164 | The value of MPV computed on orthogonal planes of the map 165 | """ 166 | pc_map = aggregate_map(pcs, ts) 167 | map_tree = o3d.geometry.KDTreeFlann(pc_map) 168 | points = np.asarray(pc_map.points) 169 | 170 | if orth_list is None: 171 | pc = pcs[0] 172 | orth_list, _, _ = extract_orthogonal_subsets(pc, config=config, eps=1e-1) 173 | 174 | orth_axes_stats = [] 175 | 176 | for chosen_points in orth_list: 177 | metric = [] 178 | for i in range(np.asarray(chosen_points).shape[0]): 179 | point = chosen_points[i] 180 | _, idx, _ = map_tree.search_radius_vector_3d(point, config.KNN_RAD) 181 | # TODO: add 3 to config 182 | if len(idx) > 3: 183 | metric.append(_plane_variance(points[idx])) 184 | 185 | avg_metric = np.median(metric) 186 | orth_axes_stats.append(avg_metric) 187 | 188 | return np.sum(orth_axes_stats) 189 | 190 | 191 | def mme( 192 | pcs: List[o3d.geometry.PointCloud], 193 | ts: List[NDArray[(4, 4), np.float64]], 194 | config: Type[BaseConfig] = LidarConfig, 195 | ) -> float: 196 | """ 197 | Mean Map Entropy 198 | A no-reference metric algorithm based on entropy 199 | 200 | Parameters 201 | ---------- 202 | pcs: List[o3d.geometry.PointCloud] 203 | Point Clouds obtained from sensors 204 | ts: List[NDArray[(4, 4), np.float64]] 205 | Transformation matrices list (i.e., Point Cloud poses) 206 | config: BaseConfig 207 | Scene hyperparameters 208 | 209 | Returns 210 | ------- 211 | mean: float 212 | Mean of given metric algorithm values 213 | """ 214 | return _mean_map_metric(pcs, ts, config, alg=_entropy) 215 | 216 | 217 | def mpv( 218 | pcs: List[o3d.geometry.PointCloud], 219 | ts: List[NDArray[(4, 4), np.float64]], 220 | config: Type[BaseConfig] = LidarConfig, 221 | ) -> float: 222 | """ 223 | Mean Plane Variance 224 | A no-reference metric algorithm based on plane variance 225 | 226 | Parameters 227 | ---------- 228 | pcs: List[o3d.geometry.PointCloud] 229 | Point Clouds obtained from sensors 230 | ts: List[NDArray[(4, 4), np.float64]] 231 | Transformation matrices list (i.e., Point Cloud poses) 232 | config: BaseConfig 233 | Scene hyperparameters 234 | 235 | Returns 236 | ------- 237 | mean: float 238 | Mean of given metric algorithm values 239 | """ 240 | return _mean_map_metric(pcs, ts, config, alg=_plane_variance) 241 | 242 | 243 | def mom( 244 | pcs: List[o3d.geometry.PointCloud], 245 | ts: List[NDArray[(4, 4), np.float64]], 246 | orth_list: List[o3d.geometry.PointCloud] = None, 247 | config: Type[BaseConfig] = LidarConfig, 248 | ): 249 | """ 250 | Mutually Orthogonal Metric 251 | A no-reference metric algorithm based on MPV on orthogonal planes subset 252 | 253 | Parameters 254 | ---------- 255 | pcs: List[o3d.geometry.PointCloud] 256 | Point Clouds obtained from sensors 257 | ts: List[NDArray[(4, 4), np.float64]] 258 | Transformation matrices list (i.e., Point Cloud poses) 259 | orth_list: List[o3d.geometry.PointCloud], default=None 260 | List of orthogonal planes of the map 261 | config: BaseConfig 262 | Scene hyperparameters 263 | 264 | Returns 265 | ------- 266 | mean: float 267 | Mean of given metric algorithm values 268 | """ 269 | return _orth_mpv(pcs, ts, config, orth_list=orth_list) 270 | -------------------------------------------------------------------------------- /map_metrics/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022, Skolkovo Institute of Science and Technology (Skoltech) 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /map_metrics/utils/orthogonal.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022, Skolkovo Institute of Science and Technology (Skoltech) 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | import numpy as np 15 | import networkx as nx 16 | import open3d as o3d 17 | 18 | from typing import Type, List 19 | from nptyping import NDArray 20 | 21 | from map_metrics.config import BaseConfig, LidarConfig 22 | from sklearn.cluster import AgglomerativeClustering 23 | from pathlib import Path 24 | 25 | 26 | __all__ = ["extract_orthogonal_subsets", "read_orthogonal_subset"] 27 | 28 | 29 | def _build_normals_and_lambdas(pc, knn_rad): 30 | pc_tree = o3d.geometry.KDTreeFlann(pc) 31 | points = np.asarray(pc.points) 32 | main_normals = np.asarray(pc.normals) 33 | normals = [] 34 | lambdas = [] 35 | new_points = [] 36 | # TODO: Add mutable tqdm bar 37 | for i in range(points.shape[0]): 38 | point = points[i] 39 | _, idx, _ = pc_tree.search_radius_vector_3d(point, knn_rad) 40 | if len(idx) > 3: 41 | cov = np.cov(points[idx].T) 42 | eigenvalues, eigenvectors = np.linalg.eig(cov) 43 | idx = eigenvalues.argsort() 44 | eigenvalues = eigenvalues[idx] 45 | if 100 * eigenvalues[0] < eigenvalues[1]: 46 | normals.append(main_normals[i]) 47 | lambdas.append(eigenvalues[0]) 48 | new_points.append(point) 49 | 50 | return np.vstack(normals), lambdas, np.vstack(new_points) 51 | 52 | 53 | def _estimate_normals(pc, knn_rad, max_nn): 54 | if not pc.has_normals(): 55 | pc.estimate_normals( 56 | search_param=o3d.geometry.KDTreeSearchParamHybrid( 57 | radius=knn_rad, max_nn=max_nn 58 | ) 59 | ) 60 | 61 | normals, lambdas, new_points = _build_normals_and_lambdas(pc, knn_rad) 62 | 63 | cut_pcd = o3d.geometry.PointCloud() 64 | cut_pcd.points = o3d.utility.Vector3dVector(new_points) 65 | cut_pcd.normals = o3d.utility.Vector3dVector(normals) 66 | 67 | return cut_pcd 68 | 69 | 70 | def _filter_clusters(clustering, normals, min_clust_size): 71 | n_clusters = np.unique(clustering.labels_).shape[0] 72 | labels = clustering.labels_ 73 | huge_clusters = [] 74 | cluster_means, cluster_means_ind = [], [] 75 | 76 | for i in range(n_clusters): 77 | ind = np.where(labels == i) 78 | if ind[0].shape[0] > min_clust_size: 79 | huge_clusters.append(i) 80 | cluster_means.append(np.mean(np.vstack(normals)[ind], axis=0)) 81 | cluster_means_ind.append(i) 82 | 83 | # Normalize means of every cluster 84 | cluster_means = np.vstack(cluster_means) 85 | cluster_means = cluster_means / np.linalg.norm(cluster_means, axis=1)[:, None] 86 | 87 | return cluster_means, cluster_means_ind 88 | 89 | 90 | def _find_max_clique(labels, cluster_means, cluster_means_ind, eps=1e-1): 91 | N = cluster_means.shape[0] 92 | adj_matrix = np.zeros((N, N)) 93 | for i in range(N): 94 | for j in range(i): 95 | x = np.abs(np.dot(cluster_means[i], cluster_means[j])) 96 | if x < eps: 97 | adj_matrix[i, j] = 1 98 | adj_matrix[j, i] = 1 99 | 100 | D = nx.Graph(adj_matrix) 101 | x = nx.algorithms.clique.find_cliques(D) 102 | 103 | full_cliques_size = [] 104 | full_cliques = [] 105 | for clique in x: 106 | if len(clique) > 2: 107 | amount = 0 108 | for j in clique: 109 | amount += np.sum(labels == cluster_means_ind[j]) 110 | full_cliques_size.append(amount) 111 | full_cliques.append(clique) 112 | 113 | if len(full_cliques) == 0: 114 | raise ValueError("Length of full_cliques == 0") 115 | 116 | max_ind = full_cliques_size.index(max(full_cliques_size)) 117 | return full_cliques[max_ind] 118 | 119 | 120 | def extract_orthogonal_subsets(pc, config: Type[BaseConfig] = LidarConfig, eps=1e-1): 121 | cut_pc = _estimate_normals(pc, knn_rad=config.KNN_RAD, max_nn=config.MAX_NN) 122 | 123 | normals = np.asarray(cut_pc.normals) 124 | 125 | clustering = AgglomerativeClustering( 126 | n_clusters=None, distance_threshold=1e-1, compute_full_tree=True 127 | ).fit(normals) 128 | labels = clustering.labels_ 129 | 130 | cluster_means, cluster_means_ind = _filter_clusters( 131 | clustering, normals, min_clust_size=config.MIN_CLUST_SIZE 132 | ) 133 | 134 | max_clique = _find_max_clique(labels, cluster_means, cluster_means_ind, eps=eps) 135 | 136 | # Obtain orth subset and normals for those cliques 137 | pc_points = np.asarray(cut_pc.points) 138 | orth_subset = [ 139 | pc_points[np.where(labels == cluster_means_ind[i])[0]] for i in max_clique 140 | ] 141 | pc_normals = np.asarray(cut_pc.normals) 142 | orth_normals = [ 143 | pc_normals[np.where(labels == cluster_means_ind[i])[0]] for i in max_clique 144 | ] 145 | clique_normals = [cluster_means[i] for i in max_clique] 146 | 147 | return orth_subset, orth_normals, clique_normals 148 | 149 | 150 | def read_orthogonal_subset( 151 | orth_subset_name: Path, orth_pose_name: Path, ts: List[NDArray[(4, 4), np.float64]] 152 | ): 153 | """Read and aggregate an orthogonal subset 154 | 155 | Parameters 156 | ---------- 157 | orth_subset_name: Path 158 | Orthogonal subset data 159 | orth_pose_name: Path 160 | Pose of orthogonal subset in the map 161 | ts: List[NDArray[(4, 4), np.float64]] 162 | Transformation matrices list (i.e., Point Cloud poses) 163 | 164 | Returns 165 | ------- 166 | orth_subset 167 | Aggregated orthogonal subset 168 | """ 169 | orth_list = np.load(str(orth_subset_name), allow_pickle=True) 170 | orth_pose = np.loadtxt(str(orth_pose_name), usecols=range(4)) 171 | orth_pose = np.linalg.inv(ts[0]) @ orth_pose 172 | 173 | return [ 174 | o3d.geometry.PointCloud(o3d.utility.Vector3dVector(surface)) 175 | .transform(orth_pose) 176 | .points 177 | for surface in orth_list 178 | ] 179 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "map_metrics" 3 | version = "0.0.4" 4 | description = "Map metrics toolkit provides a set of metrics to quantitatively evaluate trajectory quality via estimating consistency of the map aggregated from point clouds." 5 | authors = ["Anastasiia Kornilova", "Arthur Chains"] 6 | license = "Apache License 2.0" 7 | readme = "README.md" 8 | 9 | [tool.poetry.dependencies] 10 | python = "^3.6.2" 11 | networkx = "^2.5.1" 12 | nptyping = "^1.4.4" 13 | numpy = "^1.19.5" 14 | open3d = "^0.14.1" 15 | scikit-learn = "^0.24.2" 16 | 17 | [tool.poetry.dev-dependencies] 18 | black = "^22.1.0" 19 | pytest = "^6.2.5" 20 | myst-nb = {version = "^0.13.2", python = "^3.9"} 21 | 22 | [build-system] 23 | requires = ["poetry-core>=1.0.0"] 24 | build-backend = "poetry.core.masonry.api" 25 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | black 2 | networkx==2.5.1 3 | nptyping==1.4.4 4 | numpy==1.19.5 5 | open3d==0.14.1 6 | pytest==6.2.5 7 | scikit-learn==0.24.2 8 | -------------------------------------------------------------------------------- /tests/data/depth/README.md: -------------------------------------------------------------------------------- 1 | ## Depth Data collected with ARCore 2 | -------------------------------------------------------------------------------- /tests/data/depth/orth_subset/orth-0091.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/orth_subset/orth-0091.npy -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0071.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0071.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0081.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0081.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0091.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0091.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0101.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0101.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0111.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0111.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0121.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0121.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0131.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0131.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0141.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0141.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0151.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0151.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0161.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0161.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0171.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0171.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0181.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0181.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0191.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0191.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0201.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0201.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0211.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0211.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0221.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0221.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0231.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0231.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0241.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0241.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0251.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0251.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0261.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0261.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0271.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0271.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0281.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0281.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0291.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0291.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0301.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0301.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0311.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0311.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0321.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0321.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0331.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0331.pcd -------------------------------------------------------------------------------- /tests/data/depth/pcs/PC-0341.pcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/depth/pcs/PC-0341.pcd -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0071.txt: -------------------------------------------------------------------------------- 1 | -1.591694477274367414e-01 -9.528170753459725972e-01 2.584660670944833871e-01 -9.389299999999999730e-03 2 | -8.991274803081221734e-01 3.178481959251427957e-02 -4.365312123986540560e-01 5.342530000000000195e-02 3 | 4.077190957815323147e-01 -3.018763756450950075e-01 -8.617631883310352681e-01 1.483179999999999915e-02 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0081.txt: -------------------------------------------------------------------------------- 1 | -1.962638473183621057e-01 -8.957014070245160609e-01 3.989981098828628281e-01 3.923780000000000323e-02 2 | -8.950397176583163583e-01 -2.546503720946169391e-03 -4.459791689450537389e-01 3.491600000000000259e-02 3 | 4.004802192991761545e-01 -4.446487431367613929e-01 -8.011885478318960807e-01 1.838780000000000137e-01 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0091.txt: -------------------------------------------------------------------------------- 1 | -2.833913645440715445e-01 -8.104649546509733460e-01 5.126752303207594563e-01 -7.541855651986327513e-02 2 | -8.697658250098190269e-01 -7.982946226465378881e-03 -4.934001238493293529e-01 -1.225824407599575977e-01 3 | 4.039761677956228980e-01 -5.857327290259100039e-01 -7.026524218993498438e-01 1.817336031604547542e-01 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0101.txt: -------------------------------------------------------------------------------- 1 | -1.678211316299194344e-01 -7.440398454101728731e-01 6.467153749683541841e-01 -1.459555681750412948e-01 2 | -9.778528097421465004e-01 4.241672122989052773e-02 -2.049504921669984547e-01 -2.066756256769603298e-02 3 | 1.250597867335555835e-01 -6.667874700398257470e-01 -7.346798755512811141e-01 9.485651600823860607e-02 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0111.txt: -------------------------------------------------------------------------------- 1 | -2.652224861394172906e-03 -8.206346975440342861e-01 5.714469869463799645e-01 -1.828059966755805066e-01 2 | -9.965391676752435313e-01 4.964640086637370914e-02 6.667024951317145065e-02 1.055135002997748817e-01 3 | -8.308220623224817081e-02 -5.692924802487968616e-01 -8.179262918746136313e-01 8.461817868216878202e-02 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0121.txt: -------------------------------------------------------------------------------- 1 | -2.101308943276300814e-02 -9.865640904676671319e-01 1.620177319684330541e-01 -2.609606416576770171e-01 2 | -9.982716276547324297e-01 2.960011227848121512e-02 5.076997904935828809e-02 1.139467612369753774e-01 3 | -5.488358126126317849e-02 -1.606708708907922112e-01 -9.854809301833965529e-01 1.452680558647358525e-02 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0131.txt: -------------------------------------------------------------------------------- 1 | -3.542993069700091369e-02 -9.970102163864379419e-01 6.866839470873084550e-02 -2.963010828858653189e-01 2 | -9.908468285722713542e-01 2.608878140117013716e-02 -1.324459806610742418e-01 4.972258997841509653e-02 3 | 1.302585210996862752e-01 -7.273241303621308385e-02 -9.888087346776688324e-01 -6.810221770626834203e-02 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0141.txt: -------------------------------------------------------------------------------- 1 | -6.784291797248746814e-02 -9.546654677384838195e-01 2.898468271150124731e-01 -2.530885435235344927e-01 2 | -9.795445046564693614e-01 8.571485692427223413e-03 -2.010450025002766816e-01 4.684878877139274367e-03 3 | 1.894463034167995774e-01 -2.975573463060290913e-01 -9.357188273092635900e-01 -3.197054956131506476e-02 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0151.txt: -------------------------------------------------------------------------------- 1 | -1.517518416619989263e-01 -8.726941279641118321e-01 4.640865625819711737e-01 -6.799352599004029885e-02 2 | -9.581320835553464033e-01 1.454054052957052742e-02 -2.859571351496554281e-01 -4.968835438770875801e-02 3 | 2.428050432220920374e-01 -4.880507470520520918e-01 -8.383627969368943056e-01 1.113581553144769865e-01 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0161.txt: -------------------------------------------------------------------------------- 1 | -1.190953211054618377e-01 -9.875785413137146973e-01 1.024935570046369288e-01 -1.608961890508781578e-01 2 | -8.553657114277415374e-01 4.963672905398133772e-02 -5.156410523247109134e-01 -1.573159048560549833e-01 3 | 5.041485933774888517e-01 -1.490799110058007582e-01 -8.506523237668855986e-01 1.354030903245370121e-01 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0171.txt: -------------------------------------------------------------------------------- 1 | 1.030231654339722192e-01 -9.630844018057801437e-01 -2.487059757673045213e-01 -4.469887872082321523e-01 2 | -8.713590009754661470e-01 3.320239357433756727e-02 -4.895212890978003495e-01 -1.468237320790279909e-01 3 | 4.797079515736650257e-01 2.671442233314010317e-01 -8.357716465265260242e-01 4.261543634837020034e-02 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0181.txt: -------------------------------------------------------------------------------- 1 | 1.892237398418399885e-01 -8.839838455969557529e-01 -4.275124992370232246e-01 -6.729007149558771106e-01 2 | -9.053328906571080914e-01 1.152549774206463977e-02 -4.245462518928214135e-01 -9.520634197629418427e-02 3 | 3.802193227266506548e-01 4.673753562452942489e-01 -7.981187524421863300e-01 -1.383743003005683155e-02 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0191.txt: -------------------------------------------------------------------------------- 1 | 1.648511021854838221e-01 -9.186457318075780254e-01 -3.590461440260155901e-01 -9.272780200642898318e-01 2 | -9.267899412306556117e-01 -1.972230481058685758e-02 -3.750619089252277827e-01 -6.399949362428834776e-02 3 | 3.374678043042161346e-01 3.945897237950798941e-01 -8.546428674794013247e-01 -1.875014547918108787e-01 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0201.txt: -------------------------------------------------------------------------------- 1 | -2.242023701591501841e-02 -9.988403487575618911e-01 4.260622801917901548e-02 -1.300305497575870550e+00 2 | -9.169300693300294069e-01 3.560668497053689346e-03 -3.990320408166260768e-01 -7.364615619528705470e-02 3 | 3.984175961608342198e-01 -4.801332454356987967e-02 -9.159465812675409158e-01 -2.814591617254393885e-01 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0211.txt: -------------------------------------------------------------------------------- 1 | -1.481481492404922717e-01 -9.242818144523352597e-01 3.517886486930979495e-01 -1.609166691054866094e+00 2 | -9.178972189341517707e-01 -3.899922476350070610e-03 -3.967990499958746198e-01 -4.547146982189103487e-02 3 | 3.681260943611128766e-01 -3.816908671652721741e-01 -8.478179407001573686e-01 -5.568604812420516748e-01 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0221.txt: -------------------------------------------------------------------------------- 1 | -2.346636870039225942e-01 -7.186106591089019835e-01 6.546233074194609536e-01 -1.886254076588646633e+00 2 | -9.435141185927036211e-01 6.332013492992279863e-03 -3.312718122952179600e-01 -2.005557808836128109e-03 3 | 2.339103717622598999e-01 -6.953837977837802331e-01 -6.795051962728817507e-01 -7.954052077650403119e-01 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0231.txt: -------------------------------------------------------------------------------- 1 | -3.161508202059021833e-01 -5.006185134287998162e-01 8.058720511939063691e-01 -2.013731353105140176e+00 2 | -9.364776231559143183e-01 2.871601070276399298e-02 -3.495497848054950896e-01 1.289904520079628025e-02 3 | 1.518496631915413064e-01 -8.651915942389044600e-01 -4.778966259003698536e-01 -1.082055974208473881e+00 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0241.txt: -------------------------------------------------------------------------------- 1 | -3.227155997097190254e-01 -2.915659419080985915e-01 9.004687352835964997e-01 -2.140939592286563276e+00 2 | -9.403713597439959937e-01 -9.285602233494796853e-03 -3.400227688911277579e-01 3.418767206160465422e-02 3 | 1.075004533814830077e-01 -9.565056607832513880e-01 -2.711836525537094644e-01 -1.348326499568948345e+00 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0251.txt: -------------------------------------------------------------------------------- 1 | -1.820432561211706990e-01 -1.714198583724976244e-01 9.682331770066314736e-01 -2.215489335199768206e+00 2 | -9.831672099438188983e-01 4.732635189397990660e-02 -1.764722462816579740e-01 1.289708722649563488e-01 3 | -1.557209658616362340e-02 -9.840606935407797407e-01 -1.771498270841695144e-01 -1.497759031190367907e+00 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0261.txt: -------------------------------------------------------------------------------- 1 | 1.837410437049939033e-02 -3.868323540974664132e-01 9.219669853698638784e-01 -2.287091003677989232e+00 2 | -9.976062707550531483e-01 5.438990630593605602e-02 4.270206836006161522e-02 1.472813879244183610e-01 3 | -6.666423957998682259e-02 -9.205446582949924350e-01 -3.849070163634045749e-01 -1.512046144699382921e+00 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0271.txt: -------------------------------------------------------------------------------- 1 | -2.307037912906882149e-01 -5.596046529388022384e-01 7.960015031979181810e-01 -2.292320314191787833e+00 2 | -9.562406218342156539e-01 -2.089383844833513776e-02 -2.918344062460890842e-01 2.448965258054654204e-02 3 | 1.799434184353933541e-01 -8.284962763489872595e-01 -5.302964135628746023e-01 -1.541040938142185457e+00 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0281.txt: -------------------------------------------------------------------------------- 1 | -3.348967558244225207e-01 -7.525025318204414670e-01 5.670838584743023159e-01 -2.278364470546046849e+00 2 | -8.568040431500780763e-01 -7.232774142711881349e-03 -5.155914260534982807e-01 -8.044352585774752762e-02 3 | 3.920854429584915146e-01 -6.585496386621330078e-01 -6.423249791484196836e-01 -1.539809195079379300e+00 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0291.txt: -------------------------------------------------------------------------------- 1 | -1.867552740237182207e-01 -8.722729065622243372e-01 4.519540287482957108e-01 -2.183715545509379297e+00 2 | -9.478790771800926773e-01 3.909715051317643603e-02 -3.162224974064404281e-01 -1.251037544418888425e-02 3 | 2.581622022460726695e-01 -4.874539868533638853e-01 -8.341108367790333045e-01 -1.499841395996433846e+00 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0301.txt: -------------------------------------------------------------------------------- 1 | -8.989016313808217973e-02 -9.563391385622819207e-01 2.780920901876948181e-01 -2.179046638098605104e+00 2 | -9.958796478064683155e-01 8.295039236082465961e-02 -3.664641172133498159e-02 1.191777865308429329e-01 3 | 1.197854982346908612e-02 -2.802404047619423411e-01 -9.598551087966294970e-01 -1.478015623152673541e+00 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0311.txt: -------------------------------------------------------------------------------- 1 | -3.338305123165752342e-02 -9.983975186728345497e-01 -4.569427314655177125e-02 -2.348613001376990361e+00 2 | -9.994173055824813190e-01 3.302182679402052012e-02 8.637607159326533141e-03 1.526051880765746382e-01 3 | -7.114857181818222409e-03 4.595599703099543382e-02 -9.989181273478672241e-01 -1.464216096550536195e+00 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0321.txt: -------------------------------------------------------------------------------- 1 | 1.505123024486068259e-02 -9.862700092428640097e-01 -1.644534260397076397e-01 -2.468016740916499696e+00 2 | -9.908021262431649934e-01 7.409175764301570433e-03 -1.351156939312292693e-01 8.680537740692662041e-02 3 | 1.344790210409792242e-01 1.649744616071684711e-01 -9.770869049973422982e-01 -1.420410672584781597e+00 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0331.txt: -------------------------------------------------------------------------------- 1 | 4.379140100215912768e-02 -9.948074047753687754e-01 -9.187241480642623082e-02 -2.467765971818967508e+00 2 | -9.479796067613337485e-01 -1.235369036869099144e-02 -3.180912628459031111e-01 1.838953469179255285e-03 3 | 3.153045803075099629e-01 1.010228377069782579e-01 -9.435981177910089945e-01 -1.380782127283161964e+00 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/depth/poses/pose-0341.txt: -------------------------------------------------------------------------------- 1 | -1.242119429958365162e-01 -9.701593455575220348e-01 2.082360138030880936e-01 -2.294144379526066757e+00 2 | -8.718067552265965636e-01 6.486927054275656856e-03 -4.898070041543564623e-01 -6.203068139960414562e-02 3 | 4.738400307682671397e-01 -2.423814431939733949e-01 -8.465972249167454944e-01 -1.350603245057240054e+00 4 | 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+00 5 | -------------------------------------------------------------------------------- /tests/data/lidar/README.md: -------------------------------------------------------------------------------- 1 | ## KITTI_00 dataset 2 | 3 | ### Link: http://www.cvlibs.net/datasets/kitti/eval_odometry.php 4 | -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000000.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000000.bin -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000001.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000001.bin -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000002.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000002.bin -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000003.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000003.bin -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000004.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000004.bin -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000005.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000005.bin -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000006.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000006.bin -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000007.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000007.bin -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000008.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000008.bin -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000009.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000009.bin -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000010.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000010.bin -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000011.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000011.bin -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000012.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000012.bin -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000013.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000013.bin -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000014.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000014.bin -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000015.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000015.bin -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000016.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000016.bin -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000017.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000017.bin -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000018.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000018.bin -------------------------------------------------------------------------------- /tests/data/lidar/pcs/000019.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileRoboticsSkoltech/map-metrics/9688a783d4f52225312bda0602524509a1f1b3c7/tests/data/lidar/pcs/000019.bin -------------------------------------------------------------------------------- /tests/data/lidar/poses.txt: -------------------------------------------------------------------------------- 1 | 1.000000e+00 9.043680e-12 2.326809e-11 5.551115e-17 9.043683e-12 1.000000e+00 2.392370e-10 3.330669e-16 2.326810e-11 2.392370e-10 9.999999e-01 -4.440892e-16 2 | 9.999978e-01 5.272628e-04 -2.066935e-03 -4.690294e-02 -5.296506e-04 9.999992e-01 -1.154865e-03 -2.839928e-02 2.066324e-03 1.155958e-03 9.999971e-01 8.586941e-01 3 | 9.999910e-01 1.048972e-03 -4.131348e-03 -9.374345e-02 -1.058514e-03 9.999968e-01 -2.308104e-03 -5.676064e-02 4.128913e-03 2.312456e-03 9.999887e-01 1.716275e+00 4 | 9.999796e-01 1.566466e-03 -6.198571e-03 -1.406429e-01 -1.587952e-03 9.999927e-01 -3.462706e-03 -8.515762e-02 6.193102e-03 3.472479e-03 9.999747e-01 2.574964e+00 5 | 9.999637e-01 2.078471e-03 -8.263498e-03 -1.874858e-01 -2.116664e-03 9.999871e-01 -4.615826e-03 -1.135202e-01 8.253797e-03 4.633149e-03 9.999551e-01 3.432648e+00 6 | 9.999433e-01 2.586172e-03 -1.033094e-02 -2.343818e-01 -2.645881e-03 9.999798e-01 -5.770163e-03 -1.419150e-01 1.031581e-02 5.797170e-03 9.999299e-01 4.291335e+00 7 | 9.999184e-01 3.088363e-03 -1.239599e-02 -2.812195e-01 -3.174350e-03 9.999710e-01 -6.922975e-03 -1.702743e-01 1.237425e-02 6.961759e-03 9.998991e-01 5.148987e+00 8 | 9.998890e-01 3.586305e-03 -1.446384e-02 -3.281178e-01 -3.703403e-03 9.999605e-01 -8.077186e-03 -1.986703e-01 1.443430e-02 8.129853e-03 9.998627e-01 6.007777e+00 9 | 9.998551e-01 4.078705e-03 -1.652913e-02 -3.749547e-01 -4.231669e-03 9.999484e-01 -9.229794e-03 -2.270290e-01 1.649063e-02 9.298401e-03 9.998207e-01 6.865477e+00 10 | 9.998167e-01 4.566671e-03 -1.859652e-02 -4.218367e-01 -4.760342e-03 9.999347e-01 -1.038342e-02 -2.554151e-01 1.854788e-02 1.047004e-02 9.997731e-01 7.724036e+00 11 | 9.997738e-01 5.049868e-03 -2.066463e-02 -4.687329e-01 -5.289072e-03 9.999194e-01 -1.153730e-02 -2.838096e-01 2.060470e-02 1.164399e-02 9.997198e-01 8.582886e+00 12 | 9.997264e-01 5.527315e-03 -2.272922e-02 -5.155474e-01 -5.816781e-03 9.999025e-01 -1.268908e-02 -3.121547e-01 2.265686e-02 1.281782e-02 9.996611e-01 9.440275e+00 13 | 9.996745e-01 6.000540e-03 -2.479692e-02 -5.624310e-01 -6.345160e-03 9.998840e-01 -1.384246e-02 -3.405416e-01 2.471098e-02 1.399530e-02 9.995966e-01 1.029896e+01 14 | 9.996182e-01 6.468772e-03 -2.686440e-02 -6.093087e-01 -6.873365e-03 9.998639e-01 -1.499561e-02 -3.689250e-01 2.676374e-02 1.517453e-02 9.995266e-01 1.115757e+01 15 | 9.995562e-01 7.058450e-03 -2.894213e-02 -6.562052e-01 -7.530449e-03 9.998399e-01 -1.623192e-02 -3.973964e-01 2.882292e-02 1.644266e-02 9.994492e-01 1.201541e+01 16 | 9.995095e-01 5.595311e-03 -3.081450e-02 -7.018788e-01 -6.093682e-03 9.998517e-01 -1.610315e-02 -4.239119e-01 3.071983e-02 1.628303e-02 9.993953e-01 1.286965e+01 17 | 9.994226e-01 7.842768e-03 -3.306167e-02 -7.498241e-01 -8.456089e-03 9.997940e-01 -1.845198e-02 -4.540039e-01 3.291014e-02 1.872089e-02 9.992829e-01 1.373146e+01 18 | 9.993587e-01 8.704386e-03 -3.473400e-02 -7.992511e-01 -9.439421e-03 9.997338e-01 -2.105422e-02 -4.840770e-01 3.454149e-02 2.136859e-02 9.991747e-01 1.460026e+01 19 | 9.992482e-01 1.235688e-02 -3.674849e-02 -8.546642e-01 -1.320676e-02 9.996488e-01 -2.297477e-02 -5.155070e-01 3.645169e-02 2.344282e-02 9.990604e-01 1.547957e+01 20 | 9.991826e-01 1.352279e-02 -3.809783e-02 -9.072868e-01 -1.439161e-02 9.996404e-01 -2.262373e-02 -5.464705e-01 3.777819e-02 2.315352e-02 9.990178e-01 1.636940e+01 21 | -------------------------------------------------------------------------------- /tests/test_config.py: -------------------------------------------------------------------------------- 1 | # TODO: Config hyperparameters integrity tests 2 | -------------------------------------------------------------------------------- /tests/test_metrics.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | from map_metrics.config import DepthConfig 4 | from map_metrics.metrics import mme, mpv, mom 5 | from map_metrics.utils.orthogonal import read_orthogonal_subset 6 | 7 | import numpy as np 8 | import open3d as o3d 9 | import os 10 | 11 | import pytest 12 | 13 | 14 | @pytest.fixture 15 | def depth_trajectories(): 16 | ts_folder = Path("tests/data/depth/poses") 17 | ts_names = sorted(os.listdir(ts_folder)) 18 | trajectories = [] 19 | for name in ts_names: 20 | trajectories.append(np.loadtxt(f"{ts_folder}/{name}", usecols=range(4))) 21 | 22 | return trajectories 23 | 24 | 25 | @pytest.fixture 26 | def depth_pointclouds(): 27 | pcs_folder = Path("tests/data/depth/pcs") 28 | pc_names = sorted(os.listdir(pcs_folder)) 29 | pcs = [] 30 | for name in pc_names: 31 | pcs.append(o3d.io.read_point_cloud(f"{pcs_folder}/{name}")) 32 | 33 | return pcs 34 | 35 | 36 | @pytest.fixture 37 | def depth_orthsubset(depth_trajectories): 38 | orth_list_name = "tests/data/depth/orth_subset/orth-0091.npy" 39 | orth_tj_name = "tests/data/depth/poses/pose-0091.txt" 40 | 41 | orth_list = read_orthogonal_subset( 42 | orth_subset_name=Path(orth_list_name), 43 | orth_pose_name=Path(orth_tj_name), 44 | ts=depth_trajectories, 45 | ) 46 | 47 | return orth_list 48 | 49 | 50 | @pytest.mark.parametrize( 51 | "config, metric, expected", 52 | [ 53 | (DepthConfig, mme, -3.614438706), 54 | (DepthConfig, mpv, 0.003242216), 55 | ], 56 | ) 57 | def test_basic_metrics(depth_pointclouds, depth_trajectories, config, metric, expected): 58 | actual_result = metric(pcs=depth_pointclouds, ts=depth_trajectories, config=config) 59 | assert abs(actual_result - expected) < 1e-3 60 | 61 | 62 | def test_mom(depth_pointclouds, depth_trajectories, depth_orthsubset): 63 | actual_result = mom( 64 | depth_pointclouds, depth_trajectories, depth_orthsubset, config=DepthConfig 65 | ) 66 | assert abs(actual_result - 0.006183082) < 1e-3 67 | -------------------------------------------------------------------------------- /tests/test_orthogonal.py: -------------------------------------------------------------------------------- 1 | # TODO: Test functions from utils.orthogonal 2 | --------------------------------------------------------------------------------