Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .github/workflows/python-bindings-linux.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Build Python Bindings on Linux

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

env:
BUILD_TYPE: Release

jobs:
build:
runs-on: ubuntu-22.04
strategy:
matrix:
python-version: ["3.12"]

steps:
- name: Load repository cache
run: sudo apt-get update --allow-releaseinfo-change

- name: Install system libraries
run: sudo apt-get install -y --no-install-recommends libx11-dev libxi-dev libtbb-dev libegl1-mesa-dev libglu1-mesa-dev libopencv-dev

- uses: actions/checkout@v4
with:
submodules: recursive

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Display Python version
run: python --version

- name: Install CMake 4.0
run: |
wget -O cmake.sh https://github.com/Kitware/CMake/releases/download/v4.0.0/cmake-4.0.0-linux-x86_64.sh
sudo sh cmake.sh --skip-license --prefix=/usr/local
cmake --version

- name: Configure CMake with Python bindings
run: |
cmake -B ${{github.workspace}}/build_pybind \
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
-DPYBIND=ON

- name: Build Python bindings
run: cmake --build ${{github.workspace}}/build_pybind --target pybind_all --config ${{env.BUILD_TYPE}}

- name: Test Python imports
working-directory: ${{github.workspace}}/build_pybind/bin/${{env.BUILD_TYPE}}
run: |
python -c "import sys; sys.path.insert(0, '.'); import core_py; print('core_py imported successfully')"
python -c "import sys; sys.path.insert(0, '.'); import lidar_odometry_py; print('lidar_odometry_py imported successfully')"
python -c "import sys; sys.path.insert(0, '.'); import multi_view_tls_registration_py; print('multi_view_tls_registration_py imported successfully')"


56 changes: 56 additions & 0 deletions .github/workflows/python-bindings-windows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Build Python Bindings on Windows

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

env:
BUILD_TYPE: Release

jobs:
build:
runs-on: windows-latest
strategy:
matrix:
python-version: ["3.12"]

steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Display Python version
run: python --version

- name: Install CMake 4.0 on Windows
run: |
choco install cmake --version=4.0.0 -y
refreshenv
cmake --version
shell: pwsh

- name: Configure CMake with Python bindings
run: |
cmake -B ${{github.workspace}}/build_pybind `
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} `
-DPYBIND=ON `
shell: pwsh

- name: Build Python bindings
run: cmake --build ${{github.workspace}}/build_pybind --target pybind_all --config ${{env.BUILD_TYPE}}

- name: Test Python imports
working-directory: ${{github.workspace}}/build_pybind/bin/${{env.BUILD_TYPE}}
run: |
python -c "import sys; sys.path.insert(0, '.'); import core_py; print('core_py imported successfully')"
python -c "import sys; sys.path.insert(0, '.'); import lidar_odometry_py; print('lidar_odometry_py imported successfully')"
python -c "import sys; sys.path.insert(0, '.'); import multi_view_tls_registration_py; print('multi_view_tls_registration_py imported successfully')"
shell: pwsh

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,4 @@ imgui.ini
/out/install/x64-Release/bin
/out/install/x64-Release
/out_old/install

4 changes: 4 additions & 0 deletions apps/lidar_odometry_step_1/lidar_odometry_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
#include <python-scripts/constraints/constraint_fixed_parameter_jacobian.h>
#include <common/include/cauchy.h>
#include <python-scripts/point-to-feature-metrics/point_to_line_tait_bryan_wc_jacobian.h>
#if WITH_GUI == 1
#include <imgui.h>
#endif

namespace fs = std::filesystem;

Expand Down Expand Up @@ -134,7 +136,9 @@ struct LidarOdometryParams
double total_length_of_calculated_trajectory = 0.0;
NDTBucketMapType buckets_indoor;
NDTBucketMapType buckets_outdoor;
#if WITH_GUI == 1
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
#endif

bool use_removie_imu_bias_from_first_stationary_scan = false;

Expand Down
7 changes: 7 additions & 0 deletions apps/lidar_odometry_step_1/toml_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,17 @@ bool TomlIO::SaveParametersToTomlFile(const std::string &filepath, LidarOdometry
if (attribute == "in_out_params_indoor" || attribute == "in_out_params_outdoor")
continue;

#if WITH_GUI == 1
if (attribute == "clear_color")
{
const ImVec4& c = params.clear_color;
cat_tbl.insert(attribute, toml::array{ c.x, c.y, c.z, c.w });
continue;
}
#else
if (attribute == "clear_color")
continue; // Skip GUI-only parameter when building without GUI
#endif

// Check if it's a motion_model_correction parameter
auto motion_it = MOTION_MODEL_CORRECTION_POINTERS.find(attribute);
Expand Down Expand Up @@ -188,6 +193,7 @@ bool TomlIO::LoadParametersFromTomlFile(const std::string &filepath, LidarOdomet
} }, it->second);
}

#if WITH_GUI == 1
if (cat_tbl && cat_tbl->contains("clear_color"))
{
auto arr = cat_tbl->at("clear_color").as_array();
Expand All @@ -199,6 +205,7 @@ bool TomlIO::LoadParametersFromTomlFile(const std::string &filepath, LidarOdomet
params.clear_color.w = static_cast<float>(arr->at(3).as_floating_point()->get());
}
}
#endif
}
read_grid_params(params.in_out_params_indoor, tbl["in_out_params_indoor"].as_table());
read_grid_params(params.in_out_params_outdoor, tbl["in_out_params_outdoor"].as_table());
Expand Down
61 changes: 44 additions & 17 deletions pybind/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ if (MSVC)
target_compile_options(multi_view_tls_registration_py PRIVATE /bigobj)
endif()

add_custom_target(pybind_all
DEPENDS core_py lidar_odometry_py multi_view_tls_registration_py
COMMENT "Building all Python bindings"
)

target_sources(core_py
PRIVATE
${CMAKE_SOURCE_DIR}/core/src/session.cpp
Expand Down Expand Up @@ -134,33 +139,55 @@ if(WIN32)
set_target_properties(lidar_odometry_py PROPERTIES SUFFIX ".pyd")
set_target_properties(multi_view_tls_registration_py PROPERTIES SUFFIX ".pyd")
else()
set_target_properties(core_py PROPERTIES SUFFIX ".so")
set_target_properties(lidar_odometry_py PROPERTIES SUFFIX ".so")
set_target_properties(multi_view_tls_registration_py PROPERTIES SUFFIX ".so")
set_target_properties(core_py PROPERTIES
PREFIX ""
SUFFIX ".so")
set_target_properties(lidar_odometry_py PROPERTIES
PREFIX ""
SUFFIX ".so")
set_target_properties(multi_view_tls_registration_py PROPERTIES
PREFIX ""
SUFFIX ".so")
endif()

set_target_properties(core_py PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/pybind"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/pybind"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/$<CONFIG>"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/$<CONFIG>"
)

set_target_properties(lidar_odometry_py PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/pybind"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/pybind"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/$<CONFIG>"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/$<CONFIG>"
)

set_target_properties(multi_view_tls_registration_py PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/pybind"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/pybind"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/$<CONFIG>"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/$<CONFIG>"
)

set(DLL_SOURCE_DIR "${CMAKE_BINARY_DIR}/bin/Release")
set(DLL_DEST_DIR "${CMAKE_SOURCE_DIR}/pybind/Release")

file(GLOB DLL_FILES "${CMAKE_BINARY_DIR}/bin/Release/*.dll")
foreach(DLL ${DLL_FILES})
if(WIN32)
add_custom_command(
TARGET core_py
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_RUNTIME_DLLS:core_py>
"${CMAKE_BINARY_DIR}/bin/$<CONFIG>"
COMMAND_EXPAND_LISTS
)

add_custom_command(
TARGET lidar_odometry_py
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_RUNTIME_DLLS:lidar_odometry_py>
"${CMAKE_BINARY_DIR}/bin/$<CONFIG>"
COMMAND_EXPAND_LISTS
)

add_custom_command(
TARGET lidar_odometry_py POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DLL} "${CMAKE_SOURCE_DIR}/pybind/Release"
TARGET multi_view_tls_registration_py
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_RUNTIME_DLLS:multi_view_tls_registration_py>
"${CMAKE_BINARY_DIR}/bin/$<CONFIG>"
COMMAND_EXPAND_LISTS
)
endforeach()
endif()

6 changes: 4 additions & 2 deletions pybind/core_binding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@ PYBIND11_MODULE(core_py, m) {
// Bind WorkerData
py::class_<WorkerData>(m, "WorkerData")
.def(py::init<>())
.def_readwrite("intermediate_points", &WorkerData::intermediate_points)
.def_readwrite("original_points", &WorkerData::original_points)
.def_readwrite("intermediate_points_cache_file_name", &WorkerData::intermediate_points_cache_file_name)
.def_readwrite("original_points_cache_file_name", &WorkerData::original_points_cache_file_name)
.def_readwrite("original_points_to_save_cache_file_name", &WorkerData::original_points_to_save_cache_file_name)
.def_readwrite("intermediate_trajectory", &WorkerData::intermediate_trajectory)
.def_readwrite("intermediate_trajectory_motion_model", &WorkerData::intermediate_trajectory_motion_model)
.def_readwrite("intermediate_trajectory_timestamps", &WorkerData::intermediate_trajectory_timestamps)
.def_readwrite("imu_om_fi_ka", &WorkerData::imu_om_fi_ka)
.def_readwrite("show", &WorkerData::show)
;

// Bind Session
Expand Down
6 changes: 3 additions & 3 deletions pybind/tls_registration_binding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,15 @@ PYBIND11_MODULE(multi_view_tls_registration_py, m) {

py::class_<ICP>(m, "ICP")
.def(py::init<>())
.def_readwrite("search_radious", &ICP::search_radious)
.def_readwrite("search_radius", &ICP::search_radius)
.def_readwrite("number_of_threads", &ICP::number_of_threads)
.def_readwrite("number_of_iterations", &ICP::number_of_iterations)
.def_readwrite("is_adaptive_robust_kernel", &ICP::is_adaptive_robust_kernel)
.def_readwrite("is_gauss_newton", &ICP::is_gauss_newton);

py::class_<RegistrationPlaneFeature>(m, "RegistrationPlaneFeature")
.def(py::init<>())
.def_readwrite("search_radious", &RegistrationPlaneFeature::search_radious)
.def_readwrite("search_radius", &RegistrationPlaneFeature::search_radius)
.def_readwrite("number_of_threads", &RegistrationPlaneFeature::number_of_threads)
.def_readwrite("number_of_iterations", &RegistrationPlaneFeature::number_of_iterations)
.def_readwrite("is_adaptive_robust_kernel", &RegistrationPlaneFeature::is_adaptive_robust_kernel);
Expand All @@ -105,7 +105,7 @@ PYBIND11_MODULE(multi_view_tls_registration_py, m) {
.def(py::init<>())
.def_readwrite("overlap_threshold", &PoseGraphSLAM::overlap_threshold)
.def_readwrite("iterations", &PoseGraphSLAM::iterations)
.def_readwrite("search_radious", &PoseGraphSLAM::search_radious);
.def_readwrite("search_radius", &PoseGraphSLAM::search_radius);

py::class_<GNSS::GlobalPose>(m, "GlobalPose")
.def(py::init<>())
Expand Down