├── .clang-format
├── .github
└── workflows
│ └── build_test.yml
├── .gitignore
├── .gitmodules
├── LICENSE
├── README.md
├── docs
├── Doxyfile
├── Makefile
├── conf.py
├── index.rst
├── logo.gif
├── pages
│ ├── Class-Overview.rst
│ ├── Example-Outputs.rst
│ ├── Expanding-the-Docs.rst
│ ├── How-Does-ESDF-Generation-Work.rst
│ ├── Installation.rst
│ ├── Modifying-and-Contributing.rst
│ ├── Performance.rst
│ ├── Running-Voxblox.rst
│ ├── The-Voxblox-Node.rst
│ ├── Transformations.rst
│ └── Using-Voxblox-for-Planning.rst
└── requirements.txt
├── rosdoc.yaml
├── voxblox
├── CMakeLists.txt
├── include
│ └── voxblox
│ │ ├── alignment
│ │ └── icp.h
│ │ ├── core
│ │ ├── block.h
│ │ ├── block_hash.h
│ │ ├── block_inl.h
│ │ ├── color.h
│ │ ├── common.h
│ │ ├── esdf_map.h
│ │ ├── layer.h
│ │ ├── layer_inl.h
│ │ ├── occupancy_map.h
│ │ ├── tsdf_map.h
│ │ └── voxel.h
│ │ ├── integrator
│ │ ├── esdf_integrator.h
│ │ ├── esdf_occ_integrator.h
│ │ ├── integrator_utils.h
│ │ ├── intensity_integrator.h
│ │ ├── merge_integration.h
│ │ ├── occupancy_integrator.h
│ │ └── tsdf_integrator.h
│ │ ├── interpolator
│ │ ├── interpolator.h
│ │ └── interpolator_inl.h
│ │ ├── io
│ │ ├── layer_io.h
│ │ ├── layer_io_inl.h
│ │ ├── mesh_ply.h
│ │ ├── ply_writer.h
│ │ └── sdf_ply.h
│ │ ├── mesh
│ │ ├── README.md
│ │ ├── marching_cubes.h
│ │ ├── mesh.h
│ │ ├── mesh_integrator.h
│ │ ├── mesh_layer.h
│ │ └── mesh_utils.h
│ │ ├── simulation
│ │ ├── objects.h
│ │ ├── simulation_world.h
│ │ └── simulation_world_inl.h
│ │ ├── test
│ │ └── layer_test_utils.h
│ │ └── utils
│ │ ├── approx_hash_array.h
│ │ ├── bucket_queue.h
│ │ ├── camera_model.h
│ │ ├── color_maps.h
│ │ ├── distance_utils.h
│ │ ├── evaluation_utils.h
│ │ ├── layer_utils.h
│ │ ├── meshing_utils.h
│ │ ├── neighbor_tools.h
│ │ ├── planning_utils.h
│ │ ├── planning_utils_inl.h
│ │ ├── protobuf_utils.h
│ │ ├── timing.h
│ │ └── voxel_utils.h
├── package.xml
├── proto
│ └── voxblox
│ │ ├── Block.proto
│ │ └── Layer.proto
├── src
│ ├── alignment
│ │ └── icp.cc
│ ├── core
│ │ ├── block.cc
│ │ ├── esdf_map.cc
│ │ └── tsdf_map.cc
│ ├── integrator
│ │ ├── esdf_integrator.cc
│ │ ├── esdf_occ_integrator.cc
│ │ ├── integrator_utils.cc
│ │ ├── intensity_integrator.cc
│ │ └── tsdf_integrator.cc
│ ├── io
│ │ ├── mesh_ply.cc
│ │ └── sdf_ply.cc
│ ├── mesh
│ │ └── marching_cubes.cc
│ ├── simulation
│ │ ├── objects.cc
│ │ └── simulation_world.cc
│ └── utils
│ │ ├── camera_model.cc
│ │ ├── evaluation_utils.cc
│ │ ├── layer_utils.cc
│ │ ├── neighbor_tools.cc
│ │ ├── protobuf_utils.cc
│ │ ├── timing.cc
│ │ └── voxel_utils.cc
└── test
│ ├── test_approx_hash_array.cc
│ ├── test_bucket_queue.cc
│ ├── test_clear_spheres.cc
│ ├── test_layer.cc
│ ├── test_layer_utils.cc
│ ├── test_load_esdf.cc
│ ├── test_merge_integration.cc
│ ├── test_protobuf.cc
│ ├── test_sdf_integrators.cc
│ ├── test_tsdf_interpolator.cc
│ ├── test_tsdf_map.cc
│ └── tsdf_to_esdf.cc
├── voxblox_https.rosinstall
├── voxblox_msgs
├── CMakeLists.txt
├── msg
│ ├── Block.msg
│ ├── Layer.msg
│ ├── Mesh.msg
│ ├── MeshBlock.msg
│ └── VoxelEvaluationDetails.msg
├── package.xml
└── srv
│ └── FilePath.srv
├── voxblox_ros
├── CMakeLists.txt
├── cfg
│ ├── calibrations
│ │ └── euroc_camchain.yaml
│ ├── cow_and_lady.yaml
│ ├── cow_dataset.yaml
│ ├── euroc_dataset.yaml
│ ├── rgbd_dataset.yaml
│ └── stereo
│ │ ├── kitti_stereo.yaml
│ │ ├── kitti_stereo_bm.yaml
│ │ └── kitti_stereo_jager.yaml
├── include
│ └── voxblox_ros
│ │ ├── conversions.h
│ │ ├── conversions_inl.h
│ │ ├── esdf_server.h
│ │ ├── intensity_server.h
│ │ ├── intensity_vis.h
│ │ ├── interactive_slider.h
│ │ ├── mesh_pcl.h
│ │ ├── mesh_vis.h
│ │ ├── ptcloud_vis.h
│ │ ├── ros_params.h
│ │ ├── simulation_server.h
│ │ ├── transformer.h
│ │ └── tsdf_server.h
├── launch
│ ├── basement_dataset.launch
│ ├── cow_and_lady_dataset.launch
│ ├── euroc_dataset.launch
│ ├── eval
│ │ ├── eval_cow.launch
│ │ ├── eval_cow_and_lady.launch
│ │ ├── eval_euroc.launch
│ │ └── eval_kitti.launch
│ ├── kitti_dataset.launch
│ ├── rgbd_dataset.launch
│ └── sim.launch
├── mesh_results
│ └── .keep
├── package.xml
└── src
│ ├── esdf_server.cc
│ ├── esdf_server_node.cc
│ ├── intensity_server.cc
│ ├── intensity_server_node.cc
│ ├── interactive_slider.cc
│ ├── simulation_eval.cc
│ ├── simulation_server.cc
│ ├── transformer.cc
│ ├── tsdf_server.cc
│ ├── tsdf_server_node.cc
│ ├── visualize_tsdf.cc
│ └── voxblox_eval.cc
├── voxblox_rviz_plugin
├── CMakeLists.txt
├── icons
│ └── classes
│ │ └── VoxbloxMesh.png
├── include
│ └── voxblox_rviz_plugin
│ │ ├── voxblox_mesh_display.h
│ │ └── voxblox_mesh_visual.h
├── package.xml
├── plugin_description.xml
└── src
│ ├── voxblox_mesh_display.cc
│ └── voxblox_mesh_visual.cc
└── voxblox_ssh.rosinstall
/.clang-format:
--------------------------------------------------------------------------------
1 | ---
2 | Language: Cpp
3 | BasedOnStyle: Google
4 | ColumnLimit: 80
5 | IncludeBlocks: Preserve
6 | ---
7 | Language: Proto
8 | BasedOnStyle: Google
9 | ...
10 |
--------------------------------------------------------------------------------
/.github/workflows/build_test.yml:
--------------------------------------------------------------------------------
1 |
2 | name: Build Test
3 | on:
4 | push:
5 | branches:
6 | - 'master'
7 | pull_request:
8 | branches:
9 | - '*'
10 |
11 | jobs:
12 | build:
13 | runs-on: ubuntu-latest
14 | strategy:
15 | fail-fast: false
16 | matrix:
17 | config:
18 | - {rosdistro: 'melodic', container: 'ros:melodic-ros-base-bionic'}
19 | - {rosdistro: 'noetic', container: 'ros:noetic-ros-base-focal'}
20 | container: ${{ matrix.config.container }}
21 | steps:
22 | - uses: actions/checkout@v1
23 | with:
24 | token: ${{ secrets.ACCESS_TOKEN }}
25 | github-token: ${{ secrets.GITHUB_TOKEN }}
26 | - name: Install catkin-tools on melodic
27 | if: ${{ matrix.config.container == 'ros:melodic-ros-base-bionic' }}
28 | run: |
29 | apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
30 | apt update && apt install -y python3-wstool python-catkin-tools
31 | - name: Install catkin-tools on Noetic
32 | if: ${{ matrix.config.container == 'ros:noetic-ros-base-focal' }}
33 | run: |
34 | apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
35 | apt update && apt install -y python3-pip
36 | pip3 install osrf-pycommon
37 | apt update && apt install -y python3-wstool python3-catkin-tools
38 | - name: release_build_test
39 | working-directory:
40 | env:
41 | DEBIAN_FRONTEND: noninteractive
42 | run: |
43 | apt update
44 | apt install -y python3-wstool autoconf libtool git
45 | mkdir -p $HOME/catkin_ws/src;
46 | cd $HOME/catkin_ws
47 | catkin init
48 | catkin config --extend "/opt/ros/${{matrix.config.rosdistro}}"
49 | catkin config --merge-devel
50 | cd $HOME/catkin_ws/src
51 | ln -s $GITHUB_WORKSPACE
52 | cd $HOME/catkin_ws
53 | wstool init src src/voxblox/voxblox_https.rosinstall
54 | wstool update -t src -j4
55 | rosdep update
56 | rosdep install --from-paths src --ignore-src -y --rosdistro ${{matrix.config.rosdistro}}
57 | catkin config --cmake-args -DCMAKE_BUILD_TYPE=Release
58 | catkin build -j$(nproc) -l$(nproc) voxblox_ros
59 | shell: bash
60 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files
2 | *.slo
3 | *.lo
4 | *.o
5 | *.obj
6 |
7 | # Precompiled Headers
8 | *.gch
9 | *.pch
10 |
11 | # Compiled Dynamic libraries
12 | *.so
13 | *.dylib
14 | *.dll
15 |
16 | # Fortran module files
17 | *.mod
18 |
19 | # Compiled Static libraries
20 | *.lai
21 | *.la
22 | *.a
23 | *.lib
24 |
25 | # Executables
26 | *.exe
27 | *.out
28 | *.app
29 |
30 | # Eclipse
31 | .cproject
32 | .project
33 | /Debug/
34 | .settings
35 |
36 | # Python (for lint)
37 | *.pyc
38 |
39 | # Temporary files
40 | *~
41 |
42 | # Mac
43 | .DS_Store
44 |
45 | # Mesh results
46 | mesh_results
47 |
48 | # Tools
49 | autolintc
50 |
51 | # Documentation
52 | docs/_build
53 | docs/doxyoutput
54 | docs/api
55 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethz-asl/voxblox/c8066b04075d2fee509de295346b1c0b788c4f38/.gitmodules
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016, ETHZ ASL
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | * Neither the name of voxblox nor the names of its
15 | contributors may be used to endorse or promote products derived from
16 | this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Voxblox
2 |
3 | [](https://github.com/ethz-asl/voxblox/actions/workflows/build_test.yml)
4 |
5 | 
6 |
7 | Voxblox is a volumetric mapping library based mainly on Truncated Signed Distance Fields (TSDFs). It varies from other SDF libraries in the following ways:
8 | * CPU-only, can be run single-threaded or multi-threaded for some integrators
9 | * Support for multiple different layer types (containing different types of voxels)
10 | * Serialization using protobufs
11 | * Different ways of handling weighting during merging
12 | * Different ways of inserting pose information about scans
13 | * Tight ROS integration (in voxblox_ros package)
14 | * Easily extensible with whatever integrators you want
15 | * Features an implementation of building Euclidean Signed Distance Fields (ESDFs, EDTs) directly from TSDFs.
16 |
17 | **If you're looking for skeletonization/sparse topology or planning applications, please refer to the [mav_voxblox_planning](https://github.com/ethz-asl/mav_voxblox_planning) repo.**
18 | **If you want to create ground truth maps from meshes or gazebo environments, please check out the [voxblox_ground_truth](https://github.com/ethz-asl/voxblox_ground_truth) pakage!**
19 |
20 | 
21 |
22 | # Documentation
23 | * All voxblox documentation can be found on [our readthedocs page](https://voxblox.readthedocs.io/en/latest/index.html)
24 |
25 | ## Table of Contents
26 | * [Paper and Video](#paper-and-video)
27 | * [Credits](#credits)
28 | * [Example Outputs](https://voxblox.readthedocs.io/en/latest/pages/Example-Outputs.html)
29 | * [Performance](https://voxblox.readthedocs.io/en/latest/pages/Performance.html)
30 | * [Installation](https://voxblox.readthedocs.io/en/latest/pages/Installation.html)
31 | * [Running Voxblox](https://voxblox.readthedocs.io/en/latest/pages/Running-Voxblox.html)
32 | * [Using Voxblox for Planning](https://voxblox.readthedocs.io/en/latest/pages/Using-Voxblox-for-Planning.html)
33 | * [Transformations in Voxblox](https://voxblox.readthedocs.io/en/latest/pages/Transformations.html)
34 | * [Contributing to Voxblox](https://voxblox.readthedocs.io/en/latest/pages/Modifying-and-Contributing.html)
35 | * [Library API](https://voxblox.readthedocs.io/en/latest/api/library_root.html)
36 |
37 | # Paper and Video
38 | A video showing sample output from voxblox can be seen [here](https://www.youtube.com/watch?v=PlqT5zNsvwM).
39 | A video of voxblox being used for online planning on-board a multicopter can be seen [here](https://youtu.be/lrGSwAPzMOQ).
40 |
41 | If using voxblox for scientific publications, please cite the following paper, available [here](http://helenol.github.io/publications/iros_2017_voxblox.pdf):
42 |
43 | Helen Oleynikova, Zachary Taylor, Marius Fehr, Juan Nieto, and Roland Siegwart, “**Voxblox: Incremental 3D Euclidean Signed Distance Fields for On-Board MAV Planning**”, in *IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)*, 2017.
44 |
45 | ```latex
46 | @inproceedings{oleynikova2017voxblox,
47 | author={Oleynikova, Helen and Taylor, Zachary and Fehr, Marius and Siegwart, Roland and Nieto, Juan},
48 | booktitle={IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)},
49 | title={Voxblox: Incremental 3D Euclidean Signed Distance Fields for On-Board MAV Planning},
50 | year={2017}
51 | }
52 | ```
53 |
54 | # Credits
55 | This library was written primarily by Helen Oleynikova and Marius Fehr, with significant contributions from Zachary Taylor, Alexander Millane, and others. The marching cubes meshing and ROS mesh generation were taken or heavily derived from [open_chisel](https://github.com/personalrobotics/OpenChisel). We've retained the copyright headers for the relevant files.
56 |
57 | 
58 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | SPHINXPROJ = project
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)
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | name = 'voxblox'
4 |
5 | on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
6 |
7 | if not on_rtd: # only import and set the theme if we're building docs locally
8 | import sphinx_rtd_theme
9 | html_theme = 'sphinx_rtd_theme'
10 | html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
11 |
12 | html_logo = "logo.gif"
13 |
14 | source_parsers = {
15 | '.md': 'recommonmark.parser.CommonMarkParser',
16 | }
17 |
18 | extensions = [
19 | 'breathe', 'exhale', 'sphinx.ext.autosectionlabel', 'recommonmark'
20 | ]
21 |
22 | project = name
23 | master_doc = 'index'
24 |
25 | html_theme_options = {'logo_only': True}
26 |
27 | # Setup the breathe extension
28 | breathe_projects = {"project": "./doxyoutput/xml"}
29 | breathe_default_project = "project"
30 |
31 | # Setup the exhale extension
32 | exhale_args = {
33 | "verboseBuild": False,
34 | "containmentFolder": "./api",
35 | "rootFileName": "library_root.rst",
36 | "rootFileTitle": "Library API",
37 | "doxygenStripFromPath": "..",
38 | "createTreeView": True,
39 | "exhaleExecutesDoxygen": True,
40 | "exhaleUseDoxyfile": True,
41 | "pageLevelConfigMeta": ":github_url: https://github.com/ethz-asl/" + name
42 | }
43 |
44 | source_suffix = ['.rst', '.md']
45 |
46 | # Tell sphinx what the primary language being documented is.
47 | primary_domain = 'cpp'
48 |
49 | # Tell sphinx what the pygments highlight language should be.
50 | highlight_language = 'cpp'
51 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | =======
2 | Voxblox
3 | =======
4 |
5 | .. image:: https://cloud.githubusercontent.com/assets/5616392/15180357/536a8776-1781-11e6-8c1d-f2dfa34b1408.gif
6 | :align: center
7 |
8 | Voxblox is a volumetric mapping library based mainly on Truncated Signed Distance Fields (TSDFs). It varies from other SDF libraries in the following ways:
9 |
10 | * CPU-only, can be run single-threaded or multi-threaded for some integrators
11 | * Support for multiple different layer types (containing different types of voxels)
12 | * Serialization using protobufs
13 | * Different ways of handling weighting during merging
14 | * Different ways of inserting pose information about scans
15 | * Tight ROS integration (in voxblox_ros package)
16 | * Easily extensible with whatever integrators you want
17 | * Features an implementation of building Euclidean Signed Distance Fields (ESDFs, EDTs) directly from TSDFs.
18 |
19 | .. image:: http://i.imgur.com/2wLztFm.gif
20 | :align: center
21 |
22 | .. toctree::
23 | :maxdepth: 3
24 | :caption: Table of Contents
25 | :glob:
26 |
27 | pages/*
28 |
29 | api/library_root
30 |
31 | Paper and Video
32 | ===============
33 | A video showing sample output from voxblox can be seen `here `_.
34 | A video of voxblox being used for online planning on-board a multicopter can be seen `here `_.
35 |
36 | If using voxblox for scientific publications, please cite the following paper, available `here `_:
37 |
38 | Helen Oleynikova, Zachary Taylor, Marius Fehr, Juan Nieto, and Roland Siegwart, “**Voxblox: Incremental 3D Euclidean Signed Distance Fields for On-Board MAV Planning**”, in *IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)*, 2017.::
39 |
40 | @inproceedings{oleynikova2017voxblox,
41 | author={Oleynikova, Helen and Taylor, Zachary and Fehr, Marius and Siegwart, Roland and Nieto, Juan},
42 | booktitle={IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)},
43 | title={Voxblox: Incremental 3D Euclidean Signed Distance Fields for On-Board MAV Planning},
44 | year={2017}
45 | }
46 |
47 | Credits
48 | =======
49 | This library was written primarily by Helen Oleynikova and Marius Fehr, with significant contributions from Zachary Taylor, Alexander Millane, and others. The marching cubes meshing and ROS mesh generation were taken or heavily derived from `open_chisel `_. We've retained the copyright headers for the relevant files.
50 |
51 | .. image:: https://i.imgur.com/pvHhVsL.png
52 | :align: center
53 |
--------------------------------------------------------------------------------
/docs/logo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethz-asl/voxblox/c8066b04075d2fee509de295346b1c0b788c4f38/docs/logo.gif
--------------------------------------------------------------------------------
/docs/pages/Class-Overview.rst:
--------------------------------------------------------------------------------
1 | ==================
2 | Map Class Overview
3 | ==================
4 |
5 | Voxblox Maps
6 | ============
7 |
8 | Maps in Voxblox hold and maintain access to the individual voxels that contain the information about the volume. The organization of the voxels within the map is shown in the image below:
9 |
10 | .. image:: https://user-images.githubusercontent.com/730680/48905123-f638f880-ee60-11e8-9ca1-62e411320636.png
11 | :align: center
12 |
13 | Other Class Types
14 | =================
15 |
16 | A large number of other classes exist in Voxblox that interact with the maps, see the library API for the complete list. Some of the more common class types are shown below:
17 |
18 | .. image:: https://user-images.githubusercontent.com/730680/48905124-f638f880-ee60-11e8-95d4-ceca86f61335.png
19 | :align: center
20 |
--------------------------------------------------------------------------------
/docs/pages/Example-Outputs.rst:
--------------------------------------------------------------------------------
1 | ===============
2 | Example Outputs
3 | ===============
4 |
5 | Machine Hall
6 | ============
7 | A mesh produced by Voxblox running inside a manifold mapper that fuses a SLAM systems poses with the output of a realsense D415 depthcamera. The map was generated while all systems were running fully onboard the pictured micro aerial vehicle.
8 |
9 | .. image:: https://i.imgur.com/t5DHpJh.png/
10 | :align: center
11 |
12 | A higher resolution mesh of the same area that was processed by voxblox offline is shown below.
13 |
14 | .. image:: https://i.imgur.com/pvHhVsL.png/
15 | :align: center
16 |
17 | Cow and Lady Dataset
18 | ====================
19 | Voxblox running on the cow and lady dataset on a laptop equiped with an i7-4810MQ 2.80GHz CPU. In this example the system is integrating a TSDF, generating a mesh and publishing the result to RViz in real time.
20 |
21 | .. image:: http://i.imgur.com/2wLztFm.gif/
22 | :align: center
23 |
24 | Constrained Hardware
25 | ====================
26 | Voxblox running fully onboard the Atom processor of an Intel-Euclid. Again, the system is integrating, meshing and publishing in realtime. In this example the system was also sharing the CPU with the localization system (ROVIO) and the sensor drivers. This left around one CPU core for Voxblox to use.
27 |
28 | .. image:: http://i.imgur.com/98nAed3.gif/
29 | :align: center
30 |
31 | KITTI Dataset
32 | =============
33 | A mesh produced from Voxblox when run on the KITTI dataset on a Desktop PC. The given localization solution and the pointcloud produced by the Velodyne were used.
34 |
35 | .. image:: http://i.imgur.com/jAgLrZk.jpg/
36 | :align: center
37 |
38 | EuRoC Dataset
39 | =============
40 | A voxblox mesh produced by the Maplab library running on the Stereo data provided by the EuRoC dataset.
41 |
42 | .. image:: https://raw.githubusercontent.com/wiki/ethz-asl/maplab/readme_images/stereo.png
43 | :align: center
44 |
45 | Beach Mapping
46 | =============
47 | A map of a beach produced by a platform with two sets of stereo cameras flying an automated coverage path.
48 |
49 | .. image:: http://i.imgur.com/uiE7WAx.gif/
50 | :align: center
51 |
--------------------------------------------------------------------------------
/docs/pages/Expanding-the-Docs.rst:
--------------------------------------------------------------------------------
1 | ==================
2 | Expanding the Docs
3 | ==================
4 |
5 | Building Locally
6 | ================
7 |
8 | If you wish to compile the online docs locally you will need the following dependencies::
9 |
10 | sudo apt-get install python-pip doxygen python-pyaudio
11 | pip install sphinx exhale breath sphinx_rtd_theme recommonmark --user
12 |
13 |
14 | The html documentation can then be compiled by::
15 |
16 | cd ~/catkin_ws/src/voxblox/voxblox/docs
17 | make html
18 |
19 | this will generate a folder ``docs/_build`` with the homepage of the website located at ``docs/_build/html/index.html``. Note that while sphinx will fire off literally hundreds of warnings they can usually be ignored.
20 |
21 | Adding a Page
22 | =============
23 |
24 | Simply add either a ``.rst`` or ``.md`` file to the ``docs/pages`` folder, it will automatically be found and included in the docs. Note that the markdown parser used does not support tables.
25 |
26 | The Docs Generation Structure
27 | =============================
28 |
29 | The docs are generated by `Exhale `_ which automates the combined use of `Doxygen `_, `Sphnix `_ and `Breathe `_. The docs use the readthedocs theme and are hosted on `readthedocs `_ The following files are used in the docs generation:
30 |
31 | conf.py
32 | A python script that controls how Sphinx runs, responsible for loading the Breathe and Exhale extensions and setting up the project.
33 | Doxyfile
34 | A file containing all the options used by doxygen.
35 | index.rst
36 | The homepage of the generated website in ``.rst`` format. It also contains the specifications for the Sphinx TOC Tree which is displayed on the websites sidebar.
37 | logo.gif
38 | The image shown as the logo of the project.
39 | Makefile
40 | Builds the website using Sphinx.
41 | requirements.txt
42 | Used by readthedocs to install the Exhale extension.
43 | pages
44 | Folder containing the additional wiki pages in either ``.rst`` or ``.md`` format.
45 |
46 | Using the Same Documentation on Another Project
47 | ===============================================
48 |
49 | To use the same approach on another project perform the following:
50 |
51 | 1. Copy the Docs folder to the root directory of the project.
52 | 2. Change the value of the ``name`` variable in ``conf.py``.
53 | 3. Modify the index.rst to fit your new project.
54 | 4. Change the contents of the pages folder to your projects ``.md`` and ``.rst`` files.
55 | 5. Add ``docs/_build``, ``docs/doxyoutput`` and ``docs/api`` to your ``.gitignore`` file (for building locally).
56 | 6. Push the changes to github.
57 | 7. Create a new project on readthedocs.io and in advanced settings set the ``Requirements file`` path to ``docs/requirements.txt``.
58 |
--------------------------------------------------------------------------------
/docs/pages/How-Does-ESDF-Generation-Work.rst:
--------------------------------------------------------------------------------
1 | ==============================
2 | How Does ESDF Generation Work?
3 | ==============================
4 |
5 | Description of the algorithm
6 | ============================
7 |
8 | The algorithm id described in `this paper `_:
9 |
10 | Helen Oleynikova, Zachary Taylor, Marius Fehr, Juan Nieto, and Roland Siegwart, “**Voxblox: Incremental 3D Euclidean Signed Distance Fields for On-Board MAV Planning**”, in *IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)*, 2017.
11 |
12 | .. code-block:: latex
13 |
14 | @inproceedings{oleynikova2017voxblox,
15 | author={Oleynikova, Helen and Taylor, Zachary and Fehr, Marius and Siegwart, Roland and Nieto, Juan},
16 | booktitle={IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)},
17 | title={Voxblox: Incremental 3D Euclidean Signed Distance Fields for On-Board MAV Planning},
18 | year={2017}
19 | }
20 |
21 |
22 | We have some system flowcharts below to make it easier to understand the general flow of data.
23 |
24 | How TSDF values are propagated to ESDF
25 | --------------------------------------
26 |
27 | .. image:: https://user-images.githubusercontent.com/5616392/45752912-4dc7a780-bc17-11e8-80fe-9b5a43b373f5.png
28 | :align: center
29 |
30 | How the Raise Wavefront works
31 | -----------------------------
32 |
33 | .. image:: https://user-images.githubusercontent.com/5616392/45752919-50c29800-bc17-11e8-9737-69929f252d85.png
34 | :align: center
35 |
36 | How the Lower Wavefront works
37 | -----------------------------
38 |
39 | .. image:: https://user-images.githubusercontent.com/5616392/45752914-4ef8d480-bc17-11e8-93cb-4230b57eb186.png
40 | :align: center
41 |
--------------------------------------------------------------------------------
/docs/pages/Installation.rst:
--------------------------------------------------------------------------------
1 | ============
2 | Installation
3 | ============
4 |
5 | To install voxblox, please install `ROS Indigo `_, `ROS Kinetic `_ or `ROS Melodic `_.
6 | These instructions are for Ubuntu, Voxblox will also run on OS X, but you're more or less on your own there.
7 |
8 | First install additional system dependencies (swap kinetic for indigo or melodic as necessary)::
9 |
10 | sudo apt-get install python-wstool python-catkin-tools ros-kinetic-cmake-modules protobuf-compiler autoconf libprotobuf-dev protobuf-c-compiler
11 |
12 | Next, add a few other dependencies.
13 | If you don't have a catkin workspace yet, set it up as follows::
14 |
15 | mkdir -p ~/catkin_ws/src
16 | cd ~/catkin_ws
17 | catkin init
18 | catkin config --extend /opt/ros/kinetic
19 | catkin config --cmake-args -DCMAKE_BUILD_TYPE=Release
20 | catkin config --merge-devel
21 |
22 | If using `SSH keys for github `_ (recommended)::
23 |
24 | cd ~/catkin_ws/src/
25 | git clone git@github.com:ethz-asl/voxblox.git
26 | wstool init . ./voxblox/voxblox_ssh.rosinstall
27 | wstool update
28 |
29 |
30 | If **not using SSH** keys but using https instead::
31 |
32 | cd ~/catkin_ws/src/
33 | git clone https://github.com/ethz-asl/voxblox.git
34 | wstool init . ./voxblox/voxblox_https.rosinstall
35 | wstool update
36 |
37 | If you have already initalized wstool replace the above ``wstool init`` with ``wstool merge -t``
38 |
39 | Compile::
40 |
41 | cd ~/catkin_ws/src/
42 | catkin build voxblox_ros
43 |
--------------------------------------------------------------------------------
/docs/pages/Modifying-and-Contributing.rst:
--------------------------------------------------------------------------------
1 | =======================
2 | Contributing to Voxblox
3 | =======================
4 |
5 | These steps are only necessary if you plan on contributing to voxblox.
6 |
7 | Code style
8 | ==========
9 |
10 | We follow the style and best practices listed in the `Google C++ Style Guide `_.
11 |
12 | Setting up the linter
13 | ---------------------
14 |
15 | This sets up a linter which checks if the code conforms to our style guide during commits.
16 |
17 | First, install the dependencies listed `here `_.
18 |
19 | .. code-block:: bash
20 |
21 | cd ~/catkin_ws/src/
22 | git clone git@github.com:ethz-asl/linter.git
23 | cd linter
24 | echo ". $(realpath setup_linter.sh)" >> ~/.bashrc # Or the matching file for
25 | # your shell.
26 | bash
27 |
28 | # Initialize linter in voxblox repo
29 | cd ~/catkin_ws/src/voxblox
30 | init_linter_git_hooks
31 |
32 | For more information about the linter visit `ethz/linter `_
33 |
34 | Modifying Voxblox
35 | =================
36 | Here's some hints on how to extend voxblox to fit your needs...
37 |
38 | Serialization
39 | -------------
40 |
41 | Serialization is currently implemented for:
42 |
43 | * TSDF layers
44 | * ESDF layers
45 | * Occupancy layers
46 |
47 | The following serialization tools are implemented:
48 |
49 | * Store a layer to file
50 | * Load layer from file
51 | * Store a subset of the blocks of a layer to file
52 | * Load blocks from file and add to a layer
53 |
54 | How to add your own voxel/layer type
55 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
56 |
57 | - Add your own voxel type and implement the ``getVoxelType()``, e.g. ``fancy_voxel.h`` :
58 |
59 | .. code-block:: bash
60 |
61 | namespace voxblox {
62 |
63 | // Used for serialization only.
64 | namespace voxel_types {
65 | const std::string kYOUR_FANCY_VOXEL = "fancy_voxel"
66 | } // namespace voxel_types
67 |
68 | template <>
69 | inline std::string getVoxelType() {
70 | return voxel_types::kYOUR_FANCY_VOXEL;
71 | }
72 |
73 | } // namespace voxblox
74 |
75 | - Implement the block (de)serialization functions for your voxel type, e.g. ``fancy_block_serialization.cc``
76 |
77 | .. code-block:: bash
78 |
79 | namespace voxblox {
80 |
81 | template <>
82 | void Block::DeserializeVoxelData(const BlockProto& proto,
83 | YOUR_FANCY_VOXEL* voxels) {
84 | // Your serialization code.
85 | }
86 |
87 | template <>
88 | void Block::SerializeVoxelData(const YOUR_FANCY_VOXEL* voxels,
89 | BlockProto* proto) const {
90 | // Your serialization code.
91 | }
92 |
93 | } // namespace voxblox
94 |
95 | - Create your own fancy_integrator.h, fancy_mesh_integrator.h, ...
96 |
97 | **Have a look at the example package:**
98 |
99 | TODO(mfehr, helenol): add example package with a new voxel type
100 |
--------------------------------------------------------------------------------
/docs/pages/Running-Voxblox.rst:
--------------------------------------------------------------------------------
1 | ===============
2 | Running Voxblox
3 | ===============
4 |
5 | The easiest way to test out voxblox is to try it out on a dataset.
6 | We have launch files for our `own dataset `_, the `Euroc Vicon Room datasets `_, and the `KITTI raw datasets `_ processed through `kitti_to_rosbag `_.
7 |
8 | For each of these datasets, there's a launch file associated under `voxblox_ros/launch`.
9 |
10 | The easiest way to start is to download the `cow and lady dataset `_, edit the path to the bagfile in ``cow_and_lady_dataset.launch``, and then simply::
11 |
12 | roslaunch voxblox_ros cow_and_lady_dataset.launch
13 |
14 | An alternative dataset the `basement dataset `_ is also available. While this dataset lacks ground truth it demonstrates the capabilities of Voxblox running on Velodyne lidar data and uses ICP corrections to compensate for a drifting pose estimate. To run the dataset edit the path to the bagfile in ``basement_dataset.launch``, and then simply::
15 |
16 | roslaunch voxblox_ros basement_dataset.launch
17 |
18 |
19 | If you open rviz, you should be able to see the the mesh visualized on the ``/voxblox_node/mesh`` topic of type voxblox_msgs/Mesh, in the ``world`` static frame, as shown below. One should source ``catkin_ws/devel/setup.bash`` before starting rviz, to make it recognize this topic type.
20 |
21 | The mesh only updates once per second (this is a setting in the launch file).
22 |
23 | .. image:: http://i.imgur.com/nSX5Qsh.jpg
24 | :align: center
25 |
26 | The rest of the commonly-used settings are parameters in the launch file. The the voxblox node page has the full list of settings.
27 |
--------------------------------------------------------------------------------
/docs/pages/Transformations.rst:
--------------------------------------------------------------------------------
1 | ==========================
2 | Transformations in Voxblox
3 | ==========================
4 |
5 | Voxblox uses active transforms and Hamilton quaternions. For further details on the notation used throughout the code see `the minkindr wiki `_
6 |
--------------------------------------------------------------------------------
/docs/pages/Using-Voxblox-for-Planning.rst:
--------------------------------------------------------------------------------
1 | ==========================
2 | Using Voxblox for Planning
3 | ==========================
4 |
5 | The planners described in `Continuous-Time Trajectory Optimization for Online UAV Replanning `_, `Safe Local Exploration for Replanning in Cluttered Unknown Environments for Micro-Aerial Vehicles `_, and `Sparse 3D Topological Graphs for Micro-Aerial Vehicle Planning `_ will be open-sourced shortly.
6 |
7 | In the mean-time, the general idea behind using voxblox for planning is to have two nodes running: one for the mapping, which ingests pointcloud data and produces both a TSDF and an ESDF, and one for planning, which subscribes to the latest ESDF layer over ROS.
8 |
9 | The planner should have a ``voxblox::EsdfServer`` as a member, and simply remap the ``esdf_map_out`` and ``esdf_map_in`` topics to match.
10 |
11 | A sample launch file is shown below:
12 |
13 | .. code-block:: xml
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | And some scaffolding for writing your own planner using ESDF collision checking:
48 |
49 | .. code-block:: c++
50 |
51 | class YourPlannerVoxblox {
52 | public:
53 | YourPlannerVoxblox(const ros::NodeHandle& nh,
54 | const ros::NodeHandle& nh_private);
55 | virtual ~YourPlannerVoxblox() {}
56 | double getMapDistance(const Eigen::Vector3d& position) const;
57 | private:
58 | ros::NodeHandle nh_;
59 | ros::NodeHandle nh_private_;
60 |
61 | // Map!
62 | voxblox::EsdfServer voxblox_server_;
63 | };
64 |
65 | There's also a traversability pointcloud you can enable/disable, that if you set the radius to your robot's collision checking radius, can show you parts of the map the planner thinks are traversable in a pointcloud:
66 |
67 | .. code-block:: c++
68 |
69 | YourPlannerVoxblox::YourPlannerVoxblox(const ros::NodeHandle& nh,
70 | const ros::NodeHandle& nh_private)
71 | : nh_(nh),
72 | nh_private_(nh_private),
73 | voxblox_server_(nh_, nh_private_) {
74 | // Optionally load a map saved with the save_map service call in voxblox.
75 | std::string input_filepath;
76 | nh_private_.param("voxblox_path", input_filepath, input_filepath);
77 | if (!input_filepath.empty()) {
78 | if (!voxblox_server_.loadMap(input_filepath)) {
79 | ROS_ERROR("Couldn't load ESDF map!");
80 | }
81 | }
82 | double robot_radius = 1.0;
83 | voxblox_server_.setTraversabilityRadius(robot_radius);
84 | voxblox_server_.publishTraversable();
85 | }
86 |
87 |
88 | Then to check for collisions you can just compare map distance to your robot radius:
89 |
90 | .. code-block:: c++
91 |
92 | double YourPlannerVoxblox::getMapDistance(
93 | const Eigen::Vector3d& position) const {
94 | if (!voxblox_server_.getEsdfMapPtr()) {
95 | return 0.0;
96 | }
97 | double distance = 0.0;
98 | if (!voxblox_server_.getEsdfMapPtr()->getDistanceAtPosition(position,
99 | &distance)) {
100 | return 0.0;
101 | }
102 | return distance;
103 | }
104 |
--------------------------------------------------------------------------------
/docs/requirements.txt:
--------------------------------------------------------------------------------
1 | exhale
2 |
--------------------------------------------------------------------------------
/rosdoc.yaml:
--------------------------------------------------------------------------------
1 | - builder: sphinx # specify document generator. e.g) doxygen, epidoc, sphinx
2 | sphinx_root_dir: a # document directory
--------------------------------------------------------------------------------
/voxblox/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.12)
2 | project(voxblox)
3 |
4 | find_package(catkin_simple REQUIRED )
5 | catkin_simple(ALL_DEPS_REQUIRED)
6 |
7 | set(CMAKE_MACOSX_RPATH 0)
8 | add_definitions(-std=c++11 -Wall -Wextra)
9 |
10 | ############
11 | # PROTOBUF #
12 | ############
13 | # General idea: first check if we have protobuf catkin, then use that.
14 | # Otherwise use system protobuf.
15 | set(PROTO_DEFNS proto/voxblox/Block.proto
16 | proto/voxblox/Layer.proto)
17 | set(BASE_PATH "proto")
18 | set(PROTOBUF_COMPILE_PYTHON true)
19 |
20 | PROTOBUF_CATKIN_GENERATE_CPP2(${BASE_PATH} PROTO_SRCS PROTO_HDRS ${PROTO_DEFNS})
21 |
22 | ####################
23 | # SET SOURCE FILES #
24 | ####################
25 |
26 | set("${PROJECT_NAME}_SRCS"
27 | src/alignment/icp.cc
28 | src/core/block.cc
29 | src/core/esdf_map.cc
30 | src/core/tsdf_map.cc
31 | src/integrator/esdf_integrator.cc
32 | src/integrator/esdf_occ_integrator.cc
33 | src/integrator/integrator_utils.cc
34 | src/integrator/intensity_integrator.cc
35 | src/integrator/tsdf_integrator.cc
36 | src/io/mesh_ply.cc
37 | src/io/sdf_ply.cc
38 | src/mesh/marching_cubes.cc
39 | src/simulation/objects.cc
40 | src/simulation/simulation_world.cc
41 | src/utils/camera_model.cc
42 | src/utils/evaluation_utils.cc
43 | src/utils/layer_utils.cc
44 | src/utils/neighbor_tools.cc
45 | src/utils/protobuf_utils.cc
46 | src/utils/timing.cc
47 | src/utils/voxel_utils.cc
48 | )
49 |
50 | #############
51 | # LIBRARIES #
52 | #############
53 | cs_add_library(${PROJECT_NAME}_proto
54 | ${PROTO_SRCS}
55 | )
56 |
57 | cs_add_library(${PROJECT_NAME}
58 | ${${PROJECT_NAME}_SRCS}
59 | )
60 | target_link_libraries(${PROJECT_NAME} ${PROJECT_NAME}_proto)
61 |
62 | ############
63 | # BINARIES #
64 | ############
65 |
66 | add_executable(tsdf_to_esdf
67 | test/tsdf_to_esdf.cc
68 | )
69 | target_link_libraries(tsdf_to_esdf ${PROJECT_NAME})
70 |
71 | add_executable(test_load_esdf
72 | test/test_load_esdf.cc
73 | )
74 | target_link_libraries(test_load_esdf ${PROJECT_NAME})
75 |
76 | #########
77 | # TESTS #
78 | #########
79 | add_custom_target(test_data)
80 | add_custom_command(TARGET test_data
81 | COMMAND rm -rf test_data
82 | COMMAND mkdir -p test_data
83 | COMMAND cp -r ${CMAKE_SOURCE_DIR}/test/test_data/*
84 | test_data/ || :)
85 |
86 | #add_definitions(-DVISUALIZE_UNIT_TEST_RESULTS)
87 |
88 | catkin_add_gtest(test_approx_hash_array
89 | test/test_approx_hash_array.cc
90 | )
91 | target_link_libraries(test_approx_hash_array ${PROJECT_NAME})
92 |
93 | catkin_add_gtest(test_tsdf_map
94 | test/test_tsdf_map.cc
95 | )
96 | target_link_libraries(test_tsdf_map ${PROJECT_NAME})
97 |
98 | catkin_add_gtest(test_protobuf
99 | test/test_protobuf.cc
100 | )
101 | target_link_libraries(test_protobuf ${PROJECT_NAME})
102 |
103 | catkin_add_gtest(test_tsdf_interpolator
104 | test/test_tsdf_interpolator.cc
105 | )
106 | target_link_libraries(test_tsdf_interpolator ${PROJECT_NAME})
107 |
108 | catkin_add_gtest(test_layer
109 | test/test_layer.cc
110 | )
111 | target_link_libraries(test_layer ${PROJECT_NAME})
112 |
113 | catkin_add_gtest(test_merge_integration
114 | test/test_merge_integration.cc
115 | )
116 | target_link_libraries(test_merge_integration ${PROJECT_NAME})
117 |
118 | catkin_add_gtest(test_layer_utils
119 | test/test_layer_utils.cc
120 | )
121 | target_link_libraries(test_layer_utils ${PROJECT_NAME})
122 |
123 | catkin_add_gtest(test_sdf_integrators
124 | test/test_sdf_integrators.cc
125 | )
126 | target_link_libraries(test_sdf_integrators ${PROJECT_NAME})
127 |
128 | catkin_add_gtest(test_bucket_queue
129 | test/test_bucket_queue.cc
130 | )
131 | target_link_libraries(test_bucket_queue ${PROJECT_NAME})
132 |
133 | catkin_add_gtest(test_clear_spheres
134 | test/test_clear_spheres.cc
135 | )
136 | target_link_libraries(test_clear_spheres ${PROJECT_NAME})
137 |
138 | ##########
139 | # EXPORT #
140 | ##########
141 | cs_install()
142 | cs_export(INCLUDE_DIRS ${CATKIN_DEVEL_PREFIX}/include)
143 |
--------------------------------------------------------------------------------
/voxblox/include/voxblox/core/block_hash.h:
--------------------------------------------------------------------------------
1 | #ifndef VOXBLOX_CORE_BLOCK_HASH_H_
2 | #define VOXBLOX_CORE_BLOCK_HASH_H_
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #include
10 |
11 | #include "voxblox/core/common.h"
12 |
13 | namespace voxblox {
14 |
15 | /**
16 | * Performs deco hashing on block indexes. Based on recommendations of
17 | * "Investigating the impact of Suboptimal Hashing Functions" by L. Buckley et
18 | * al.
19 | */
20 | struct AnyIndexHash {
21 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW
22 |
23 | /// number was arbitrarily chosen with no good justification
24 | static constexpr size_t sl = 17191;
25 | static constexpr size_t sl2 = sl * sl;
26 |
27 | std::size_t operator()(const AnyIndex& index) const {
28 | return static_cast(index.x() + index.y() * sl +
29 | index.z() * sl2);
30 | }
31 | };
32 |
33 | template
34 | struct AnyIndexHashMapType {
35 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW
36 |
37 | typedef std::unordered_map<
38 | AnyIndex, ValueType, AnyIndexHash, std::equal_to,
39 | Eigen::aligned_allocator > >
40 | type;
41 | };
42 |
43 | typedef std::unordered_set,
44 | Eigen::aligned_allocator >
45 | IndexSet;
46 |
47 | typedef typename AnyIndexHashMapType::type HierarchicalIndexMap;
48 |
49 | typedef typename AnyIndexHashMapType::type HierarchicalIndexSet;
50 |
51 | typedef typename HierarchicalIndexMap::value_type HierarchicalIndex;
52 |
53 | /// Hash for large index values, see AnyIndexHash.
54 | struct LongIndexHash {
55 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW
56 |
57 | static constexpr size_t sl = 17191;
58 | static constexpr size_t sl2 = sl * sl;
59 |
60 | std::size_t operator()(const LongIndex& index) const {
61 | return static_cast(index.x() + index.y() * sl +
62 | index.z() * sl2);
63 | }
64 | };
65 |
66 | template
67 | struct LongIndexHashMapType {
68 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW
69 |
70 | typedef std::unordered_map<
71 | LongIndex, ValueType, LongIndexHash, std::equal_to,
72 | Eigen::aligned_allocator > >
73 | type;
74 | };
75 |
76 | typedef std::unordered_set,
77 | Eigen::aligned_allocator >
78 | LongIndexSet;
79 |
80 | } // namespace voxblox
81 |
82 | #endif // VOXBLOX_CORE_BLOCK_HASH_H_
83 |
--------------------------------------------------------------------------------
/voxblox/include/voxblox/core/block_inl.h:
--------------------------------------------------------------------------------
1 | #ifndef VOXBLOX_CORE_BLOCK_INL_H_
2 | #define VOXBLOX_CORE_BLOCK_INL_H_
3 |
4 | #include
5 | #include
6 |
7 | #include "voxblox/Block.pb.h"
8 | #include "voxblox/utils/voxel_utils.h"
9 |
10 | namespace voxblox {
11 |
12 | template
13 | size_t Block::computeLinearIndexFromVoxelIndex(
14 | const VoxelIndex& index) const {
15 | size_t linear_index = static_cast(
16 | index.x() +
17 | voxels_per_side_ * (index.y() + index.z() * voxels_per_side_));
18 |
19 | DCHECK(index.x() >= 0 && index.x() < static_cast(voxels_per_side_));
20 | DCHECK(index.y() >= 0 && index.y() < static_cast(voxels_per_side_));
21 | DCHECK(index.z() >= 0 && index.z() < static_cast(voxels_per_side_));
22 |
23 | DCHECK_LT(linear_index,
24 | voxels_per_side_ * voxels_per_side_ * voxels_per_side_);
25 | DCHECK_GE(linear_index, 0u);
26 | return linear_index;
27 | }
28 |
29 | template
30 | VoxelIndex Block::computeTruncatedVoxelIndexFromCoordinates(
31 | const Point& coords) const {
32 | const IndexElement max_value = voxels_per_side_ - 1;
33 | VoxelIndex voxel_index =
34 | getGridIndexFromPoint(coords - origin_, voxel_size_inv_);
35 | // check is needed as getGridIndexFromPoint gives results that have a tiny
36 | // chance of being outside the valid voxel range.
37 | return VoxelIndex(std::max(std::min(voxel_index.x(), max_value), 0),
38 | std::max(std::min(voxel_index.y(), max_value), 0),
39 | std::max(std::min(voxel_index.z(), max_value), 0));
40 | }
41 |
42 | template
43 | VoxelIndex Block::computeVoxelIndexFromLinearIndex(
44 | size_t linear_index) const {
45 | int rem = linear_index;
46 | VoxelIndex result;
47 | std::div_t div_temp = std::div(rem, voxels_per_side_ * voxels_per_side_);
48 | rem = div_temp.rem;
49 | result.z() = div_temp.quot;
50 | div_temp = std::div(rem, voxels_per_side_);
51 | result.y() = div_temp.quot;
52 | result.x() = div_temp.rem;
53 | return result;
54 | }
55 |
56 | template
57 | bool Block::isValidVoxelIndex(const VoxelIndex& index) const {
58 | if (index.x() < 0 ||
59 | index.x() >= static_cast(voxels_per_side_)) {
60 | return false;
61 | }
62 | if (index.y() < 0 ||
63 | index.y() >= static_cast(voxels_per_side_)) {
64 | return false;
65 | }
66 | if (index.z() < 0 ||
67 | index.z() >= static_cast(voxels_per_side_)) {
68 | return false;
69 | }
70 | return true;
71 | }
72 |
73 | template
74 | Block::Block(const BlockProto& proto)
75 | : Block(proto.voxels_per_side(), proto.voxel_size(),
76 | Point(proto.origin_x(), proto.origin_y(), proto.origin_z())) {
77 | has_data_ = proto.has_data();
78 |
79 | // Convert the data into a vector of integers.
80 | std::vector data;
81 | data.reserve(proto.voxel_data_size());
82 |
83 | for (uint32_t word : proto.voxel_data()) {
84 | data.push_back(word);
85 | }
86 |
87 | deserializeFromIntegers(data);
88 | }
89 |
90 | template
91 | void Block::getProto(BlockProto* proto) const {
92 | CHECK_NOTNULL(proto);
93 |
94 | proto->set_voxels_per_side(voxels_per_side_);
95 | proto->set_voxel_size(voxel_size_);
96 |
97 | proto->set_origin_x(origin_.x());
98 | proto->set_origin_y(origin_.y());
99 | proto->set_origin_z(origin_.z());
100 |
101 | proto->set_has_data(has_data_);
102 |
103 | std::vector data;
104 | serializeToIntegers(&data);
105 | // Not quite actually a word since we're in a 64-bit age now, but whatever.
106 | for (uint32_t word : data) {
107 | proto->add_voxel_data(word);
108 | }
109 | }
110 |
111 | template
112 | void Block::mergeBlock(const Block& other_block) {
113 | CHECK_EQ(other_block.voxel_size(), voxel_size());
114 | CHECK_EQ(other_block.voxels_per_side(), voxels_per_side());
115 |
116 | if (!other_block.has_data()) {
117 | return;
118 | } else {
119 | has_data() = true;
120 | updated().set();
121 |
122 | for (IndexElement voxel_idx = 0;
123 | voxel_idx < static_cast(num_voxels()); ++voxel_idx) {
124 | mergeVoxelAIntoVoxelB(
125 | other_block.getVoxelByLinearIndex(voxel_idx),
126 | &(getVoxelByLinearIndex(voxel_idx)));
127 | }
128 | }
129 | }
130 |
131 | template
132 | size_t Block::getMemorySize() const {
133 | size_t size = 0u;
134 |
135 | // Calculate size of members
136 | size += sizeof(voxels_per_side_);
137 | size += sizeof(voxel_size_);
138 | size += sizeof(origin_);
139 | size += sizeof(num_voxels_);
140 | size += sizeof(voxel_size_inv_);
141 | size += sizeof(block_size_);
142 |
143 | size += sizeof(has_data_);
144 | size += sizeof(updated_);
145 |
146 | if (num_voxels_ > 0u) {
147 | size += (num_voxels_ * sizeof(voxels_[0]));
148 | }
149 | return size;
150 | }
151 |
152 | } // namespace voxblox
153 |
154 | #endif // VOXBLOX_CORE_BLOCK_INL_H_
155 |
--------------------------------------------------------------------------------
/voxblox/include/voxblox/core/color.h:
--------------------------------------------------------------------------------
1 | #ifndef VOXBLOX_CORE_COLOR_H_
2 | #define VOXBLOX_CORE_COLOR_H_
3 |
4 | #include "voxblox/core/common.h"
5 |
6 | namespace voxblox {
7 |
8 | // Color maps.
9 |
10 | /**
11 | * Maps an input h from a value between 0.0 and 1.0 into a rainbow. Copied from
12 | * OctomapProvider in octomap.
13 | */
14 | inline Color rainbowColorMap(double h) {
15 | Color color;
16 | color.a = 255;
17 | // blend over HSV-values (more colors)
18 |
19 | double s = 1.0;
20 | double v = 1.0;
21 |
22 | h -= floor(h);
23 | h *= 6;
24 | int i;
25 | double m, n, f;
26 |
27 | i = floor(h);
28 | f = h - i;
29 | if (!(i & 1)) f = 1 - f; // if i is even
30 | m = v * (1 - s);
31 | n = v * (1 - s * f);
32 |
33 | switch (i) {
34 | case 6:
35 | case 0:
36 | color.r = 255 * v;
37 | color.g = 255 * n;
38 | color.b = 255 * m;
39 | break;
40 | case 1:
41 | color.r = 255 * n;
42 | color.g = 255 * v;
43 | color.b = 255 * m;
44 | break;
45 | case 2:
46 | color.r = 255 * m;
47 | color.g = 255 * v;
48 | color.b = 255 * n;
49 | break;
50 | case 3:
51 | color.r = 255 * m;
52 | color.g = 255 * n;
53 | color.b = 255 * v;
54 | break;
55 | case 4:
56 | color.r = 255 * n;
57 | color.g = 255 * m;
58 | color.b = 255 * v;
59 | break;
60 | case 5:
61 | color.r = 255 * v;
62 | color.g = 255 * m;
63 | color.b = 255 * n;
64 | break;
65 | default:
66 | color.r = 255;
67 | color.g = 127;
68 | color.b = 127;
69 | break;
70 | }
71 |
72 | return color;
73 | }
74 |
75 | /// Maps an input h from a value between 0.0 and 1.0 into a grayscale color.
76 | inline Color grayColorMap(double h) {
77 | Color color;
78 | color.a = 255;
79 |
80 | color.r = round(h * 255);
81 | color.b = color.r;
82 | color.g = color.r;
83 |
84 | return color;
85 | }
86 |
87 | inline Color randomColor() {
88 | Color color;
89 |
90 | color.a = 255;
91 |
92 | color.r = rand() % 256;
93 | color.b = rand() % 256;
94 | color.g = rand() % 256;
95 |
96 | return color;
97 | }
98 |
99 | } // namespace voxblox
100 |
101 | #endif // VOXBLOX_CORE_COLOR_H_
102 |
--------------------------------------------------------------------------------
/voxblox/include/voxblox/core/occupancy_map.h:
--------------------------------------------------------------------------------
1 | #ifndef VOXBLOX_CORE_OCCUPANCY_MAP_H_
2 | #define VOXBLOX_CORE_OCCUPANCY_MAP_H_
3 |
4 | #include
5 | #include
6 |
7 | #include
8 |
9 | #include "voxblox/core/common.h"
10 | #include "voxblox/core/layer.h"
11 | #include "voxblox/core/voxel.h"
12 |
13 | namespace voxblox {
14 | /// Map holding an Occupancy Layer, inspired by Octomap.
15 | class OccupancyMap {
16 | public:
17 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW
18 |
19 | typedef std::shared_ptr Ptr;
20 |
21 | struct Config {
22 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW
23 |
24 | FloatingPoint occupancy_voxel_size = 0.2;
25 | size_t occupancy_voxels_per_side = 16u;
26 | };
27 |
28 | explicit OccupancyMap(const Config& config)
29 | : occupancy_layer_(new Layer(
30 | config.occupancy_voxel_size, config.occupancy_voxels_per_side)) {
31 | block_size_ =
32 | config.occupancy_voxel_size * config.occupancy_voxels_per_side;
33 | }
34 |
35 | // Creates a new OccupancyMap based on a COPY of this layer.
36 | explicit OccupancyMap(const Layer& layer)
37 | : OccupancyMap(aligned_shared>(layer)) {}
38 |
39 | // Creates a new OccupancyMap that contains this layer.
40 | explicit OccupancyMap(Layer::Ptr layer)
41 | : occupancy_layer_(layer) {
42 | CHECK(layer);
43 | block_size_ = layer->block_size();
44 | }
45 |
46 | virtual ~OccupancyMap() {}
47 |
48 | Layer* getOccupancyLayerPtr() {
49 | return occupancy_layer_.get();
50 | }
51 | const Layer& getOccupancyLayer() const {
52 | return *occupancy_layer_;
53 | }
54 |
55 | FloatingPoint block_size() const { return block_size_; }
56 |
57 | protected:
58 | FloatingPoint block_size_;
59 |
60 | // The layers.
61 | Layer::Ptr occupancy_layer_;
62 | };
63 |
64 | } // namespace voxblox
65 |
66 | #endif // VOXBLOX_CORE_OCCUPANCY_MAP_H_
67 |
--------------------------------------------------------------------------------
/voxblox/include/voxblox/core/tsdf_map.h:
--------------------------------------------------------------------------------
1 | #ifndef VOXBLOX_CORE_TSDF_MAP_H_
2 | #define VOXBLOX_CORE_TSDF_MAP_H_
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #include
9 |
10 | #include "voxblox/core/common.h"
11 | #include "voxblox/core/layer.h"
12 | #include "voxblox/core/voxel.h"
13 | #include "voxblox/interpolator/interpolator.h"
14 |
15 | namespace voxblox {
16 | /**
17 | * Map holding a Truncated Signed Distance Field Layer. Contains functions for
18 | * interacting with the layer and getting gradient and distance information.
19 | */
20 | class TsdfMap {
21 | public:
22 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW
23 |
24 | typedef std::shared_ptr Ptr;
25 |
26 | struct Config {
27 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW
28 |
29 | FloatingPoint tsdf_voxel_size = 0.2;
30 | size_t tsdf_voxels_per_side = 16u;
31 |
32 | std::string print() const;
33 | };
34 |
35 | explicit TsdfMap(const Config& config)
36 | : tsdf_layer_(new Layer(config.tsdf_voxel_size,
37 | config.tsdf_voxels_per_side)),
38 | interpolator_(tsdf_layer_.get()) {
39 | block_size_ = config.tsdf_voxel_size * config.tsdf_voxels_per_side;
40 | }
41 |
42 | /// Creates a new TsdfMap based on a COPY of this layer.
43 | explicit TsdfMap(const Layer& layer)
44 | : TsdfMap(aligned_shared>(layer)) {}
45 |
46 | /// Creates a new TsdfMap that contains this layer.
47 | explicit TsdfMap(Layer::Ptr layer)
48 | : tsdf_layer_(layer), interpolator_(tsdf_layer_.get()) {
49 | if (!layer) {
50 | /* NOTE(mereweth@jpl.nasa.gov) - throw std exception for Python to catch
51 | * This is idiomatic when wrapping C++ code for Python, especially with
52 | * pybind11
53 | */
54 | throw std::runtime_error(std::string("Null Layer::Ptr") +
55 | " in TsdfMap constructor");
56 | }
57 |
58 | CHECK(layer);
59 | block_size_ = layer->block_size();
60 | }
61 |
62 | virtual ~TsdfMap() {}
63 |
64 | Layer* getTsdfLayerPtr() { return tsdf_layer_.get(); }
65 | const Layer* getTsdfLayerConstPtr() const {
66 | return tsdf_layer_.get();
67 | }
68 | const Layer& getTsdfLayer() const { return *tsdf_layer_; }
69 |
70 | FloatingPoint block_size() const { return block_size_; }
71 | FloatingPoint voxel_size() const { return tsdf_layer_->voxel_size(); }
72 |
73 | /* NOTE(mereweth@jpl.nasa.gov)
74 | * EigenDRef is fully dynamic stride type alias for Numpy array slices
75 | * Use column-major matrices; column-by-column traversal is faster
76 | * Convenience alias borrowed from pybind11
77 | */
78 | using EigenDStride = Eigen::Stride;
79 | template
80 | using EigenDRef = Eigen::Ref;
81 |
82 | /**
83 | * Extract all voxels on a slice plane that is parallel to one of the
84 | * axis-aligned planes. free_plane_index specifies the free coordinate
85 | * (zero-based; x, y, z order) free_plane_val specifies the plane intercept
86 | * coordinate along that axis
87 | */
88 | unsigned int coordPlaneSliceGetDistanceWeight(
89 | unsigned int free_plane_index, double free_plane_val,
90 | EigenDRef>& positions,
91 | Eigen::Ref distances,
92 | Eigen::Ref weights, unsigned int max_points) const;
93 |
94 | bool getWeightAtPosition(const Eigen::Vector3d& position,
95 | double* weight) const;
96 | bool getWeightAtPosition(const Eigen::Vector3d& position,
97 | const bool interpolate, double* weight) const;
98 |
99 | protected:
100 | FloatingPoint block_size_;
101 |
102 | // The layers.
103 | Layer::Ptr tsdf_layer_;
104 |
105 | // Interpolator for the layer.
106 | Interpolator interpolator_;
107 | };
108 |
109 | } // namespace voxblox
110 |
111 | #endif // VOXBLOX_CORE_TSDF_MAP_H_
112 |
--------------------------------------------------------------------------------
/voxblox/include/voxblox/core/voxel.h:
--------------------------------------------------------------------------------
1 | #ifndef VOXBLOX_CORE_VOXEL_H_
2 | #define VOXBLOX_CORE_VOXEL_H_
3 |
4 | #include
5 | #include
6 |
7 | #include "voxblox/core/color.h"
8 | #include "voxblox/core/common.h"
9 |
10 | namespace voxblox {
11 |
12 | struct TsdfVoxel {
13 | float distance = 0.0f;
14 | float weight = 0.0f;
15 | Color color;
16 | };
17 |
18 | struct EsdfVoxel {
19 | float distance = 0.0f;
20 |
21 | bool observed = false;
22 | /**
23 | * Whether the voxel was copied from the TSDF (false) or created from a pose
24 | * or some other source (true). This member is not serialized!!!
25 | */
26 | bool hallucinated = false;
27 | bool in_queue = false;
28 | bool fixed = false;
29 |
30 | /**
31 | * Relative direction toward parent. If itself, then either uninitialized
32 | * or in the fixed frontier.
33 | */
34 | Eigen::Vector3i parent = Eigen::Vector3i::Zero();
35 |
36 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW
37 | };
38 |
39 | struct OccupancyVoxel {
40 | float probability_log = 0.0f;
41 | bool observed = false;
42 | };
43 |
44 | struct IntensityVoxel {
45 | float intensity = 0.0f;
46 | float weight = 0.0f;
47 | };
48 |
49 | /// Used for serialization only.
50 | namespace voxel_types {
51 | const std::string kNotSerializable = "not_serializable";
52 | const std::string kTsdf = "tsdf";
53 | const std::string kEsdf = "esdf";
54 | const std::string kOccupancy = "occupancy";
55 | const std::string kIntensity = "intensity";
56 | } // namespace voxel_types
57 |
58 | template
59 | std::string getVoxelType() {
60 | return voxel_types::kNotSerializable;
61 | }
62 |
63 | template <>
64 | inline std::string getVoxelType() {
65 | return voxel_types::kTsdf;
66 | }
67 |
68 | template <>
69 | inline std::string getVoxelType() {
70 | return voxel_types::kEsdf;
71 | }
72 |
73 | template <>
74 | inline std::string getVoxelType() {
75 | return voxel_types::kOccupancy;
76 | }
77 |
78 | template <>
79 | inline std::string getVoxelType() {
80 | return voxel_types::kIntensity;
81 | }
82 |
83 | } // namespace voxblox
84 |
85 | #endif // VOXBLOX_CORE_VOXEL_H_
86 |
--------------------------------------------------------------------------------
/voxblox/include/voxblox/integrator/esdf_occ_integrator.h:
--------------------------------------------------------------------------------
1 | #ifndef VOXBLOX_INTEGRATOR_ESDF_OCC_INTEGRATOR_H_
2 | #define VOXBLOX_INTEGRATOR_ESDF_OCC_INTEGRATOR_H_
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #include
10 | #include
11 |
12 | #include "voxblox/core/layer.h"
13 | #include "voxblox/core/voxel.h"
14 | #include "voxblox/integrator/integrator_utils.h"
15 | #include "voxblox/utils/bucket_queue.h"
16 | #include "voxblox/utils/timing.h"
17 |
18 | namespace voxblox {
19 |
20 | /**
21 | * Builds an ESDF layer out of a given occupancy layer.
22 | */
23 | class EsdfOccIntegrator {
24 | public:
25 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW
26 |
27 | struct Config {
28 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW
29 |
30 | /**
31 | * Maximum distance to calculate the actual distance to.
32 | * Any values above this will be set to default_distance_m.
33 | */
34 | FloatingPoint max_distance_m = 2.0;
35 | /// Default distance set for unknown values and values > max_distance_m.
36 | FloatingPoint default_distance_m = 2.0;
37 | /// Number of buckets for the bucketed priority queue.
38 | int num_buckets = 20;
39 | };
40 |
41 | EsdfOccIntegrator(const Config& config, Layer* occ_layer,
42 | Layer* esdf_layer);
43 |
44 | /**
45 | * Fixed is overloaded as occupied in this case.
46 | * Only batch operations are currently supported for the occupancy map.
47 | */
48 | void updateFromOccLayerBatch();
49 | void updateFromOccBlocks(const BlockIndexList& occ_blocks);
50 |
51 | void processOpenSet();
52 |
53 | /**
54 | * Uses 26-connectivity and quasi-Euclidean distances.
55 | * Directions is the direction that the neighbor voxel lives in. If you
56 | * need the direction FROM the neighbor voxel TO the current voxel, take
57 | * negative of the given direction.
58 | */
59 | void getNeighborsAndDistances(
60 | const BlockIndex& block_index, const VoxelIndex& voxel_index,
61 | AlignedVector* neighbors, AlignedVector* distances,
62 | AlignedVector* directions) const;
63 | void getNeighbor(const BlockIndex& block_index, const VoxelIndex& voxel_index,
64 | const Eigen::Vector3i& direction,
65 | BlockIndex* neighbor_block_index,
66 | VoxelIndex* neighbor_voxel_index) const;
67 |
68 | protected:
69 | Config config_;
70 |
71 | Layer* occ_layer_;
72 | Layer* esdf_layer_;
73 |
74 | /**
75 | * Open Queue for incremental updates. Contains global voxel indices
76 | * for the ESDF layer.
77 | */
78 | BucketQueue open_;
79 |
80 | /** Raise set for updates; these are values that used to be in the fixed
81 | * frontier and now have a higher value, or their children which need to have
82 | * their values invalidated.
83 | */
84 | AlignedQueue raise_;
85 |
86 | size_t esdf_voxels_per_side_;
87 | FloatingPoint esdf_voxel_size_;
88 | };
89 |
90 | } // namespace voxblox
91 |
92 | #endif // VOXBLOX_INTEGRATOR_ESDF_OCC_INTEGRATOR_H_
93 |
--------------------------------------------------------------------------------
/voxblox/include/voxblox/integrator/intensity_integrator.h:
--------------------------------------------------------------------------------
1 | #ifndef VOXBLOX_INTEGRATOR_INTENSITY_INTEGRATOR_H_
2 | #define VOXBLOX_INTEGRATOR_INTENSITY_INTEGRATOR_H_
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #include
10 | #include
11 |
12 | #include "voxblox/core/layer.h"
13 | #include "voxblox/core/voxel.h"
14 | #include "voxblox/integrator/integrator_utils.h"
15 | #include "voxblox/utils/timing.h"
16 |
17 | namespace voxblox {
18 |
19 | /**
20 | * Integrates intensities from a set of bearing vectors (i.e., an intensity
21 | * image, such as a thermal image) by projecting them onto the TSDF surface
22 | * and coloring near the surface crossing.
23 | */
24 | class IntensityIntegrator {
25 | public:
26 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW
27 |
28 | IntensityIntegrator(const Layer& tsdf_layer,
29 | Layer* intensity_layer);
30 |
31 | /// Set the max distance for projecting into the TSDF layer.
32 | void setMaxDistance(const FloatingPoint max_distance) {
33 | max_distance_ = max_distance;
34 | }
35 | FloatingPoint getMaxDistance() const { return max_distance_; }
36 |
37 | /**
38 | * Integrates intensities into the intensity layer by projecting normalized
39 | * bearing vectors (in the WORLD coordinate frame) from the origin (also in
40 | * the world coordinate frame) into the TSDF layer, and then setting the
41 | * intensities near the surface boundaries.
42 | */
43 | void addIntensityBearingVectors(const Point& origin,
44 | const Pointcloud& bearing_vectors,
45 | const std::vector& intensities);
46 |
47 | private:
48 | FloatingPoint max_distance_;
49 | float max_weight_;
50 | /// Number of voxels to propagate from the surface along the bearing vector.
51 | int intensity_prop_voxel_radius_;
52 |
53 | const Layer& tsdf_layer_;
54 | Layer* intensity_layer_;
55 | };
56 |
57 | } // namespace voxblox
58 |
59 | #endif // VOXBLOX_INTEGRATOR_INTENSITY_INTEGRATOR_H_
60 |
--------------------------------------------------------------------------------
/voxblox/include/voxblox/interpolator/interpolator.h:
--------------------------------------------------------------------------------
1 | #ifndef VOXBLOX_INTERPOLATOR_INTERPOLATOR_H_
2 | #define VOXBLOX_INTERPOLATOR_INTERPOLATOR_H_
3 |
4 | #include
5 |
6 | #include "voxblox/core/common.h"
7 | #include "voxblox/core/layer.h"
8 | #include "voxblox/core/voxel.h"
9 |
10 | namespace voxblox {
11 |
12 | /**
13 | * Interpolates voxels to give distances and gradients
14 | */
15 | template
16 | class Interpolator {
17 | public:
18 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW
19 |
20 | typedef std::shared_ptr Ptr;
21 |
22 | explicit Interpolator(const Layer* layer);
23 |
24 | bool getGradient(const Point& pos, Point* grad,
25 | const bool interpolate = false) const;
26 |
27 | bool getDistance(const Point& pos, FloatingPoint* distance,
28 | bool interpolate = false) const;
29 |
30 | bool getWeight(const Point& pos, FloatingPoint* weight,
31 | bool interpolate = false) const;
32 |
33 | bool getVoxel(const Point& pos, VoxelType* voxel,
34 | bool interpolate = false) const;
35 |
36 | /**
37 | * This tries to use whatever information is available to interpolate the
38 | * distance and gradient -- if only one side is available, for instance,
39 | * this will still estimate a 1-sided gradient. Should give the same results
40 | * as getGradient() and getDistance() if all neighbors are filled.
41 | */
42 | bool getAdaptiveDistanceAndGradient(const Point& pos, FloatingPoint* distance,
43 | Point* grad) const;
44 |
45 | /// Without interpolation.
46 | bool getNearestDistanceAndWeight(const Point& pos, FloatingPoint* distance,
47 | float* weight) const;
48 |
49 | bool setIndexes(const Point& pos, BlockIndex* block_index,
50 | InterpIndexes* voxel_indexes) const;
51 |
52 | bool getVoxelsAndQVector(const Point& pos, const VoxelType** voxels,
53 | InterpVector* q_vector) const;
54 |
55 | private:
56 | /**
57 | * Q vector from http://spie.org/samples/PM159.pdf
58 | * Relates the interpolation distance of any arbitrary point inside a voxel
59 | * to the values of the voxel corners.
60 | */
61 | void getQVector(const Point& voxel_pos, const Point& pos,
62 | const FloatingPoint voxel_size_inv,
63 | InterpVector* q_vector) const;
64 |
65 | bool getVoxelsAndQVector(const BlockIndex& block_index,
66 | const InterpIndexes& voxel_indexes, const Point& pos,
67 | const VoxelType** voxels,
68 | InterpVector* q_vector) const;
69 |
70 | bool getInterpDistance(const Point& pos, FloatingPoint* distance) const;
71 |
72 | bool getNearestDistance(const Point& pos, FloatingPoint* distance) const;
73 |
74 | bool getInterpWeight(const Point& pos, FloatingPoint* weight) const;
75 |
76 | bool getNearestWeight(const Point& pos, FloatingPoint* weight) const;
77 |
78 | bool getInterpVoxel(const Point& pos, VoxelType* voxel) const;
79 |
80 | bool getNearestVoxel(const Point& pos, VoxelType* voxel) const;
81 |
82 | static float getVoxelSdf(const VoxelType& voxel);
83 | static float getVoxelWeight(const VoxelType& voxel);
84 |
85 | static uint8_t getRed(const VoxelType& voxel);
86 | static uint8_t getBlue(const VoxelType& voxel);
87 | static uint8_t getGreen(const VoxelType& voxel);
88 | static uint8_t getAlpha(const VoxelType& voxel);
89 |
90 | template
91 | static FloatingPoint interpMember(const InterpVector& q_vector,
92 | const VoxelType** voxels,
93 | TGetter (*getter)(const VoxelType&));
94 |
95 | static VoxelType interpVoxel(const InterpVector& q_vector,
96 | const VoxelType** voxels);
97 |
98 | const Layer* layer_;
99 | };
100 |
101 | } // namespace voxblox
102 |
103 | #endif // VOXBLOX_INTERPOLATOR_INTERPOLATOR_H_
104 |
105 | #include "voxblox/interpolator/interpolator_inl.h"
106 |
--------------------------------------------------------------------------------
/voxblox/include/voxblox/io/layer_io.h:
--------------------------------------------------------------------------------
1 | #ifndef VOXBLOX_IO_LAYER_IO_H_
2 | #define VOXBLOX_IO_LAYER_IO_H_
3 |
4 | #include
5 |
6 | #include
7 |
8 | #include "voxblox/core/common.h"
9 | #include "voxblox/core/layer.h"
10 |
11 | namespace voxblox {
12 | namespace io {
13 |
14 | /**
15 | * By default, loads blocks without multiple layer support.
16 | * Loading blocks assumes that the layer is already setup and allocated.
17 | */
18 | template
19 | bool LoadBlocksFromFile(
20 | const std::string& file_path,
21 | typename Layer::BlockMergingStrategy strategy,
22 | Layer* layer_ptr);
23 |
24 | /**
25 | * By default, loads blocks without multiple layer support.
26 | * Loading the full layer allocates a layer of the correct size.
27 | */
28 | template
29 | bool LoadBlocksFromFile(
30 | const std::string& file_path,
31 | typename Layer::BlockMergingStrategy strategy,
32 | bool multiple_layer_support, Layer* layer_ptr);
33 |
34 | template
35 | bool LoadBlocksFromStream(
36 | const size_t num_blocks,
37 | typename Layer::BlockMergingStrategy strategy,
38 | std::istream* proto_file_ptr, Layer* layer_ptr,
39 | uint64_t* tmp_byte_offset_ptr);
40 |
41 | /**
42 | * Unlike LoadBlocks above, this actually allocates the layer as well.
43 | * By default loads without multiple layer support (i.e., only checks the first
44 | * layer in the file).
45 | */
46 | template
47 | bool LoadLayer(const std::string& file_path,
48 | typename Layer::Ptr* layer_ptr);
49 |
50 | /**
51 | * Unlike LoadBlocks, this actually allocates the layer as well.
52 | * By default loads without multiple layer support (i.e., only checks the first
53 | * layer in the file).
54 | */
55 | template
56 | bool LoadLayer(const std::string& file_path, const bool multiple_layer_support,
57 | typename Layer::Ptr* layer_ptr);
58 |
59 | /**
60 | * By default, clears (truncates) the output file. Set clear_file to false in
61 | * case writing the second (or subsequent) layer into the same file.
62 | */
63 | template
64 | bool SaveLayer(const Layer& layer, const std::string& file_path,
65 | bool clear_file = true);
66 |
67 | /// Saves only some parts of the layer to the file. Clears the file by default.
68 | template
69 | bool SaveLayerSubset(const Layer& layer,
70 | const std::string& file_path,
71 | const BlockIndexList& blocks_to_include,
72 | bool include_all_blocks);
73 |
74 | } // namespace io
75 | } // namespace voxblox
76 |
77 | #include "voxblox/io/layer_io_inl.h"
78 |
79 | #endif // VOXBLOX_IO_LAYER_IO_H_
80 |
--------------------------------------------------------------------------------
/voxblox/include/voxblox/io/mesh_ply.h:
--------------------------------------------------------------------------------
1 | // NOTE: From open_chisel: github.com/personalrobotics/OpenChisel/
2 | // The MIT License (MIT)
3 | // Copyright (c) 2014 Matthew Klingensmith and Ivan Dryanovski
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | // SOFTWARE.
22 |
23 | #ifndef VOXBLOX_IO_MESH_PLY_H_
24 | #define VOXBLOX_IO_MESH_PLY_H_
25 |
26 | #include
27 | #include
28 | #include
29 |
30 | #include "voxblox/mesh/mesh_layer.h"
31 |
32 | namespace voxblox {
33 |
34 | /**
35 | * Generates a mesh from the mesh layer.
36 | * @param connected_mesh if true veracities will be shared between triangles
37 | * @param vertex_proximity_threshold verticies that are within the specified
38 | * thershold distance will be merged together, simplifying the mesh.
39 | */
40 | bool convertMeshLayerToMesh(
41 | const MeshLayer& mesh_layer, Mesh* mesh, const bool connected_mesh = true,
42 | const FloatingPoint vertex_proximity_threshold = 1e-10);
43 |
44 | /// Default behaviour is to simplify the mesh.
45 | bool outputMeshLayerAsPly(const std::string& filename,
46 | const MeshLayer& mesh_layer);
47 |
48 | /**
49 | * @param connected_mesh if true vertices will be shared between triangles
50 | */
51 | bool outputMeshLayerAsPly(const std::string& filename,
52 | const bool connected_mesh,
53 | const MeshLayer& mesh_layer);
54 |
55 | bool outputMeshAsPly(const std::string& filename, const Mesh& mesh);
56 |
57 | } // namespace voxblox
58 |
59 | #endif // VOXBLOX_IO_MESH_PLY_H_
60 |
--------------------------------------------------------------------------------
/voxblox/include/voxblox/io/ply_writer.h:
--------------------------------------------------------------------------------
1 | #ifndef VOXBLOX_IO_PLY_WRITER_H_
2 | #define VOXBLOX_IO_PLY_WRITER_H_
3 |
4 | #include // NOLINT
5 | #include
6 |
7 | #include
8 |
9 | #include "voxblox/core/common.h"
10 |
11 | namespace voxblox {
12 |
13 | namespace io {
14 | /**
15 | * Writes a mesh to a .ply file. For reference on the format, see:
16 | * http://paulbourke.net/dataformats/ply/
17 | */
18 | class PlyWriter {
19 | public:
20 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW
21 |
22 | explicit PlyWriter(const std::string& filename)
23 | : header_written_(false),
24 | parameters_set_(false),
25 | vertices_total_(0),
26 | vertices_written_(0),
27 | has_color_(false),
28 | file_(filename) {}
29 |
30 | virtual ~PlyWriter() {}
31 |
32 | void addVerticesWithProperties(size_t num_vertices, bool has_color) {
33 | vertices_total_ = num_vertices;
34 | has_color_ = has_color;
35 | parameters_set_ = true;
36 | }
37 |
38 | bool writeHeader() {
39 | if (!file_) {
40 | // Output a warning -- couldn't open file?
41 | LOG(WARNING) << "Could not open file for PLY output.";
42 | return false;
43 | }
44 | if (!parameters_set_) {
45 | LOG(WARNING) << "Could not write header out -- parameters not set.";
46 | return false;
47 | }
48 | if (header_written_) {
49 | LOG(WARNING) << "Header already written.";
50 | return false;
51 | }
52 |
53 | file_ << "ply" << std::endl;
54 | file_ << "format ascii 1.0" << std::endl;
55 | file_ << "element vertex " << vertices_total_ << std::endl;
56 | file_ << "property float x" << std::endl;
57 | file_ << "property float y" << std::endl;
58 | file_ << "property float z" << std::endl;
59 |
60 | if (has_color_) {
61 | file_ << "property uchar red" << std::endl;
62 | file_ << "property uchar green" << std::endl;
63 | file_ << "property uchar blue" << std::endl;
64 | }
65 |
66 | file_ << "end_header" << std::endl;
67 |
68 | header_written_ = true;
69 | return true;
70 | }
71 |
72 | bool writeVertex(const Point& coord) {
73 | if (!header_written_) {
74 | if (!writeHeader()) {
75 | return false;
76 | }
77 | }
78 | if (vertices_written_ >= vertices_total_ || has_color_) {
79 | return false;
80 | }
81 | file_ << coord.x() << " " << coord.y() << " " << coord.z() << std::endl;
82 | return true;
83 | }
84 |
85 | bool writeVertex(const Point& coord, const Color& rgb) {
86 | if (!header_written_) {
87 | if (!writeHeader()) {
88 | return false;
89 | }
90 | }
91 | if (vertices_written_ >= vertices_total_ || !has_color_) {
92 | return false;
93 | }
94 | file_ << coord.x() << " " << coord.y() << " " << coord.z() << " ";
95 | file_ << static_cast(rgb.r) << " " << static_cast(rgb.g) << " "
96 | << static_cast(rgb.b) << std::endl;
97 | return true;
98 | }
99 |
100 | void closeFile() { file_.close(); }
101 |
102 | private:
103 | bool header_written_;
104 | bool parameters_set_;
105 |
106 | size_t vertices_total_;
107 | size_t vertices_written_;
108 | bool has_color_;
109 |
110 | std::ofstream file_;
111 | };
112 |
113 | } // namespace io
114 |
115 | } // namespace voxblox
116 |
117 | #endif // VOXBLOX_IO_PLY_WRITER_H_
118 |
--------------------------------------------------------------------------------
/voxblox/include/voxblox/mesh/README.md:
--------------------------------------------------------------------------------
1 | # NOTICE
2 |
3 | This code is mostly adapted from OpenChisel:
4 | https://github.com/personalrobotics/OpenChisel
5 | We've retained the license headers whenever relevant.
6 |
--------------------------------------------------------------------------------
/voxblox/include/voxblox/simulation/simulation_world.h:
--------------------------------------------------------------------------------
1 | #ifndef VOXBLOX_SIMULATION_SIMULATION_WORLD_H_
2 | #define VOXBLOX_SIMULATION_SIMULATION_WORLD_H_
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 |
9 | #include "voxblox/core/common.h"
10 | #include "voxblox/core/layer.h"
11 | #include "voxblox/core/voxel.h"
12 | #include "voxblox/simulation/objects.h"
13 |
14 | namespace voxblox {
15 |
16 | class SimulationWorld {
17 | public:
18 | EIGEN_MAKE_ALIGNED_OPERATOR_NEW
19 |
20 | SimulationWorld();
21 | virtual ~SimulationWorld() {}
22 |
23 | /// === Creating an environment ===
24 | void addObject(std::unique_ptr