pyorbslam3 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyorbslam3-0.1.1/.dockerignore +8 -0
- pyorbslam3-0.1.1/.github/workflows/wheels.yml +48 -0
- pyorbslam3-0.1.1/.gitignore +12 -0
- pyorbslam3-0.1.1/BENCHMARKS.md +139 -0
- pyorbslam3-0.1.1/CMakeLists.txt +192 -0
- pyorbslam3-0.1.1/Dockerfile +79 -0
- pyorbslam3-0.1.1/PKG-INFO +327 -0
- pyorbslam3-0.1.1/README.md +312 -0
- pyorbslam3-0.1.1/build.sh +9 -0
- pyorbslam3-0.1.1/cmake/deps/CMakeLists.txt +106 -0
- pyorbslam3-0.1.1/configs/euroc/mono.yaml +78 -0
- pyorbslam3-0.1.1/configs/euroc/mono_inertial.yaml +84 -0
- pyorbslam3-0.1.1/configs/euroc/stereo.yaml +96 -0
- pyorbslam3-0.1.1/configs/euroc/stereo_inertial.yaml +114 -0
- pyorbslam3-0.1.1/configs/kitti/mono_2011_09_26.yaml +64 -0
- pyorbslam3-0.1.1/configs/kitti/stereo_2011_09_26.yaml +63 -0
- pyorbslam3-0.1.1/configs/tum_rgbd/mono_fr1.yaml +65 -0
- pyorbslam3-0.1.1/configs/tum_rgbd/mono_fr3.yaml +64 -0
- pyorbslam3-0.1.1/configs/tum_rgbd/rgbd_fr1.yaml +71 -0
- pyorbslam3-0.1.1/configs/tum_rgbd/rgbd_fr3.yaml +70 -0
- pyorbslam3-0.1.1/configs/tumvi/mono.yaml +64 -0
- pyorbslam3-0.1.1/configs/tumvi/mono_inertial.yaml +83 -0
- pyorbslam3-0.1.1/configs/tumvi/stereo.yaml +96 -0
- pyorbslam3-0.1.1/configs/tumvi/stereo_inertial.yaml +113 -0
- pyorbslam3-0.1.1/docker/patches/0001-cmake-static-pic-modern-targets.patch +789 -0
- pyorbslam3-0.1.1/docker/patches/0002-localmapping-keyframeculling-guards.patch +39 -0
- pyorbslam3-0.1.1/docker/patches/README.md +14 -0
- pyorbslam3-0.1.1/docs/benchmarks_header.md +47 -0
- pyorbslam3-0.1.1/docs/benchmarks_notes.md +40 -0
- pyorbslam3-0.1.1/examples/benchmark.py +388 -0
- pyorbslam3-0.1.1/examples/make_report.py +94 -0
- pyorbslam3-0.1.1/examples/run_tumvi.py +188 -0
- pyorbslam3-0.1.1/pyorbslam3/__init__.py +24 -0
- pyorbslam3-0.1.1/pyorbslam3/slam.py +216 -0
- pyorbslam3-0.1.1/pyorbslam3/vocab.py +70 -0
- pyorbslam3-0.1.1/pyproject.toml +56 -0
- pyorbslam3-0.1.1/src/orbslam3_pybind.cpp +432 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
name: wheels
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
sdist:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- uses: actions/setup-python@v5
|
|
14
|
+
with: { python-version: "3.12" }
|
|
15
|
+
- run: pip install build && python -m build --sdist
|
|
16
|
+
- uses: actions/upload-artifact@v4
|
|
17
|
+
with: { name: sdist, path: dist/*.tar.gz }
|
|
18
|
+
|
|
19
|
+
wheels:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
timeout-minutes: 300
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
- uses: pypa/cibuildwheel@v2.22.0
|
|
25
|
+
- uses: actions/upload-artifact@v4
|
|
26
|
+
with: { name: wheels, path: wheelhouse/*.whl }
|
|
27
|
+
|
|
28
|
+
github-release:
|
|
29
|
+
needs: [sdist, wheels]
|
|
30
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
permissions: { contents: write }
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/download-artifact@v4
|
|
35
|
+
with: { path: dist, merge-multiple: true }
|
|
36
|
+
- uses: softprops/action-gh-release@v2
|
|
37
|
+
with: { files: dist/* }
|
|
38
|
+
|
|
39
|
+
pypi:
|
|
40
|
+
needs: [sdist, wheels]
|
|
41
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
environment: pypi
|
|
44
|
+
permissions: { id-token: write } # PyPI trusted publishing (no token stored)
|
|
45
|
+
steps:
|
|
46
|
+
- uses: actions/download-artifact@v4
|
|
47
|
+
with: { path: dist, merge-multiple: true }
|
|
48
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# pyorbslam3 benchmarks
|
|
2
|
+
|
|
3
|
+
Results of running the bindings on public datasets with `examples/benchmark.py`.
|
|
4
|
+
Every row is one full sequence run; the raw records are in
|
|
5
|
+
`results/benchmarks.jsonl` and the trajectories in `results/`. Regenerate this
|
|
6
|
+
file with `python3 examples/make_report.py -o BENCHMARKS.md --header docs/benchmarks_header.md --footer docs/benchmarks_notes.md`.
|
|
7
|
+
|
|
8
|
+
## Setup
|
|
9
|
+
|
|
10
|
+
* Machine: Intel Core i5-1035G1 (4 cores / 8 threads, 1.0 GHz base), 15 GB RAM,
|
|
11
|
+
Ubuntu 22.04, Python 3.10, OpenCV 4.5.4. No GPU is used by ORB-SLAM3.
|
|
12
|
+
* Bindings linked against ORB-SLAM3 upstream commit `4452a3c4` with the two
|
|
13
|
+
patches in `docker/patches/`. Viewer off.
|
|
14
|
+
* Settings files: the stock ORB-SLAM3 examples for each dataset
|
|
15
|
+
(`configs/<dataset>/`), with two corrections: the TUM-VI stereo file's
|
|
16
|
+
`Camera.overlapping*` keys renamed to `Camera1.*` (the upstream spelling is
|
|
17
|
+
ignored by the parser), and the KITTI stereo file rewritten as two identical
|
|
18
|
+
`PinHole` cameras instead of `Camera.type: "Rectified"`, which crashes in the
|
|
19
|
+
settings printer upstream.
|
|
20
|
+
* Frames are fed sequentially as fast as tracking allows (no real-time pacing),
|
|
21
|
+
so `fps` is the throughput on this CPU, not a dataset rate. `track ms` is the
|
|
22
|
+
median wall time of one track call.
|
|
23
|
+
|
|
24
|
+
## Metrics
|
|
25
|
+
|
|
26
|
+
* **Tracked OK** — frames for which ORB-SLAM3 reported `TrackingState.OK`. In
|
|
27
|
+
inertial modes the frames before IMU initialization count as not OK, which is
|
|
28
|
+
why mono-inertial rates sit below the non-inertial ones.
|
|
29
|
+
* **IMU init** — seconds of sequence time until `imu_initialized()` turned true.
|
|
30
|
+
* **ATE sim(3)** — RMSE of position error after a similarity (Umeyama) alignment
|
|
31
|
+
of the estimated trajectory to ground truth, over the poses that associate to
|
|
32
|
+
a ground-truth sample within 20 ms. **scale** is the similarity scale found by
|
|
33
|
+
that alignment: 1.0 means the estimate is already metric. For monocular runs
|
|
34
|
+
the scale is arbitrary by construction; for stereo, RGB-D and inertial runs it
|
|
35
|
+
should be close to 1.0.
|
|
36
|
+
* **ATE SE(3)** — the same error with scale fixed at 1 (rigid alignment only).
|
|
37
|
+
This is the number that matters for a metric system; it is meaningless for
|
|
38
|
+
plain monocular runs.
|
|
39
|
+
|
|
40
|
+
Ground truth: TUM-VI mocap (`mocap0`), EuRoC `state_groundtruth_estimate0`,
|
|
41
|
+
TUM RGB-D `groundtruth.txt`, KITTI raw OXTS GPS/INS converted to a local metric
|
|
42
|
+
frame (the odometry-benchmark drives with published poses are not in the raw
|
|
43
|
+
download set, so GPS/INS is used; its accuracy is at the decimetre level, which
|
|
44
|
+
sets a floor on the KITTI numbers).
|
|
45
|
+
|
|
46
|
+
ORB-SLAM3 is multi-threaded and not deterministic; repeated runs of the same
|
|
47
|
+
sequence vary by a few percent in tracked frames and ATE.
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
### TUM-VI
|
|
51
|
+
|
|
52
|
+
| Sequence | Mode | Frames | Tracked OK | IMU init | ATE sim(3) | scale | ATE SE(3) | fps | track ms |
|
|
53
|
+
|---|---|---:|---:|---:|---:|---:|---:|---:|---:|
|
|
54
|
+
| room1 (run 1) | mono | 2821 | 2724 (96.6%) | n/a | 7.29 cm | 1.785 | n/a | 7.1 | 67.0 |
|
|
55
|
+
| room1 (run 2) | mono | 2821 | 2724 (96.6%) | n/a | 97.42 cm | 8.485 | n/a | 17.7 | 45.8 |
|
|
56
|
+
| room1 (run 1) | mono-imu | 2821 | 2700 (95.7%) | 8.4 s | 1.22 cm | 1.000 | 1.22 cm | 3.3 | 56.7 |
|
|
57
|
+
| room1 (run 2) | mono-imu | 2821 | 2700 (95.7%) | 8.4 s | 1.28 cm | 0.998 | 1.30 cm | 19.0 | 43.3 |
|
|
58
|
+
| room1 (run 1) | stereo | 2821 | 2821 (100.0%) | n/a | 7.15 cm | 0.974 | 7.62 cm | 4.9 | 102.9 |
|
|
59
|
+
| room1 (run 2) | stereo | 2821 | 2821 (100.0%) | n/a | 7.16 cm | 0.975 | 7.60 cm | 9.8 | 84.1 |
|
|
60
|
+
| room1 | stereo-imu | 2821 | 2746 (97.3%) | 2.5 s | 0.76 cm | 1.005 | 0.90 cm | 6.7 | 86.0 |
|
|
61
|
+
|
|
62
|
+
### EuRoC MAV
|
|
63
|
+
|
|
64
|
+
| Sequence | Mode | Frames | Tracked OK | IMU init | ATE sim(3) | scale | ATE SE(3) | fps | track ms |
|
|
65
|
+
|---|---|---:|---:|---:|---:|---:|---:|---:|---:|
|
|
66
|
+
| V1_01_easy | mono | 2912 | 2802 (96.2%) | n/a | 8.87 cm | 2.058 | n/a | 25.8 | 30.2 |
|
|
67
|
+
| V1_01_easy | mono-imu | 2911 | 2798 (96.1%) | 7.9 s | 3.25 cm | 1.011 | 3.83 cm | 24.3 | 32.3 |
|
|
68
|
+
| V1_01_easy | stereo | 2912 | 2912 (100.0%) | n/a | 8.82 cm | 1.005 | 8.86 cm | 16.6 | 53.5 |
|
|
69
|
+
| V1_01_easy | stereo-imu | 2911 | 2864 (98.4%) | 2.5 s | 3.45 cm | 1.009 | 3.83 cm | 12.7 | 68.1 |
|
|
70
|
+
| V1_02_medium | mono | 1710 | 1531 (89.5%) | n/a | 9.40 cm | 0.216 | n/a | 29.1 | 24.8 |
|
|
71
|
+
| V1_02_medium | mono-imu | 1709 | 1594 (93.3%) | 11.0 s | 1.94 cm | 1.004 | 2.06 cm | 27.8 | 26.5 |
|
|
72
|
+
| V1_02_medium | stereo | 1710 | 1710 (100.0%) | n/a | 8.10 cm | 1.008 | 8.22 cm | 17.5 | 51.2 |
|
|
73
|
+
| V1_02_medium | stereo-imu | 1709 | 1687 (98.7%) | 2.4 s | 1.41 cm | 1.007 | 1.90 cm | 15.1 | 60.9 |
|
|
74
|
+
| V1_03_difficult | mono | 2149 | 1737 (80.8%) | n/a | 13.34 cm | 3.806 | n/a | 31.5 | 22.7 |
|
|
75
|
+
| V1_03_difficult | mono-imu | 2149 | 1790 (83.3%) | 9.8 s | 2.17 cm | 1.015 | 2.83 cm | 29.9 | 24.1 |
|
|
76
|
+
| V1_03_difficult | stereo | 2149 | 2149 (100.0%) | n/a | 15.12 cm | 1.018 | 15.38 cm | 18.7 | 48.4 |
|
|
77
|
+
| V1_03_difficult | stereo-imu | 2149 | 2071 (96.4%) | 2.4 s | 1.99 cm | 1.013 | 2.79 cm | 16.7 | 56.2 |
|
|
78
|
+
|
|
79
|
+
### KITTI raw
|
|
80
|
+
|
|
81
|
+
| Sequence | Mode | Frames | Tracked OK | IMU init | ATE sim(3) | scale | ATE SE(3) | fps | track ms |
|
|
82
|
+
|---|---|---:|---:|---:|---:|---:|---:|---:|---:|
|
|
83
|
+
| 2011_09_26_drive_0036 (run 1) | mono | 803 | 802 (99.9%) | n/a | 801.9 cm | 12.176 | n/a | 18.4 | 41.0 |
|
|
84
|
+
| 2011_09_26_drive_0036 (run 2) | mono | 803 | 802 (99.9%) | n/a | 895.0 cm | 12.781 | n/a | 19.8 | 38.1 |
|
|
85
|
+
| 2011_09_26_drive_0036 | stereo | 803 | 803 (100.0%) | n/a | 85.59 cm | 1.007 | 151.4 cm | 6.0 | 88.9 |
|
|
86
|
+
| 2011_09_26_drive_0101 | mono | 936 | 845 (90.3%) | n/a | 2602.1 cm | 117.2 | n/a | 6.4 | 39.7 |
|
|
87
|
+
| 2011_09_26_drive_0101 | stereo | 936 | 936 (100.0%) | n/a | 107.7 cm | 1.000 | 107.8 cm | 4.5 | 117.4 |
|
|
88
|
+
|
|
89
|
+
### TUM RGB-D
|
|
90
|
+
|
|
91
|
+
| Sequence | Mode | Frames | Tracked OK | IMU init | ATE sim(3) | scale | ATE SE(3) | fps | track ms |
|
|
92
|
+
|---|---|---:|---:|---:|---:|---:|---:|---:|---:|
|
|
93
|
+
| fr1_desk | mono | 596 | 492 (82.6%) | n/a | 1.50 cm | 1.043 | n/a | 17.9 | 34.8 |
|
|
94
|
+
| fr1_desk | rgbd | 596 | 596 (100.0%) | n/a | 1.60 cm | 0.996 | 1.64 cm | 6.5 | 60.4 |
|
|
95
|
+
| fr3_long_office (run 1) | mono | 2488 | 2463 (99.0%) | n/a | 105.6 cm | 2.715 | n/a | 15.7 | 41.0 |
|
|
96
|
+
| fr3_long_office (run 2) | mono | 2488 | 2463 (99.0%) | n/a | 2.60 cm | 2.435 | n/a | 18.5 | 34.5 |
|
|
97
|
+
| fr3_long_office | rgbd | 2488 | 2488 (100.0%) | n/a | 1.65 cm | 0.986 | 3.44 cm | 12.6 | 59.4 |
|
|
98
|
+
|
|
99
|
+
## Reading the results
|
|
100
|
+
|
|
101
|
+
* **Inertial modes recover metric scale.** Across all eight inertial runs
|
|
102
|
+
(TUM-VI room1, EuRoC V1_01–V1_03) the similarity-alignment scale lies within
|
|
103
|
+
1.5 % of 1.0 and the ATE is 0.8–3.5 cm. Stereo-inertial initializes the IMU in
|
|
104
|
+
about 2.5 s on every sequence; mono-inertial needs 8–11 s of motion.
|
|
105
|
+
* **Stereo tracks every frame.** 100 % of frames `OK` on all seven stereo
|
|
106
|
+
sequences, scale 0.97–1.02 without any IMU. Indoor ATE is 7–15 cm; the KITTI
|
|
107
|
+
drives give about 1 m over 800–940 frames of driving against GPS/INS ground
|
|
108
|
+
truth, whose own accuracy is at the decimetre level.
|
|
109
|
+
* **RGB-D** tracks every frame on both TUM sequences with 1.6 cm ATE and metric
|
|
110
|
+
scale.
|
|
111
|
+
* **Plain monocular is the least repeatable mode.** Scale is arbitrary by
|
|
112
|
+
construction, and whenever ORB-SLAM3 re-initializes a map mid-sequence the
|
|
113
|
+
saved trajectory contains segments with different scales, which a single
|
|
114
|
+
similarity alignment cannot undo. That is what the paired runs show: room1 mono
|
|
115
|
+
7 cm in one run and 97 cm in the next, fr3_long_office 106 cm and then 2.6 cm,
|
|
116
|
+
with identical tracking rates. On the KITTI driving sequences monocular drifts
|
|
117
|
+
in scale by one to two orders of magnitude (no loop closures on these drives),
|
|
118
|
+
which is expected and why the ORB-SLAM3 authors report KITTI with stereo only.
|
|
119
|
+
For anything that needs a usable trajectory, use stereo, RGB-D or an inertial
|
|
120
|
+
mode.
|
|
121
|
+
* **Throughput.** On this 1.0 GHz laptop CPU the bindings run EuRoC (752×480)
|
|
122
|
+
at 13–29 fps and TUM-VI (512×512 fisheye) at 10–19 fps depending on mode. The
|
|
123
|
+
"run 1" TUM-VI rows were measured while a Docker image was compiling on the
|
|
124
|
+
same machine; the "run 2" rows of the same modes show the uncontended speed.
|
|
125
|
+
The Python layer adds no measurable overhead: the median track-call time is
|
|
126
|
+
the ORB-SLAM3 tracking thread's own frame time.
|
|
127
|
+
|
|
128
|
+
Where a mode was run twice, `results/` holds the trajectory of the later run
|
|
129
|
+
(the `_run2` files for the two repeats that were run into a separate folder,
|
|
130
|
+
otherwise the file was overwritten); the JSONL keeps both sets of metrics.
|
|
131
|
+
|
|
132
|
+
## Not covered here
|
|
133
|
+
|
|
134
|
+
* Real-camera results (ZED 2i, RealSense D435i) live in the `orbulation` ROS 2
|
|
135
|
+
package's user guide. D435i stereo-inertial is configured but still needs a
|
|
136
|
+
handheld test with motion.
|
|
137
|
+
* TUM-VI corridor/magistrale/outdoor sequences, EuRoC machine hall and
|
|
138
|
+
vicon_room2, and the KITTI odometry benchmark proper were not run.
|
|
139
|
+
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.16)
|
|
2
|
+
project(pyorbslam3 LANGUAGES CXX)
|
|
3
|
+
|
|
4
|
+
if(NOT CMAKE_BUILD_TYPE)
|
|
5
|
+
set(CMAKE_BUILD_TYPE Release)
|
|
6
|
+
endif()
|
|
7
|
+
set(CMAKE_CXX_STANDARD 17)
|
|
8
|
+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
9
|
+
|
|
10
|
+
# ---------------------------------------------------------------------------
|
|
11
|
+
# Where does ORB-SLAM3 come from? Three options, tried in this order:
|
|
12
|
+
#
|
|
13
|
+
# (a) ORBSLAM3_ROOT (+ optional ORBSLAM3_BUILD_DIR, default <root>/build):
|
|
14
|
+
# a standalone ORB_SLAM3 source tree already built as static libraries,
|
|
15
|
+
# with Pangolin discoverable through find_package(Pangolin) / Pangolin_DIR.
|
|
16
|
+
# Also read from the environment, so `ORBSLAM3_ROOT=... pip install .` works.
|
|
17
|
+
# (b) ORBSLAM_DEPS: legacy — the _deps dir of a PRBonn ORB-SLAM-Python build.
|
|
18
|
+
# (c) PYORBSLAM3_FETCH_DEPS=ON (automatic when neither of the above exists):
|
|
19
|
+
# download and compile Pangolin + ORB-SLAM3 (cmake/deps). Slow (30–60 min)
|
|
20
|
+
# but needs nothing beyond the system packages listed in the README.
|
|
21
|
+
# ---------------------------------------------------------------------------
|
|
22
|
+
set(ORBSLAM3_ROOT "$ENV{ORBSLAM3_ROOT}" CACHE PATH "Standalone ORB_SLAM3 source tree")
|
|
23
|
+
set(ORBSLAM3_BUILD_DIR "" CACHE PATH "Build dir of ORBSLAM3_ROOT (default <root>/build)")
|
|
24
|
+
set(ORBSLAM_DEPS
|
|
25
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/../ORB-SLAM-Python/build/cp310-cp310-linux_x86_64/_deps"
|
|
26
|
+
CACHE PATH "Legacy: _deps dir of an ORB-SLAM-Python build")
|
|
27
|
+
option(PYORBSLAM3_FETCH_DEPS "Download and build Pangolin + ORB-SLAM3" OFF)
|
|
28
|
+
# Self-contained: also build a static minimal OpenCV and Eigen, so the module
|
|
29
|
+
# does not depend on the system OpenCV (used for the manylinux wheels).
|
|
30
|
+
if(DEFINED ENV{PYORBSLAM3_SELF_CONTAINED} AND NOT "$ENV{PYORBSLAM3_SELF_CONTAINED}" STREQUAL "" AND NOT "$ENV{PYORBSLAM3_SELF_CONTAINED}" STREQUAL "0")
|
|
31
|
+
set(_default_self_contained ON)
|
|
32
|
+
else()
|
|
33
|
+
set(_default_self_contained OFF)
|
|
34
|
+
endif()
|
|
35
|
+
option(PYORBSLAM3_SELF_CONTAINED "Bundle OpenCV + Eigen in the dependency build" ${_default_self_contained})
|
|
36
|
+
if(PYORBSLAM3_SELF_CONTAINED)
|
|
37
|
+
set(PYORBSLAM3_FETCH_DEPS ON)
|
|
38
|
+
endif()
|
|
39
|
+
# Where the dependency build lives (shared between Python versions in CI).
|
|
40
|
+
set(PYORBSLAM3_DEPS_DIR "$ENV{PYORBSLAM3_DEPS_DIR}" CACHE PATH "Directory for the dependency superbuild")
|
|
41
|
+
if(DEFINED ENV{PYORBSLAM3_JOBS} AND NOT "$ENV{PYORBSLAM3_JOBS}" STREQUAL "")
|
|
42
|
+
set(_default_jobs "$ENV{PYORBSLAM3_JOBS}")
|
|
43
|
+
else()
|
|
44
|
+
set(_default_jobs 2)
|
|
45
|
+
endif()
|
|
46
|
+
set(PYORBSLAM3_JOBS "${_default_jobs}" CACHE STRING "Parallel jobs for the dependency build")
|
|
47
|
+
if(PYORBSLAM3_JOBS STREQUAL "")
|
|
48
|
+
set(PYORBSLAM3_JOBS 2)
|
|
49
|
+
endif()
|
|
50
|
+
|
|
51
|
+
if(ORBSLAM3_ROOT STREQUAL "" AND NOT PYORBSLAM3_FETCH_DEPS
|
|
52
|
+
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../ORB_SLAM3/build/libORB_SLAM3.a")
|
|
53
|
+
set(ORBSLAM3_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../ORB_SLAM3")
|
|
54
|
+
endif()
|
|
55
|
+
if(ORBSLAM3_ROOT STREQUAL "" AND NOT PYORBSLAM3_FETCH_DEPS
|
|
56
|
+
AND NOT EXISTS "${ORBSLAM_DEPS}/orb_slam3-build/libORB_SLAM3.a")
|
|
57
|
+
set(PYORBSLAM3_FETCH_DEPS ON)
|
|
58
|
+
endif()
|
|
59
|
+
|
|
60
|
+
if(PYORBSLAM3_FETCH_DEPS)
|
|
61
|
+
if(PYORBSLAM3_DEPS_DIR STREQUAL "")
|
|
62
|
+
set(_deps "${CMAKE_BINARY_DIR}/deps")
|
|
63
|
+
else()
|
|
64
|
+
set(_deps "${PYORBSLAM3_DEPS_DIR}")
|
|
65
|
+
endif()
|
|
66
|
+
message(STATUS "pyorbslam3: building Pangolin + ORB-SLAM3 from source in ${_deps} "
|
|
67
|
+
"(jobs=${PYORBSLAM3_JOBS}, self-contained=${PYORBSLAM3_SELF_CONTAINED}; this takes a while)")
|
|
68
|
+
# Generator, make program and compilers are passed explicitly so that a
|
|
69
|
+
# dependency build cached from an earlier pip run (whose temporary build
|
|
70
|
+
# environment is gone) is refreshed instead of pointing at stale paths.
|
|
71
|
+
execute_process(
|
|
72
|
+
COMMAND ${CMAKE_COMMAND} -S "${CMAKE_CURRENT_SOURCE_DIR}/cmake/deps" -B "${_deps}"
|
|
73
|
+
-G "${CMAKE_GENERATOR}" "-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}"
|
|
74
|
+
"-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}" "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
|
|
75
|
+
-DJOBS=${PYORBSLAM3_JOBS} -DSELF_CONTAINED=${PYORBSLAM3_SELF_CONTAINED}
|
|
76
|
+
RESULT_VARIABLE _rc)
|
|
77
|
+
if(NOT _rc EQUAL 0)
|
|
78
|
+
message(FATAL_ERROR "configuring the dependency superbuild failed")
|
|
79
|
+
endif()
|
|
80
|
+
execute_process(COMMAND ${CMAKE_COMMAND} --build "${_deps}" RESULT_VARIABLE _rc)
|
|
81
|
+
if(NOT _rc EQUAL 0)
|
|
82
|
+
message(FATAL_ERROR "building Pangolin / ORB-SLAM3 failed (see output above)")
|
|
83
|
+
endif()
|
|
84
|
+
set(ORBSLAM3_ROOT "${_deps}/orbslam3-src")
|
|
85
|
+
set(ORBSLAM3_BUILD_DIR "${_deps}/orbslam3-build")
|
|
86
|
+
set(Pangolin_DIR "${_deps}/pangolin-install/lib/cmake/Pangolin" CACHE PATH "" FORCE)
|
|
87
|
+
if(PYORBSLAM3_SELF_CONTAINED)
|
|
88
|
+
# prepend so the bundled OpenCV/Eigen win over any system copies
|
|
89
|
+
list(PREPEND CMAKE_PREFIX_PATH "${_deps}/opencv-install" "${_deps}/eigen-install")
|
|
90
|
+
endif()
|
|
91
|
+
endif()
|
|
92
|
+
|
|
93
|
+
find_package(Python COMPONENTS Interpreter Development.Module REQUIRED)
|
|
94
|
+
find_package(pybind11 CONFIG REQUIRED)
|
|
95
|
+
find_package(OpenCV 4.4 REQUIRED)
|
|
96
|
+
find_package(Eigen3 REQUIRED)
|
|
97
|
+
# Boost.Serialization is linked shared on purpose: distribution static builds
|
|
98
|
+
# are usually not -fPIC (manylinux's is not), and auditwheel bundles the .so.
|
|
99
|
+
find_package(Boost REQUIRED COMPONENTS serialization)
|
|
100
|
+
find_package(OpenSSL REQUIRED)
|
|
101
|
+
|
|
102
|
+
pybind11_add_module(_core MODULE src/orbslam3_pybind.cpp)
|
|
103
|
+
|
|
104
|
+
if(PYORBSLAM3_SELF_CONTAINED)
|
|
105
|
+
set(_win_uri "x11") # manylinux builds have no Wayland
|
|
106
|
+
else()
|
|
107
|
+
set(_win_uri "wayland")
|
|
108
|
+
endif()
|
|
109
|
+
target_compile_definitions(
|
|
110
|
+
_core PRIVATE HAVE_GLEW HAVE_EIGEN _LINUX_ PANGO_DEFAULT_WIN_URI="${_win_uri}"
|
|
111
|
+
BOOST_ALL_NO_LIB BOOST_SERIALIZATION_DYN_LINK)
|
|
112
|
+
|
|
113
|
+
if(NOT ORBSLAM3_ROOT STREQUAL "")
|
|
114
|
+
# ---- (a)/(c) standalone tree ---------------------------------------------
|
|
115
|
+
if(ORBSLAM3_BUILD_DIR STREQUAL "")
|
|
116
|
+
set(ORBSLAM3_BUILD_DIR "${ORBSLAM3_ROOT}/build")
|
|
117
|
+
endif()
|
|
118
|
+
if(NOT EXISTS "${ORBSLAM3_BUILD_DIR}/libORB_SLAM3.a")
|
|
119
|
+
message(FATAL_ERROR "libORB_SLAM3.a not found in ${ORBSLAM3_BUILD_DIR}; build ORB_SLAM3 first.")
|
|
120
|
+
endif()
|
|
121
|
+
find_package(Pangolin REQUIRED)
|
|
122
|
+
message(STATUS "pyorbslam3: linking ORB_SLAM3 from ${ORBSLAM3_ROOT} (build ${ORBSLAM3_BUILD_DIR})")
|
|
123
|
+
|
|
124
|
+
target_include_directories(
|
|
125
|
+
_core SYSTEM
|
|
126
|
+
PRIVATE "${ORBSLAM3_ROOT}"
|
|
127
|
+
"${ORBSLAM3_ROOT}/include"
|
|
128
|
+
"${ORBSLAM3_ROOT}/include/CameraModels"
|
|
129
|
+
"${ORBSLAM3_ROOT}/Thirdparty/Sophus"
|
|
130
|
+
${Pangolin_INCLUDE_DIRS}
|
|
131
|
+
${OpenCV_INCLUDE_DIRS})
|
|
132
|
+
|
|
133
|
+
target_link_libraries(
|
|
134
|
+
_core
|
|
135
|
+
PRIVATE
|
|
136
|
+
-Wl,--start-group
|
|
137
|
+
"${ORBSLAM3_BUILD_DIR}/libORB_SLAM3.a"
|
|
138
|
+
"${ORBSLAM3_BUILD_DIR}/Thirdparty/DBoW2/libDBoW2.a"
|
|
139
|
+
"${ORBSLAM3_BUILD_DIR}/Thirdparty/g2o/libg2o.a"
|
|
140
|
+
${Pangolin_LIBRARIES}
|
|
141
|
+
-Wl,--end-group
|
|
142
|
+
Eigen3::Eigen
|
|
143
|
+
${OpenCV_LIBS}
|
|
144
|
+
Boost::serialization
|
|
145
|
+
OpenSSL::Crypto)
|
|
146
|
+
else()
|
|
147
|
+
# ---- (b) legacy ORB-SLAM-Python _deps tree ------------------------------
|
|
148
|
+
set(ORBSLAM_SRC "${ORBSLAM_DEPS}/orb_slam3-src")
|
|
149
|
+
set(ORBSLAM_BUILD "${ORBSLAM_DEPS}/orb_slam3-build")
|
|
150
|
+
set(PANGOLIN_SRC "${ORBSLAM_DEPS}/pangolin-src")
|
|
151
|
+
set(PANGOLIN_BUILD "${ORBSLAM_DEPS}/pangolin-build")
|
|
152
|
+
message(STATUS "pyorbslam3: linking legacy ORB-SLAM-Python deps at ${ORBSLAM_DEPS}")
|
|
153
|
+
|
|
154
|
+
file(GLOB PANGOLIN_COMPONENT_INCLUDES "${PANGOLIN_SRC}/components/*/include")
|
|
155
|
+
file(GLOB PANGOLIN_LIBS "${PANGOLIN_BUILD}/libpango_*.a")
|
|
156
|
+
|
|
157
|
+
target_include_directories(
|
|
158
|
+
_core SYSTEM
|
|
159
|
+
PRIVATE "${ORBSLAM_SRC}"
|
|
160
|
+
"${ORBSLAM_SRC}/include"
|
|
161
|
+
"${ORBSLAM_SRC}/include/CameraModels"
|
|
162
|
+
"${ORBSLAM_SRC}/Thirdparty/Sophus"
|
|
163
|
+
${PANGOLIN_COMPONENT_INCLUDES}
|
|
164
|
+
"${PANGOLIN_BUILD}/include"
|
|
165
|
+
${OpenCV_INCLUDE_DIRS})
|
|
166
|
+
|
|
167
|
+
target_link_libraries(
|
|
168
|
+
_core
|
|
169
|
+
PRIVATE
|
|
170
|
+
-Wl,--start-group
|
|
171
|
+
"${ORBSLAM_BUILD}/libORB_SLAM3.a"
|
|
172
|
+
"${ORBSLAM_BUILD}/Thirdparty/DBoW2/libDBoW2.a"
|
|
173
|
+
"${ORBSLAM_BUILD}/Thirdparty/g2o/libg2o.a"
|
|
174
|
+
${PANGOLIN_LIBS}
|
|
175
|
+
"${PANGOLIN_BUILD}/libtinyobj.a"
|
|
176
|
+
-Wl,--end-group
|
|
177
|
+
Eigen3::Eigen
|
|
178
|
+
${OpenCV_LIBS}
|
|
179
|
+
Boost::serialization
|
|
180
|
+
OpenSSL::Crypto
|
|
181
|
+
GLEW OpenGL GLX GLU EGL SM ICE X11 Xext
|
|
182
|
+
wayland-client wayland-egl wayland-cursor xkbcommon rt)
|
|
183
|
+
endif()
|
|
184
|
+
|
|
185
|
+
if(SKBUILD)
|
|
186
|
+
# pip / scikit-build-core: the module goes into the wheel's package dir.
|
|
187
|
+
install(TARGETS _core LIBRARY DESTINATION pyorbslam3)
|
|
188
|
+
else()
|
|
189
|
+
# ./build.sh: drop the built module straight into the source package.
|
|
190
|
+
set_target_properties(_core PROPERTIES
|
|
191
|
+
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/pyorbslam3")
|
|
192
|
+
endif()
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1
|
|
2
|
+
# pyorbslam3 — self-contained image: Pangolin v0.9 + ORB-SLAM3 (patched) + Python bindings.
|
|
3
|
+
#
|
|
4
|
+
# docker build -t pyorbslam3 . # ~30-60 min, needs ~6 GB RAM at JOBS=3
|
|
5
|
+
# docker run --rm -it -v /path/to/datasets:/data pyorbslam3 \
|
|
6
|
+
# python3 examples/benchmark.py --dataset tumvi --root /data/dataset-room1_512_16 --mode stereo-imu
|
|
7
|
+
#
|
|
8
|
+
# Build parallelism is capped (ARG JOBS) because a few ORB-SLAM3 translation
|
|
9
|
+
# units need ~2 GB each to compile.
|
|
10
|
+
|
|
11
|
+
ARG UBUNTU=22.04
|
|
12
|
+
|
|
13
|
+
# ---------------------------------------------------------------------------
|
|
14
|
+
FROM ubuntu:${UBUNTU} AS builder
|
|
15
|
+
ARG JOBS=3
|
|
16
|
+
ARG ORBSLAM3_COMMIT=4452a3c4ab75b1cde34e5505a36ec3f9edcdc4c4
|
|
17
|
+
ARG PANGOLIN_VERSION=0.9
|
|
18
|
+
ENV DEBIAN_FRONTEND=noninteractive
|
|
19
|
+
|
|
20
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
21
|
+
build-essential git ca-certificates pkg-config wget \
|
|
22
|
+
python3-dev python3-pip python3-numpy \
|
|
23
|
+
libopencv-dev libeigen3-dev libboost-serialization-dev libssl-dev \
|
|
24
|
+
libglew-dev libgl1-mesa-dev libegl1-mesa-dev libglu1-mesa-dev \
|
|
25
|
+
libwayland-dev libxkbcommon-dev wayland-protocols \
|
|
26
|
+
libx11-dev libxext-dev libsm-dev libice-dev \
|
|
27
|
+
&& rm -rf /var/lib/apt/lists/* \
|
|
28
|
+
&& pip3 install --no-cache-dir "cmake>=3.25,<4" "pybind11>=2.10" # ORB-SLAM3 needs CMake >= 3.25
|
|
29
|
+
|
|
30
|
+
# ---- Pangolin (static, PIC, viewer only) ----------------------------------
|
|
31
|
+
RUN wget -qO- https://github.com/stevenlovegrove/Pangolin/archive/refs/tags/v${PANGOLIN_VERSION}.tar.gz \
|
|
32
|
+
| tar xz -C /opt \
|
|
33
|
+
&& cmake -S /opt/Pangolin-${PANGOLIN_VERSION} -B /opt/Pangolin-${PANGOLIN_VERSION}/build \
|
|
34
|
+
-DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF \
|
|
35
|
+
-DCMAKE_POSITION_INDEPENDENT_CODE=ON \
|
|
36
|
+
-DBUILD_TOOLS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_TESTS=OFF \
|
|
37
|
+
-DBUILD_PANGOLIN_PYTHON=OFF -DBUILD_PANGOLIN_VIDEO=OFF \
|
|
38
|
+
&& cmake --build /opt/Pangolin-${PANGOLIN_VERSION}/build -j${JOBS} \
|
|
39
|
+
&& cmake --install /opt/Pangolin-${PANGOLIN_VERSION}/build \
|
|
40
|
+
&& rm -rf /opt/Pangolin-${PANGOLIN_VERSION}
|
|
41
|
+
|
|
42
|
+
# ---- ORB-SLAM3 (pinned commit + patches) ----------------------------------
|
|
43
|
+
COPY docker/patches /tmp/patches
|
|
44
|
+
RUN git init -q /opt/ORB_SLAM3 && cd /opt/ORB_SLAM3 \
|
|
45
|
+
&& git remote add origin https://github.com/UZ-SLAMLab/ORB_SLAM3.git \
|
|
46
|
+
&& git fetch -q --depth 1 origin ${ORBSLAM3_COMMIT} \
|
|
47
|
+
&& git checkout -q FETCH_HEAD \
|
|
48
|
+
&& git apply --whitespace=nowarn /tmp/patches/0001-*.patch /tmp/patches/0002-*.patch \
|
|
49
|
+
&& rm -rf .git Examples_old Examples/*/TUM_IMU \
|
|
50
|
+
&& tar -xzf Vocabulary/ORBvoc.txt.tar.gz -C Vocabulary
|
|
51
|
+
RUN cmake -S /opt/ORB_SLAM3 -B /opt/ORB_SLAM3/build -DCMAKE_BUILD_TYPE=Release \
|
|
52
|
+
&& cmake --build /opt/ORB_SLAM3/build -j${JOBS}
|
|
53
|
+
|
|
54
|
+
# ---- pyorbslam3 (PEP 517 build against the tree above) ---------------------
|
|
55
|
+
COPY . /src/pyorbslam3
|
|
56
|
+
RUN cd /src/pyorbslam3 \
|
|
57
|
+
&& ORBSLAM3_ROOT=/opt/ORB_SLAM3 pip3 install --no-cache-dir --no-deps --target /opt/pyinstall . \
|
|
58
|
+
&& python3 -c "import sys; sys.path.insert(0, '/opt/pyinstall'); import pyorbslam3"
|
|
59
|
+
|
|
60
|
+
# ---------------------------------------------------------------------------
|
|
61
|
+
FROM ubuntu:${UBUNTU}
|
|
62
|
+
ENV DEBIAN_FRONTEND=noninteractive
|
|
63
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
64
|
+
python3 python3-numpy python3-opencv \
|
|
65
|
+
libboost-serialization1.74.0 libssl3 libglew2.2 libgl1 libglx0 libopengl0 libegl1 libglu1-mesa \
|
|
66
|
+
libwayland-client0 libwayland-egl1 libwayland-cursor0 libxkbcommon0 \
|
|
67
|
+
libx11-6 libxext6 libsm6 libice6 \
|
|
68
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
69
|
+
|
|
70
|
+
COPY --from=builder /opt/pyinstall/ /usr/local/lib/python3.10/dist-packages/
|
|
71
|
+
COPY --from=builder /opt/ORB_SLAM3/Vocabulary/ORBvoc.txt /opt/pyorbslam3/vocabulary/ORBvoc.txt
|
|
72
|
+
COPY configs /opt/pyorbslam3/configs
|
|
73
|
+
COPY examples /opt/pyorbslam3/examples
|
|
74
|
+
COPY README.md /opt/pyorbslam3/README.md
|
|
75
|
+
|
|
76
|
+
WORKDIR /opt/pyorbslam3
|
|
77
|
+
ENV PYORBSLAM3_VOCAB=/opt/pyorbslam3/vocabulary/ORBvoc.txt
|
|
78
|
+
RUN python3 -c "import pyorbslam3; print('pyorbslam3 OK:', [s.name for s in pyorbslam3.Sensor.__members__.values()])"
|
|
79
|
+
CMD ["python3", "-c", "import pyorbslam3; print('pyorbslam3 ready; see examples/benchmark.py --help')"]
|