diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000000..f6cb8ad931f --- /dev/null +++ b/.clang-format @@ -0,0 +1 @@ +BasedOnStyle: Google diff --git a/.github/workflows/cmake_ci.yaml b/.github/workflows/cmake_ci.yaml new file mode 100644 index 00000000000..7d3e51d3d3d --- /dev/null +++ b/.github/workflows/cmake_ci.yaml @@ -0,0 +1,73 @@ +name: Build + +on: + pull_request: + push: + branches: + - master + workflow_dispatch: + +jobs: + build-project: + name: Build Project + runs-on: ubuntu-24.04 + steps: + - name: Checkout Project + uses: actions/checkout@v4.2.2 + with: + submodules: true + + # Load the set of APT dependencies from the install_apt_dependencies scripts + # to reduce repetition + - name: Generate dependency list + id: generate_deps + run: | + # Run your script and capture its output into a shell variable + SCRIPT_OUTPUT=$(./install_apt_dependencies.sh --deps) + + # Write the variable to the GITHUB_OUTPUT file + echo "apt_deps=$SCRIPT_OUTPUT" >> "$GITHUB_OUTPUT" + + - name: Install apt dependencies + uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: ${{ steps.generate_deps.outputs.apt_deps }} + version: 1.0 + + # I think this necessary to ensure alternatives are set up (for libblas, etc) + # It's not properly set up when restoring packages from cache + - name: Force install libblas and liblapack + run: sudo apt-get install --reinstall libblas-dev liblapack-dev + shell: bash + + # Based on sample workflow from https://github.com/lukka/CppCMakeVcpkgTemplate/blob/v11/.github/workflows/hosted-ninja-vcpkg_submod.yml + - uses: lukka/get-cmake@latest + + # + - name: Cache vcpkg + uses: actions/cache@v4 + with: + path: ${{ github.workspace }}/vcpkg_cache + key: vcpkg-${{ matrix.triplet }}-${{ hashFiles('vcpkg.json', 'vcpkg_overlay/**', 'CMakeLists.txt', '**/CMakeLists.txt', 'CMakePresets.json') }} + + - name: Restore from cache and setup vcpkg executable and data files. + uses: lukka/run-vcpkg@v11 + with: + doNotCache: false + vcpkgGitCommitId: e3db8f65d2414c301c29a8467c6aee94e3ba09fc + + # Note: if the preset misses the "configuration", it is possible to explicitly select the + # configuration with the additional `--config` flag, e.g.: + # buildPreset: 'ninja-vcpkg' + # buildPresetAdditionalArgs: "[`--config`, `Release`]" + # testPreset: 'ninja-vcpkg' + # testPresetAdditionalArgs: "[`--config`, `Release`]" + - name: Run CMake+vcpkg+Ninja+CTest to build packages and generate/build/test the code. + uses: lukka/run-cmake@v10 + env: + VCPKG_BINARY_SOURCES: clear;files,${{ github.workspace }}/vcpkg_cache,readwrite + VCPKG_DEFAULT_TRIPLET: ${{ matrix.triplet }} + with: + configurePreset: 'ninja-multi-vcpkg' + buildPreset: 'ninja-vcpkg-release' + testPreset: 'test-release' diff --git a/.gitignore b/.gitignore index 7227515c0a3..907b1aa6044 100644 --- a/.gitignore +++ b/.gitignore @@ -66,6 +66,7 @@ Thirdparty/g2o/config.h Thirdparty/g2o/lib/ Vocabulary/ORBvoc.txt build/ +builds/ lib/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000000..a0a57f3d70f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "vcpkg"] + path = vcpkg + url = https://github.com/microsoft/vcpkg.git diff --git a/CMakeLists.txt b/CMakeLists.txt index a03a584b5f2..73fe275306f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,14 +25,16 @@ find_package(OpenCV 4.4) MESSAGE("OPENCV VERSION:") MESSAGE(${OpenCV_VERSION}) -find_package(Eigen3 3.1.0 REQUIRED) -find_package(Pangolin REQUIRED) -find_package(Sophus REQUIRED) +find_package(Eigen3 REQUIRED) +find_package(Pangolin CONFIG REQUIRED) +find_package(Sophus CONFIG REQUIRED) find_package(g2o REQUIRED) find_package(fmt REQUIRED) find_package(spdlog REQUIRED) find_package(Boost REQUIRED COMPONENTS serialization) +add_subdirectory(Thirdparty/DBoW2) + include_directories( ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/include @@ -73,13 +75,14 @@ add_library(${PROJECT_NAME} SHARED src/TwoViewReconstruction.cc src/Viewer.cc ) +target_compile_definitions(${PROJECT_NAME} PUBLIC REGISTER_TIMES) target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS} Eigen3::Eigen Sophus::Sophus ${Pangolin_LIBRARIES} - ${PROJECT_SOURCE_DIR}/Thirdparty/DBoW2/lib/libDBoW2.so + DBoW2 fmt::fmt g2o::core g2o::types_sim3 diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 00000000000..db9b6595a43 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,59 @@ +{ + "version": 8, + "cmakeMinimumRequired": { + "major": 3, + "minor": 21, + "patch": 0 + }, + "configurePresets": [ + { + "name": "ninja-multi-vcpkg", + "displayName": "Ninja Multi-Config", + "description": "Configure with vcpkg toolchain and generate Ninja project files for all configurations", + "binaryDir": "${sourceDir}/builds/${presetName}", + "generator": "Ninja Multi-Config", + "toolchainFile": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake" + } + ], + "buildPresets": [ + { + "name": "ninja-vcpkg-debug", + "configurePreset": "ninja-multi-vcpkg", + "displayName": "Build (Debug)", + "description": "Build with Ninja/vcpkg (Debug)", + "configuration": "Debug" + }, + { + "name": "ninja-vcpkg-release", + "configurePreset": "ninja-multi-vcpkg", + "displayName": "Build (Release)", + "description": "Build with Ninja/vcpkg (Release)", + "configuration": "Release" + } + ], + "testPresets": [ + { + "name": "test-ninja-vcpkg", + "configurePreset": "ninja-multi-vcpkg", + "hidden": true + }, + { + "name": "test-debug", + "description": "Test (Debug)", + "displayName": "Test (Debug)", + "configuration": "Debug", + "inherits": [ + "test-ninja-vcpkg" + ] + }, + { + "name": "test-release", + "description": "Test (Release)", + "displayName": "Test (Release)", + "configuration": "Release", + "inherits": [ + "test-ninja-vcpkg" + ] + } + ] +} diff --git a/README.md b/README.md index 6534edb898d..934f6932f88 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,39 @@ > [!NOTE] -> This is my personal "working" fork of ORBSLAM3, which focuses on integrating ORBSLAM3 into ROS2. The actual ROS2 integration is implemented in [orbslam3_ros2](https://gitlab.com/apl-ocean-engineering/orbslam3_ros2). +> This is my personal "working" fork of ORBSLAM3, which is part of a larger effort to integrate ORBSLAM3 into ROS2. This repo remains (distantly) related to the author's original upstream repo, and contains no ROS2-specific code. The actual ROS2 integration is implemented in [orbslam3_ros2](https://gitlab.com/apl-ocean-engineering/orbslam3_ros2) which includes this repo as a submodule. -Relative to the original code, this repo contains multiple updates: +As I dug further into the code, I got more opinionated and have made multiple stylistic changes. My intention is to make only positive readability, portability and performance improvements but YMMV: -* I removed the "ThirdParty" copies of "Sophus" and "g2o" in lieu of packages which can be installed "rosdep" (or `apt`). Due to API changes, this necessitated some syntactically invasive (but functionally equivalent) changes. -* This branch contains preliminary migration to [spdlog](https://github.com/gabime/spdlog) as a more controllable logging backend. This is a slow-motion migration to better manage text output from ORBSLAM3. -* As I dug further into the code, I got more opinionated. I also added [pre-commit](.pre-commit-config.yaml), which introduced significant textual changes. No going back! -* [`Thirdparty/tl/`](Thirdparty/tl/) includes a copy of [TartanLlama's expected](https://github.com/TartanLlama/expected) which is released under the [CC0-1.0 (Public doamin) license](http://creativecommons.org/publicdomain/zero/1.0/) +* Started modernization, currently to C++17 +* Replace bare pointers with managed pointers in most cases. +* Minor updates to the System and Setting initialization procedure, primarily to separate creation of the Settings (from a file or otherwise) from the initialization of System, and provide more paths to catching and reporting errors during initialization. See the [Examples/](Examples/). +* Added [pre-commit](.pre-commit-config.yaml), which introduced significant textual changes. +* Cleanup on dependencies: + * Removed built-in `g2o` and `Sophus` sources, get these from a dependency manager (vcpkg for non-ROS, and rosdep for ROS) + * Add [TartanLlama's expected](https://github.com/TartanLlama/expected) which is released under the [CC0-1.0 (Public doamin) license](http://creativecommons.org/publicdomain/zero/1.0/) (this may be remove if/when I standardize on C++20) +* I am only targetting Ubuntu 24.04 right now. I've updated the build process as follows: + * When building for ROS2, use [orbslam3_ros2](https://gitlab.com/apl-ocean-engineering/orbslam3_ros2) which includes this repo as a submodule. Dependencies (g2o, Sophus, Pangolin) are included from ROS apt via rosdep. + * For non-ROS builds, I am now using `vcpkg` as a dependency manager as it can build the non-apt-gettable dependencies (Pangolin). **However** I am using overlays to preferentially use apt versions of packages whenever feasible (ffmpeg, etc). + * In some cases (`g2o` and its dependencies) we use vcpkg's version to ensure dependencies stay in sycn. +* Other minor changes: + * Removed integrated Realsense support. Realsense-enabled binaries should go in a separate package. -> [!WARNING] -> I _am not_ testing this repo outside of ROS2. I am *only* checking [orbslam3_ros2](https://gitlab.com/apl-ocean-engineering/orbslam3_ros2) in a ROS2 / colcon environment. I do not expect this to build with `cmake` nor do I expect the original `Examples/` to run. + +## Building + +I am only testing on Ubuntu 24.04. + +As noted above, I prefer to use system packages as much as possible and use `vcpkg` for dependencies with no published binaries (outside of ROS). To override this behavior and have vcpkg build additional packages from source, remove the relevant directories from the [`vcpkg_overlays/`](vcpkg_overlays/) directory. + +I've gone full koolaid and adopted `ninja` as a builder as well. + +To build in Ubuntu, use the convenience scripts: + +``` +./install_apt_dependencies.sh +./build.sh +``` + +This will build Release versions the ORB_SLAM3 library and all of the `Examples`. ----- ----- diff --git a/build.sh b/build.sh index 87f9c4bf653..aa18f2fe39b 100755 --- a/build.sh +++ b/build.sh @@ -1,40 +1,9 @@ -echo "Configuring and building Thirdparty/DBoW2 ..." +# Options are "release" and "debug" (see CMakePresets.json) +BUILD_TYPE=${BUILD_TYPE:-release} -cd Thirdparty/DBoW2 -mkdir build -cd build -cmake .. -DCMAKE_BUILD_TYPE=Release -make -j2 - -cd ../../g2o - -echo "Configuring and building Thirdparty/g2o ..." - -mkdir build -cd build -cmake .. -DCMAKE_BUILD_TYPE=Release -make -j2 - -cd ../../Sophus - -echo "Configuring and building Thirdparty/Sophus ..." - -mkdir build -cd build -cmake .. -DCMAKE_BUILD_TYPE=Release -make -j2 - -cd ../../../ - -echo "Uncompress vocabulary ..." - -cd Vocabulary -tar -xf ORBvoc.txt.tar.gz +git submodule sync vcpkg +cd vcpkg && ./bootstrap-vcpkg.sh cd .. -echo "Configuring and building ORB_SLAM3 ..." - -mkdir build -cd build -cmake .. -DCMAKE_BUILD_TYPE=Release -make -j2 +cmake --preset ninja-multi-vcpkg +cmake --build --preset ninja-vcpkg-${BUILD_TYPE} diff --git a/build_ros.sh b/build_ros.sh deleted file mode 100755 index 1f13d2155fc..00000000000 --- a/build_ros.sh +++ /dev/null @@ -1,7 +0,0 @@ -echo "Building ROS nodes" - -cd Examples/ROS/ORB_SLAM3 -mkdir build -cd build -cmake .. -DROS_BUILD_TYPE=Release -make -j diff --git a/install_apt_dependencies.sh b/install_apt_dependencies.sh new file mode 100755 index 00000000000..c5d94ddc453 --- /dev/null +++ b/install_apt_dependencies.sh @@ -0,0 +1,41 @@ +#!/usr/bin/bash + +APT_DEPENDENCIES="cmake \ + g++ \ + libavcodec-dev \ + libavdevice-dev \ + libavfilter-dev \ + libavformat-dev \ + libavutil-dev \ + libblas-dev \ + libboost-serialization-dev \ + libc++-dev \ + libegl1-mesa-dev \ + libeigen3-dev \ + libepoxy-dev \ + libfmt-dev \ + libgl1-mesa-dev \ + libgles2-mesa-dev \ + libglew-dev \ + liblapack-dev \ + libopencv-dev \ + libspdlog-dev \ + libswresample-dev \ + libswscale-dev \ + libwayland-dev \ + libx11-dev \ + libxkbcommon-dev \ + nasm \ + ninja-build \ + wayland-protocols" + + +myarg=$1 +if [[ "$myarg" = "--deps" ]]; then + echo $APT_DEPENDENCIES + exit 0 +fi + + +sudo apt-get update && \ +sudo apt-get install --no-install-recommends -y $APT_DEPENDENCIES diff --git a/src/Settings.cc b/src/Settings.cc index 736aa162f97..e88b5cc0e8f 100644 --- a/src/Settings.cc +++ b/src/Settings.cc @@ -117,7 +117,7 @@ void Settings::setMonoCamera(CameraType type, const std::vector& k, // vOverlapping; // } } else { - spdlog::error("Error: {} not known", type); + spdlog::error("Error: {} not known", static_cast(type)); exit(-1); } } diff --git a/vcpkg b/vcpkg new file mode 160000 index 00000000000..2cf2bcc60ad --- /dev/null +++ b/vcpkg @@ -0,0 +1 @@ +Subproject commit 2cf2bcc60add50f79b2c418487d9cd1b6c7c1fec diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 00000000000..bced0c493ce --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,21 @@ +{ + "name": "main", + "version-string": "latest", + "configuration": { + "default-registry": + { + "kind": "git", + "baseline": "e3db8f65d2414c301c29a8467c6aee94e3ba09fc", + "repository": "https://github.com/Microsoft/vcpkg" + }, + "overlay-ports": [ + "vcpkg_overlay" + ] + }, + "dependencies": [ + "pangolin", + "sophus", + "g2o", + "eigen3" + ] +} diff --git a/vcpkg_overlay/ffmpeg/portfile.cmake b/vcpkg_overlay/ffmpeg/portfile.cmake new file mode 100644 index 00000000000..065116c276a --- /dev/null +++ b/vcpkg_overlay/ffmpeg/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/vcpkg_overlay/ffmpeg/vcpkg.json b/vcpkg_overlay/ffmpeg/vcpkg.json new file mode 100644 index 00000000000..91b34b7c2c5 --- /dev/null +++ b/vcpkg_overlay/ffmpeg/vcpkg.json @@ -0,0 +1,24 @@ +{ + "name": "ffmpeg", + "version": "6.1.1", + "features": { + "avcodec": { + "description": "" + }, + "avdevice": { + "description": "" + }, + "avfilter": { + "description": "" + }, + "avformat": { + "description": "" + }, + "swresample": { + "description": "" + }, + "swscale": { + "description": "" + } + } +}