Odometry Library¶
A templated C++-only library without any ROS2 dependencies. It contains all core functionalities of the localization and may be used for low-level developments. It also defines the built executables that may later be used in the ROS wrappers. Read the documentation to understand the software architecture.
Design¶
- the folder base defines a base class and base types which all other modules are built on:
- the base class holds a config and debug object (custom structs) which specify the values necessary for configuration of the module and the values that are to be logged for debugging
- the base types holds the definition of the structs for each class (config and debug) and further specify custom, templated variables for interfaces between the modules (diagnostic status, point type)
- the base types also hold the config with the template arguments for the construction of the single modules/pipelines/nodes
- the folder modules implements the singles modules necessary for the whole odometry node
- each module consists of a base module that specifies the config and debug variables of it and the interfaces of the modules with other modules (inherited of odometry_base)
- implementations of specific modules (e.g. ICP) inherit from its base class (e.g. RegistationHandler) and implement overrides for the virtual interface functions of the module base class
- each module is a header-only library
- for each specific implementation, there is an exemplary executable in the folder
example/module.cppthat can be used to see how to use it - for each specific implementation, there are unit tests to test correct functionality, leveraging GoogleTest
- if you add a new implementation for a module, make sure to also add unit tests and and example
- the folder pipeline combines all modules to a full odometry pipeline as a shared library and holds the single modules as member variables. It also holds an example and several unit tests
Develop¶
- the library is a native C++ library without any ROS2 deps.
- currently, it depends on the following libraries:
- Eigen3 (
sudo apt install libeigen3-dev) - Sophus
- robinmap (MapHandler)
- tbb (CPU Multithreading)
- robinmap, tbb and Sophus are automatically fetched via CMake with a specific tag
- generate the build files using the following commands:
- then build the library:
- execute the example executables to debug (exemplary):
- run the unit tests before creating merge requests:
- add the flag
--verboseto see additional information if a test fails
CUDA¶
- building the library with CUDA support involves the following additional dependencies:
- CUDA (installation of nvcc compiler and cuda toolkit)
- cuCollections (automatically fetched via Cmake with a specific tag)
- the library support CUDA implementations for the following modules right now:
PolynomUndistortion(DistortionHandler)LidarPreprocessing(PreprocessingHandler)VoxelHashMap(MapHandler)ICP,GICP(RegistrationHandler)voxel_downsampling(VoxelTools)- to build the library with CUDA-capability, check the architecture of your target device in the NVCC GPU Feature List.
- set the architecture of your GPU as a build-argument:
cmake -S path/to/odometry_cpp -B path/to/build_folder -DBUILD_TESTING=ON -DBUILD_CUDA=ON -DCUDA_ARCHITECTURES=<num>
Testing with Example Data¶
Example¶
See this example on how to use the test data for registration testing. To register a single point cloud to the map, call:
If using the test data, select one frame and the odometry file with the closest timestamp (from the timestamp). This will give you output on the iterations and the registration time. However, feel free to customize it.
Extensibility¶
Adding an Executable¶
To add an executable to the library, that can be used in the Examples or within the ROS2 node, follow these steps:
- add a new config struct to the odometry_config.hpp
- add your config-struct to the list of template-instantiations
(bottom of the file, also adjust the respective
.cpp-file) - for usage in the ROS2 node, also adjust the
.cpp-file andCMakeLists.txtof tam_odometry
Adding a Module¶
To add a new implementation for one of the modules, follow these steps:
- in the respective module, open its corresponding
<module>_handler_base.hpp-file - identify the module's
config- anddebug-signals - following existing implementations, create a new
.hpp-file with your implementation that inherits from the base-handler and overrides its virtual interface functions - add a unit test under
test/covering at least construction from both constructors (param manager & logger, and config & debug) and register it in the module'sCMakeLists.txtby adding its name to theTESTSlist - add an example under
example/and register it in theEXAMPLESlist of the sameCMakeLists.txt(both lists are iterated over, so no further CMake changes are required)
Visualization¶
For visualization, the cmake-argument VISUALIZATION is provided that installs
rerun. It is fetched from github via cmake, but will take some time
to build so it is highly recommended to use some additional cores when building the library with
visualization:
cmake -S path/to/odometry_cpp -B path/to/build_folder -DBUILD_TESTING=ON -DCMAKE_BUILD_TYPE=Release -DVISUALIZATION=ON
cmake --build path/to/build_folder -j <num_threads>
Rerun is based on a streamer-viewer concept: In your cpp-code, you can then stream data via TCP, when using Rerun. The streamed data can then be visualized in the viewer, which needs to installed via
If you prefer a different installation method, refer to the documentation.
To use rerun within your code, the compiler definition USE_VISUALIZATION is provided (if DVISUALIZATION=ON).
It provides the option to compile code in your example file, depending on the VISUALIZATION and may be used
with the following makro:
For an example on the basic visualization of a point cloud, refer to the voxel_hash_map_example