Compare commits

...
Author SHA1 Message Date
matlabbe 9eca73a951 Merge branch 'master' into track_datatabase_changes_feature 2026-07-12 14:11:38 -07:00
matlabbe d96c30710e CI: remove conflicting ros2-testing-apt-source before setup-ros (roll… (#1737)
* CI: remove conflicting ros2-testing-apt-source before setup-ros (rolling)

* fixing rolling testing packages

* skip gtsam rolling

* cleanup
2026-07-11 13:08:22 -07:00
matlabbe b99e8fa263 fixing ios version bump once for all 2026-07-10 21:15:15 -07:00
matlabbe 9f9ce646d4 fixing ci errors 2026-07-10 21:10:39 -07:00
matlabbe b532319885 used dbu extension for update files 2026-07-10 20:54:51 -07:00
matlabbe e61a45e44f fixing mac ci 2026-07-10 20:39:42 -07:00
matlabbe 4056c152f0 added --rewind, use sqlite3 changeset instead of patchset 2026-07-10 20:28:55 -07:00
matlabbe 9cd2318e37 cleanup 2026-07-10 20:09:08 -07:00
matlabbe 8f63846b66 added option to reduceGraph and detectMoreLoopClosures tools 2026-07-10 20:06:54 -07:00
matlabbe 15109dfa9e Reprocess: added -track_changes option. Added rtabmap-dpupdate. 2026-07-10 19:39:22 -07:00
Pierre ELISandmatlabbe e321999b15 Faster graph zoom by using a snapshot-preview (#1728)
* Faster graph zoom by using a snapshot-preview

* Added "Fast Zooming..." menu option

---------

Co-authored-by: matlabbe <[email protected]>
2026-07-05 13:06:08 -07:00
matlabbe d069becc72 Windows CI: make vcpkg download compatible with draft release (#1727)
* Windows CI: make vcpkg download compatible with draft release

* forcing nvdia driver dll to be ignored in fixup_bundle

* disabling opencv cudec and python

* disabling rtabmap-console --version on cuda build

* Added assert when bad imu data is provided. Added checks when zed sdk is returning nan imu data.

* Updated zed sdk5 resolution and quality

* Updated zed sdk5 resolution and quality

* Fixing parameters reloaded when testing camera. Also fixed app freezing when closing Preferences dialog after using test camera dialog

* cleanup and debug logs

* Added dialogs when starting/stopping sensors/detection. Fixed nullptr bug on MainWindow::handleEvents

* renamed

* found a way to expose ZED model downloads

* Updated default config path on Windows

* Fixed extra endline in file logging (windows)

* Fixed camera local transform when used with lidar and odomSensor

* CI(macos): build g2o from source with OpenMP (libomp include/link fix)

* Mac: added ceres dep, fixed omp not found by cmake

* Mac: bundle orbbec extensions

* stripping rpath of orbbec's extensions

* cleanup

* Realsense2 error as error (not warning)

* Fixed config ownership changed to root when sarting in sudo. LidarVLP16: fixed crash on Mac by reimplementing our own socket threading

* LidarVLP16: own socket implementation only for Mac (linux and windows use original PCL's reader)
2026-07-04 18:16:37 -07:00
matlabbe cb34c4bd37 MacOS and Windows binaries update (0.23.8) (#1726)
* Windows CI: more sensor drivers + Windows/macOS bundle scripts

* added opengv to mac build

* windows bundle fixes

* zed extra neural ddl in separate package

* OpenGV macos eigen version error

* opengv macos build issues
2026-07-01 18:11:28 -07:00
matlabbe 9d30b174e6 Fixed rtabmap-report build without Qt 2026-06-26 09:29:10 -07:00
matlabbe c55c05a97e CameraImages: support reading multicamera image and calibration files (#1721)
* CameraImages: support reading multicamera image and calibration files

* Added multi camera support for CameraStereoImages. Refactored single calib per frame option.

* refactored

* refactor

* bump 0.23.8
2026-06-23 19:13:18 -07:00
matlabbe bc724a2125 iOS CI (#1722)
* iOS CI

* g2o hard-coded path

* bump ios version

* Fixed opencv 4.10.0 build on docker resolute
2026-06-21 12:44:03 -07:00
matlabbe 1a3beebcbb CI Ubuntu 26.04 / ROS2 Lyrical and Rolling (#1716)
* CI Ubuntu 26.04 / ROS2 Lyrical and Rolling

* Added resolute docker

* added skip keys

* rolling

* Disabling rolling

* Updated ci config

* Enabling docker build (no push) on PR

* cancel pr jobs on recommit

* Added resolute to docker ci matrix

* OpenGV min cmake version

* bump package.xml version

* enabling rolling

* refactored cmake ros ci jobs
2026-06-20 18:06:55 -07:00
matlabbe a9dcc52d4c Reprocess: adding --stop_loop option (#1720) 2026-06-16 16:21:38 -07:00
matlabbe 9f464db7c9 OpenVINS config file support (#1719) 2026-06-13 16:20:37 -07:00
matlabbe 1dddb350b9 TORO: adding support to load 2d graph (#1718)
* TORO: adding support to load 2d graph

* making marker detection with multicam less verbose

* wrong edge index size

* skip landmarks
2026-06-09 12:05:30 -07:00
matlabbe 468f6e6f28 Fixing empty descriptors on bad signatures (#1714), (bug from #1698) (#1717)
* Fixing empty descriptors on bad signatures (#1714), (bug from #1698)

* PyDetector: dont assert (just error) if descriptors/keypoints don't match. SuperPoint approaches: try re-initializing superpoint detection on the provided image if descriptors could not be fetched the first time (auto recover).
2026-06-07 13:19:31 -07:00
matlabbe f29676deb0 PyDetector: adding check if returned descriptors are empty (#1715)
* PyDetector: adding check if returned descriptors are empty (addressing #1714)

* Throwing error instead of asserting if keypoints and descriptors mistmatch

* ading error instead of warning

* lets do warnings instead (could be possible that images are blanck)
2026-06-01 21:04:08 -07:00
matlabbe 6f34498651 rtabmap-info: fixing empty parameter strings showing of as NA (#1712)
* rtabmap-info: fixing empty parameter strings showing of as NA

* show all strings with quotes
2026-05-29 13:09:21 -07:00
matlabbe bb95cc081a Fixed backward compatibility with bionic (Qt::ItemFlags) (#1710)
* Fixed backward compatibility with bionic (Qt::ItemFlags)

* dont remove occupancy grid with not publish last signature data
2026-05-27 17:42:21 -07:00
matlabbe 4756474367 Adding support for AprilTag v3 library (#1702)
* Adding support for AprilTag v3 library

* New parameter: Marker/Strategy (default opencv-aruco as before). Optimized multicameras marker detection (do only once with stitched image)

* Exposed all AprilTag parameters. Sharing Marker/Dictionary between opencv and apriltag implementation. Added new Marker/Lengths parameter.

* Support AprilTAg library not built with aruco

* cleanup

* Added marker range support

* Make apriltag detection in same orientation than opencv

* fixed shenanigans when rendering markers with multi cameras

* Don't update odom cache (localization mode) when not moving (detecting loop/landmark or not)

* fixed some quirks (camera viewer + tag working)

* Setting quad decimate to 1 by default

* typo

* Implemented OptimizerG2O::loadGraph()

* added apriltag's aruco support info in the cmake config summary

* fixed warning

* fixed isam2 assert when using landmarks

* Fixed homography on multicam

* Adding marker detection time for convenience

* Added missing MIP 36h12 tag family in UI
2026-05-26 17:43:34 -07:00
matlabbe 49aa566613 Fixed empty global map on ros (regression from #1698) (#1709) 2026-05-23 13:36:15 -07:00
matlabbe a9146f5be6 Fix #1698 (#1708) 2026-05-22 09:33:17 -07:00
matlabbe 27ca7ec058 Fixing libpng warning: iCCP: known incorrect sRGB profile (#1703) 2026-05-15 07:18:15 -07:00
matlabbeandBorong Yuan 8d0692eab0 Save intermediate node input features (#1698)
* Avoid removing nodes from STM when using CreateIntermediateNodes

* Clean up the data of the intermediate node when IntermediateNodeDataKept is false

* Save intermediate node input features

* Don't delete intermediate nodes

* comment typo

* Updated parameter description, bump patch for DBReader API chang

* When ID is not udpated to new one, don't disable words because that signature is still used in the bayes filter

* updated comment

* rtabmap-reprocess: support Rtabmap/DetectionRate when intermediate nodes are created and -skip option is not used

* Fixed smallMovement when rehearsal is not trigdered at the same time

* GUI: visualize rehearsal darkblue when intermediate nodes are used

* Fixed RtabmapThread not transfering input features on intermediate nodes

* Do not override smallMovement and fastMovement when converting to intermediate nodes to keep GUI visualization color working

---------

Co-authored-by: Borong Yuan <[email protected]>
2026-05-14 09:20:09 -07:00
matlabbe afe8aadff1 Remove macos ci cache (#1701)
* removed macos caching
2026-05-10 21:46:37 -07:00
matlabbe 440e143d87 Adding CI Macos status in readme (#1700)
* Added macos-15-intel and macos-15 build

* Cache brew pkgs

* added tahoe build, adding debug logs

* g2o csparse optional

* removed ls

* build package on

* disabling bundle for now

* updated cache name

* Added MacOS CI status in README.md
2026-05-10 20:07:46 -07:00
matlabbe 72833c89bb Adding macos CI (#1699)
* Added macos-15-intel and macos-15 build

* Cache brew pkgs

* added tahoe build, adding debug logs

* g2o csparse optional

* removed ls

* build package on

* disabling bundle for now

* updated cache name
2026-05-10 20:04:30 -07:00
matlabbe f04067fa16 Fixing Rolling CI on Noble (#1696)
* Fixing Rolling CI on Noble

* setup env var correctly
2026-05-05 11:15:34 -07:00
matlabbe c1ef13a8d6 Various QoL (refactored RTABMAP_VERSION_COMPARE) (#1695) 2026-05-04 20:12:31 -07:00
matlabbe 37f8fa63c5 Auto graph repairing (#1691)
* Auto graph repairing: detect and remove bad loop closures accepted in the past that block new good loop closures to be accepted

* Added parameter RGBD/OptimizeMaxErrorRepairRadius: added approach to repair the graph (remove bad loop closures added in the past). Refactored max optimization error function, split repairGraph to its own function.

* Handling optimization from graph end in repair

* MaxGraphErrors: changed link's pointers to copy directly to avoid seg fault down the road if not used properly

* Dont publish optimization statistics if it was not computed.
2026-05-04 16:02:55 -07:00
Borong Yuan 0cf2e45c81 Preserve the attributes of intermediate nodes when retrieving data from the database (#1694) 2026-04-29 08:04:37 -07:00
matlabbe f48db0ee51 Fixing GUI warning when SIFT/MaxGaussianThreshold=0 2026-04-26 15:43:04 -07:00
matlabbe 2314c4dfa5 Updated noble dev container with nvidia runtime example 2026-04-26 15:40:26 -07:00
Borong Yuanandmatlabbe ebba7e4878 Correct the Jacobian calculation of GravityFactor (#1692)
* correct the Jacobian calculation of GravityFactor

* reimplement GravityFactor's analytical Jacobian

* adopt some minor changes from the GTSAM mainline

* use GTSAM's native AttitudeFactor instead of GravityFactor

* add missing header file and namespace prefix

* Removed GravityFactor. Fixed build with latest GTSAM version from source. Require c++17 when building with GTSAM>=4.3.0.

* Fixed cmake error when gtsam is not installed

---------

Co-authored-by: matlabbe <[email protected]>
2026-04-26 15:33:05 -07:00
matlabbe aa6d20775f Init python interface if built with python (related to #1693) 2026-04-25 14:55:59 -07:00
matlabbe 9cbe84e445 Support intermediate nodes with memory management enabled (#1687)
* Support intermediate nodes with memory management enabled

* Adding fix from #1686

* Fixed odomCache overlay shown in mapping mode

* Fixed local retrieval with intermediate nodes

* bumping version for updating API. Fixed getting graph error.

* Disable planning if intermediate nodes are there. Updated usage of Kp/BadSignRatio to support intermediate nodes.
2026-04-19 16:08:03 -07:00
matlabbe cc86af4399 GraphViewer: Fixed ground truth and gps context menu option disabled even if there are there, after hiding them, saving and reopening UI 2026-04-18 12:57:35 -07:00
matlabbe 79ff91d293 Added Statisics: Loop/Optimization_max_error_from_id and Loop/Optimization_max_error_to_id to help with debugging rejected loop closures 2026-04-16 17:39:58 -07:00
matlabbe aa7546ec62 Enable WITH_PYTHON on CI (#1689)
* Enable WITH_PYTHON on CI

* add python-dev

* use python3-dev instead of libpython3-dev

* use action to instlal python

* pybind now missing

* Fixed python build on linux

* warning

* try to install compatible pybind

* explicitly set where to find pybind
2026-04-14 12:09:41 -07:00
matlabbe a8fd7f043d CloudViewer: fixed rendering camera rotation not normalized warning 2026-04-13 01:16:58 +00:00
Abhijithandmatlabbe a9f63bd5fd Add LIO-SAM as an odometry strategy (#1684)
* Added liosam odometry integration

* Add kXYZIRT scan format with per-point ring channel for LIO-SAM integration

Introduce PointXYZIRT point type and kXYZIRT LaserScan format (x,y,z,
intensity,ring,time) so that ring indices survive the scan pipeline.
Update OdometryLIOSAM to require kXYZIRT and properly split ring/time
into the parallel buffers LIO-SAM expects. Extend deskewing to preserve
ring data and disable base-class deskew in OdometryLIOSAM since LIO-SAM
handles it internally.

* Address PR review: config file, deferred init, and GUI panel for LIO-SAM

- Add OdomLIOSAM/ConfigPath parameter to load LIO-SAM settings from a
  YAML file. When set, individual params are ignored. Extrinsics from
  sensor local transforms always override config file values.
- Defer LioSamCore initialization until both IMU and lidar local
  transforms are available, computing T_lidar_imu from sensor data.
  IMU samples are buffered and replayed after init.
- Fix deferred init for scan-only messages that arrive after IMU
  local transform is already cached.
- Add LIO-SAM entry to odometry strategy combo box (index 14) with
  full PreferencesDialog panel including config path browse button
  and all parameter widgets.

* OdometryLIOSAM: propagate deskewed scan to SensorData

Capture the deskewed cloud produced by LIO-SAM's image projection
stage and replace the raw scan on SensorData with it, so loop closure
registration and other downstream stages operate on the motion-
compensated points instead of the raw pre-deskew input.

* Minor updates for rtabmap_ros

---------

Co-authored-by: matlabbe <[email protected]>
2026-04-12 18:06:44 -07:00
matlabbe 8fd701aabe Fixing prior and gravity constraints support for SBA with orbslam dep… (#1683)
* Fixing prior and gravity constraints support for SBA with orbslam dependency

* Updated an error log msg
2026-04-05 12:36:54 -07:00
matlabbe 1ea8fa2e06 New rtabmap-reduceGraph CLI tool (#1655)
* New rtabmap-reduceGraph CLI tool

* fixed some edge cases

* Regenerating optimized map if there was one before reducing the graph

* addMoreLoopClosures: refactored how ctrl-c is handled to stop faster when no loop closures are added

* Added kilted status

* Make offline tool always propagate neighbor merged links

* removed a parameter

* fixed disconnected graph

* fixed --help

* Added error log on Kp/NNStrategy not compatible with huge vocabulary. ReduceGraph/DetectMoreLoopClosures: Make sure original parameters are saved back on closing. g2o: fixing optimizer to Levenberg for SBA to avoid [SetJac] infinite jac fatal error.

* exposing neighbor merged ratio parameter to the tool

* show param in log

* refactored detectMoreLoopClosures to ignore too close nodes in terms of neighbor links based on Mem/STMSize parameter. Reduce graph: added direction parameter.

* Simplified: removed ratio parameter, removed recursive reduction. Just don't reduce if a NM link is longer than maxDistance.

* Removed NNStrategy override, as it was still done on closing when we changed back to original params

* DBViewer: show missing links when showing OptimizedPoses in GraphView, fixed clicking on landmark links

* DetectMoreLoopClosures: Added support for min graph distance option in MainWindow and DbViewer

* slight renaming of ROS jobs

* reprocess: added option --params_last
2026-04-04 19:48:03 -07:00
matlabbe 51cfc37923 Update CI badges (#1681)
* OptimizerG2O: adding support for priors in SBA

* Fixed computeError

* don't fix root id roll/pitch if gravity constraints are fed (SBA)

* changed number_t to double

* forward compatibility

* cleanup

* log

* Updated CI status

* split cmake workflow in linux and windows

* bump release badge version

* uniformize name

* fixing android build
2026-03-29 12:34:09 -07:00
matlabbe 26bab2ba15 OptimizerG2O: adding support for priors in SBA (#1670)
* OptimizerG2O: adding support for priors in SBA

* Fixed computeError

* don't fix root id roll/pitch if gravity constraints are fed (SBA)

* changed number_t to double

* forward compatibility

* cleanup

* log
2026-03-29 11:30:33 -07:00
matlabbe 20409d2bf6 Cudasift tuning and SSC supporting multicameras (#1677)
* CudaSIFT: filter doubles

* removed fixed threshold

* SSC can be used with multicameras. Refactored CudaSIFT to support SSC. Add new parameter SIFT/MaxGaussianThreshold. DbViewer: show negative features with gray color (so that we can know which features are in the vocabulary)

* Added SIFT/MaxGaussianThreshold parameter

* Updated parameter description
2026-03-28 18:47:46 -07:00
matlabbe 94bd3601fc rtabmap-matcher: Added option to recfify raw images for convenience (#1663) 2026-03-28 18:47:18 -07:00
matlabbe f94a963463 CID-SIMS support (#1676)
* cid-sims dataset support

* Added cli tool to test CID-SIMS dataset

* removed debug log
2026-03-28 14:33:26 -07:00
Borong Yuanandmatlabbe 5b985f69be Add params to filter out poor stereo flow matches (#1667)
* Add params to filter out poor stereo flow matches

* Added parameters: Vis/CorFlowUseMinEigenVals, Vis/CorFlowMinEigThreshold, Vis/CorFlowErrorThreshold. Renamed Stereo/GetMinEigenVals to Stereo/UseMinEigenVals

* Setting suggested default value of 20 for Vis/CorFlowErrorThreshold

---------

Co-authored-by: matlabbe <[email protected]>
2026-03-17 21:53:14 -07:00
matlabbe 0151f8cdfb Split CI artifacts (#1672)
* Split artifacts

* do exe if not pull request
2026-03-15 17:21:29 -07:00
matlabbe 018b804a46 Adding OpenGV as submodule (optional) and use Github actions for windows CI (#1656)
* Adding OpenGV as submodule (optional)

* Remove submodule to migrate to FetchContent

* using FetchContent

* remove empty .gitmodules

* Fixing OpenGV not able to find eigen on windows

* patching opengv to adjust -march=native based on PCL

* fixing patching on windows

* eigen fix

* PR cancel on-going CI builds if new commit is added to PR

* try another approach

* updating patch with some logs

* more debug mesage

* fixing EIGEN_INCLUDE_DIR

* enable rolling_builds on appveyor

* removed rolling_builds appveyor

* fixing eigen cache

* test

* more debug logs

* another try

* cleanup

* updated appveyor to work with fetchcontent

* removed mkdir build (appveyor)

* appveyor: trying ninja to increase CI speed

* removed mkdr

* appveyor: spitting opengv and rtabmap builds to be under 60 min per job

* appveyor: caching dependencies

* using global configuration

* using baked image

* fixing wget in ps

* fixing not support for

* pip error

* reverted pip install

* fixed realsense cache

* fixing multi step build

* removing baked image

* typo

* Windows: Converted appveyor to github actions

* updated boost version

* fixing boost

* udpated  boost config

* boost...

* platform_version

* install boost directly

* silent boost install

* very silent boost

* fixing ls

* added boost install dir

* showing boost install dir

* moved windows dependencies in external action file

* explicitly save boost cache to same time on iterations

* pip install gdown

* update

* caching more deps

* caching all depts

* removed explicit boost cache save

* mscv 14.0

* forcing building visual studio 14 2015

* installing v12 in 2022 instead

* setup cmd prompt

* init right toolset

* fixing system version for opengv compilation error

* fixing package and artifact

* CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION

* removing cmd

* find manually psapi.lib

* resolve

* refactor psapi env

* forcing 10.0.19041.0

* using windows=2022 runner instead

* added vcpkg

* commenting windows-latest for now

* trying vcpkg instead

* search path

* updated path

* moved json

* removed deleted file for git

* adding a real version

* using version-string

* cleanup vcpkg

* building artifacts with vcpkg

* removed old windows build approach, added custom dependencies (gtsam, libpointmatcher) to vcpkg build

* udpated vcpkg version for issue https://github.com/microsoft/vcpkg/pull/49103

* try with minimal dep first

* disable opengv for now

* try vcpkg single compilation

* space

* updated link

* fixed qupote

* fixing cache name

* adding debug folder

* adjust path

* adjust path

* providing vcpkg binaries instead

* ident

* added triplet

* added BOOST_ROOT

* boost root

* boost root

* fixed path

* adding eigen headers

* try path

* cmake prefix path

* boost timer def

* libnabo fixes

* pointmatcher prefix

* disabling pointmathcer tests

* updated cmake parameters

* changed how file is downloaded

* trying curl instead

* puttoing backe InvokeWeb because it is a dropbox issue

* skipping optional deps for now

* ficing env variable

* triplet

* installing triplets

* not overriding default vcpkg env variables

* missing path

* manifet install off

* that was working locally

* missing protobuf path

* fixing tiff not found

* fixing vtk not found

* more vtk fixes

* another thy

* changing download url

* updated url

* try

* shoudl work now

* protobuf exe

* readding tiff

* explicit vcpkg installed folder

* missing commands

* try without tiff

* ficing vtk comple path

* -DPSAPI_LIBRARIES=Psapi.lib

* quoting

* fixing psapi required

* Set up MSVC Developer Command Prompt

* disabling pckaging for now

* openni.ini

* renabling packing

* Added stripped deps

* fix name

* updated binaries

* format

* updated opengv eigen path

* added tbb dep

* updatd archive name with vs version

* updated archive in action

* fixing patch error

* corrupted

* updated gtsam version / vcpkg

* removed appveyor. Set internal opengv build disabled by defaut (because build can be very long on some machines), will enable it inside the ros release branches instead.

* updated opengv patch

* gtsam mkl dep

* updated vcpkg binaries

* updated patches

* removed mkl dep

* missing eigen in gtsam dep

* disabling gtsam till we find a compatible version locally

* all working locally!

* removed ninja

* working python calls

* fixed hard symlink for python3.dll

* fixed qt missing png, fixed opengv not finding eigen with config, fixed python3.dll missing

* fixed flaoting dockwidget on start, removed cmd line window when launching bundled app

* use sub-packages cudnn

* Added cuda dev workflow

* fixed archive name

* Updated deps with pytorch cuda

* updating ci PATH

* fixing ci build without torch

* rename cuda artifacts

* cache cuda, add job to test internal opengv build

* Updated output artifacts zip name

* windows package: only zip on pull request

* Change USE_INTERNAL_OPENGV to BUILD_OPENGV

* use use-github-cache

* updated artifacts path
2026-03-15 14:57:27 -07:00
matlabbe 8051be45b3 Automated dictionary recovery/repairing (#1669)
* Automated dictionary recovery/repairing

* typo

* updated comment

* updating dictionary after fixing it

* Fixing missing ref

* Adding helping assert msg in case of repairing failure
2026-03-11 15:10:52 -07:00
matlabbe 0ef907757b Detect more loop closures from/to specific map ID only option (#1653)
* Detect more loop closures from/to specific map ID only option

* default value -1

* Added elapsed time

* Avoid loading ALL signatures in RAM, only load them when necessary

* Avoid creating flann index when initializing with Kp/NNStrategy>=3

* Setting opt params by default
2026-02-13 10:49:12 -08:00
matlabbe d6cf470402 Support proximity detection when switching from localization mode to slam mode (#1644) 2026-02-13 10:46:26 -08:00
matlabbe b3b8fbddbe export: fixed exported NaN points when voxel filter is not used 2026-02-08 16:23:55 -08:00
matlabbe b47c4093a6 CudaSIFT: using abs(sharpness) instead of sharpness as response value (this slightly change how most significant features are retained with Vis/MaxFeatures or Kp/MaxFeatures). OptimizerTORO: changed a fatal log to error log when loading a link with not existing poses. 2026-02-05 15:45:29 -08:00
matlabbe e23c38f471 DataRecorder: fixed record in RAM option. 2026-01-31 13:33:23 -08:00
Borong Yuan 040de14ec8 fix another typo for ceres optimizer (#1645) 2026-01-26 13:27:00 -08:00
matlabbe e6bc39028a Fixed RGBD/StartAtOrigin using landmark position 2026-01-22 17:42:04 -08:00
matlabbe da55168f60 Read-only localization mode (#1643)
* Read-only localization mode

* Localization: don't update map's node timestamps if statistic after run are not saved

* Updated Mem/LocalizationReadOnly description

* Updated description of Kp/FlannIndexSaved
2026-01-22 15:59:55 -08:00
matlabbe 48f529b4c6 Cleanup OccupancyGrid's cellCount_ unused member (#1639) (#1640) 2026-01-19 15:43:14 -08:00
matlabbe 42faef3941 DBReader: added ignore imu option, GUI: added tf overrides option (#1637)
* DBReader: added ignore imu option, GUI: added tf overrides option

* transform offset
2026-01-17 18:21:16 -08:00
matlabbe 7db14533f1 Added realsense2 playback support (bag) (#1636) 2026-01-17 18:07:32 -08:00
matlabbe 93ca4ed8d7 ImageView: fixed depth colormap in height with multicameras 2026-01-12 10:42:46 -08:00
matlabbe 92aff2129f CameraOrbbec: support explicit rate on non-TOF cameras. (#1627)
* rtabmap-rgbd_camera: added width/height options, 
* using CameraViewer for visualization by default (use -pcl option for old visualization). 
* CameraViewer: added capture and render rate.
* Note that non-TOF orbbec cameras could not be tested.
2025-12-21 11:52:38 -08:00
matlabbe af10d6b778 Reduced android-deps docker image size (fixing android CI out of space issue) 2025-12-20 18:50:36 -08:00
matlabbe 6f715b4a8d Merge branch 'v4hn-gtsam-4.3' 2025-12-20 14:48:30 -08:00
matlabbe 72bd453078 Fixing build with gtsam 4.3 binaries 2025-12-20 14:48:09 -08:00
matlabbe 86d5c99f5d Merge branch 'gtsam-4.3' of github.com:v4hn/rtabmap into v4hn-gtsam-4.3 2025-12-20 13:58:54 -08:00
matlabbe 07c3b8c901 updating words have changed with getNodeWordsAndGlobalDescriptors() 2025-12-18 17:09:06 -08:00
matlabbe 26573456c2 Fixed assert on words index <0 when addMoreLoopClosures is called 2025-12-18 16:38:13 -08:00
matlabbe af7ff60a6c Added missing cuvslam panel in UI 2025-12-15 15:12:06 -08:00
106874845f CuVSLAM 14 Update (#1618)
* update cuvslam api call to adhere to new v4.0 changes

* update comment

* parse cuvslam major version from the header and throw an error if theversion doesn't match the expected

* moving average filter + extensive debug logging

* lots more logs

* improvement by turning off use_motion_model in cuvslam config. lots of debug logs.

* slight improvements to velocity guard logic. lots of debug logs

* removing debug logs. working.

* let find_package_handle_standard_args handle the version comparison logic. Custom logic to handle newer then requested major version

* proper warning message if the major version doesn't match

* add back debug logs. Handle no guess transform case.

* adding warnings when no guess transform is provided

* clean up comments

* lowering average window to 5

* moderate odometry mode, 5 value averaging window

* adding comment

* add reset logs to investigate reset issue

* try returning guess or identity on init to avoid reset cascade

* disable motion model again

* big log when tracking

* remove some debug logs

* flag to use original covariance from cuVSLAM

* use raw covariance

* data collection for revised lost detection

* compare guess to estimated transform for lost detection

* re-enable motion model, it appears to reduce false-positives for the new lost detection

* run pose estimation afer init on first frame

* don't initialize if we don't have enough features

* dont warm up GPU everytime we reset

* low estimate velocity guard. Passes all challenges. Debug comments still everywhere.

* Remove debug logs. Add thresholds to header in a config section.

* Cleanup logs

* exposing multi-cam mode as a rtabmap param

* remove max frame delta

* change to use assertion instead of conditional

* replaced some UERROR by UWARN

---------

Co-authored-by: Felix Toft <[email protected]>
Co-authored-by: matlabbe <[email protected]>
2025-12-15 14:21:32 -08:00
v4hn 1e7ad82af6 support gtsam 4.3 header migration
as currently in their development branch
2025-12-06 01:46:08 +01:00
matlabbe 65867c47ae RegVis: updated error msg on 2D-2D estimation when there are not enough features (https://github.com/introlab/rtabmap_ros/issues/1381) 2025-12-03 21:52:47 -08:00
matlabbe c7da53ac3d Fixed regression when MapVisibility is not shown, poses are missing when exporting clouds #1625 2025-12-01 19:42:27 -08:00
matlabbe 16c0d2fec5 Removed gcc 4 constraint on unix (#1624) 2025-11-29 17:28:27 -08:00
matlabbe 90d7cc3045 Fixed cropBoxImpl() asserting when voxel filtering large 2D clouds (where min z == max z) 2025-11-28 14:41:39 -08:00
matlabbe 3268707c00 g2o: update initial pose estimate when prior is provided (https://github.com/introlab/rtabmap_ros/issues/1371) 2025-11-23 14:07:01 -08:00
matlabbe 3093df8e71 Localization: updated how poses with fixed priors are fed to optimization for faster convergence (see https://github.com/introlab/rtabmap_ros/issues/1371) 2025-11-23 13:47:15 -08:00
matlabbe 1edb6a8647 log msg typo 2025-11-23 12:03:17 -08:00
matlabbe 0bf2160939 Fixed odom cache overlay not visible 2025-11-23 11:33:26 -08:00
matlabbe e75baec73e Graph viewer optimizations (#1616)
* DbViewer: coloring graph based on env sensor value (e.g., wifi signal strength)

* GraphViewer optimizations

* Fixed link memory allocation

* refactor

* more optimizations

* mainwindow keypoints optimization

* MainWindow optimizations

* Shrink graphics scene on clearAll
2025-11-16 18:56:55 -08:00
matlabbe 82fb7ff5d2 DbViewer: coloring graph based on env sensor value (e.g., wifi signal strength) (#1613) 2025-11-16 11:37:47 -08:00
Felix ToftandFelix Toft d1b5d62d21 Limit Max Features (#1614)
* limit max features internally inside pydetector and superpoint_rpautrat to  limit keypoint/desc data size and improve performance

* avoid full reset when max features is changed to work around the memory temprorary param update logic

* remove leftover comment

* try using image roi instead

* revert and regenerate

* unintended change

* fixing issue with pydetector, adding mask filtering

---------

Co-authored-by: Felix Toft <[email protected]>
2025-11-16 11:37:03 -08:00
matlabbe e612d103bf ORB-SLAM3 IMU support fixes (#1612)
* Working IMU_RGBD and IMU_STEREO. Changing Inter IMU base frame is now possible.

* Output error msg when vocabulary path is wrong.

* Showing full local feature map
2025-11-11 14:09:13 -08:00
matlabbe c97f0c10dd Graph: reading pose format 10 or 12 from files saved with format 11 should work 2025-11-10 09:09:39 -08:00
matlabbe e3a60c8672 Set back min RGBD/LocalizationPriorError to 0.0001 (rtabmap_ros#1371) 2025-11-09 09:46:19 -08:00
matlabbe e9c6180d56 Prioritize neighbor links in Optimizer::getConnectedGraph() (#1610)
* Prioritize neighbor links in Optimizer::getConnectedGraph() to avoid odometry jumps.

* Fixed landmark order

* report: added search for first valid id

* Fixed non-neighbor comparison logic

* RGBD/LocalizationPriorError can now be 0 (disabled) to avoid using priors to fix the graph (https://github.com/introlab/rtabmap_ros/issues/1371)

* amend previous commit
2025-11-08 10:58:34 -08:00
Felix ToftandFelix Toft 5e4fd171e2 SuperPoint Rpautrat (MIT license) (#1603)
* initial python implementation of superpoint rpautrat

* working python implementation of superpoint

* small tweaks to try and work around the GIL issue

* fix missing os import

* begging cpp impl of superpoint python model

* finishing cpp superpoint impl using the same SPDetector interface

* finalizing superpoint cpp impl, working with cpu but needs to be cleaned

* fixing feature matching by reworking nms and filtering logic

* speeding up nms with batched operations and cleaning up

* updating conversion script

* adding args for image dimensions and cuda usage to model tracer

* wiring up UI to parse superpoint params

* adding label to superpoint rpautrat ui

* reverting some unintended ui changes

* typo

* oneline revert

* removing nms and threshold filtering from cpp, this is handled internally by the superpoint model

* using python interface to run the superpoint _to_torchscript.py script at runtime

* generate and load model file on the first incoming frame

* reverting unintented change

* ui changes appear mysteriously again, reverting

* remove topk from model to prevent issue when number of detected keypoints is lower then the k value (scripting fails in this case)

* cleaning up for review

* change dest for model file and remove debug logs

* bump patch and add version comment

* rm unucessary comment

* use resources to load file to ensure it works when rtabmap isn't built from source

* execute with pybind runpy instead of system call

* only build superpoint rpautrat if we have torch and python support

* changing param to accept a path to the weights .pth file directly

* parse the default working directory to save the model file in

* rm extraneous change

* rm setters and re-initialize the detector whenever params change. We cannot support changing params after the model is constructed

* update UI text

* only enable superpoint rpautrat when built with python and torch

* more build information regarding superpoint rpautrat

* generate temporary python script in the working dir

* rm unecessary changes to rtabmap_superpoint.py

* fix comment and only add repo root to sys.path

* introduce a new parameter for the superpoint python model definition

* execute script from string instead of writing to a file

* wrap parse params in a single compiler directive

* remove descriptor spatial matching logic and rely on upstream RTAB-Map processes to take the top-K desc and kpts

* only add python script to resources if built with superpoint rpautrat support. supress warning with type casting

* isolate pybind11 setup so it can't affect any other modules or potential regnerations of the model file

* update about dialog to show superpoint rpautrat

* remove debug logs

---------

Co-authored-by: Felix Toft <[email protected]>
2025-11-07 17:22:35 -08:00
matlabbe f44a4fc478 GUI: disabling cuvslam from the detector comboboxes if not built with it. 2025-11-02 17:53:01 -08:00
matlabbe a20e161a5b Fixed a realsense2 camera crash on start. Refactored VINS-Fusion to always use rtabmap's calibration model no matter what (improved usability). Preferences/IMU: fixed publish inter imu checkbox disappearing if no imu filter is selected. 2025-11-01 13:07:50 -07:00
matlabbe b04f607828 fixed warning 2025-11-01 10:12:38 -07:00
matlabbe a3076392b5 Fixed RGBD/LocalizationPriorError not used when adding external links 2025-10-28 20:57:32 -07:00
matlabbe 210aadb92b RGBD/LinearUpdate and RGBD/AngularUpdate: updated description and now require both to be 0 to skip motion check. 2025-10-28 20:56:54 -07:00
matlabbe 1def668578 export: support --color_radius disabled (-1) 2025-10-20 20:27:14 -07:00
matlabbe b9d7e8077c DbViewer: fixed new priors added 2 times 2025-10-20 17:38:46 -07:00
matlabbe 098db33547 ios: updated rtabmap include path 2025-10-18 14:09:44 -07:00
matlabbe 5cc16e371c 0.23.2: make g2o sba type check more portable (vcpkg build issue) (#1597)
* make g2o sba type check more portable

* try fixing latest g2o build
2025-10-13 22:54:35 -07:00
matlabbe edebf18043 reprocess: handling Rtabmap/CreateIntermediateNodes when recomputing odometry 2025-10-13 15:46:58 -07:00
matlabbe 1c8ac2b82b report: missing end of line in help 2025-10-13 13:53:56 -07:00
matlabbe 17fc6e3485 OrbbecSDK: install extensions folder when packaging 2025-10-12 16:54:05 -07:00
matlabbe 4e5a094491 cleanup 2025-10-12 16:28:25 -07:00
matlabbe 56aa26ce1d MacOSX: fixed combined entitlements and bundle icon 2025-10-12 15:48:50 -07:00
matlabbe 739628aef9 MacOSX: added entitlements to access Documents and camera 2025-10-12 13:30:16 -07:00
matlabbe f54b7685f3 cmake: removed QUIET keywords on default OFF options 2025-10-12 10:35:30 -07:00
matlabbe 99471819d5 reprocess: accepting Identity covariance (cuvslam first frames) 2025-10-10 14:47:50 -07:00
matlabbe ad8bbdc4b2 reprocess: fixing lost odom recovery when -odom_guess_input option is used 2025-10-09 15:39:19 -07:00
matlabbe 059cda85dc reprocess: fixed crash when odometry returns empty covariance. Also added more checks about that in the code in general. 2025-10-09 14:44:13 -07:00
matlabbe d60c15593d reprocess: show number of sessions linked to last pose 2025-10-09 14:04:29 -07:00
matlabbe 1abb70ef36 Let rtabmap-reprocess return 0 when there is no error 2025-10-09 13:37:52 -07:00
matlabbe 40ac961079 Fixed typos 2025-10-09 11:03:04 -07:00
matlabbe f0dab18005 Orbbec SDK v2 integration (new CameraOrbbecSDK class) (#1590)
* Orbbec SDK 2 integration (new CameraOrbbecSDK class)

* Added rectification option, fixed the build without orbbec sdk

* Fixed timestamp issue on Windows

* Removed WITH_ORBBEC_SDK=ON by default in case v1 is installed. Enabled inter imu when selecting orbbec sdk.

* requiring orbbec version=2 to avoid confusion

* Finalizing options
2025-10-07 10:22:16 -07:00
5aec9bacec CuVSLAM VO Strategy (#1583)
* integrating cuvslam, stereo cam initialization

* fixing transformations

* use isaac ros TocuVSLAMPose

* organizing

* handling covariance conversion

* cleaning up config

* moving cmake instructions to FindCuVSLAM.cmake file

* fixing ui integration

* updating software license for cuvslam

* improving memory management

* cleaning up header more

* reverting mistake in GUI

* using opaque pointers for header definitions, compiles

* back to typed definitions using forward-referencing

* fixing dangling pointer

* cleaning up

* fixing variable scope issues

* Using cuda to allocate gpu memory

* fixing transfrom from cuvslam back to ros coordinate frame

* reducing excessive logs

* removing redundant if true in cuvslam cmake

* moving find cuda into cuvslam cmake

* cleaning cmake to use modern target

* adding copyright line

* Finding tf2 and eigen3 in cmake

* simplifying clean up logic

* better logs

* moving cuvslam implementation methods into cpp

* fixing build with implmentation function declarations moved to the cpp

* cleaning transformation logic and adding grayscale support

* typo

* removing unecessary class member variable for processed images

* remove trailing underscore from initialize cuvslam function signature

* locally scoping config params since they are copied by cuvslam

* removing unecessary member variables and using locally scoped values since cuvslam seems to copy them

* more cleaning and refactoring

* fixing cmake inconsistancies and surpress warning

* fixing up baseline transform

* trying to remove tf2 for transformations

* fixing incorect baseline transform swap

* comment, begin reset logic investigation

* better handling of previous pose and transform during error cases

* hunting for reset bug, not found

* observation export implementatin, currently getting strange errors

* multi cam support

* Memory fixes

* comments

* make cuda stream a member variable so it isn't initialized and destroyed on every frame

* preparing to add ground constraints

* adding ground constraints, working

* adding wheel odom fusion into cuvslam tracker

* parsing parameter to apply planar constraints

* removing planar constraint in config, doesn't do anything

* using proper cuda stream type for member variable

* cleaning up for merge

* only parse params when cuvslam is compiled

* updating error message if using rgb-d instead of stereo

* removing wheel odom testing logs

* reverting bgr to rgb conversion

* fixing initial pose logic

* return null transform on invalid covariance

* debugging covariance

* guard against low velocity situations where cuvslam covariance spikes, but we aren't lost

* cleaning things up

---------

Co-authored-by: Felix Toft <[email protected]>
Co-authored-by: matlabbe <[email protected]>
2025-10-03 11:49:21 -07:00
matlabbe 5f1eccb2cd Odom F2M always report 9999 when lost (#1589) 2025-10-02 09:07:58 -07:00
matlabbe 11577fb553 When external guess is provided, don't report lost for the first ever frame (only on reset). Updated Odom/ResetCountdown description. (#1588) 2025-10-01 10:27:24 -07:00
matlabbe 05f077b950 Fixed auto reset identity jump. If external guess, do not report lost on recovery after auto reset. (#1587) 2025-09-30 16:22:54 -07:00
matlabbe 0f37bafd66 Added source odometry guess option in standalone app 2025-09-28 16:31:42 -07:00
matlabbe a552bdfb2f GUI: Support Optimizer/Robust with RGBD/OptimizeMaxError at the same time. DBReader: fixed repeated odom covariance when Mem/ReduceGraph is used. Memory: avoid error msg when receiving frames without features while we expect odometry features. See also #1573 2025-09-24 23:24:32 -07:00
matlabbe c774ef641a rgbd_dataset: added support for rgbd_bonn ground truth format 2025-09-20 18:08:38 -07:00
matlabbe cb0cc9ed18 VINS Fusion overhaul (#1580)
* Updated correct focal length used by VINS, updated VINS visualization.

* Renamed OdometryVINS to OdometryVINSFusion
2025-09-14 19:29:28 -07:00
matlabbe 6a435c968f reorganized includes (added SYSTEM keyword) (#1578) 2025-09-13 15:58:40 -07:00
matlabbe a96d574517 ImageView: fixed assert when depth image is smaller than rgb image if depth colormap is projected in base frame 2025-09-12 10:49:08 -07:00
matlabbe 668494948c fixed build: missing fstream 2025-09-06 16:52:29 -07:00
matlabbe efcfb9be16 Export: added options to export 2D oocupancy grid (--map) and octomap (--octomap) 2025-09-06 16:30:01 -07:00
matlabbeandMathieu Labbe 4603f09389 Loading time optimization (#1569)
* On init, rebuild the dictionnary only once

* Fixed first dictionary update to avoid rebuilding multiple times. Commented some very verbose debug logs (should create a new level: UVERBOSE or UTRACE)

* bump version 0.23: added parameters "Mem/LoadVisualLocalFeaturesOnInit", "Mem/FlannIndexSaved", "Kp/SerializeWithChecksum".

* Renamed Mem/FlannIndexSaved to Kp/FlannIndexSaved. Update UI Preferences with new parameters.

* commented some very verbose debug logs

* Warn flann index serialization not implemented on windows

* Warn flann index deserialization not implemented on windows

* Removing some verbose logs

* missing header (win32)

* Added GlobalMap::fullUpdateNeeded() function

* Adding log

* Save flann index even if links changed

* log time to serialize flann index

* Make dictionary modified only after we update

---------

Co-authored-by: Mathieu Labbe <[email protected]>
2025-09-03 16:55:54 -07:00
matlabbe 349580299c Fixing chessboard generation #1572 2025-09-03 15:59:37 -07:00
matlabbe 52e770e2d4 Update Dockerfile 2025-08-12 00:13:19 -07:00
matlabbe b9db73a239 devcontainer: don't mount Documents/RTAB-Map by default. latest_deps: using qt5 instead of qt6 because back window issue 2025-08-10 19:03:56 -07:00
matlabbe be5cd3998d Report: fixed gui not built with Qt6. Improved dev containers. Add latest deps dev container for convenience. 2025-08-10 17:00:34 -07:00
matlabbe 7d1a987d5d Planning: fix robot stuck when RGBD/LocalRadius is smaller than a link on the planned path. 2025-08-07 21:16:40 -07:00
matlabbe 4970474320 results_common.m fixed typo 2025-08-06 20:53:14 -07:00
matlabbe f2b9cc1cdd illumination invariant dataset: fixed typo 2025-08-06 20:29:22 -07:00
matlabbe 8328b22c3f depthai: Adding assert for min expected coeffs 2025-08-04 19:40:52 -07:00
Borong Yuan 330fda6522 Minor correction on using tilted sensor model for OAK camera 2025-07-29 14:09:42 +08:00
matlabbe 9650b71d8e CMake/Eigen: increased minimum major version to 3 if version not set (fixing g2o dep searching eigen without specifying version) 2025-07-13 23:15:06 -07:00
matlabbe df6300e0ba Windows-deploy: added missing zed's dll file. 2025-07-13 16:56:55 -07:00
matlabbe 94e31dcad1 Windows: fixed missing exported symbols (PythonInterface) 2025-07-13 04:15:03 -07:00
295 changed files with 206173 additions and 56528 deletions
-152
View File
@@ -1,152 +0,0 @@
branches:
only:
- master
- devel
os: Visual Studio 2015
clone_folder: c:\projects\rtabmap
platform: x64
configuration: Release
init:
- cmake --version
- call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64
- call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64
install:
# To download from google drive
- set PATH=C:\Python38-x64;C:\Python38-x64\Scripts;%PATH%
- ps: py -m pip --disable-pip-version-check install gdown>=5.1.0
# Qt
- set QTDIR=C:\Qt\5.10.1\msvc2015_64
# make sure Qt bin path is before cmake bin path to avoid copying qt5 dlls from cmake before qt installation
- set PATH=%QTDIR%\bin;%PATH%
# Boost
- set PATH=%PATH%;C:\Libraries\boost_1_62_0\lib64-msvc-14.0
# Openni2
- ps: wget 'https://dl.dropboxusercontent.com/s/d98jv79l6oy9fxz/OpenNI2.exe?dl=0' -outfile OpenNI2.exe
- cmd: OpenNI2.exe -o"C:\Program Files" -y
- ECHO "Installed OpenNI2:"
- ps: "ls \"C:/Program Files/OpenNI2\""
- set PATH=%PATH%;C:\Program Files\OpenNI2\Redist
- set OPENNI2_INCLUDE64=C:\Program Files\OpenNI2\Include
- set OPENNI2_LIB64=C:\Program Files\OpenNI2\Lib
- set OPENNI2_REDIST64=C:\Program Files\OpenNI2\Redist
# OpenCV
#- appveyor-retry appveyor DownloadFile http://downloads.sourceforge.net/project/opencvlibrary/4.5.2/opencv-4.5.2-vc14_vc15.exe
#- cmd: opencv-4.5.2-vc14_vc15.exe -o"C:\Program Files" -y
#- ECHO "Installed OpenCV:"
#- ps: "ls \"C:/Program Files/opencv/build\""
#- set PATH=%PATH%;C:\Program Files\opencv\build\x64\vc14\bin
- ps: wget 'https://dl.dropboxusercontent.com/s/o6ofn491bc0jso1/opencv450_vc14.exe?dl=0' -outfile opencv.exe
- cmd: opencv.exe -o"C:\Program Files" -y
- ECHO "Installed OpenCV:"
- ps: "ls \"C:/Program Files/opencv\""
- set PATH=%PATH%;C:\Program Files\opencv\x64\vc14\bin
# VTK (including QVTK)
- ps: wget 'https://dl.dropboxusercontent.com/s/1l33b5l3f3y52gf/VTK-6_3-msvc140.exe?dl=0' -outfile VTK-6_3.exe
- cmd: VTK-6_3.exe -o"C:\Program Files" -y
- ECHO "Installed VTK:"
- ps: "ls \"C:/Program Files/VTK\""
- set PATH=%PATH%;C:\Program Files\VTK\bin
# QHull
- ps: wget 'https://dl.dropboxusercontent.com/s/9widnk9msdsh2b8/Qhull-msvc140.exe?dl=0' -outfile Qhull.exe
- cmd: Qhull.exe -o"C:\Program Files" -y
- ECHO "Installed QHull:"
- ps: "ls \"C:/Program Files/Qhull\""
- set PATH=%PATH%;C:\Program Files\Qhull\bin
# FLANN
- ps: wget 'https://dl.dropboxusercontent.com/s/7k58jbmqa51sxmh/FLANN-msvc140.exe?dl=0' -outfile FLANN.exe
- cmd: FLANN.exe -o"C:\Program Files" -y
- ECHO "Installed FLANN:"
- ps: "ls \"C:/Program Files/FLANN\""
- set PATH=%PATH%;C:\Program Files\FLANN\bin
# Eigen
- ps: wget 'https://dl.dropboxusercontent.com/s/3v6i9i8dxj4o8ji/Eigen.exe?dl=0' -outfile Eigen.exe
- cmd: Eigen.exe -o"C:\Program Files" -y
- ECHO "Installed Eigen:"
- ps: "ls \"C:/Program Files/Eigen\""
# PCL
- ps: wget 'https://dl.dropboxusercontent.com/s/2iayr4lyqa50i9j/PCL_181_August2018_x64_vc14.exe?dl=0' -outfile PCL_1.8.1.exe
- cmd: PCL_1.8.1.exe -o"C:\Program Files" -y
- ECHO "Installed PCL:"
- ps: "ls \"C:/Program Files/PCL\""
- set PATH=%PATH%;C:\Program Files\PCL\bin
# zlib
- ps: gdown -q 0B46akLGdg-uaYm9MTTI4MUtUcmc
- ps: Expand-Archive zlib-1.2.8-vc2010-x64.zip -DestinationPath 'C:\Program Files'
- ECHO "Installed zlib:"
- ps: "ls \"C:/Program Files/zlib\""
- set PATH=%PATH%;C:\Program Files\zlib\bin
# g2o
- ps: wget 'https://dl.dropboxusercontent.com/s/ht74s5pa21wokzw/g2o.exe?dl=0' -outfile g2o.exe
- cmd: g2o.exe -o"C:\Program Files" -y
- ECHO "Installed g2o:"
- ps: "ls \"C:/Program Files/g2o\""
- set PATH=%PATH%;C:\Program Files\g2o\bin
# GTSAM
- ps: wget 'https://dl.dropboxusercontent.com/s/0fpr6r4cgsqmvhf/GTSAM-4_0_0_alpha2-msvc140.exe?dl=0' -outfile GTSAM.exe
- cmd: GTSAM.exe -o"C:\Program Files" -y
- ECHO "Installed GTSAM:"
- ps: "ls \"C:/Program Files/GTSAM\""
- set PATH=%PATH%;C:\Program Files\GTSAM\bin
# OctoMap
- ps: wget 'https://dl.dropboxusercontent.com/s/6jpxu0nm8ne6e54/octomap_x64_vc14.exe?dl=0' -outfile octomap.exe
- cmd: octomap.exe -o"C:\Program Files" -y
- ECHO "Installed OctoMap:"
- ps: "ls \"C:/Program Files/octomap-distribution\""
- set PATH=%PATH%;C:\Program Files\octomap-distribution\bin
# CPU-TSDF
- ps: wget 'https://dl.dropboxusercontent.com/s/mgges9va1uzxr0q/cpu_tsdf_sept2015_x64_vc14.exe?dl=0' -outfile cpu_tsdf.exe
- cmd: cpu_tsdf.exe -o"C:\Program Files" -y
- ECHO "Installed CPU-TSDF:"
- ps: "ls \"C:/Program Files/cpu_tsdf\""
- set PATH=%PATH%;C:\Program Files\cpu_tsdf\bin
# Open Chisel
- ps: wget 'https://dl.dropboxusercontent.com/s/0aaphcde4acrinm/open_chisel_x64_vc14.exe?dl=0' -outfile open_chisel.exe
- cmd: open_chisel.exe -o"C:\Program Files" -y
- ECHO "Installed Open Chisel:"
- ps: "ls \"C:/Program Files/open_chisel\""
- set PATH=%PATH%;C:\Program Files\open_chisel\bin
# yaml-cpp
- ps: wget 'https://dl.dropboxusercontent.com/s/22qfvftwj6zq8tj/yaml-cpp_x64_vc14.exe?dl=0' -outfile yaml-cpp.exe
- cmd: yaml-cpp.exe -o"C:\Program Files" -y
- ECHO "Installed yaml-cpp:"
- ps: "ls \"C:/Program Files/yaml-cpp\""
# RealSense2
- ps: wget 'https://github.com/IntelRealSense/librealsense/releases/download/v2.40.0/Intel.RealSense.SDK-WIN10-2.40.0.2482.exe' -outfile realsense2.exe
- cmd: realsense2.exe /VERYSILENT
- ECHO "Installed RealSense2:"
- ps: "ls \"C:/Program Files (x86)/Intel RealSense SDK 2.0\""
- set PATH=%PATH%;C:\Program Files (x86)\Intel RealSense SDK 2.0\bin\x64
- set RealSense2_ROOT_DIR=C:\Program Files (x86)\Intel RealSense SDK 2.0
# Kinect 4 Azure
- ps: wget 'https://download.microsoft.com/download/3/d/6/3d6d9e99-a251-4cf3-8c6a-8e108e960b4b/Azure%20Kinect%20SDK%201.4.1.exe' -outfile azure.exe
- cmd: azure.exe /quiet
- ECHO "Installed Kinect For Azure:"
- ps: "ls \"C:/Program Files/Azure Kinect SDK v1.4.1\""
- set PATH=%PATH%;C:\Program Files\Azure Kinect SDK v1.4.1\tools
- set K4A_ROOT_DIR=C:\Program Files\Azure Kinect SDK v1.4.1
before_build:
- cd c:\projects\rtabmap\build
- ECHO %PROGRAMFILES%
- ECHO %PATH%
- cmake -G "Visual Studio 14 2015 Win64" -DOpenCV_DIR="C:\Program Files\opencv\build" -DPCL_DIR="C:\Program Files\PCL\cmake" -DCPUTSDF_DIR="C:\Program Files\cpu_tsdf\share\cpu_tsdf" -Dyaml-cpp_DIR="C:\Program Files\yaml-cpp\CMake" -DBUILD_AS_BUNDLE=ON ..
after_build :
- cmake --build . --config Release --target package
artifacts:
- path: build\RTABMap-*
notifications:
- provider: Email
to:
- [email protected]
on_build_success: false
on_build_failure: false
on_build_status_changed: true
+21
View File
@@ -0,0 +1,21 @@
FROM introlab3it/rtabmap:focal-deps
RUN apt-get update && apt-get install -y sudo && \
apt-get clean && rm -rf /var/lib/apt/lists/
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=1000
RUN set -ex && \
groupadd --gid ${USER_GID} ${USERNAME} && \
useradd --uid ${USER_UID} --gid ${USER_GID} -m ${USERNAME} && \
usermod -a -G sudo ${USERNAME} && \
echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${USERNAME} && \
chmod 0440 /etc/sudoers.d/${USERNAME}
RUN mkdir -p /home/${USERNAME}/Documents/RTAB-Map && chown -R ${USERNAME} /home/${USERNAME}
RUN echo "source /usr/share/bash-completion/completions/git" >> /home/${USERNAME}/.bashrc
+12 -2
View File
@@ -1,8 +1,18 @@
{ {
"image": "introlab3it/rtabmap:20.04", "build": {
"dockerfile": "Dockerfile"
},
"customizations": { "customizations": {
"vscode": { "vscode": {
"extensions": ["ms-vscode.cpptools-themes", "ms-vscode.cmake-tools"] "extensions": ["ms-vscode.cpptools-themes", "ms-vscode.cmake-tools"]
} }
} },
"workspaceMount": "source=${localWorkspaceFolder},target=/home/vscode/rtabmap,type=bind",
"workspaceFolder": "/home/vscode/rtabmap",
//"mounts": ["source=${localEnv:HOME}/Documents/RTAB-Map,target=/home/vscode/Documents/RTAB-Map,type=bind,consistency=cached"],
"settings": {
"terminal.integrated.defaultProfile.linux": "bash"
},
"remoteUser": "vscode",
"runArgs": ["--privileged", "--network=host"]
} }
+21
View File
@@ -0,0 +1,21 @@
FROM introlab3it/rtabmap:jammy-deps
RUN apt-get update && apt-get install -y sudo && \
apt-get clean && rm -rf /var/lib/apt/lists/
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=1000
RUN set -ex && \
groupadd --gid ${USER_GID} ${USERNAME} && \
useradd --uid ${USER_UID} --gid ${USER_GID} -m ${USERNAME} && \
usermod -a -G sudo ${USERNAME} && \
echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${USERNAME} && \
chmod 0440 /etc/sudoers.d/${USERNAME}
RUN mkdir -p /home/${USERNAME}/Documents/RTAB-Map && chown -R ${USERNAME} /home/${USERNAME}
RUN echo "source /usr/share/bash-completion/completions/git" >> /home/${USERNAME}/.bashrc
+12 -2
View File
@@ -1,8 +1,18 @@
{ {
"image": "introlab3it/rtabmap:22.04", "build": {
"dockerfile": "Dockerfile"
},
"customizations": { "customizations": {
"vscode": { "vscode": {
"extensions": ["ms-vscode.cpptools-themes", "ms-vscode.cmake-tools"] "extensions": ["ms-vscode.cpptools-themes", "ms-vscode.cmake-tools"]
} }
} },
"workspaceMount": "source=${localWorkspaceFolder},target=/home/vscode/rtabmap,type=bind",
"workspaceFolder": "/home/vscode/rtabmap",
//"mounts": ["source=${localEnv:HOME}/Documents/RTAB-Map,target=/home/vscode/Documents/RTAB-Map,type=bind,consistency=cached"],
"settings": {
"terminal.integrated.defaultProfile.linux": "bash"
},
"remoteUser": "vscode",
"runArgs": ["--privileged", "--network=host"]
} }
@@ -0,0 +1,104 @@
ARG ROS_DISTRO=jazzy
FROM osrf/ros:${ROS_DISTRO}-desktop
# Install build dependencies with Qt6 (issue: rtabmap has black window)
#RUN apt-get update && \
# apt-get install -y git software-properties-common ros-${ROS_DISTRO}-rtabmap-ros libqt6* qt6* qml6* && \
# apt-get remove -y ros-${ROS_DISTRO}-rtabmap* ros-${ROS_DISTRO}-gtsam ros-${ROS_DISTRO}-libg2o libpcl* libqt5* qt5* libvtk* libopencv* && \
# apt-get clean && rm -rf /var/lib/apt/lists/
# Install build dependencies with Qt5
RUN apt-get update && \
apt-get install -y git software-properties-common ros-${ROS_DISTRO}-rtabmap-ros && \
apt-get remove -y ros-${ROS_DISTRO}-rtabmap* ros-${ROS_DISTRO}-gtsam ros-${ROS_DISTRO}-libg2o libpcl* libvtk* libopencv* && \
apt-get clean && rm -rf /var/lib/apt/lists/
# remove ubuntu user
RUN touch /var/mail/ubuntu && chown ubuntu /var/mail/ubuntu && userdel -r ubuntu
RUN apt-get update && apt-get install -y sudo && \
apt-get clean && rm -rf /var/lib/apt/lists/
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=1000
RUN set -ex && \
groupadd --gid ${USER_GID} ${USERNAME} && \
useradd --uid ${USER_UID} --gid ${USER_GID} -m ${USERNAME} && \
usermod -a -G sudo ${USERNAME} && \
echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${USERNAME} && \
chmod 0440 /etc/sudoers.d/${USERNAME}
RUN mkdir -p /home/${USERNAME}/Documents/RTAB-Map
RUN echo "source /usr/share/bash-completion/completions/git" >> /home/${USERNAME}/.bashrc
WORKDIR /home/${USERNAME}/
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
# We build main dependencies from source, cleaning up the
# build directory after install but keeping the source code
# to change version/reinstall from inside the dev container
# if needed.
# Build latest VTK with Qt6
RUN git clone https://github.com/Kitware/VTK.git
RUN cd VTK && \
mkdir build && \
cd build && \
cmake -DVTK_GROUP_ENABLE_Qt=YES .. && \
make -j$(nproc) && \
make install && \
make clean
# Build latest PCL with latest VTK
# Make sure all libraries depending on Eigen are built with same CXX standard (17)
RUN git clone https://github.com/PointCloudLibrary/pcl.git
RUN cd pcl && \
mkdir build && \
cd build && \
cmake -DCMAKE_CXX_STANDARD=17 -DBUILD_tools=ON -DPCL_ENABLE_AVX=OFF -DPCL_ENABLE_MARCHNATIVE=OFF -DPCL_ENABLE_SSE=OFF .. && \
make -j$(nproc) && \
make install && \
make clean
# Build latest OpenCV
RUN git clone https://github.com/opencv/opencv.git
RUN git clone https://github.com/opencv/opencv_contrib.git
RUN cd opencv && \
mkdir build && \
cd build && \
cmake -DBUILD_opencv_python3=OFF -DBUILD_opencv_python_bindings_generator=OFF -DBUILD_opencv_python_tests=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF -DOPENCV_ENABLE_NONFREE=ON -DOPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules .. && \
make -j$(nproc) && \
make install && \
make clean
# Build latest gtsam
RUN git clone https://github.com/borglab/gtsam.git
RUN cd gtsam && \
mkdir build && \
cd build && \
cmake -DCMAKE_CXX_STANDARD=17 -DGTSAM_BUILD_WITH_MARCH_NATIVE=OFF -DGTSAM_BUILD_EXAMPLES_ALWAYS=OFF -DGTSAM_BUILD_TESTS=OFF -DGTSAM_BUILD_STATIC_LIBRARY=OFF -DGTSAM_BUILD_UNSTABLE=OFF -DGTSAM_INSTALL_CPPUNILITE=OFF -DGTSAM_USE_SYSTEM_EIGEN=ON -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \
make install && \
make clean
# Build latest g2o
RUN git clone https://github.com/RainerKuemmerle/g2o.git
RUN cd g2o && \
mkdir build && \
cd build && \
cmake -DCMAKE_CXX_STANDARD=17 -DBUILD_WITH_MARCH_NATIVE=OFF -DG2O_BUILD_APPS=OFF -DG2O_BUILD_EXAMPLES=OFF -DG2O_USE_OPENGL=OFF -DCMAKE_BUILD_TYPE=Release .. && \
make -j$(nproc) && \
make install && \
make clean
# ros2 seems not sourcing by default its multi-arch folders
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/ros/${ROS_DISTRO}/lib/x86_64-linux-gnu
RUN ldconfig
RUN chown -R ${USERNAME} /home/${USERNAME}
@@ -0,0 +1,21 @@
{
"build": {
"dockerfile": "Dockerfile",
"args": {
"ROS_DISTRO": "jazzy"
}
},
"customizations": {
"vscode": {
"extensions": ["ms-vscode.cpptools-themes", "ms-vscode.cmake-tools"]
}
},
"workspaceMount": "source=${localWorkspaceFolder},target=/home/vscode/rtabmap,type=bind",
"workspaceFolder": "/home/vscode/rtabmap",
//"mounts": ["source=${localEnv:HOME}/Documents/RTAB-Map,target=/home/vscode/Documents/RTAB-Map,type=bind,consistency=cached"],
"settings": {
"terminal.integrated.defaultProfile.linux": "bash"
},
"remoteUser": "vscode",
"runArgs": ["--privileged", "--network=host"]
}
+25
View File
@@ -0,0 +1,25 @@
FROM introlab3it/rtabmap:noble-deps
# For devcontainer
# remove ubuntu user
RUN touch /var/mail/ubuntu && chown ubuntu /var/mail/ubuntu && userdel -r ubuntu
RUN apt-get update && apt-get install -y sudo && \
apt-get clean && rm -rf /var/lib/apt/lists/
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=1000
RUN set -ex && \
groupadd --gid ${USER_GID} ${USERNAME} && \
useradd --uid ${USER_UID} --gid ${USER_GID} -m ${USERNAME} && \
usermod -a -G sudo ${USERNAME} && \
echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${USERNAME} && \
chmod 0440 /etc/sudoers.d/${USERNAME}
RUN mkdir -p /home/${USERNAME}/Documents/RTAB-Map && chown -R ${USERNAME} /home/${USERNAME}
RUN echo "source /usr/share/bash-completion/completions/git" >> /home/${USERNAME}/.bashrc
+25 -3
View File
@@ -1,8 +1,30 @@
{ {
"image": "introlab3it/rtabmap:24.04", "build": {
"dockerfile": "Dockerfile"
},
"customizations": { "customizations": {
"vscode": { "vscode": {
"extensions": ["ms-vscode.cpptools-themes", "ms-vscode.cmake-tools"] "extensions": ["ms-vscode.cpptools-themes", "ms-vscode.cmake-tools", "ms-vscode.cpptools-extension-pack"]
} }
} },
"workspaceMount": "source=${localWorkspaceFolder},target=/home/vscode/rtabmap,type=bind",
"workspaceFolder": "/home/vscode/rtabmap",
//"mounts": ["source=${localEnv:HOME}/Documents/RTAB-Map,target=/home/vscode/Documents/RTAB-Map,type=bind,consistency=cached"],
"settings": {
"terminal.integrated.defaultProfile.linux": "bash"
},
"remoteUser": "vscode",
"hostRequirements": {
"gpu": "optional"
},
"runArgs": ["--privileged",
"--network=host",
"--gpus=all",
//"--runtime=nvidia", // uncommment this if rtabmap doesn't show up in nvidia-smi on the host computer
"--env=DISPLAY",
"--env=QT_X11_NO_MITSHM=1",
"--volume=/tmp/.X11-unix:/tmp/.X11-unix"],
"containerEnv": {
"NVIDIA_VISIBLE_DEVICES": "all"
}
} }
+25
View File
@@ -0,0 +1,25 @@
FROM introlab3it/rtabmap:resolute-deps
# For devcontainer
# remove ubuntu user
RUN touch /var/mail/ubuntu && chown ubuntu /var/mail/ubuntu && userdel -r ubuntu
RUN apt-get update && apt-get install -y sudo && \
apt-get clean && rm -rf /var/lib/apt/lists/
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=1000
RUN set -ex && \
groupadd --gid ${USER_GID} ${USERNAME} && \
useradd --uid ${USER_UID} --gid ${USER_GID} -m ${USERNAME} && \
usermod -a -G sudo ${USERNAME} && \
echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${USERNAME} && \
chmod 0440 /etc/sudoers.d/${USERNAME}
RUN mkdir -p /home/${USERNAME}/Documents/RTAB-Map && chown -R ${USERNAME} /home/${USERNAME}
RUN echo "source /usr/share/bash-completion/completions/git" >> /home/${USERNAME}/.bashrc
+30
View File
@@ -0,0 +1,30 @@
{
"build": {
"dockerfile": "Dockerfile"
},
"customizations": {
"vscode": {
"extensions": ["ms-vscode.cpptools-themes", "ms-vscode.cmake-tools", "ms-vscode.cpptools-extension-pack"]
}
},
"workspaceMount": "source=${localWorkspaceFolder},target=/home/vscode/rtabmap,type=bind",
"workspaceFolder": "/home/vscode/rtabmap",
//"mounts": ["source=${localEnv:HOME}/Documents/RTAB-Map,target=/home/vscode/Documents/RTAB-Map,type=bind,consistency=cached"],
"settings": {
"terminal.integrated.defaultProfile.linux": "bash"
},
"remoteUser": "vscode",
"hostRequirements": {
"gpu": "optional"
},
"runArgs": ["--privileged",
"--network=host",
"--gpus=all",
//"--runtime=nvidia", // uncommment this if rtabmap doesn't show up in nvidia-smi on the host computer
"--env=DISPLAY",
"--env=QT_X11_NO_MITSHM=1",
"--volume=/tmp/.X11-unix:/tmp/.X11-unix"],
"containerEnv": {
"NVIDIA_VISIBLE_DEVICES": "all"
}
}
+6 -3
View File
@@ -6,11 +6,12 @@ ENV DEBIAN_FRONTEND=noninteractive
# Install ROS2 # Install ROS2
RUN apt update && \ RUN apt update && \
apt install software-properties-common -y && \ apt install software-properties-common -y && \
add-apt-repository universe && \ add-apt-repository universe -y && \
apt update && \ apt update && \
apt install curl -y && \ apt install curl -y && \
curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg && \ export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F "tag_name" | awk -F\" '{print $4}') && \
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | tee /etc/apt/sources.list.d/ros2.list > /dev/null && \ curl -L -o /tmp/ros2-apt-source.deb "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release && echo ${UBUNTU_CODENAME:-${VERSION_CODENAME}})_all.deb" && \
apt install /tmp/ros2-apt-source.deb && \
apt-get clean && rm -rf /var/lib/apt/lists/ apt-get clean && rm -rf /var/lib/apt/lists/
# Install build dependencies # Install build dependencies
@@ -73,5 +74,7 @@ RUN set -ex && \
echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${USERNAME} && \ echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${USERNAME} && \
chmod 0440 /etc/sudoers.d/${USERNAME} chmod 0440 /etc/sudoers.d/${USERNAME}
RUN mkdir -p /home/${USERNAME}/Documents/RTAB-Map && chown -R ${USERNAME} /home/${USERNAME}
RUN echo "source /usr/share/bash-completion/completions/git" >> /home/${USERNAME}/.bashrc RUN echo "source /usr/share/bash-completion/completions/git" >> /home/${USERNAME}/.bashrc
+14 -1
View File
@@ -9,9 +9,22 @@
}, },
"workspaceMount": "source=${localWorkspaceFolder},target=/home/vscode/rtabmap,type=bind", "workspaceMount": "source=${localWorkspaceFolder},target=/home/vscode/rtabmap,type=bind",
"workspaceFolder": "/home/vscode/rtabmap", "workspaceFolder": "/home/vscode/rtabmap",
//"mounts": ["source=${localEnv:HOME}/Documents/RTAB-Map,target=/home/vscode/Documents/RTAB-Map,type=bind,consistency=cached"],
"settings": { "settings": {
"terminal.integrated.defaultProfile.linux": "bash" "terminal.integrated.defaultProfile.linux": "bash"
}, },
"remoteUser": "vscode", "remoteUser": "vscode",
"runArgs": ["--privileged", "--network=host"] "hostRequirements": {
"gpu": "optional"
},
"runArgs": ["--privileged",
"--network=host",
"--gpus=all",
//"--runtime=nvidia", // uncommment this if rtabmap doesn't show up in nvidia-smi on the host computer
"--env=DISPLAY",
"--env=QT_X11_NO_MITSHM=1",
"--volume=/tmp/.X11-unix:/tmp/.X11-unix"],
"containerEnv": {
"NVIDIA_VISIBLE_DEVICES": "all"
}
} }
@@ -0,0 +1,266 @@
name: 'Install macOS Source Dependencies'
description: 'Builds (and per-dependency caches) the source-only deps not available from Homebrew (GTSAM, libnabo+libpointmatcher, OrbbecSDK, depthai) and installs them into /usr/local.'
inputs:
os:
description: 'Runner os label (e.g. matrix.os), used to namespace the per-dependency caches. Required because intel/arm produce different binaries with identical Homebrew version strings.'
required: true
build_type:
description: 'CMake build type.'
required: false
default: 'Release'
runs:
using: "composite"
steps:
- name: Resolve dependency versions
id: depver
shell: bash
# The source deps link against these Homebrew libraries and are compiled
# with Xcode's toolchain, so both are folded into the cache keys: a
# Homebrew bump (e.g. a new Eigen) or an Xcode update forces a rebuild.
run: |
BREW=$(brew list --versions eigen boost yaml-cpp | sort)
XCODE=$(xcodebuild -version 2>/dev/null || clang --version | head -1)
HASH=$(printf '%s\n%s\n' "$BREW" "$XCODE" | shasum | cut -d' ' -f1)
echo "hash=$HASH" >> "$GITHUB_OUTPUT"
# ----------------------------- GTSAM -----------------------------
- name: Cache GTSAM
id: cache-gtsam
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/deps-stage/gtsam
key: gtsam-4.2.1-${{ inputs.os }}-${{ hashFiles('.github/actions/install-macos-source-deps/patches/gtsam-4.2.1-eigen5.patch') }}-${{ steps.depver.outputs.hash }}
- name: Build GTSAM
if: steps.cache-gtsam.outputs.cache-hit != 'true'
shell: bash
run: |
set -e
NPROC=$(sysctl -n hw.logicalcpu)
PATCHES="${{ github.action_path }}/patches"
SRC="${{ runner.temp }}/src-deps/gtsam"
STAGE="${{ runner.temp }}/deps-stage/gtsam"
rm -rf "$SRC"; mkdir -p "$SRC" "$STAGE"
git clone --depth 1 --branch 4.2.1 https://github.com/borglab/gtsam.git "$SRC/gtsam"
cd "$SRC/gtsam"
git apply "$PATCHES/gtsam-4.2.1-eigen5.patch"
cmake -B build \
-DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \
-DGTSAM_BUILD_WITH_MARCH_NATIVE=OFF \
-DGTSAM_WITH_TBB=OFF \
-DGTSAM_BUILD_EXAMPLES_ALWAYS=OFF \
-DGTSAM_BUILD_TESTS=OFF \
-DGTSAM_BUILD_UNSTABLE=OFF \
-DGTSAM_USE_SYSTEM_EIGEN=ON \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
cmake --build build -j$NPROC
DESTDIR="$STAGE" cmake --install build
# ----------------- libnabo + libpointmatcher --------------------
# Built together: libpointmatcher depends on libnabo, so keeping them in one
# unit keeps the build order internal (lpm finds libnabo in the unit's stage).
- name: Cache pointmatcher
id: cache-pointmatcher
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/deps-stage/pointmatcher
key: pointmatcher-nabo1.1.2-lpm1.4.4-${{ inputs.os }}-${{ hashFiles('.github/actions/install-macos-source-deps/patches/libnabo-1.1.2.patch', '.github/actions/install-macos-source-deps/patches/libpointmatcher-1.4.4-boost.patch') }}-${{ steps.depver.outputs.hash }}
- name: Build pointmatcher
if: steps.cache-pointmatcher.outputs.cache-hit != 'true'
shell: bash
run: |
set -e
NPROC=$(sysctl -n hw.logicalcpu)
PATCHES="${{ github.action_path }}/patches"
SRC="${{ runner.temp }}/src-deps/pointmatcher"
STAGE="${{ runner.temp }}/deps-stage/pointmatcher"
rm -rf "$SRC"; mkdir -p "$SRC" "$STAGE"
# libnabo (required by libpointmatcher)
git clone --depth 1 --branch 1.1.2 https://github.com/ethz-asl/libnabo.git "$SRC/libnabo"
cd "$SRC/libnabo"
git apply "$PATCHES/libnabo-1.1.2.patch"
cmake -B build -DCMAKE_BUILD_TYPE=${{ inputs.build_type }}
cmake --build build -j$NPROC
DESTDIR="$STAGE" cmake --install build
# libpointmatcher (finds libnabo from the unit's staged prefix)
git clone --depth 1 --branch 1.4.4 https://github.com/ethz-asl/libpointmatcher.git "$SRC/libpointmatcher"
cd "$SRC/libpointmatcher"
git apply "$PATCHES/libpointmatcher-1.4.4-boost.patch"
cmake -B build -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DCMAKE_PREFIX_PATH="$STAGE/usr/local" -DBUILD_EVALUATIONS=OFF -DBUILD_EXAMPLES=OFF
cmake --build build -j$NPROC
DESTDIR="$STAGE" cmake --install build
# ----------------------------- OrbbecSDK ------------------------
- name: Cache OrbbecSDK
id: cache-orbbec
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/deps-stage/orbbec
key: orbbec-2.8.7-usrlocal-${{ inputs.os }}-${{ hashFiles('.github/actions/install-macos-source-deps/patches/orbbecsdk-2.8.7-cmake-config-install.patch') }}-${{ steps.depver.outputs.hash }}
- name: Build OrbbecSDK
if: steps.cache-orbbec.outputs.cache-hit != 'true'
shell: bash
run: |
set -e
NPROC=$(sysctl -n hw.logicalcpu)
PATCHES="${{ github.action_path }}/patches"
SRC="${{ runner.temp }}/src-deps/orbbec"
STAGE="${{ runner.temp }}/deps-stage/orbbec"
rm -rf "$SRC"; mkdir -p "$SRC" "$STAGE"
git clone --depth 1 --branch v2.8.7 https://github.com/orbbec/OrbbecSDK_v2.git "$SRC/OrbbecSDK_v2"
cd "$SRC/OrbbecSDK_v2"
git apply "$PATCHES/orbbecsdk-2.8.7-cmake-config-install.patch"
# OrbbecSDK defaults its install prefix to /opt/OrbbecSDK; force /usr/local
# so it stages under usr/local like the other deps and is installed/found.
cmake -B build -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DCMAKE_INSTALL_PREFIX=/usr/local -DOB_BUILD_DOCS=OFF -DOB_BUILD_EXAMPLES=OFF -DOB_BUILD_TOOLS=OFF -DOB_INSTALL_EXAMPLES_SOURCE=OFF
cmake --build build -j$NPROC
DESTDIR="$STAGE" cmake --install build
# ----------------------------- depthai --------------------------
- name: Cache depthai
id: cache-depthai
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/deps-stage/depthai
key: depthai-2.32.0-usrlocal-${{ inputs.os }}-${{ hashFiles('.github/actions/install-macos-source-deps/patches/depthai-2.32.0-hunter-macos.patch') }}-${{ steps.depver.outputs.hash }}
- name: Build depthai
if: steps.cache-depthai.outputs.cache-hit != 'true'
shell: bash
run: |
set -e
NPROC=$(sysctl -n hw.logicalcpu)
PATCHES="${{ github.action_path }}/patches"
SRC="${{ runner.temp }}/src-deps/depthai"
STAGE="${{ runner.temp }}/deps-stage/depthai"
rm -rf "$SRC"; mkdir -p "$SRC" "$STAGE"
# depthai 2.32.0 (Hunter-based; v2 does NOT use vcpkg/CMake presets)
git clone --depth 1 --branch v2.32.0 https://github.com/luxonis/depthai-core.git "$SRC/depthai-core"
cd "$SRC/depthai-core"
git submodule update --init --recursive
# Route zlib to Homebrew: Hunter's pinned zlib fork has a classic
# TARGET_OS_MAC fdopen block that won't compile against the modern macOS SDK.
git apply "$PATCHES/depthai-2.32.0-hunter-macos.patch"
# v2 and its old Hunter deps declare cmake_minimum_required < 3.5, which the
# runner's CMake 4.x rejects, and CMAKE_POLICY_VERSION_MINIMUM does not
# propagate into Hunter's sub-builds. Use a pinned CMake 3.x just for depthai
# (Hunter reuses the same cmake binary for its dependency sub-builds).
python3 -m venv "$SRC/cmake3-venv"
"$SRC/cmake3-venv/bin/pip" install -q "cmake==3.31.6"
CMAKE3="$SRC/cmake3-venv/bin/cmake"
# DEPTHAI_ENABLE_CURL=OFF: Hunter's CURL drags in the broken zlib and also
# fails to configure on this toolchain; rtabmap doesn't need depthai's CURL.
# depthai-core defaults its install prefix to <build>/install; force
# /usr/local so it stages under usr/local like the other deps.
"$CMAKE3" -B build \
-DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DBUILD_SHARED_LIBS=ON \
-DDEPTHAI_ENABLE_CURL=OFF \
-DDEPTHAI_BUILD_TESTS=OFF \
-DDEPTHAI_BUILD_EXAMPLES=OFF \
-DCMAKE_PREFIX_PATH="$(brew --prefix zlib)"
"$CMAKE3" --build build -j$NPROC
DESTDIR="$STAGE" "$CMAKE3" --install build
# ----------------------------- opengv ---------------------------
- name: Cache opengv
id: cache-opengv
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/deps-stage/opengv
key: opengv-91f4b19c-usrlocal-${{ inputs.os }}-${{ hashFiles('.github/actions/install-macos-source-deps/patches/opengv-91f4b19c-macos.patch') }}-${{ steps.depver.outputs.hash }}
- name: Build opengv
if: steps.cache-opengv.outputs.cache-hit != 'true'
shell: bash
run: |
set -e
NPROC=$(sysctl -n hw.logicalcpu)
PATCHES="${{ github.action_path }}/patches"
SRC="${{ runner.temp }}/src-deps/opengv"
STAGE="${{ runner.temp }}/deps-stage/opengv"
rm -rf "$SRC"; mkdir -p "$SRC" "$STAGE"
# opengv pins a commit (not a tag), so clone then checkout.
git clone https://github.com/laurentkneip/opengv.git "$SRC/opengv"
cd "$SRC/opengv"
git checkout 91f4b19c73450833a40e463ad3648aae80b3a7f3
# Disable the -march=native/armv7-a/armv8-a flags so it builds portably on
# both Intel and Apple Silicon runners.
git apply "$PATCHES/opengv-91f4b19c-macos.patch"
# CMAKE_POLICY_VERSION_MINIMUM=3.5: opengv declares an ancient
# cmake_minimum_required that modern CMake rejects. EIGEN_INCLUDE_DIR points
# opengv's bundled FindEigen at Homebrew's eigen (covers /opt/homebrew on arm64).
cmake -B build \
-DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DBUILD_TESTS=OFF \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
-DEIGEN_INCLUDE_DIR="$(brew --prefix eigen)/include/eigen3"
cmake --build build -j$NPROC
DESTDIR="$STAGE" cmake --install build
# ----------------------------- g2o ------------------------------
- name: Cache g2o
id: cache-g2o
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/deps-stage/g2o
key: g2o-67cbe15c-${{ inputs.os }}-${{ steps.depver.outputs.hash }}
- name: Build g2o
if: steps.cache-g2o.outputs.cache-hit != 'true'
shell: bash
run: |
set -e
NPROC=$(sysctl -n hw.logicalcpu)
SRC="${{ runner.temp }}/src-deps/g2o"
STAGE="${{ runner.temp }}/deps-stage/g2o"
rm -rf "$SRC"; mkdir -p "$SRC" "$STAGE"
# g2o pins a commit (not a tag), so clone then checkout.
git clone https://github.com/RainerKuemmerle/g2o.git "$SRC/g2o"
cd "$SRC/g2o"
git checkout 67cbe15c998737ac6705d3cd18201a72be0d073d
# CMAKE_INSTALL_PREFIX=/usr/local so it stages under usr/local like the
# other deps. Homebrew's libomp is keg-only and g2o does not propagate
# OpenMP's include/lib dirs, so with Apple clang <omp.h> isn't found and
# libomp isn't linked; add its include (-I) and lib (-L -lomp) explicitly.
LIBOMP=$(brew --prefix libomp)
cmake -B build \
-DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DCMAKE_PREFIX_PATH="$LIBOMP" \
-DCMAKE_C_FLAGS="-I$LIBOMP/include" \
-DCMAKE_CXX_FLAGS="-I$LIBOMP/include" \
-DCMAKE_EXE_LINKER_FLAGS="-L$LIBOMP/lib -lomp" \
-DCMAKE_SHARED_LINKER_FLAGS="-L$LIBOMP/lib -lomp" \
-DG2O_BUILD_APPS=OFF \
-DG2O_BUILD_EXAMPLES=OFF \
-DG2O_USE_OPENMP=ON \
-DG2O_USE_OPENGL=OFF
cmake --build build -j$NPROC
DESTDIR="$STAGE" cmake --install build
# ------------------- install all units into /usr/local ----------
- name: Install source dependencies into /usr/local
shell: bash
# Copy each (cached or freshly built) staged tree into /usr/local so
# rtabmap's find_package() and the bundle fixup (which search /usr/local)
# pick them up. Runs on both cache hit and miss.
run: |
set -e
STAGE="${{ runner.temp }}/deps-stage"
found=0
for unit in gtsam pointmatcher orbbec depthai opengv g2o; do
if [ -d "$STAGE/$unit/usr/local" ]; then
sudo cp -a "$STAGE/$unit/usr/local/." /usr/local/
found=1
fi
done
if [ "$found" != "1" ]; then
echo "No staged source dependencies found under $STAGE" >&2
exit 1
fi
@@ -0,0 +1,41 @@
diff --git a/cmake/depthaiDependencies.cmake b/cmake/depthaiDependencies.cmake
index 6b0b44f98..672c26402 100644
--- a/cmake/depthaiDependencies.cmake
+++ b/cmake/depthaiDependencies.cmake
@@ -17,7 +17,9 @@ else()
hunter_add_package(FP16)
hunter_add_package(libarchive-luxonis)
hunter_add_package(spdlog)
- hunter_add_package(ZLIB)
+ # ZLIB: use the system/Homebrew copy instead of Hunter's (the old pinned
+ # zlib fork fails to build against the modern macOS SDK). Found below via
+ # the standard FindZLIB module, which provides the same ZLIB::ZLIB target.
if(DEPTHAI_ENABLE_BACKWARD)
hunter_add_package(Backward)
endif()
@@ -45,8 +47,23 @@ if(NOT CONFIG_MODE OR (CONFIG_MODE AND NOT DEPTHAI_SHARED_LIBS))
# libarchive for firmware packages
find_package(archive_static ${_QUIET} CONFIG REQUIRED)
find_package(lzma ${_QUIET} CONFIG REQUIRED)
- # ZLIB for compressing Apps
- find_package(ZLIB CONFIG REQUIRED)
+ # ZLIB for compressing Apps.
+ # Use the system/Homebrew zlib directly instead of Hunter's: Hunter's pinned
+ # zlib fork fails to build against the modern macOS SDK, and Hunter also
+ # intercepts find_package(ZLIB) via its own FindZLIB on the module path, so
+ # we locate it manually and expose the ZLIB::zlib target depthai expects.
+ find_path(SYSTEM_ZLIB_INCLUDE_DIR NAMES zlib.h)
+ find_library(SYSTEM_ZLIB_LIBRARY NAMES z)
+ if(NOT SYSTEM_ZLIB_INCLUDE_DIR OR NOT SYSTEM_ZLIB_LIBRARY)
+ message(FATAL_ERROR "System zlib not found (looked for zlib.h and libz). Install via: brew install zlib")
+ endif()
+ if(NOT TARGET ZLIB::zlib)
+ add_library(ZLIB::zlib UNKNOWN IMPORTED)
+ set_target_properties(ZLIB::zlib PROPERTIES
+ IMPORTED_LOCATION "${SYSTEM_ZLIB_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${SYSTEM_ZLIB_INCLUDE_DIR}"
+ )
+ endif()
# spdlog for library and device logging
find_package(spdlog ${_QUIET} CONFIG REQUIRED)
@@ -0,0 +1,83 @@
diff --git a/cmake/HandleEigen.cmake b/cmake/HandleEigen.cmake
index b3b4f66b6..651cd1009 100644
--- a/cmake/HandleEigen.cmake
+++ b/cmake/HandleEigen.cmake
@@ -59,7 +59,12 @@ else()
endif()
# Detect Eigen version:
-set(EIGEN_VER_H "${GTSAM_EIGEN_INCLUDE_FOR_BUILD}/Eigen/src/Core/util/Macros.h")
+# Since Eigen 5.0.0 the version macros moved from Eigen/src/Core/util/Macros.h
+# to a dedicated Eigen/Version header, so check the new location first.
+set(EIGEN_VER_H "${GTSAM_EIGEN_INCLUDE_FOR_BUILD}/Eigen/Version")
+if (NOT EXISTS ${EIGEN_VER_H})
+ set(EIGEN_VER_H "${GTSAM_EIGEN_INCLUDE_FOR_BUILD}/Eigen/src/Core/util/Macros.h")
+endif()
if (EXISTS ${EIGEN_VER_H})
file(READ "${EIGEN_VER_H}" STR_EIGEN_VERSION)
diff --git a/gtsam/base/Matrix.h b/gtsam/base/Matrix.h
index cfedf6d8c..9c9771407 100644
--- a/gtsam/base/Matrix.h
+++ b/gtsam/base/Matrix.h
@@ -54,7 +54,7 @@ using Matrix7##N = Eigen::Matrix<double, 7, N>; \
using Matrix8##N = Eigen::Matrix<double, 8, N>; \
using Matrix9##N = Eigen::Matrix<double, 9, N>; \
static const Eigen::MatrixBase<Matrix##N>::IdentityReturnType I_##N##x##N = Matrix##N::Identity(); \
-static const Eigen::MatrixBase<Matrix##N>::ConstantReturnType Z_##N##x##N = Matrix##N::Zero();
+static const decltype(Matrix##N::Zero()) Z_##N##x##N = Matrix##N::Zero();
GTSAM_MAKE_MATRIX_DEFS(1)
GTSAM_MAKE_MATRIX_DEFS(2)
diff --git a/gtsam/base/Vector.h b/gtsam/base/Vector.h
index f7923ff88..5410393f6 100644
--- a/gtsam/base/Vector.h
+++ b/gtsam/base/Vector.h
@@ -27,6 +27,7 @@
#include <gtsam/global_includes.h>
#include <Eigen/Core>
+#include <cassert>
#include <iosfwd>
#include <list>
@@ -42,14 +43,14 @@ typedef Eigen::Matrix<double, 1, 1> Vector1;
typedef Eigen::Vector2d Vector2;
typedef Eigen::Vector3d Vector3;
-static const Eigen::MatrixBase<Vector2>::ConstantReturnType Z_2x1 = Vector2::Zero();
-static const Eigen::MatrixBase<Vector3>::ConstantReturnType Z_3x1 = Vector3::Zero();
+static const decltype(Vector2::Zero()) Z_2x1 = Vector2::Zero();
+static const decltype(Vector3::Zero()) Z_3x1 = Vector3::Zero();
// Create handy typedefs and constants for vectors with N>3
// VectorN and Z_Nx1, for N=1..9
#define GTSAM_MAKE_VECTOR_DEFS(N) \
using Vector##N = Eigen::Matrix<double, N, 1>; \
- static const Eigen::MatrixBase<Vector##N>::ConstantReturnType Z_##N##x1 = Vector##N::Zero();
+ static const decltype(Vector##N::Zero()) Z_##N##x1 = Vector##N::Zero();
GTSAM_MAKE_VECTOR_DEFS(4)
GTSAM_MAKE_VECTOR_DEFS(5)
diff --git a/gtsam/linear/iterative.h b/gtsam/linear/iterative.h
index 22f65b8de..20a0c936e 100644
--- a/gtsam/linear/iterative.h
+++ b/gtsam/linear/iterative.h
@@ -61,7 +61,7 @@ namespace gtsam {
/** Apply operator A'*e */
Vector operator^(const Vector& e) const {
- return A_ ^ e;
+ return gtsam::operator^(A_, e);
}
/**
@@ -71,7 +71,7 @@ namespace gtsam {
/** gradient of objective function 0.5*|Ax-b_|^2 at x = A_'*(Ax-b_) */
Vector gradient(const Vector& x) const {
- return A() ^ (A() * x - b());
+ return gtsam::operator^(A(), Vector(A() * x - b()));
}
/** Apply operator A */
@@ -0,0 +1,87 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a5f0c44..69340e4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -78,18 +78,18 @@ elseif ()
endif ()
endif ()
-# enable C++11 support.
+# enable C++14 support (required by recent Eigen versions).
if (CMAKE_VERSION VERSION_LESS "3.1")
if (MSVC)
message(FATAL_ERROR "CMake version 3.1 or later is required to compile ${PROJECT_NAME} with Microsoft Visual C++")
endif ()
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
- set (CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}")
+ set (CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_FLAGS}")
else ()
- set (CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
+ set (CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_FLAGS}")
endif ()
else ()
- set (CMAKE_CXX_STANDARD 11)
+ set (CMAKE_CXX_STANDARD 14)
endif ()
#======================== External Dependencies ===============================
diff --git a/experimental/kdtree_cpu.cpp b/experimental/kdtree_cpu.cpp
index 302b672..d63fcd3 100644
--- a/experimental/kdtree_cpu.cpp
+++ b/experimental/kdtree_cpu.cpp
@@ -31,6 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "nabo_experimental.h"
#include "../nabo/index_heap.h"
+#include <cassert>
#include <iostream>
#include <stdexcept>
#include <limits>
diff --git a/nabo/kdtree_cpu.cpp b/nabo/kdtree_cpu.cpp
index cb1f8d1..52a444f 100644
--- a/nabo/kdtree_cpu.cpp
+++ b/nabo/kdtree_cpu.cpp
@@ -37,6 +37,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <queue>
#include <algorithm>
#include <utility>
+#include <cassert>
#ifdef HAVE_OPENMP
#include <omp.h>
#endif
diff --git a/nabo/kdtree_opencl.cpp b/nabo/kdtree_opencl.cpp
index 5a9fee2..fb1345f 100644
--- a/nabo/kdtree_opencl.cpp
+++ b/nabo/kdtree_opencl.cpp
@@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "nabo_private.h"
#include "index_heap.h"
+#include <cassert>
#include <iostream>
#include <sstream>
#include <fstream>
diff --git a/tests/knnshow.cpp b/tests/knnshow.cpp
index 6f4d3fc..c612378 100644
--- a/tests/knnshow.cpp
+++ b/tests/knnshow.cpp
@@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "nabo/nabo.h"
+#include <cassert>
#include <iostream>
#include <fstream>
#include <stdexcept>
diff --git a/tests/knnvalidate.cpp b/tests/knnvalidate.cpp
index 2430249..2a7dcc4 100644
--- a/tests/knnvalidate.cpp
+++ b/tests/knnvalidate.cpp
@@ -32,6 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "nabo/nabo.h"
#include "helpers.h"
//#include "experimental/nabo_experimental.h"
+#include <cassert>
#include <iostream>
#include <fstream>
#include <stdexcept>
@@ -0,0 +1,32 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9dabfd0..7b73418 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -128,9 +128,9 @@ endif()
#--------------------
# DEPENDENCY: boost
#--------------------
-find_package(Boost REQUIRED COMPONENTS thread system program_options date_time)
+find_package(Boost REQUIRED COMPONENTS thread program_options date_time)
if (Boost_MINOR_VERSION GREATER 47)
- find_package(Boost REQUIRED COMPONENTS thread system program_options date_time chrono)
+ find_package(Boost REQUIRED COMPONENTS thread program_options date_time chrono)
endif ()
#--------------------
diff --git a/libpointmatcherConfig.cmake.in b/libpointmatcherConfig.cmake.in
index 6de2c85..7c887fd 100644
--- a/libpointmatcherConfig.cmake.in
+++ b/libpointmatcherConfig.cmake.in
@@ -7,9 +7,9 @@
include(CMakeFindDependencyMacro)
find_dependency(libnabo REQUIRED)
find_dependency(yaml-cpp REQUIRED)
-find_package(Boost COMPONENTS thread system program_options date_time REQUIRED)
+find_package(Boost COMPONENTS thread program_options date_time REQUIRED)
if (Boost_MINOR_VERSION GREATER 47)
- find_package(Boost COMPONENTS thread system program_options date_time chrono REQUIRED)
+ find_package(Boost COMPONENTS thread program_options date_time chrono REQUIRED)
endif ()
include(${CMAKE_CURRENT_LIST_DIR}/libpointmatcher-config.cmake)
@@ -0,0 +1,309 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9660f55..0186da4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,12 +31,12 @@ IF(MSVC)
add_definitions(-D_USE_MATH_DEFINES)
ELSE()
IF (CMAKE_SYSTEM_PROCESSOR MATCHES "(arm64)|(ARM64)|(aarch64)|(AARCH64)")
- add_definitions (-march=armv8-a)
+ #add_definitions (-march=armv8-a)
ELSEIF (CMAKE_SYSTEM_PROCESSOR MATCHES
"(arm)|(ARM)|(armhf)|(ARMHF)|(armel)|(ARMEL)")
- add_definitions (-march=armv7-a)
+ #add_definitions (-march=armv7-a)
ELSE ()
- add_definitions (-march=native) #TODO use correct c++11 def once everybody has moved to gcc 4.7 # for now I even removed std=gnu++0x
+ #add_definitions (-march=native) #TODO use correct c++11 def once everybody has moved to gcc 4.7 # for now I even removed std=gnu++0x
ENDIF()
add_definitions (
-O3
@@ -181,7 +181,7 @@ add_library( random_generators test/random_generators.cpp test/random_generators
set_target_properties( opengv random_generators PROPERTIES
SOVERSION ${PROJECT_VERSION}
VERSION ${PROJECT_VERSION}
- CXX_STANDARD 11
+ CXX_STANDARD 14
CXX_STANDARD_REQUIRED ON
DEBUG_POSTFIX d )
@@ -329,7 +329,7 @@ IF (BUILD_TESTS)
test_Sturm
PROPERTIES
- CXX_STANDARD 11
+ CXX_STANDARD 14
CXX_STANDARD_REQUIRED ON
DEBUG_POSTFIX d )
diff --git a/modules/FindEigen.cmake b/modules/FindEigen.cmake
index 126f4a0..39b5524 100644
--- a/modules/FindEigen.cmake
+++ b/modules/FindEigen.cmake
@@ -30,7 +30,13 @@ if(NOT Eigen_FIND_VERSION)
endif(NOT Eigen_FIND_VERSION)
macro(_eigen3_check_version)
- file(READ "${EIGEN_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header)
+ # Since Eigen 5.0.0 the version macros moved from Eigen/src/Core/util/Macros.h
+ # to a dedicated Eigen/Version header, so check the new location first.
+ if(EXISTS "${EIGEN_INCLUDE_DIR}/Eigen/Version")
+ file(READ "${EIGEN_INCLUDE_DIR}/Eigen/Version" _eigen3_version_header)
+ else()
+ file(READ "${EIGEN_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header)
+ endif()
string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}")
set(EIGEN_WORLD_VERSION "${CMAKE_MATCH_1}")
diff --git a/src/absolute_pose/CentralAbsoluteAdapter.cpp b/src/absolute_pose/CentralAbsoluteAdapter.cpp
index 684fa7e..a4ff2bd 100644
--- a/src/absolute_pose/CentralAbsoluteAdapter.cpp
+++ b/src/absolute_pose/CentralAbsoluteAdapter.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/absolute_pose/CentralAbsoluteAdapter.hpp>
diff --git a/src/absolute_pose/MACentralAbsolute.cpp b/src/absolute_pose/MACentralAbsolute.cpp
index 6edbabc..1687d45 100644
--- a/src/absolute_pose/MACentralAbsolute.cpp
+++ b/src/absolute_pose/MACentralAbsolute.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/absolute_pose/MACentralAbsolute.hpp>
diff --git a/src/absolute_pose/MANoncentralAbsolute.cpp b/src/absolute_pose/MANoncentralAbsolute.cpp
index d9b5b09..a7ae689 100644
--- a/src/absolute_pose/MANoncentralAbsolute.cpp
+++ b/src/absolute_pose/MANoncentralAbsolute.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/absolute_pose/MANoncentralAbsolute.hpp>
opengv::absolute_pose::MANoncentralAbsolute::MANoncentralAbsolute(
diff --git a/src/absolute_pose/NoncentralAbsoluteAdapter.cpp b/src/absolute_pose/NoncentralAbsoluteAdapter.cpp
index 30176aa..6a0e405 100644
--- a/src/absolute_pose/NoncentralAbsoluteAdapter.cpp
+++ b/src/absolute_pose/NoncentralAbsoluteAdapter.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/absolute_pose/NoncentralAbsoluteAdapter.hpp>
opengv::absolute_pose::NoncentralAbsoluteAdapter::NoncentralAbsoluteAdapter(
diff --git a/src/absolute_pose/NoncentralAbsoluteMultiAdapter.cpp b/src/absolute_pose/NoncentralAbsoluteMultiAdapter.cpp
index 88c237a..58a82f4 100644
--- a/src/absolute_pose/NoncentralAbsoluteMultiAdapter.cpp
+++ b/src/absolute_pose/NoncentralAbsoluteMultiAdapter.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/absolute_pose/NoncentralAbsoluteMultiAdapter.hpp>
opengv::absolute_pose::NoncentralAbsoluteMultiAdapter::NoncentralAbsoluteMultiAdapter(
diff --git a/src/absolute_pose/methods.cpp b/src/absolute_pose/methods.cpp
index b1f0889..19c4eaf 100644
--- a/src/absolute_pose/methods.cpp
+++ b/src/absolute_pose/methods.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/absolute_pose/methods.hpp>
#include <opengv/Indices.hpp>
diff --git a/src/absolute_pose/modules/main.cpp b/src/absolute_pose/modules/main.cpp
index ed0c271..99f7f35 100644
--- a/src/absolute_pose/modules/main.cpp
+++ b/src/absolute_pose/modules/main.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <Eigen/NonLinearOptimization>
#include <Eigen/NumericalDiff>
diff --git a/src/math/arun.cpp b/src/math/arun.cpp
index a0d6296..f5c0ac3 100644
--- a/src/math/arun.cpp
+++ b/src/math/arun.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/math/arun.hpp>
opengv::rotation_t
diff --git a/src/point_cloud/MAPointCloud.cpp b/src/point_cloud/MAPointCloud.cpp
index 81fd5dd..cdccae3 100644
--- a/src/point_cloud/MAPointCloud.cpp
+++ b/src/point_cloud/MAPointCloud.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/point_cloud/MAPointCloud.hpp>
opengv::point_cloud::MAPointCloud::MAPointCloud(
diff --git a/src/point_cloud/PointCloudAdapter.cpp b/src/point_cloud/PointCloudAdapter.cpp
index f9faaeb..28fbb7e 100644
--- a/src/point_cloud/PointCloudAdapter.cpp
+++ b/src/point_cloud/PointCloudAdapter.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/point_cloud/PointCloudAdapter.hpp>
opengv::point_cloud::PointCloudAdapter::PointCloudAdapter(
diff --git a/src/point_cloud/methods.cpp b/src/point_cloud/methods.cpp
index 5409eeb..7a26e6a 100644
--- a/src/point_cloud/methods.cpp
+++ b/src/point_cloud/methods.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/point_cloud/methods.hpp>
#include <opengv/Indices.hpp>
diff --git a/src/relative_pose/CentralRelativeAdapter.cpp b/src/relative_pose/CentralRelativeAdapter.cpp
index 38e9a62..5018bd8 100644
--- a/src/relative_pose/CentralRelativeAdapter.cpp
+++ b/src/relative_pose/CentralRelativeAdapter.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/relative_pose/CentralRelativeAdapter.hpp>
opengv::relative_pose::CentralRelativeAdapter::CentralRelativeAdapter(
diff --git a/src/relative_pose/CentralRelativeMultiAdapter.cpp b/src/relative_pose/CentralRelativeMultiAdapter.cpp
index 2ab7476..49a3a07 100644
--- a/src/relative_pose/CentralRelativeMultiAdapter.cpp
+++ b/src/relative_pose/CentralRelativeMultiAdapter.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/relative_pose/CentralRelativeMultiAdapter.hpp>
opengv::relative_pose::CentralRelativeMultiAdapter::CentralRelativeMultiAdapter(
diff --git a/src/relative_pose/CentralRelativeWeightingAdapter.cpp b/src/relative_pose/CentralRelativeWeightingAdapter.cpp
index a6ab478..7684526 100644
--- a/src/relative_pose/CentralRelativeWeightingAdapter.cpp
+++ b/src/relative_pose/CentralRelativeWeightingAdapter.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/relative_pose/CentralRelativeWeightingAdapter.hpp>
opengv::relative_pose::CentralRelativeWeightingAdapter::CentralRelativeWeightingAdapter(
diff --git a/src/relative_pose/MACentralRelative.cpp b/src/relative_pose/MACentralRelative.cpp
index ec2959f..75e76d5 100644
--- a/src/relative_pose/MACentralRelative.cpp
+++ b/src/relative_pose/MACentralRelative.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/relative_pose/MACentralRelative.hpp>
opengv::relative_pose::MACentralRelative::MACentralRelative(
diff --git a/src/relative_pose/MANoncentralRelative.cpp b/src/relative_pose/MANoncentralRelative.cpp
index cea9c14..8566aeb 100644
--- a/src/relative_pose/MANoncentralRelative.cpp
+++ b/src/relative_pose/MANoncentralRelative.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/relative_pose/MANoncentralRelative.hpp>
opengv::relative_pose::MANoncentralRelative::MANoncentralRelative(
diff --git a/src/relative_pose/MANoncentralRelativeMulti.cpp b/src/relative_pose/MANoncentralRelativeMulti.cpp
index 49f8ecf..8b62e07 100644
--- a/src/relative_pose/MANoncentralRelativeMulti.cpp
+++ b/src/relative_pose/MANoncentralRelativeMulti.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/relative_pose/MANoncentralRelativeMulti.hpp>
opengv::relative_pose::MANoncentralRelativeMulti::MANoncentralRelativeMulti(
diff --git a/src/relative_pose/NoncentralRelativeAdapter.cpp b/src/relative_pose/NoncentralRelativeAdapter.cpp
index 552f180..775d520 100644
--- a/src/relative_pose/NoncentralRelativeAdapter.cpp
+++ b/src/relative_pose/NoncentralRelativeAdapter.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/relative_pose/NoncentralRelativeAdapter.hpp>
opengv::relative_pose::NoncentralRelativeAdapter::NoncentralRelativeAdapter(
diff --git a/src/relative_pose/NoncentralRelativeMultiAdapter.cpp b/src/relative_pose/NoncentralRelativeMultiAdapter.cpp
index f41edbe..733023c 100644
--- a/src/relative_pose/NoncentralRelativeMultiAdapter.cpp
+++ b/src/relative_pose/NoncentralRelativeMultiAdapter.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/relative_pose/NoncentralRelativeMultiAdapter.hpp>
opengv::relative_pose::NoncentralRelativeMultiAdapter::NoncentralRelativeMultiAdapter(
diff --git a/src/relative_pose/methods.cpp b/src/relative_pose/methods.cpp
index 0027dae..7678567 100644
--- a/src/relative_pose/methods.cpp
+++ b/src/relative_pose/methods.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/relative_pose/methods.hpp>
#include <opengv/Indices.hpp>
diff --git a/src/relative_pose/modules/fivept_nister/modules.cpp b/src/relative_pose/modules/fivept_nister/modules.cpp
index 4b134c5..258d416 100644
--- a/src/relative_pose/modules/fivept_nister/modules.cpp
+++ b/src/relative_pose/modules/fivept_nister/modules.cpp
@@ -29,6 +29,7 @@
******************************************************************************/
+#include <cassert>
#include <opengv/relative_pose/modules/fivept_nister/modules.hpp>
#include <Eigen/NonLinearOptimization>
#include <Eigen/NumericalDiff>
@@ -0,0 +1,29 @@
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 261f2cda..644e068f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -92,17 +92,20 @@ if(OB_IS_MAIN_PROJECT)
)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/generated/Export.h" DESTINATION include/libobsensor/h)
- install(EXPORT ${OB_SDK_LIB_NAME}Config NAMESPACE ob:: DESTINATION lib)
+ install(EXPORT ${OB_SDK_LIB_NAME}Config NAMESPACE ob:: DESTINATION lib/cmake/${OB_SDK_LIB_NAME})
include(CMakePackageConfigHelpers)
+ # Name the version file <pkg>ConfigVersion.cmake (not <pkg>Version.cmake) and
+ # install it next to the config in lib/cmake/<pkg>, so find_package(OrbbecSDK)
+ # discovers it in config mode and reads its version.
write_basic_package_version_file(
- "${CMAKE_CURRENT_BINARY_DIR}/${OB_SDK_LIB_NAME}Version.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/${OB_SDK_LIB_NAME}ConfigVersion.cmake"
VERSION "${PROJECT_VERSION}"
COMPATIBILITY SameMajorVersion
)
install(
- FILES "${CMAKE_CURRENT_BINARY_DIR}/${OB_SDK_LIB_NAME}Version.cmake"
- DESTINATION lib
+ FILES "${CMAKE_CURRENT_BINARY_DIR}/${OB_SDK_LIB_NAME}ConfigVersion.cmake"
+ DESTINATION lib/cmake/${OB_SDK_LIB_NAME}
)
if(MSVC)
install(FILES $<TARGET_PDB_FILE:${OB_SDK_LIB_NAME}> DESTINATION bin OPTIONAL)
@@ -0,0 +1,70 @@
name: 'Install Windows Dependencies with CUDA'
description: 'Installs PCL, Qt, VTK, g2o and others'
runs:
using: "composite"
steps:
- name: Set up MSVC Developer Command Prompt
uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
- name: Install CUDA
uses: Jimver/[email protected]
id: cuda-toolkit
with:
cuda: '13.0.0'
use-github-cache: True
- name: Verify CUDA
shell: bash
run: |
nvcc --version
echo "CUDA Path: $CUDA_PATH"
- name: Cache vcpkg
id: cache-vcpkg
uses: actions/cache@v4
with:
path: ${{ runner.workspace }}/vcpkg_installed
key: ${{ runner.os }}-vcpkg-export-66c0373d-x64-vs2022-cuda130_v4
- name: Download and Install vcpkg
if: steps.cache-vcpkg.outputs.cache-hit != 'true'
shell: pwsh
run: |
$install_dir = "${{ runner.workspace }}\vcpkg_installed"
$archivePath = "${{ runner.workspace }}\vcpkg-export.7z"
# The 7z is built locally with bundle_windows_deps_cuda.bat and uploaded to a
# GitHub release. Resolve it by filename via the API (authenticated with the
# built-in token) so it works even from a *draft* release and regardless of
# the (changing) asset id. Requires the workflow to run in-repo (github.token
# can't read introlab drafts from a fork PR).
$repo = "introlab/rtabmap"
$releaseTag = "0.23.8"
$assetName = "vcpkg-export-66c0373d-x64-vs2022-cuda130.7z"
$apiHeaders = @{ Authorization = "Bearer ${{ github.token }}"; "User-Agent" = "rtabmap-ci"; Accept = "application/vnd.github+json" }
# Select the release by tag_name (populated on drafts too, and unique), then
# take the asset from THAT release so concurrent releases can't be confused.
$rel = (Invoke-RestMethod -Uri "https://api.github.com/repos/$repo/releases?per_page=100" -Headers $apiHeaders) |
Where-Object { $_.tag_name -eq $releaseTag } | Select-Object -First 1
if (-not $rel) { throw "Release tagged $releaseTag not found (including drafts)" }
$asset = $rel.assets | Where-Object { $_.name -eq $assetName } | Select-Object -First 1
if (-not $asset) { throw "Asset $assetName not found in release $releaseTag" }
Write-Host "Downloading $assetName (asset id $($asset.id)) ..."
$dlHeaders = @{ Authorization = "Bearer ${{ github.token }}"; "User-Agent" = "rtabmap-ci"; Accept = "application/octet-stream" }
Invoke-WebRequest -Uri $asset.url -Headers $dlHeaders -OutFile $archivePath
& 7z x $archivePath "-o$install_dir" -y
- name: Add vcpkg to PATH and env variable
shell: pwsh
run: |
$vcpkg_path = "${{ runner.workspace }}\vcpkg_installed"
echo "VCPKG_EXPORT_PATH=$vcpkg_path" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
echo "$vcpkg_path\installed\x64-windows-release\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
# K4A runtime DLLs (k4a.dll, k4arecord.dll) live in the SDK bin; needed on PATH so fixup_bundle resolves them at package time.
echo "$vcpkg_path\installed\x64-windows-release\sdk\windows-desktop\amd64\release\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
echo "${{env.CUDA_PATH}}\bin\x64" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
echo "${{env.CUDA_PATH}}\extras\CUPTI\lib64" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
echo "$vcpkg_path\installed\x64-windows-release\tools\python3\Lib\site-packages\torch\lib" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
echo "$vcpkg_path\installed\x64-windows-release\tools\python3\Lib\site-packages\numpy.libs" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
@@ -0,0 +1,54 @@
name: 'Install Windows Dependencies'
description: 'Installs PCL, Qt, VTK, g2o and others'
runs:
using: "composite"
steps:
- name: Set up MSVC Developer Command Prompt
uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
- name: Cache vcpkg
id: cache-vcpkg
uses: actions/cache@v4
with:
path: ${{ runner.workspace }}/vcpkg_installed
key: ${{ runner.os }}-vcpkg-export-66c0373d-x64-vs2022-v6
- name: Download and Install vcpkg
if: steps.cache-vcpkg.outputs.cache-hit != 'true'
shell: pwsh
run: |
$install_dir = "${{ runner.workspace }}\vcpkg_installed"
$archivePath = "${{ runner.workspace }}\vcpkg-export.7z"
# The 7z is built locally with bundle_windows_deps.bat and uploaded to a
# GitHub release. Resolve it by filename via the API (authenticated with the
# built-in token) so it works even from a *draft* release and regardless of
# the (changing) asset id. Requires the workflow to run in-repo (github.token
# can't read introlab drafts from a fork PR).
$repo = "introlab/rtabmap"
$releaseTag = "0.23.8"
$assetName = "vcpkg-export-66c0373d-x64-vs2022.7z"
$apiHeaders = @{ Authorization = "Bearer ${{ github.token }}"; "User-Agent" = "rtabmap-ci"; Accept = "application/vnd.github+json" }
# Select the release by tag_name (populated on drafts too, and unique), then
# take the asset from THAT release so concurrent releases can't be confused.
$rel = (Invoke-RestMethod -Uri "https://api.github.com/repos/$repo/releases?per_page=100" -Headers $apiHeaders) |
Where-Object { $_.tag_name -eq $releaseTag } | Select-Object -First 1
if (-not $rel) { throw "Release tagged $releaseTag not found (including drafts)" }
$asset = $rel.assets | Where-Object { $_.name -eq $assetName } | Select-Object -First 1
if (-not $asset) { throw "Asset $assetName not found in release $releaseTag" }
Write-Host "Downloading $assetName (asset id $($asset.id)) ..."
$dlHeaders = @{ Authorization = "Bearer ${{ github.token }}"; "User-Agent" = "rtabmap-ci"; Accept = "application/octet-stream" }
Invoke-WebRequest -Uri $asset.url -Headers $dlHeaders -OutFile $archivePath
& 7z x $archivePath "-o$install_dir" -y
- name: Add vcpkg to PATH and env variable
shell: pwsh
run: |
$vcpkg_path = "${{ runner.workspace }}\vcpkg_installed"
echo "VCPKG_EXPORT_PATH=$vcpkg_path" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
echo "$vcpkg_path\installed\x64-windows-release\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
# K4A runtime DLLs (k4a.dll, k4arecord.dll) live in the SDK bin; needed on PATH so fixup_bundle resolves them at package time.
echo "$vcpkg_path\installed\x64-windows-release\sdk\windows-desktop\amd64\release\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
echo "$vcpkg_path\installed\x64-windows-release\tools\python3\Lib\site-packages\numpy.libs" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
@@ -0,0 +1,15 @@
name: Cleanup PR Artifacts
on:
pull_request:
types: [closed]
jobs:
delete-artifacts:
runs-on: ubuntu-latest
permissions:
actions: write
steps:
- name: Delete PR Artifacts
uses: geekyeggo/delete-artifact@v5
with:
name: build-output-*
+80
View File
@@ -0,0 +1,80 @@
name: CMake-Linux
on:
push:
branches:
- master
pull_request:
branches:
- '**'
env:
BUILD_TYPE: Release
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
build:
name: ${{ matrix.build_name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
build_name: [ubuntu-22.04, ubuntu-24.04, ubuntu-24.04-with-opengv, ubuntu-26.04]
include:
- build_name: ubuntu-22.04
os: ubuntu-22.04
extra_deps: "libunwind-dev libceres-dev"
extra_cmake_def: "-DWITH_CERES=ON -DWITH_PYTHON=ON"
- build_name: ubuntu-24.04
os: ubuntu-24.04
extra_deps: "libg2o-dev libceres-dev"
extra_cmake_def: "-DWITH_CERES=ON -DWITH_PYTHON=ON"
- build_name: ubuntu-24.04-with-opengv
os: ubuntu-24.04
extra_deps: "libg2o-dev libceres-dev"
extra_cmake_def: "-DWITH_CERES=ON -DWITH_PYTHON=ON -DBUILD_OPENGV=ON"
- build_name: ubuntu-26.04
os: ubuntu-26.04
extra_deps: "libg2o-dev libceres-dev"
extra_cmake_def: "-DWITH_CERES=ON -DWITH_PYTHON=ON -DBUILD_OPENGV=ON"
steps:
- uses: actions/checkout@v4
- name: Install Linux Dependencies
run: |
DEBIAN_FRONTEND=noninteractive
sudo apt-get update
sudo apt-get -y install libopencv-dev libpcl-dev git cmake software-properties-common libyaml-cpp-dev ${{ matrix.extra_deps }}
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install Python Dependencies
run: |
python -m pip install --upgrade pip
pip install numpy pybind11
- name: Configure CMake
run: |
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DPython3_EXECUTABLE=$(which python3) -Dpybind11_DIR=$(python3 -m pybind11 --cmakedir) ${{ matrix.extra_cmake_def }}
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Info
working-directory: ${{github.workspace}}/build/bin
run: |
./rtabmap-console --version
# - name: Test
# working-directory: ${{github.workspace}}/build
# # Execute tests defined by the CMake configuration.
# # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
# run: ctest -C ${{env.BUILD_TYPE}}
+96
View File
@@ -0,0 +1,96 @@
name: CMake-MacOS
on:
push:
branches:
- master
pull_request:
branches:
- '**'
env:
BUILD_TYPE: Release
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
build:
name: ${{ matrix.build_name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
build_name: [macos-sequoia-intel, macos-sequoia-apple-silicon, macos-tahoe-intel, macos-tahoe-apple-silicon]
include:
- build_name: macos-sequoia-intel
os: macos-15-intel
- build_name: macos-sequoia-apple-silicon
os: macos-15
- build_name: macos-tahoe-intel
os: macos-26-intel
- build_name: macos-tahoe-apple-silicon
os: macos-26
steps:
- uses: actions/checkout@v4
- name: Install Brew Dependencies
run: |
# Update brew and install from Brewfile if present, or specific packages
brew install pcl opencv octomap pdal yaml-cpp librealsense libfreenect libusb zlib libomp suite-sparse ceres-solver
- name: Install Source Dependencies
# Build (and per-dependency cache) the source-only deps not available from
# Homebrew, then install them into /usr/local. See the composite action.
uses: ./.github/actions/install-macos-source-deps
with:
os: ${{ matrix.os }}
build_type: ${{ env.BUILD_TYPE }}
- name: Configure CMake
run: |
# Apple clang has no built-in OpenMP; point find_package(OpenMP) at
# Homebrew's keg-only libomp so PCL/g2o/rtabmap enable OpenMP instead of
# repeatedly logging "Could NOT find OpenMP".
LIBOMP=$(brew --prefix libomp)
cmake -B ${{github.workspace}}/build \
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \
-DBUILD_AS_BUNDLE=ON \
-DWITH_ORBBEC_SDK=ON \
-DWITH_DEPTHAI=ON \
-DWITH_CERES=ON \
-DOpenMP_C_FLAGS="-Xclang -fopenmp -I$LIBOMP/include" \
-DOpenMP_C_LIB_NAMES=omp \
-DOpenMP_CXX_FLAGS="-Xclang -fopenmp -I$LIBOMP/include" \
-DOpenMP_CXX_LIB_NAMES=omp \
-DOpenMP_omp_LIBRARY="$LIBOMP/lib/libomp.dylib"
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Info
working-directory: ${{github.workspace}}/build/bin
run: |
./rtabmap-console --version
- name: Build MacOS Package
run: |
cmake --build ${{ github.workspace }}/build --config ${{ env.BUILD_TYPE }} --target package
- name: Upload RTABMap Artifacts (DMG)
uses: actions/upload-artifact@v4
with:
name: RTABMap-Binaries-${{ matrix.build_name }}-nonsigned-zip
path: |
build/RTABMap-*.dmg
compression-level: 0
if-no-files-found: warn
retention-days: ${{ github.event_name == 'pull_request' && 1 || 90 }}
# - name: Test
# working-directory: ${{github.workspace}}/build
# # Execute tests defined by the CMake configuration.
# # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
# run: ctest -C ${{env.BUILD_TYPE}}
+28 -46
View File
@@ -9,66 +9,48 @@ on:
- '**' - '**'
env: env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release BUILD_TYPE: Release
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs: jobs:
build: build:
# The CMake configure and build commands are platform agnostic and should work equally name: ${{ matrix.ros_distribution }}
# well on Windows or Mac. You can convert this to a matrix build if you need runs-on: ubuntu-latest
# cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
name: Build on ros ${{ matrix.ros_distribution }} and ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
ros_distribution: [ humble, jazzy, kilted, rolling ] ros_distribution: [ humble, jazzy, kilted, lyrical, rolling]
include: include:
- ros_distribution: 'humble' - ros_distribution: 'humble'
os: ubuntu-22.04 skip_keys: ""
- ros_distribution: 'jazzy' - ros_distribution: 'jazzy'
os: ubuntu-24.04 skip_keys: ""
- ros_distribution: 'kilted' - ros_distribution: 'kilted'
os: ubuntu-24.04 skip_keys: ""
- ros_distribution: 'lyrical'
skip_keys: "libpointmatcher"
- ros_distribution: 'rolling' - ros_distribution: 'rolling'
os: ubuntu-24.04 skip_keys: "libpointmatcher gtsam"
use_ros2_testing: true # Rolling is using ros2-testing (nightly)
container:
image: osrf/ros:${{ matrix.ros_distribution }}-desktop-full
steps: steps:
- name: Setup ROS2 - uses: actions/checkout@v4
# https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debs.html # Newer osrf/ros images (e.g. rolling) ship "ros2-testing-apt-source", which conflicts
run: | # with the "ros2-apt-source" package that setup-ros installs. Remove it first so setup-ros
sudo apt install software-properties-common # can install its apt source cleanly (no-op on images that don't have it).
sudo add-apt-repository universe - name: Remove conflicting ros2 apt source package
sudo apt update && sudo apt install curl -y run: apt-get remove -y ros2-testing-apt-source || true
export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F "tag_name" | awk -F\" '{print $4}')
curl -L -o /tmp/ros2-apt-source.deb "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release && echo $VERSION_CODENAME)_all.deb"
sudo apt install /tmp/ros2-apt-source.deb
sudo apt update
- uses: ros-tooling/[email protected] - uses: ros-tooling/[email protected]
with: with:
required-ros-distributions: ${{ matrix.ros_distribution }} required-ros-distributions: ${{ matrix.ros_distribution }}
use-ros2-testing: ${{ matrix.use_ros2_testing || false }}
- uses: actions/checkout@v4 - uses: ros-tooling/action-ros-ci@v0.4
with:
- name: Install dependencies package-name: rtabmap
run: | target-ros2-distro: ${{ matrix.ros_distribution }}
source /opt/ros/${{ matrix.ros_distribution }}/setup.bash rosdep-skip-keys: "${{ matrix.skip_keys }}"
rosdep update
rosdep install --from-paths ${{github.workspace}} -y
- name: Configure CMake
run: |
source /opt/ros/${{ matrix.ros_distribution }}/setup.bash
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Info
working-directory: ${{github.workspace}}/build/bin
run: |
source /opt/ros/${{ matrix.ros_distribution }}/setup.bash
./rtabmap-console --version
+125
View File
@@ -0,0 +1,125 @@
name: CMake-Windows
on:
push:
branches:
- master
pull_request:
branches:
- '**'
env:
BUILD_TYPE: Release
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
build:
name: ${{ matrix.build_name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
build_name: [windows-2022, windows-2022-cuda]
include:
- build_name: windows-2022
os: windows-2022
extra_deps: ""
extra_cmake_def: '-DWITH_TORCH=OFF -DWITH_ZED=OFF'
- build_name: windows-2022-cuda
os: windows-2022
extra_deps: ""
extra_cmake_def: '-DWITH_TORCH=ON -DWITH_ZED=ON -DWITH_CUDASIFT=ON'
steps:
- uses: actions/checkout@v4
- name: Install Windows Dependencies
if: matrix.build_name == 'windows-2022'
uses: ./.github/actions/install-windows-deps
- name: Install Windows Dependencies with CUDA
if: matrix.build_name == 'windows-2022-cuda'
uses: ./.github/actions/install-windows-cuda-deps
- name: Configure CMake
run: |
# K4A, K4W2 and ZED are located via these env vars (FindK4A.cmake / FindKinectSDK2.cmake
# and the install rules), pointing at the export where the bundle staged their SDK files.
$env:K4A_ROOT_DIR = "${{env.VCPKG_EXPORT_PATH}}/installed/x64-windows-release"
$env:KINECTSDK20_DIR = "${{env.VCPKG_EXPORT_PATH}}/installed/x64-windows-release"
$env:ZED_SDK_ROOT_DIR = "${{env.VCPKG_EXPORT_PATH}}/installed/x64-windows-release"
cmake `
-B ${{github.workspace}}/build `
-DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} `
-DBUILD_AS_BUNDLE=ON `
-DWITH_PYTHON=ON `
-DWITH_CERES=ON `
-DWITH_ORBBEC_SDK=ON `
-DWITH_FREENECT2=ON `
-DWITH_K4W2=ON `
-DWITH_K4A=ON `
-DWITH_DEPTHAI=ON `
-DWITH_REALSENSE2=ON `
-DWITH_CCCORELIB=ON `
${{ matrix.extra_cmake_def }} `
-DVCPKG_MANIFEST_INSTALL=OFF `
-DVCPKG_TARGET_TRIPLET=x64-windows-release `
-DVCPKG_INSTALLED_DIR="${{env.VCPKG_EXPORT_PATH}}/installed" `
-DCMAKE_TOOLCHAIN_FILE=${{env.VCPKG_EXPORT_PATH}}/scripts/buildsystems/vcpkg.cmake `
-DTorch_DIR=${{env.VCPKG_EXPORT_PATH}}/installed/x64-windows-release/tools/python3/Lib/site-packages/torch/share/cmake/Torch
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Info
# Skipped for CUDA: the binary links ZED (sl_zed64.dll -> nvcuvid/nvEncodeAPI64),
# which need the NVIDIA driver; the GPU-less runner can't load the exe.
if: matrix.build_name != 'windows-2022-cuda'
working-directory: ${{github.workspace}}/build/bin
run: |
./rtabmap-console --version
- name: Build Windows Package
shell: pwsh
run: |
if ("${{ github.event_name }}" -eq "pull_request") {
cpack --config build/CPackConfig.cmake -G ZIP -B build
} else {
cmake --build ${{ github.workspace }}/build --config ${{ env.BUILD_TYPE }} --target package
}
- name: Rename CUDA artifacts
if: matrix.build_name == 'windows-2022-cuda'
shell: pwsh
run: Get-ChildItem -Path "build" -Filter "RTABMap-*" | Rename-Item -NewName { $_.BaseName + "_cuda" + $_.Extension }
- name: Upload RTABMap Artifacts (ZIP)
uses: actions/upload-artifact@v4
with:
name: RTABMap-Binaries-${{ matrix.build_name }}-zip
path: |
build/RTABMap-*.zip
compression-level: 0
if-no-files-found: warn
retention-days: ${{ github.event_name == 'pull_request' && 1 || 90 }}
- name: Upload RTABMap Artifacts (Installer)
if: github.event_name != 'pull_request'
uses: actions/upload-artifact@v4
with:
name: RTABMap-Binaries-${{ matrix.build_name }}-exe
path: |
build/RTABMap-*.exe
compression-level: 0
if-no-files-found: warn
retention-days: ${{ github.event_name == 'pull_request' && 1 || 90 }}
# - name: Test
# working-directory: ${{github.workspace}}/build
# # Execute tests defined by the CMake configuration.
# # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
# run: ctest -C ${{env.BUILD_TYPE}}
-56
View File
@@ -1,56 +0,0 @@
name: CMake
on:
push:
branches:
- master
pull_request:
branches:
- '**'
env:
BUILD_TYPE: Release
jobs:
build:
name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-24.04, ubuntu-22.04]
include:
- os: ubuntu-22.04
extra_deps: "libunwind-dev libceres-dev"
extra_cmake_def: ""
- os: ubuntu-24.04
extra_deps: "libg2o-dev libceres-dev"
extra_cmake_def: "-DWITH_CERES=ON"
steps:
- name: Install dependencies
run: |
DEBIAN_FRONTEND=noninteractive
sudo apt-get update
sudo apt-get -y install libopencv-dev libpcl-dev git cmake software-properties-common libyaml-cpp-dev ${{ matrix.extra_deps }}
- uses: actions/checkout@v4
- name: Configure CMake
run: |
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} ${{ matrix.extra_cmake_def }}
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Info
working-directory: ${{github.workspace}}/build/bin
run: |
./rtabmap-console --version
# - name: Test
# working-directory: ${{github.workspace}}/build
# # Execute tests defined by the CMake configuration.
# # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
# run: ctest -C ${{env.BUILD_TYPE}}
+35 -5
View File
@@ -4,6 +4,13 @@ on:
push: push:
branches: branches:
- 'master' - 'master'
pull_request:
branches:
- '**'
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs: jobs:
docker_deps: docker_deps:
@@ -15,14 +22,15 @@ jobs:
# $ sudo apt-get upgrade qemu-user-static # $ sudo apt-get upgrade qemu-user-static
# $ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes -c yes # $ docker run --rm --privileged multiarch/qemu-user-static --reset -p yes -c yes
# More info: https://github.com/introlab/rtabmap/issues/1454 # More info: https://github.com/introlab/rtabmap/issues/1454
# if: false # Skipped on pull requests; built and pushed only on push to master.
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
docker_tag: [focal-deps, jammy-deps, noble-deps, noble-kilted-deps] docker_tag: [focal-deps, jammy-deps, noble-deps, noble-kilted-deps, resolute-deps]
include: include:
- docker_tag: focal-deps - docker_tag: focal-deps
docker_tags: | docker_tags: |
@@ -52,6 +60,13 @@ jobs:
linux/amd64 linux/amd64
linux/arm64 linux/arm64
docker_path: 'noble-kilted/deps' docker_path: 'noble-kilted/deps'
- docker_tag: resolute-deps
docker_tags: |
introlab3it/rtabmap:resolute-deps
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'resolute/deps'
steps: steps:
- -
@@ -85,12 +100,14 @@ jobs:
docker: docker:
needs: docker_deps needs: docker_deps
# Run even when docker_deps is skipped (it is, on pull requests).
if: ${{ !cancelled() && !failure() }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
docker_tag: [bionic, focal, jammy, noble, noble-kilted, android23, android24, android26, android30] docker_tag: [bionic, focal, jammy, noble, noble-kilted, resolute, android23, android24, android26, android30]
include: include:
- docker_tag: bionic - docker_tag: bionic
docker_tags: | docker_tags: |
@@ -142,6 +159,16 @@ jobs:
linux/amd64 linux/amd64
linux/arm64 linux/arm64
docker_path: 'noble-kilted' docker_path: 'noble-kilted'
- docker_tag: resolute
docker_tags: |
introlab3it/rtabmap:resolute
introlab3it/rtabmap:26.04
docker_args: |
NOT_USED=0
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'resolute'
- docker_tag: android23 - docker_tag: android23
docker_tags: | docker_tags: |
introlab3it/rtabmap:android23 introlab3it/rtabmap:android23
@@ -190,6 +217,9 @@ jobs:
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- -
name: Login to DockerHub name: Login to DockerHub
# Only needed when pushing; skipped on pull requests (secrets are
# unavailable for fork PRs and we don't push there anyway).
if: github.event_name != 'pull_request'
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
@@ -199,8 +229,8 @@ jobs:
uses: docker/build-push-action@v6 uses: docker/build-push-action@v6
with: with:
context: . context: .
push: true push: ${{ github.event_name != 'pull_request' }}
platforms: ${{ matrix.docker_platforms }} platforms: ${{ github.event_name == 'pull_request' && 'linux/amd64' || matrix.docker_platforms }}
file: ./docker/${{ matrix.docker_path }}/Dockerfile file: ./docker/${{ matrix.docker_path }}/Dockerfile
build-args: | build-args: |
${{ matrix.docker_args }} ${{ matrix.docker_args }}
+114
View File
@@ -0,0 +1,114 @@
name: iOS
on:
push:
branches:
- master
paths: &ios_paths
- '.github/workflows/ios.yml'
- 'app/ios/**'
- 'app/android/jni/**'
- 'corelib/**'
- 'utilite/**'
- 'cmake_modules/**'
- 'CMakeLists.txt'
pull_request:
branches:
- '**'
paths: *ios_paths
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
env:
# Pre-built iOS dependencies (content of app/ios/RTABMapApp/Libraries, generated by install_deps.sh).
# Bump this when the dependency set changes (must match the Xcode toolchain below).
DEPS_URL: https://github.com/introlab/rtabmap/releases/download/0.23.1/libraries-ios-xcode26.5.zip
XCODE_VERSION: '26.5'
jobs:
build:
name: build-ios
# macos-26 (Tahoe) ships Xcode 26.x, matching the toolchain used to build the prebuilt libraries.
runs-on: macos-26
steps:
- uses: actions/checkout@v4
- name: Select Xcode ${{ env.XCODE_VERSION }}
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: ${{ env.XCODE_VERSION }}
- name: Versions
run: |
xcodebuild -version
cmake --version || brew install cmake
- name: Cache prebuilt dependencies archive
id: deps-cache
uses: actions/cache@v4
with:
path: deps.zip
# Keyed on the archive URL (release tag + filename), so the cache is
# reused until DEPS_URL is bumped, regardless of other workflow edits.
key: ${{ runner.os }}-ios-deps-${{ env.DEPS_URL }}
- name: Download prebuilt dependencies
if: steps.deps-cache.outputs.cache-hit != 'true'
run: curl -L "$DEPS_URL" -o deps.zip
- name: Extract dependencies into Libraries
run: |
set -eux
mkdir -p app/ios/RTABMapApp/Libraries
rm -rf deps_extract && mkdir -p deps_extract
unzip -q deps.zip -d deps_extract
# The archive holds the *content* of the Libraries folder (include/ lib/ share/),
# but tolerate an extra top-level Libraries/ wrapper just in case.
if [ -d deps_extract/Libraries ]; then
SRC=deps_extract/Libraries
else
SRC=deps_extract
fi
cp -R "$SRC"/. app/ios/RTABMapApp/Libraries/
test -d app/ios/RTABMapApp/Libraries/include
test -d app/ios/RTABMapApp/Libraries/lib
- name: Build rtabmap core (third-party deps are skipped, already provided by the archive)
working-directory: app/ios/RTABMapApp
run: ./install_deps.sh
- name: Build RTABMapApp
run: |
xcodebuild \
-project app/ios/RTABMapApp.xcodeproj \
-scheme RTABMapApp \
-configuration Release \
-sdk iphoneos \
-destination 'generic/platform=iOS' \
-derivedDataPath build \
CODE_SIGNING_ALLOWED=NO \
CODE_SIGNING_REQUIRED=NO \
CODE_SIGN_IDENTITY="" \
DEVELOPMENT_TEAM="" \
build
- name: Package app (unsigned .ipa)
run: |
set -eux
APP_DIR="build/Build/Products/Release-iphoneos"
rm -rf Payload && mkdir Payload
cp -R "$APP_DIR/RTABMapApp.app" Payload/
# Unsigned .ipa: not installable as-is, but ready for later (re)signing.
zip -q -r RTABMapApp-unsigned.ipa Payload
- name: Upload app artifact
uses: actions/upload-artifact@v4
with:
name: RTABMapApp-ios-unsigned
path: RTABMapApp-unsigned.ipa
compression-level: 0
if-no-files-found: error
retention-days: ${{ github.event_name == 'pull_request' && 1 || 90 }}
+6
View File
@@ -12,3 +12,9 @@ compile_flags.txt
tags tags
build_* build_*
*.bak *.bak
# Windows bundle: vcpkg tree, build output, and deps built from source (bundle_windows_deps.bat)
vcpkg/
vcpkg_installed/
vcpkg_binaries/
vcpkg_deps_from_source/
+282 -108
View File
@@ -1,5 +1,6 @@
# Top-Level CmakeLists.txt # Top-Level CmakeLists.txt
cmake_minimum_required(VERSION 3.14) cmake_minimum_required(VERSION 3.14)
PROJECT( RTABMap ) PROJECT( RTABMap )
SET(PROJECT_PREFIX rtabmap) SET(PROJECT_PREFIX rtabmap)
@@ -11,6 +12,7 @@ IF(NOT MULTI_ARCH AND NOT DEFINED CMAKE_INSTALL_LIBDIR)
ENDIF(NOT MULTI_ARCH AND NOT DEFINED CMAKE_INSTALL_LIBDIR) ENDIF(NOT MULTI_ARCH AND NOT DEFINED CMAKE_INSTALL_LIBDIR)
INCLUDE(GNUInstallDirs) INCLUDE(GNUInstallDirs)
INCLUDE(FetchContent)
####### local cmake modules ####### ####### local cmake modules #######
SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules") SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
@@ -19,11 +21,19 @@ SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
# VERSION # VERSION
####################### #######################
SET(RTABMAP_MAJOR_VERSION 0) SET(RTABMAP_MAJOR_VERSION 0)
SET(RTABMAP_MINOR_VERSION 22) SET(RTABMAP_MINOR_VERSION 24)
SET(RTABMAP_PATCH_VERSION 1) SET(RTABMAP_PATCH_VERSION 0)
SET(RTABMAP_VERSION SET(RTABMAP_VERSION
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION}) ${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})
# Make sure we have valid version so that RTABMAP_VERSION_COMPARE logic in Version.h works
IF(RTABMAP_MINOR_VERSION GREATER 99)
MESSAGE(FATAL_ERROR "RTABMAP_MINOR_VERSION must be < 100, bump major version and restart minor to 0!")
ENDIF()
IF(RTABMAP_PATCH_VERSION GREATER 99)
MESSAGE(FATAL_ERROR "RTABMAP_PATCH_VERSION must be < 100, bump minor version and restart patch to 0!")
ENDIF()
SET(PROJECT_VERSION "${RTABMAP_VERSION}") SET(PROJECT_VERSION "${RTABMAP_VERSION}")
SET(PROJECT_VERSION_MAJOR ${RTABMAP_MAJOR_VERSION}) SET(PROJECT_VERSION_MAJOR ${RTABMAP_MAJOR_VERSION})
@@ -83,14 +93,6 @@ IF(MINGW)
SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--enable-auto-import") SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--enable-auto-import")
ENDIF(MINGW) ENDIF(MINGW)
# GCC 4 required
IF(UNIX OR MINGW)
EXEC_PROGRAM( gcc ARGS "-dumpversion" OUTPUT_VARIABLE GCC_VERSION )
IF(GCC_VERSION VERSION_LESS "4.0.0")
MESSAGE(FATAL_ERROR "GCC ${GCC_VERSION} found, but version 4.x.x minimum is required")
ENDIF(GCC_VERSION VERSION_LESS "4.0.0")
ENDIF(UNIX OR MINGW)
#The CDT Error Parser cannot handle error messages that span #The CDT Error Parser cannot handle error messages that span
#more than one line, which is the default gcc behavior. #more than one line, which is the default gcc behavior.
#In order to force gcc to generate single line error messages with no line wrapping #In order to force gcc to generate single line error messages with no line wrapping
@@ -198,15 +200,17 @@ option(WITH_CCCORELIB "Include CCCoreLib support" OFF)
option(WITH_OPEN3D "Include Open3D support" OFF) option(WITH_OPEN3D "Include Open3D support" OFF)
option(WITH_LOAM "Include LOAM support" OFF) option(WITH_LOAM "Include LOAM support" OFF)
option(WITH_FLOAM "Include FLOAM support" OFF) option(WITH_FLOAM "Include FLOAM support" OFF)
option(WITH_LIOSAM "Include LIO-SAM support" OFF)
option(WITH_FLYCAPTURE2 "Include FlyCapture2/Triclops support" ON) option(WITH_FLYCAPTURE2 "Include FlyCapture2/Triclops support" ON)
option(WITH_ZED "Include ZED sdk support" ON) option(WITH_ZED "Include ZED sdk support" ON)
option(WITH_ZEDOC "Include ZED Open Capture support" ON) option(WITH_ZEDOC "Include ZED Open Capture support" ON)
option(WITH_REALSENSE "Include RealSense support" ON) option(WITH_REALSENSE "Include RealSense support" ON)
option(WITH_REALSENSE_SLAM "Include RealSenseSlam support" ON) option(WITH_REALSENSE_SLAM "Include RealSenseSlam support" ON)
option(WITH_REALSENSE2 "Include RealSense support" ON) option(WITH_REALSENSE2 "Include RealSense2 support" ON)
option(WITH_MYNTEYE "Include mynteye-s support" ON) option(WITH_MYNTEYE "Include mynteye-s support" ON)
option(WITH_DEPTHAI "Include depthai-core support" OFF) option(WITH_DEPTHAI "Include depthai-core v2 support" OFF)
option(WITH_XVSDK "Include XVisio SDK support" OFF) option(WITH_XVSDK "Include XVisio SDK support" OFF)
option(WITH_ORBBEC_SDK "Include Orbbec SDK v2 support" OFF)
option(WITH_OCTOMAP "Include OctoMap support" ON) option(WITH_OCTOMAP "Include OctoMap support" ON)
option(WITH_GRIDMAP "Include GridMap support" OFF) option(WITH_GRIDMAP "Include GridMap support" OFF)
option(WITH_CPUTSDF "Include CPUTSDF support" OFF) option(WITH_CPUTSDF "Include CPUTSDF support" OFF)
@@ -218,12 +222,15 @@ option(WITH_DVO "Include DVO support" OFF)
option(WITH_ORB_SLAM "Include ORB_SLAM2 or ORB_SLAM3 support" OFF) option(WITH_ORB_SLAM "Include ORB_SLAM2 or ORB_SLAM3 support" OFF)
option(WITH_OKVIS "Include OKVIS support" OFF) option(WITH_OKVIS "Include OKVIS support" OFF)
option(WITH_MSCKF_VIO "Include MSCKF_VIO support" OFF) option(WITH_MSCKF_VIO "Include MSCKF_VIO support" OFF)
option(WITH_VINS "Include VINS-Fusion support" OFF) option(WITH_VINS_FUSION "Include VINS-Fusion support" OFF)
option(WITH_OPENVINS "Include OpenVINS support" OFF) option(WITH_OPENVINS "Include OpenVINS support" OFF)
option(WITH_CUVSLAM "Include cuVSLAM support" OFF)
option(WITH_MADGWICK "Include Madgwick IMU filtering support" ON) option(WITH_MADGWICK "Include Madgwick IMU filtering support" ON)
option(WITH_FASTCV "Include FastCV support" ON) option(WITH_FASTCV "Include FastCV support" ON)
option(WITH_OPENMP "Include OpenMP support" ON) option(WITH_OPENMP "Include OpenMP support" ON)
option(WITH_OPENGV "Include OpenGV support" ON) option(WITH_OPENGV "Include OpenGV support" ON)
option(BUILD_OPENGV "Build OpenGV internally instead of using the system one" OFF)
option(WITH_APRILTAG "Include AprilTag support" OFF)
IF(MOBILE_BUILD) IF(MOBILE_BUILD)
option(PCL_OMP "With PCL OMP implementations" OFF) option(PCL_OMP "With PCL OMP implementations" OFF)
ELSE() ELSE()
@@ -396,7 +403,7 @@ IF(NOT VTK_FOUND)
ENDIF(NOT VTK_FOUND) ENDIF(NOT VTK_FOUND)
IF(WITH_TORCH) IF(WITH_TORCH)
FIND_PACKAGE(Torch QUIET) FIND_PACKAGE(Torch)
IF(TORCH_FOUND) IF(TORCH_FOUND)
MESSAGE(STATUS "Found Torch: ${TORCH_INCLUDE_DIRS}") MESSAGE(STATUS "Found Torch: ${TORCH_INCLUDE_DIRS}")
ENDIF(TORCH_FOUND) ENDIF(TORCH_FOUND)
@@ -418,14 +425,14 @@ IF(WITH_PDAL)
ENDIF(WITH_PDAL) ENDIF(WITH_PDAL)
IF(WITH_LIBLAS) IF(WITH_LIBLAS)
FIND_PACKAGE(libLAS QUIET) FIND_PACKAGE(libLAS)
IF(libLAS_FOUND) IF(libLAS_FOUND)
MESSAGE(STATUS "Found libLAS ${libLAS_VERSION}: ${libLAS_INCLUDE_DIRS}") MESSAGE(STATUS "Found libLAS ${libLAS_VERSION}: ${libLAS_INCLUDE_DIRS}")
ENDIF(libLAS_FOUND) ENDIF(libLAS_FOUND)
ENDIF(WITH_LIBLAS) ENDIF(WITH_LIBLAS)
IF(WITH_CUDASIFT) IF(WITH_CUDASIFT)
FIND_PACKAGE(CudaSift 3 QUIET) FIND_PACKAGE(CudaSift 3)
IF(CudaSift_FOUND) IF(CudaSift_FOUND)
MESSAGE(STATUS "Found CudaSift") MESSAGE(STATUS "Found CudaSift")
ENDIF(CudaSift_FOUND) ENDIF(CudaSift_FOUND)
@@ -496,35 +503,34 @@ ENDIF(WITH_DC1394)
IF(WITH_G2O) IF(WITH_G2O)
FIND_PACKAGE(g2o NO_MODULE) FIND_PACKAGE(g2o NO_MODULE)
IF(g2o_FOUND) IF(g2o_FOUND)
MESSAGE(STATUS "Found g2o (targets)") MESSAGE(STATUS "Found g2o (targets)")
SET(G2O_FOUND ${g2o_FOUND}) SET(G2O_FOUND ${g2o_FOUND})
get_target_property(G2O_INCLUDES g2o::core INTERFACE_INCLUDE_DIRECTORIES) get_target_property(G2O_INCLUDES g2o::core INTERFACE_INCLUDE_DIRECTORIES)
MESSAGE(STATUS "g2o include dir: ${G2O_INCLUDES}") MESSAGE(STATUS "g2o include dir: ${G2O_INCLUDES}")
FIND_FILE(G2O_FACTORY_FILE g2o/core/factory.h FIND_FILE(G2O_FACTORY_FILE g2o/core/factory.h
PATHS ${G2O_INCLUDES} PATHS ${G2O_INCLUDES}
NO_DEFAULT_PATH) NO_DEFAULT_PATH)
FILE(READ ${G2O_FACTORY_FILE} TMPTXT) FILE(READ ${G2O_FACTORY_FILE} TMPTXT)
STRING(FIND "${TMPTXT}" "shared_ptr" matchres) STRING(FIND "${TMPTXT}" "shared_ptr" matchres)
IF(${matchres} EQUAL -1) IF(${matchres} EQUAL -1)
MESSAGE(STATUS "Old g2o factory version detected without shared ptr (factory file: ${G2O_FACTORY_FILE}).") MESSAGE(STATUS "Old g2o factory version detected without shared ptr (factory file: ${G2O_FACTORY_FILE}).")
SET(G2O_CPP11 2) SET(G2O_CPP11 2)
ELSE() ELSE()
MESSAGE(STATUS "Latest g2o factory version detected with shared ptr (factory file: ${G2O_FACTORY_FILE}).") MESSAGE(STATUS "Latest g2o factory version detected with shared ptr (factory file: ${G2O_FACTORY_FILE}).")
SET(G2O_CPP11 1) SET(G2O_CPP11 1)
ENDIF() ENDIF()
FIND_FILE(G2O_SBA_UTILS_FILE g2o/types/sba/sba_utils.h
PATHS ${G2O_INCLUDES}
NO_DEFAULT_PATH)
IF(G2O_SBA_UTILS_FILE)
SET(G2O_WITH_SBA_UTILS 1)
ELSE()
SET(G2O_WITH_SBA_UTILS 0)
ENDIF()
ELSE() ELSE()
FIND_PACKAGE(G2O QUIET) FIND_PACKAGE(G2O QUIET)
IF(G2O_FOUND) IF(G2O_FOUND)
MESSAGE(STATUS "Found g2o: ${G2O_INCLUDE_DIRS}") MESSAGE(STATUS "Found g2o: ${G2O_INCLUDE_DIRS}")
FIND_FILE(G2O_FACTORY_FILE g2o/core/factory.h
PATHS ${G2O_INCLUDES}
NO_DEFAULT_PATH)
FILE(READ ${G2O_FACTORY_FILE} TMPTXT)
STRING(FIND "${TMPTXT}" "shared_ptr" matchres)
IF(NOT ${matchres} EQUAL -1)
MESSAGE(STATUS "Latest g2o factory version detected with shared ptr (factory file: ${G2O_FACTORY_FILE}).")
SET(G2O_CPP11 1)
ENDIF()
ENDIF(G2O_FOUND) ENDIF(G2O_FOUND)
ENDIF() ENDIF()
ENDIF(WITH_G2O) ENDIF(WITH_G2O)
@@ -532,6 +538,16 @@ ENDIF(WITH_G2O)
IF(WITH_GTSAM) IF(WITH_GTSAM)
# Force config mode to ignore PCL's findGTSAM.cmake file # Force config mode to ignore PCL's findGTSAM.cmake file
FIND_PACKAGE(GTSAM CONFIG QUIET) FIND_PACKAGE(GTSAM CONFIG QUIET)
IF(GTSAM_FOUND)
# For issue https://github.com/introlab/rtabmap/pull/1626
FIND_FILE(GTSAM_NOISE_MODEL_FACTOR_N_FILE gtsam/nonlinear/NoiseModelFactorN.h
PATHS ${GTSAM_INCLUDE_DIR}
NO_DEFAULT_PATH)
IF(GTSAM_NOISE_MODEL_FACTOR_N_FILE)
MESSAGE(STATUS "GTSAM with NoiseModelFactorN.h")
ADD_DEFINITIONS("-DGTSAM_WITH_NOISE_MODEL_FACTOR_N")
ENDIF(GTSAM_NOISE_MODEL_FACTOR_N_FILE)
ENDIF(GTSAM_FOUND)
ENDIF(WITH_GTSAM) ENDIF(WITH_GTSAM)
IF(WITH_MRPT) IF(WITH_MRPT)
@@ -550,7 +566,7 @@ IF(WITH_FLYCAPTURE2)
ENDIF(WITH_FLYCAPTURE2) ENDIF(WITH_FLYCAPTURE2)
IF(WITH_CVSBA) IF(WITH_CVSBA)
FIND_PACKAGE(cvsba QUIET) FIND_PACKAGE(cvsba)
IF(cvsba_FOUND) IF(cvsba_FOUND)
MESSAGE(STATUS "Found cvsba: ${cvsba_INCLUDE_DIRS}") MESSAGE(STATUS "Found cvsba: ${cvsba_INCLUDE_DIRS}")
ENDIF(cvsba_FOUND) ENDIF(cvsba_FOUND)
@@ -576,10 +592,14 @@ IF(WITH_POINTMATCHER)
ENDIF(WITH_POINTMATCHER) ENDIF(WITH_POINTMATCHER)
IF(libpointmatcher_FOUND OR GTSAM_FOUND) IF(libpointmatcher_FOUND OR GTSAM_FOUND)
find_package(Boost COMPONENTS thread filesystem system program_options date_time REQUIRED) find_package(Boost COMPONENTS thread filesystem program_options date_time REQUIRED)
IF(Boost_MINOR_VERSION GREATER 47) IF(Boost_MINOR_VERSION GREATER 80)
find_package(Boost COMPONENTS thread filesystem program_options date_time chrono timer serialization REQUIRED)
ELSEIF(Boost_MINOR_VERSION GREATER 47)
find_package(Boost COMPONENTS thread filesystem system program_options date_time chrono timer serialization REQUIRED) find_package(Boost COMPONENTS thread filesystem system program_options date_time chrono timer serialization REQUIRED)
ENDIF(Boost_MINOR_VERSION GREATER 47) ELSE()
find_package(Boost COMPONENTS thread filesystem system program_options date_time REQUIRED)
ENDIF()
IF(WIN32) IF(WIN32)
MESSAGE(STATUS "Boost_LIBRARY_DIRS=${Boost_LIBRARY_DIRS}") MESSAGE(STATUS "Boost_LIBRARY_DIRS=${Boost_LIBRARY_DIRS}")
link_directories(${Boost_LIBRARY_DIRS}) link_directories(${Boost_LIBRARY_DIRS})
@@ -587,7 +607,7 @@ IF(libpointmatcher_FOUND OR GTSAM_FOUND)
ENDIF(libpointmatcher_FOUND OR GTSAM_FOUND) ENDIF(libpointmatcher_FOUND OR GTSAM_FOUND)
IF(WITH_CCCORELIB) IF(WITH_CCCORELIB)
find_package(CCCoreLib QUIET) find_package(CCCoreLib)
IF(CCCoreLib_FOUND) IF(CCCoreLib_FOUND)
MESSAGE(STATUS "Found CCCoreLib: ${CCCoreLib_INCLUDE_DIRS}") MESSAGE(STATUS "Found CCCoreLib: ${CCCoreLib_INCLUDE_DIRS}")
ENDIF(CCCoreLib_FOUND) ENDIF(CCCoreLib_FOUND)
@@ -599,7 +619,7 @@ IF(WITH_OPEN3D)
ELSE() ELSE()
# Build Open3D like this to avoid linker errors in rtabmap: # Build Open3D like this to avoid linker errors in rtabmap:
# cmake -DBUILD_SHARED_LIBS=ON -DGLIBCXX_USE_CXX11_ABI=ON -DCMAKE_BUILD_TYPE=Release .. # cmake -DBUILD_SHARED_LIBS=ON -DGLIBCXX_USE_CXX11_ABI=ON -DCMAKE_BUILD_TYPE=Release ..
find_package(Open3D QUIET) find_package(Open3D)
IF(Open3D_FOUND) IF(Open3D_FOUND)
MESSAGE(STATUS "Found Open3D: ${Open3DINCLUDE_DIRS}") MESSAGE(STATUS "Found Open3D: ${Open3DINCLUDE_DIRS}")
ENDIF(Open3D_FOUND) ENDIF(Open3D_FOUND)
@@ -607,19 +627,25 @@ IF(WITH_OPEN3D)
ENDIF(WITH_OPEN3D) ENDIF(WITH_OPEN3D)
IF(WITH_LOAM) IF(WITH_LOAM)
find_package(loam_velodyne QUIET) find_package(loam_velodyne)
IF(loam_velodyne_FOUND) IF(loam_velodyne_FOUND)
MESSAGE(STATUS "Found loam_velodyne: ${loam_velodyne_INCLUDE_DIRS}") MESSAGE(STATUS "Found loam_velodyne: ${loam_velodyne_INCLUDE_DIRS}")
ENDIF(loam_velodyne_FOUND) ENDIF(loam_velodyne_FOUND)
ENDIF(WITH_LOAM) ENDIF(WITH_LOAM)
IF(WITH_FLOAM) IF(WITH_FLOAM)
find_package(floam QUIET) find_package(floam)
IF(floam_FOUND) IF(floam_FOUND)
MESSAGE(STATUS "Found floam: ${floam_INCLUDE_DIRS}") MESSAGE(STATUS "Found floam: ${floam_INCLUDE_DIRS}")
FIND_PACKAGE(Ceres QUIET REQUIRED) FIND_PACKAGE(Ceres REQUIRED)
ENDIF(floam_FOUND) ENDIF(floam_FOUND)
ENDIF(WITH_FLOAM) ENDIF(WITH_FLOAM)
IF(WITH_LIOSAM)
find_package(lio_sam QUIET)
IF(lio_sam_FOUND)
MESSAGE(STATUS "Found lio_sam: ${lio_sam_INCLUDE_DIRS}")
ENDIF(lio_sam_FOUND)
ENDIF(WITH_LIOSAM)
SET(ZED_FOUND FALSE) SET(ZED_FOUND FALSE)
IF(WITH_ZED) IF(WITH_ZED)
@@ -632,7 +658,8 @@ IF(WITH_ZED)
IF(CUDA_FOUND) IF(CUDA_FOUND)
MESSAGE(STATUS "Found CUDA: ${CUDA_INCLUDE_DIRS}") MESSAGE(STATUS "Found CUDA: ${CUDA_INCLUDE_DIRS}")
ELSE() ELSE()
MESSAGE(FATAL_ERROR "CUDA is required to build with Zed sdk! Set -DWITH_ZED=OFF if you don't have CUDA.") MESSAGE(WARNING "CUDA is required to build with Zed sdk! Set -DWITH_ZED=OFF if you don't have CUDA.")
SET(ZED_FOUND FALSE)
ENDIF() ENDIF()
ENDIF(ZED_FOUND) ENDIF(ZED_FOUND)
ENDIF(WITH_ZED) ENDIF(WITH_ZED)
@@ -684,19 +711,28 @@ IF(WITH_MYNTEYE)
ENDIF(WITH_MYNTEYE) ENDIF(WITH_MYNTEYE)
IF(WITH_DEPTHAI) IF(WITH_DEPTHAI)
FIND_PACKAGE(depthai 2.24 QUIET) # Force DepthAI major version 2 (>=2.24, <3.0): the v3 API is not yet
# supported (see CameraDepthAI).
FIND_PACKAGE(depthai 2.24...<3.0)
IF(depthai_FOUND) IF(depthai_FOUND)
MESSAGE(STATUS "Found depthai-core (targets)") MESSAGE(STATUS "Found depthai-core (targets)")
ENDIF(depthai_FOUND) ENDIF(depthai_FOUND)
ENDIF(WITH_DEPTHAI) ENDIF(WITH_DEPTHAI)
IF(WITH_XVSDK) IF(WITH_XVSDK)
FIND_PACKAGE(xvsdk QUIET) FIND_PACKAGE(xvsdk)
IF(xvsdk_FOUND) IF(xvsdk_FOUND)
MESSAGE(STATUS "Found xvsdk (targets)") MESSAGE(STATUS "Found xvsdk (targets)")
ENDIF(xvsdk_FOUND) ENDIF(xvsdk_FOUND)
ENDIF(WITH_XVSDK) ENDIF(WITH_XVSDK)
IF(WITH_ORBBEC_SDK)
FIND_PACKAGE(OrbbecSDK 2)
IF(OrbbecSDK_FOUND)
MESSAGE(STATUS "Found OrbbecSDK v2 (targets)")
ENDIF(OrbbecSDK_FOUND)
ENDIF(WITH_ORBBEC_SDK)
IF(WITH_OCTOMAP) IF(WITH_OCTOMAP)
FIND_PACKAGE(octomap QUIET) FIND_PACKAGE(octomap QUIET)
IF(octomap_FOUND) IF(octomap_FOUND)
@@ -708,35 +744,35 @@ IF(WITH_OCTOMAP)
ENDIF(WITH_OCTOMAP) ENDIF(WITH_OCTOMAP)
IF(WITH_GRIDMAP) IF(WITH_GRIDMAP)
FIND_PACKAGE(grid_map_core QUIET) FIND_PACKAGE(grid_map_core)
IF(grid_map_core_FOUND) IF(grid_map_core_FOUND)
MESSAGE(STATUS "Found grid_map_core ${grid_map_core_VERSION}: ${grid_map_core_INCLUDE_DIRS}") MESSAGE(STATUS "Found grid_map_core ${grid_map_core_VERSION}: ${grid_map_core_INCLUDE_DIRS}")
ENDIF(grid_map_core_FOUND) ENDIF(grid_map_core_FOUND)
ENDIF(WITH_GRIDMAP) ENDIF(WITH_GRIDMAP)
IF(WITH_CPUTSDF) IF(WITH_CPUTSDF)
FIND_PACKAGE(CPUTSDF QUIET) FIND_PACKAGE(CPUTSDF)
IF(CPUTSDF_FOUND) IF(CPUTSDF_FOUND)
MESSAGE(STATUS "Found CPUTSDF: ${CPUTSDF_INCLUDE_DIRS}") MESSAGE(STATUS "Found CPUTSDF: ${CPUTSDF_INCLUDE_DIRS}")
ENDIF(CPUTSDF_FOUND) ENDIF(CPUTSDF_FOUND)
ENDIF(WITH_CPUTSDF) ENDIF(WITH_CPUTSDF)
IF(WITH_OPENCHISEL) IF(WITH_OPENCHISEL)
find_package(open_chisel QUIET) find_package(open_chisel)
if(open_chisel_FOUND) if(open_chisel_FOUND)
MESSAGE(STATUS "Found open_chisel: ${open_chisel_INCLUDE_DIRS}") MESSAGE(STATUS "Found open_chisel: ${open_chisel_INCLUDE_DIRS}")
endif(open_chisel_FOUND) endif(open_chisel_FOUND)
ENDIF(WITH_OPENCHISEL) ENDIF(WITH_OPENCHISEL)
IF(WITH_ALICE_VISION) IF(WITH_ALICE_VISION)
find_package(AliceVision CONFIG QUIET) find_package(AliceVision CONFIG)
IF(AliceVision_FOUND) IF(AliceVision_FOUND)
IF(${AliceVision_VERSION} VERSION_LESS_EQUAL "2.2") IF(${AliceVision_VERSION} VERSION_LESS_EQUAL "2.2")
find_package(Boost COMPONENTS log log_setup container REQUIRED) find_package(Boost COMPONENTS log log_setup container REQUIRED)
ENDIF(${AliceVision_VERSION} VERSION_LESS_EQUAL "2.2") ENDIF(${AliceVision_VERSION} VERSION_LESS_EQUAL "2.2")
SET(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};/usr/local/lib/cmake/modules") SET(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};/usr/local/lib/cmake/modules")
find_package(Geogram REQUIRED QUIET) find_package(Geogram REQUIRED)
find_package(assimp QUIET) find_package(assimp)
add_definitions("-DRTABMAP_ALICE_VISION_MAJOR=${AliceVision_VERSION_MAJOR}") add_definitions("-DRTABMAP_ALICE_VISION_MAJOR=${AliceVision_VERSION_MAJOR}")
add_definitions("-DRTABMAP_ALICE_VISION_MINOR=${AliceVision_VERSION_MINOR}") add_definitions("-DRTABMAP_ALICE_VISION_MINOR=${AliceVision_VERSION_MINOR}")
add_definitions("-DRTABMAP_ALICE_VISION_PATCH=${AliceVision_VERSION_PATCH}") add_definitions("-DRTABMAP_ALICE_VISION_PATCH=${AliceVision_VERSION_PATCH}")
@@ -744,34 +780,32 @@ IF(WITH_ALICE_VISION)
ENDIF(WITH_ALICE_VISION) ENDIF(WITH_ALICE_VISION)
IF(WITH_FOVIS) IF(WITH_FOVIS)
FIND_PACKAGE(libfovis QUIET) FIND_PACKAGE(libfovis)
IF(libfovis_FOUND) IF(libfovis_FOUND)
MESSAGE(STATUS "Found libfovis: ${libfovis_INCLUDE_DIRS}") MESSAGE(STATUS "Found libfovis: ${libfovis_INCLUDE_DIRS}")
ENDIF(libfovis_FOUND) ENDIF(libfovis_FOUND)
ENDIF(WITH_FOVIS) ENDIF(WITH_FOVIS)
IF(WITH_VISO2) IF(WITH_VISO2)
FIND_PACKAGE(libviso2 QUIET) FIND_PACKAGE(libviso2)
IF(libviso2_FOUND) IF(libviso2_FOUND)
MESSAGE(STATUS "Found libviso2: ${libviso2_INCLUDE_DIRS}") MESSAGE(STATUS "Found libviso2: ${libviso2_INCLUDE_DIRS}")
ENDIF(libviso2_FOUND) ENDIF(libviso2_FOUND)
ENDIF(WITH_VISO2) ENDIF(WITH_VISO2)
IF(WITH_DVO) IF(WITH_DVO)
FIND_PACKAGE(dvo_core QUIET) FIND_PACKAGE(dvo_core)
IF(dvo_core_FOUND) IF(dvo_core_FOUND)
MESSAGE(STATUS "Found dvo_core: ${dvo_core_INCLUDE_DIRS}") MESSAGE(STATUS "Found dvo_core: ${dvo_core_INCLUDE_DIRS}")
ENDIF(dvo_core_FOUND) ENDIF(dvo_core_FOUND)
ENDIF(WITH_DVO) ENDIF(WITH_DVO)
IF(WITH_OKVIS) IF(WITH_OKVIS)
FIND_PACKAGE(okvis 1.1 QUIET) FIND_PACKAGE(okvis 1.1)
IF(okvis_FOUND) IF(okvis_FOUND)
MESSAGE(STATUS "Found okvis: ${OKVIS_INCLUDE_DIRS}") MESSAGE(STATUS "Found okvis: ${OKVIS_INCLUDE_DIRS}")
find_package(brisk 2 REQUIRED) find_package(brisk 2 REQUIRED)
MESSAGE(STATUS "Found brisk: ${BRISK_INCLUDE_DIRS}") MESSAGE(STATUS "Found brisk: ${BRISK_INCLUDE_DIRS}")
find_package(opengv REQUIRED)
MESSAGE(STATUS "Found opengv: ${OPENGV_INCLUDE_DIRS}")
find_package(Ceres 1.9.0 REQUIRED EXACT) # OKVIS requires this specific version find_package(Ceres 1.9.0 REQUIRED EXACT) # OKVIS requires this specific version
MESSAGE(STATUS "Found ceres ${Ceres_VERSION}: ${CERES_INCLUDE_DIRS}") MESSAGE(STATUS "Found ceres ${Ceres_VERSION}: ${CERES_INCLUDE_DIRS}")
ENDIF(okvis_FOUND) ENDIF(okvis_FOUND)
@@ -780,7 +814,7 @@ ENDIF(WITH_OKVIS)
# If built with okvis, we found already ceres above # If built with okvis, we found already ceres above
IF(WITH_CERES) IF(WITH_CERES)
IF(NOT okvis_FOUND AND NOT floam_FOUND) IF(NOT okvis_FOUND AND NOT floam_FOUND)
FIND_PACKAGE(Ceres QUIET) FIND_PACKAGE(Ceres)
MESSAGE(STATUS "Found ceres ${Ceres_VERSION}: ${CERES_INCLUDE_DIRS}") MESSAGE(STATUS "Found ceres ${Ceres_VERSION}: ${CERES_INCLUDE_DIRS}")
ENDIF(NOT okvis_FOUND AND NOT floam_FOUND) ENDIF(NOT okvis_FOUND AND NOT floam_FOUND)
ELSEIF(Ceres_FOUND) ELSEIF(Ceres_FOUND)
@@ -788,39 +822,29 @@ ELSEIF(Ceres_FOUND)
ENDIF() ENDIF()
IF(WITH_MSCKF_VIO) IF(WITH_MSCKF_VIO)
FIND_PACKAGE(msckf_vio QUIET) FIND_PACKAGE(msckf_vio)
IF(msckf_vio_FOUND) IF(msckf_vio_FOUND)
MESSAGE(STATUS "Found msckf_vio: ${msckf_vio_INCLUDE_DIRS}") MESSAGE(STATUS "Found msckf_vio: ${msckf_vio_INCLUDE_DIRS}")
ENDIF(msckf_vio_FOUND) ENDIF(msckf_vio_FOUND)
ENDIF(WITH_MSCKF_VIO) ENDIF(WITH_MSCKF_VIO)
IF(WITH_VINS) IF(WITH_VINS AND NOT WITH_VINS_FUSION)
FIND_PACKAGE(vins QUIET) message(DEPRECATION "The option WITH_VINS is deprecated and will be removed in a future version. Please use WITH_VINS_FUSION instead.")
set(WITH_VINS_FUSION ON)
ENDIF(WITH_VINS AND NOT WITH_VINS_FUSION)
IF(WITH_VINS_FUSION)
FIND_PACKAGE(vins)
IF(vins_FOUND) IF(vins_FOUND)
MESSAGE(STATUS "Found vins: ${vins_INCLUDE_DIRS}") MESSAGE(STATUS "Found vins-fusion: ${vins_INCLUDE_DIRS}")
IF(okvis_FOUND) IF(okvis_FOUND)
MESSAGE(WARNING "VINS and OKVIS will be both linked to project, make sure VINS has been built with against same Ceres version than OKVIS to avoid some crashes.") MESSAGE(WARNING "VINS-Fusion and OKVIS will be both linked to project, make sure VINS-Fusion has been built with against same Ceres version than OKVIS to avoid some crashes.")
ENDIF(okvis_FOUND) ENDIF(okvis_FOUND)
ENDIF(vins_FOUND) ENDIF(vins_FOUND)
ENDIF(WITH_VINS) ENDIF(WITH_VINS_FUSION)
IF(WITH_OPENVINS) IF(WITH_OPENVINS)
FIND_PACKAGE(ov_msckf QUIET) FIND_PACKAGE(OpenVINS)
# On ROS2, the indirect includes and libraries
# are not forwarded by ov_msckf target, append them manually
FIND_PACKAGE(ov_core QUIET)
FIND_PACKAGE(ov_init QUIET)
IF(ov_msckf_FOUND AND ov_core_FOUND AND ov_init_FOUND)
SET(ov_msckf_INCLUDE_DIRS
${ov_msckf_INCLUDE_DIRS}
${ov_core_INCLUDE_DIRS}
${ov_init_INCLUDE_DIRS})
SET(ov_msckf_LIBRARIES
${ov_msckf_LIBRARIES}
${ov_core_LIBRARIES}
${ov_init_LIBRARIES})
MESSAGE(STATUS "Found OpenVINS: ${ov_msckf_INCLUDE_DIRS}")
ENDIF()
ENDIF(WITH_OPENVINS) ENDIF(WITH_OPENVINS)
IF(WITH_FASTCV) IF(WITH_FASTCV)
@@ -830,27 +854,97 @@ IF(WITH_FASTCV)
ENDIF(FastCV_FOUND) ENDIF(FastCV_FOUND)
ENDIF(WITH_FASTCV) ENDIF(WITH_FASTCV)
IF(WITH_OPENGV) IF(WITH_APRILTAG)
FIND_PACKAGE(opengv QUIET) FIND_PACKAGE(apriltag QUIET)
IF(opengv_FOUND) IF(apriltag_FOUND)
MESSAGE(STATUS "Found OpenGV: ${opengv_INCLUDE_DIRS}") get_target_property(APRILTAG_LOCATION apriltag::apriltag LOCATION)
ENDIF(opengv_FOUND) get_target_property(APRILTAG_INCLUDES apriltag::apriltag INTERFACE_INCLUDE_DIRECTORIES)
ENDIF(WITH_OPENGV) FIND_FILE(apriltag_aruco_4x4_50_header NAMES tagAruco4x4_50.h PATH_SUFFIXES aruco PATHS ${APRILTAG_INCLUDES} NO_DEFAULT_PATH)
SET(WITH_APRILTAG_ARUCO NO)
IF(apriltag_aruco_4x4_50_header)
SET(WITH_APRILTAG_ARUCO YES)
ENDIF()
MESSAGE(STATUS "Found apriltag (with aruco=${WITH_APRILTAG_ARUCO}): ${APRILTAG_LOCATION} ${APRILTAG_INCLUDES}")
ENDIF(apriltag_FOUND)
ENDIF(WITH_APRILTAG)
IF(WITH_OPENGV OR okvis_FOUND)
if(NOT BUILD_OPENGV)
FIND_PACKAGE(opengv QUIET)
endif()
if(opengv_FOUND)
MESSAGE(STATUS "Found system-installed OpenGV: ${opengv_INCLUDE_DIRS}")
elseif(BUILD_OPENGV)
SET(PCL_USING_MARCHNATIVE OFF)
if(PCL_COMPILE_OPTIONS)
if("${PCL_COMPILE_OPTIONS}" MATCHES "-march=native")
set(PCL_USING_MARCHNATIVE ON)
endif()
elseif("${PCL_DEFINITIONS}" MATCHES "-march=native")
set(PCL_USING_MARCHNATIVE ON)
endif()
SET(MSG_EXTRA "without -march-native (not used by PCL)")
if(PCL_USING_MARCHNATIVE)
set(MSG_EXTRA "with -march-native (used by PCL)")
endif()
message(STATUS "Download/Build OpenGV internally (BUILD_OPENGV=ON) ${MSG_EXTRA}.")
function(add_submodule_opengv)
FetchContent_Declare(
opengv
GIT_REPOSITORY https://github.com/laurentkneip/opengv.git
GIT_TAG 91f4b19c73450833a40e463ad3648aae80b3a7f3
PATCH_COMMAND ${CMAKE_COMMAND}
-DPATCH_FILE=${CMAKE_CURRENT_LIST_DIR}/patches/opengv_91f4b19c.patch
-P ${CMAKE_CURRENT_LIST_DIR}/patches/apply_patch.cmake
)
set(BUILD_SHARED_LIBS OFF)
set(BUILD_TESTS OFF)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
# OpenGV's CMakeLists.txt declares cmake_minimum_required(VERSION 2.x),
# which CMake >= 4.0 (e.g. recent Ubuntu) rejects. Allow it to configure.
set(CMAKE_POLICY_VERSION_MINIMUM 3.5)
# Eigen should have been already added by PCL, just populate the compatible variables
IF(EIGEN_INCLUDE_DIRS)
set(EIGEN_INCLUDE_DIRS "${EIGEN_INCLUDE_DIRS}" CACHE PATH "Eigen include dirs" FORCE)
set(EIGEN_INCLUDE_DIR "${EIGEN_INCLUDE_DIRS}" CACHE PATH "Eigen include dir" FORCE)
ELSEIF(Eigen3_INCLUDE_DIRS)
set(EIGEN_INCLUDE_DIRS "${Eigen3_INCLUDE_DIRS}" CACHE PATH "Eigen include dirs" FORCE)
set(EIGEN_INCLUDE_DIR "${Eigen3_INCLUDE_DIRS}" CACHE PATH "Eigen include dir" FORCE)
ENDIF()
set(BUILD_WITH_MARCHNATIVE ${PCL_USING_MARCHNATIVE})
FetchContent_MakeAvailable(opengv)
endfunction()
add_submodule_opengv()
set(opengv_FOUND TRUE)
set(opengv_VERSION "internal")
endif()
ENDIF()
IF(WITH_ORB_SLAM AND NOT G2O_FOUND) IF(WITH_ORB_SLAM AND NOT G2O_FOUND)
FIND_PACKAGE(ORB_SLAM QUIET) FIND_PACKAGE(ORB_SLAM)
IF(ORB_SLAM_FOUND) IF(ORB_SLAM_FOUND)
MESSAGE(STATUS "Found ORB_SLAM${ORB_SLAM_VERSION}: ${ORB_SLAM_INCLUDE_DIRS}") MESSAGE(STATUS "Found ORB_SLAM${ORB_SLAM_VERSION}: ${ORB_SLAM_INCLUDE_DIRS}")
ENDIF(ORB_SLAM_FOUND) ENDIF(ORB_SLAM_FOUND)
ENDIF(WITH_ORB_SLAM AND NOT G2O_FOUND) ENDIF(WITH_ORB_SLAM AND NOT G2O_FOUND)
IF(WITH_CUVSLAM)
FIND_PACKAGE(CuVSLAM 14.0.0)
IF(CUVSLAM_FOUND)
MESSAGE(STATUS "Found cuVSLAM: ${CUVSLAM_INCLUDE_DIRS}")
ENDIF()
ENDIF(WITH_CUVSLAM)
SET(DISABLE_NEW_DTAGS_FLAG "--disable-new-dtags") SET(DISABLE_NEW_DTAGS_FLAG "--disable-new-dtags")
IF(NOT (APPLE OR WIN32) AND BUILD_WITH_RPATH_NOT_RUNPATH) IF(NOT (APPLE OR WIN32) AND BUILD_WITH_RPATH_NOT_RUNPATH)
ADD_LINK_OPTIONS(LINKER:${DISABLE_NEW_DTAGS_FLAG}) ADD_LINK_OPTIONS(LINKER:${DISABLE_NEW_DTAGS_FLAG})
ENDIF() ENDIF()
IF(NOT MSVC) IF(NOT MSVC)
IF(Qt6_FOUND OR (G2O_FOUND AND G2O_CPP11 EQUAL 1) OR TORCH_FOUND OR MRPT_FOUND) IF(Qt6_FOUND OR (G2O_FOUND AND G2O_CPP11 EQUAL 1) OR (GTSAM_FOUND AND GTSAM_VERSION VERSION_GREATER_EQUAL "4.3.0") OR TORCH_FOUND OR MRPT_FOUND)
# Qt6 requires c++17 # Qt6 requires c++17
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++17" COMPILER_SUPPORTS_CXX17) CHECK_CXX_COMPILER_FLAG("-std=c++17" COMPILER_SUPPORTS_CXX17)
@@ -938,10 +1032,14 @@ ENDIF()
IF(NOT G2O_FOUND) IF(NOT G2O_FOUND)
SET(G2O "//") SET(G2O "//")
SET(G2O_CPP_CONF "//") SET(G2O_CPP_CONF "//")
SET(G2O_WITH_SBA_UTILS "//")
ELSE() ELSE()
IF(NOT G2O_CPP11) IF(NOT G2O_CPP11)
SET(G2O_CPP_CONF "//") SET(G2O_CPP_CONF "//")
ENDIF(NOT G2O_CPP11) ENDIF(NOT G2O_CPP11)
IF(NOT G2O_WITH_SBA_UTILS)
SET(G2O_WITH_SBA_UTILS_CONF "//")
ENDIF(NOT G2O_WITH_SBA_UTILS)
ENDIF() ENDIF()
IF(NOT GTSAM_FOUND) IF(NOT GTSAM_FOUND)
SET(GTSAM "//") SET(GTSAM "//")
@@ -973,6 +1071,12 @@ ENDIF(NOT Open3D_FOUND)
IF(NOT FastCV_FOUND) IF(NOT FastCV_FOUND)
SET(FASTCV "//") SET(FASTCV "//")
ENDIF(NOT FastCV_FOUND) ENDIF(NOT FastCV_FOUND)
IF(NOT apriltag_FOUND)
SET(APRILTAG "//")
SET(APRILTAG_ARUCO "//")
ELSEIF(NOT WITH_APRILTAG_ARUCO)
SET(APRILTAG_ARUCO "//")
ENDIF()
IF(NOT opengv_FOUND OR NOT WITH_OPENGV) IF(NOT opengv_FOUND OR NOT WITH_OPENGV)
SET(OPENGV "//") SET(OPENGV "//")
ENDIF(NOT opengv_FOUND OR NOT WITH_OPENGV) ENDIF(NOT opengv_FOUND OR NOT WITH_OPENGV)
@@ -991,6 +1095,9 @@ ENDIF(NOT loam_velodyne_FOUND)
IF(NOT floam_FOUND) IF(NOT floam_FOUND)
SET(FLOAM "//") SET(FLOAM "//")
ENDIF(NOT floam_FOUND) ENDIF(NOT floam_FOUND)
IF(NOT lio_sam_FOUND)
SET(LIOSAM "//")
ENDIF(NOT lio_sam_FOUND)
IF(NOT Freenect_FOUND) IF(NOT Freenect_FOUND)
SET(FREENECT "//") SET(FREENECT "//")
ENDIF() ENDIF()
@@ -1067,6 +1174,9 @@ IF(NOT xvsdk_FOUND)
ELSE() ELSE()
SET(CONF_WITH_XVSDK 1) SET(CONF_WITH_XVSDK 1)
ENDIF() ENDIF()
IF(NOT OrbbecSDK_FOUND)
SET(ORBBEC_SDK "//")
ENDIF(NOT OrbbecSDK_FOUND)
IF(NOT octomap_FOUND) IF(NOT octomap_FOUND)
SET(OCTOMAP "//") SET(OCTOMAP "//")
SET(CONF_WITH_OCTOMAP 0) SET(CONF_WITH_OCTOMAP 0)
@@ -1101,11 +1211,14 @@ IF(NOT msckf_vio_FOUND)
SET(MSCKF_VIO "//") SET(MSCKF_VIO "//")
ENDIF() ENDIF()
IF(NOT vins_FOUND) IF(NOT vins_FOUND)
SET(VINS "//") SET(VINSFUSION "//")
ENDIF() ENDIF()
IF(NOT ov_msckf_FOUND) IF(NOT OpenVINS_FOUND)
SET(OPENVINS "//") SET(OPENVINS "//")
ENDIF() ENDIF()
IF(NOT CUVSLAM_FOUND)
SET(CUVSLAM "//")
ENDIF()
IF(NOT ORB_SLAM_FOUND) IF(NOT ORB_SLAM_FOUND)
SET(ORB_SLAM "//") SET(ORB_SLAM "//")
ENDIF() ENDIF()
@@ -1249,7 +1362,17 @@ install(FILES package.xml DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_PR
####################### #######################
IF(BUILD_AS_BUNDLE) IF(BUILD_AS_BUNDLE)
SET(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT runtime) SET(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT runtime)
IF(WIN32)
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "
ExecWait '\\\"$INSTDIR\\\\vc_redist.x64.exe\\\" /quiet /norestart'
")
ENDIF()
INCLUDE(InstallRequiredSystemLibraries) INCLUDE(InstallRequiredSystemLibraries)
set(CPACK_NSIS_COMPONENT_INSTALL OFF)
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
set(CPACK_COMPONENTS_GROUPING ALL_COMPONENTS_IN_ONE)
set(CPACK_COMPONENTS_ALL runtime)
ENDIF(BUILD_AS_BUNDLE) ENDIF(BUILD_AS_BUNDLE)
SET(CPACK_PACKAGE_NAME "${PROJECT_NAME}") SET(CPACK_PACKAGE_NAME "${PROJECT_NAME}")
@@ -1363,28 +1486,33 @@ ENDIF(PCL_COMPILE_OPTIONS)
MESSAGE(STATUS "") MESSAGE(STATUS "")
MESSAGE(STATUS "Optional dependencies ('*' affects some default parameters) :") MESSAGE(STATUS "Optional dependencies ('*' affects some default parameters) :")
IF(OpenCV_FOUND) IF(OpenCV_FOUND)
IF(OPENCV_ARUCO_FOUND)
set(ARUCO_STR "YES")
ELSE()
set(ARUCO_STR "NO")
ENDIF()
IF(OpenCV_VERSION_MAJOR EQUAL 2) IF(OpenCV_VERSION_MAJOR EQUAL 2)
IF(OPENCV_NONFREE_FOUND) IF(OPENCV_NONFREE_FOUND)
MESSAGE(STATUS " *With OpenCV 2 nonfree module (SIFT/SURF) = YES (License: Non commercial)") MESSAGE(STATUS " *With OpenCV 2 nonfree module (SIFT/SURF) = YES, aruco = ${ARUCO_STR} (License: Non commercial)")
ELSE() ELSE()
MESSAGE(STATUS " *With OpenCV 2 nonfree module (SIFT/SURF) = NO (not found, License: BSD)") MESSAGE(STATUS " *With OpenCV 2 nonfree module (SIFT/SURF) = NO, aruco = ${ARUCO_STR} (not found, License: BSD)")
ENDIF() ENDIF()
ELSE() ELSE()
IF(OPENCV_XFEATURES2D_FOUND) IF(OPENCV_XFEATURES2D_FOUND)
IF(NONFREE STREQUAL "//") IF(NONFREE STREQUAL "//")
IF((OpenCV_VERSION_MAJOR LESS 4) OR ((OpenCV_VERSION_MAJOR EQUAL 4) AND (OpenCV_VERSION_MINOR LESS 5))) IF((OpenCV_VERSION_MAJOR LESS 4) OR ((OpenCV_VERSION_MAJOR EQUAL 4) AND (OpenCV_VERSION_MINOR LESS 5)))
MESSAGE(STATUS " *With OpenCV ${OpenCV_VERSION} xfeatures2d = YES, nonfree = NO (License: BSD)") MESSAGE(STATUS " *With OpenCV ${OpenCV_VERSION} xfeatures2d = YES, nonfree = NO, aruco = ${ARUCO_STR} (License: BSD)")
ELSE() ELSE()
MESSAGE(STATUS " *With OpenCV ${OpenCV_VERSION} xfeatures2d = YES, nonfree = NO (License: Apache 2)") MESSAGE(STATUS " *With OpenCV ${OpenCV_VERSION} xfeatures2d = YES, nonfree = NO, aruco = ${ARUCO_STR} (License: Apache 2)")
ENDIF() ENDIF()
ELSE() ELSE()
MESSAGE(STATUS " *With OpenCV ${OpenCV_VERSION} xfeatures2d = YES, nonfree = YES (License: Non commercial)") MESSAGE(STATUS " *With OpenCV ${OpenCV_VERSION} xfeatures2d = YES, nonfree = YES, aruco = ${ARUCO_STR} (License: Non commercial)")
ENDIF() ENDIF()
ELSE() ELSE()
IF((OpenCV_VERSION_MAJOR LESS 4) OR ((OpenCV_VERSION_MAJOR EQUAL 4) AND (OpenCV_VERSION_MINOR LESS 5))) IF((OpenCV_VERSION_MAJOR LESS 4) OR ((OpenCV_VERSION_MAJOR EQUAL 4) AND (OpenCV_VERSION_MINOR LESS 5)))
MESSAGE(STATUS " *With OpenCV ${OpenCV_VERSION} xfeatures2d = NO, nonfree = NO (License: BSD)") MESSAGE(STATUS " *With OpenCV ${OpenCV_VERSION} xfeatures2d = NO, nonfree = NO, aruco = ${ARUCO_STR} (License: BSD)")
ELSE() ELSE()
MESSAGE(STATUS " *With OpenCV ${OpenCV_VERSION} xfeatures2d = NO, nonfree = NO (License: Apache 2)") MESSAGE(STATUS " *With OpenCV ${OpenCV_VERSION} xfeatures2d = NO, nonfree = NO, aruco = ${ARUCO_STR} (License: Apache 2)")
ENDIF() ENDIF()
ENDIF() ENDIF()
ENDIF() ENDIF()
@@ -1419,15 +1547,26 @@ MESSAGE(STATUS " With ORB OcTree = NO (WITH_ORB_OCTREE=OFF)")
ENDIF() ENDIF()
IF(TORCH_FOUND) IF(TORCH_FOUND)
MESSAGE(STATUS " With SuperPoint = YES (License: GPLv3) libtorch=${Torch_VERSION}") MESSAGE(STATUS " With SuperPoint = YES (License: GPLv3) libtorch=${Torch_VERSION}")
ELSEIF(NOT WITH_TORCH) ELSEIF(NOT WITH_TORCH)
MESSAGE(STATUS " With SuperPoint = NO (WITH_TORCH=OFF)") MESSAGE(STATUS " With SuperPoint = NO (WITH_TORCH=OFF)")
ELSE() ELSE()
MESSAGE(STATUS " With SuperPoint = NO (libtorch not found)") MESSAGE(STATUS " With SuperPoint = NO (libtorch not found)")
ENDIF() ENDIF()
IF(TORCH_FOUND AND WITH_PYTHON AND Python3_FOUND)
MESSAGE(STATUS " With Superpoint Rpautrat = YES (Liscense: MIT) libtorch=${Torch_VERSION}")
ELSEIF(NOT WITH_TORCH)
MESSAGE(STATUS " With Superpoint Rpautrat = NO (WITH_TORCH=OFF)")
ELSEIF(NOT WITH_PYTHON)
MESSAGE(STATUS " With Superpoint Rpautrat = NO (WITH_PYTHON=OFF)")
ELSE()
MESSAGE(STATUS " Wtih Superpoint Rpautrat = NO (libtorch and/or python3 not found)")
ENDIF()
IF(WITH_PYTHON AND Python3_FOUND) IF(WITH_PYTHON AND Python3_FOUND)
MESSAGE(STATUS " With Python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR} = YES (License: PSF)") MESSAGE(STATUS " With Python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR} = YES (License: PSF)")
ELSEIF(NOT WITH_PYTHON) ELSEIF(NOT WITH_PYTHON)
MESSAGE(STATUS " With Python3 = NO (WITH_PYTHON=OFF)") MESSAGE(STATUS " With Python3 = NO (WITH_PYTHON=OFF)")
ELSE() ELSE()
@@ -1448,6 +1587,14 @@ ELSE()
MESSAGE(STATUS " With FastCV = NO (FastCV not found)") MESSAGE(STATUS " With FastCV = NO (FastCV not found)")
ENDIF() ENDIF()
IF(apriltag_FOUND)
MESSAGE(STATUS " With AprilTag ${apriltag_VERSION} = YES (aruco=${WITH_APRILTAG_ARUCO}) (License: BSD 2-Clause License)")
ELSEIF(NOT WITH_APRILTAG)
MESSAGE(STATUS " With AprilTag = NO (WITH_APRILTAG=OFF)")
ELSE()
MESSAGE(STATUS " With AprilTag = NO (apriltag not found)")
ENDIF()
IF(PDAL_FOUND) IF(PDAL_FOUND)
MESSAGE(STATUS " With PDAL ${PDAL_VERSION} = YES (License: BSD)") MESSAGE(STATUS " With PDAL ${PDAL_VERSION} = YES (License: BSD)")
ELSEIF(NOT WITH_PDAL) ELSEIF(NOT WITH_PDAL)
@@ -1557,7 +1704,11 @@ MESSAGE(STATUS " With Open3D = NO (Open3D not found)")
ENDIF() ENDIF()
IF(opengv_FOUND AND WITH_OPENGV) IF(opengv_FOUND AND WITH_OPENGV)
IF(opengv_VERSION STREQUAL "internal")
MESSAGE(STATUS " With OpenGV (internal) = YES (License: BSD)")
ELSE()
MESSAGE(STATUS " With OpenGV ${opengv_VERSION} = YES (License: BSD)") MESSAGE(STATUS " With OpenGV ${opengv_VERSION} = YES (License: BSD)")
ENDIF()
ELSEIF(NOT WITH_OPENGV) ELSEIF(NOT WITH_OPENGV)
MESSAGE(STATUS " With OpenGV = NO (WITH_OPENGV=OFF)") MESSAGE(STATUS " With OpenGV = NO (WITH_OPENGV=OFF)")
ELSE() ELSE()
@@ -1576,7 +1727,7 @@ ENDIF()
IF(grid_map_core_FOUND) IF(grid_map_core_FOUND)
MESSAGE(STATUS " With GridMap ${grid_map_core_VERSION} = YES (License: BSD)") MESSAGE(STATUS " With GridMap ${grid_map_core_VERSION} = YES (License: BSD)")
ELSEIF(NOT WITH_OCTOMAP) ELSEIF(NOT WITH_GRIDMAP)
MESSAGE(STATUS " With GridMap = NO (WITH_GRIDMAP=OFF)") MESSAGE(STATUS " With GridMap = NO (WITH_GRIDMAP=OFF)")
ELSE() ELSE()
MESSAGE(STATUS " With GridMap = NO (grid_map_core not found)") MESSAGE(STATUS " With GridMap = NO (grid_map_core not found)")
@@ -1672,7 +1823,7 @@ ELSE()
MESSAGE(STATUS " With FlyCapture2/Triclops = NO (Point Grey SDK not found)") MESSAGE(STATUS " With FlyCapture2/Triclops = NO (Point Grey SDK not found)")
ENDIF() ENDIF()
IF(ZED_FOUND AND CUDA_FOUND) IF(ZED_FOUND)
MESSAGE(STATUS " With ZED = YES") MESSAGE(STATUS " With ZED = YES")
ELSEIF(NOT WITH_ZED) ELSEIF(NOT WITH_ZED)
MESSAGE(STATUS " With ZED = NO (WITH_ZED=OFF)") MESSAGE(STATUS " With ZED = NO (WITH_ZED=OFF)")
@@ -1728,7 +1879,7 @@ MESSAGE(STATUS " With DepthAI ${depthai_VERSION} = YES (License: MIT)")
ELSEIF(NOT WITH_DEPTHAI) ELSEIF(NOT WITH_DEPTHAI)
MESSAGE(STATUS " With DepthAI = NO (WITH_DEPTHAI=OFF)") MESSAGE(STATUS " With DepthAI = NO (WITH_DEPTHAI=OFF)")
ELSE() ELSE()
MESSAGE(STATUS " With DepthAI = NO (depthai-core not found)") MESSAGE(STATUS " With DepthAI = NO (depthai-core v2 not found)")
ENDIF() ENDIF()
IF(xvsdk_FOUND) IF(xvsdk_FOUND)
@@ -1739,6 +1890,14 @@ ELSE()
MESSAGE(STATUS " With XVisio SDK = NO (xvsdk not found)") MESSAGE(STATUS " With XVisio SDK = NO (xvsdk not found)")
ENDIF() ENDIF()
IF(OrbbecSDK_FOUND)
MESSAGE(STATUS " With Orbbec SDK ${OrbbecSDK_VERSION} = YES (License: MIT)")
ELSEIF(NOT WITH_ORBBEC_SDK)
MESSAGE(STATUS " With Orbbec SDK = NO (WITH_ORBBEC_SDK=OFF)")
ELSE()
MESSAGE(STATUS " With Orbbec SDK = NO (OrbbecSDK v2 not found)")
ENDIF()
MESSAGE(STATUS "") MESSAGE(STATUS "")
MESSAGE(STATUS " Odometry Approaches:") MESSAGE(STATUS " Odometry Approaches:")
IF(loam_velodyne_FOUND) IF(loam_velodyne_FOUND)
@@ -1756,6 +1915,13 @@ MESSAGE(STATUS " With floam = NO (WITH_FLOAM=OFF)")
ELSE() ELSE()
MESSAGE(STATUS " With floam = NO (floam not found)") MESSAGE(STATUS " With floam = NO (floam not found)")
ENDIF() ENDIF()
IF(lio_sam_FOUND)
MESSAGE(STATUS " With lio_sam = YES (License: BSD)")
ELSEIF(NOT WITH_LIOSAM)
MESSAGE(STATUS " With lio_sam = NO (WITH_LIOSAM=OFF)")
ELSE()
MESSAGE(STATUS " With lio_sam = NO (lio_sam not found)")
ENDIF()
IF(libfovis_FOUND) IF(libfovis_FOUND)
MESSAGE(STATUS " With libfovis = YES (License: GPLv2)") MESSAGE(STATUS " With libfovis = YES (License: GPLv2)")
@@ -1800,12 +1966,12 @@ ENDIF()
IF(vins_FOUND) IF(vins_FOUND)
MESSAGE(STATUS " With VINS-Fusion = YES (License: GPLv3)") MESSAGE(STATUS " With VINS-Fusion = YES (License: GPLv3)")
ELSEIF(NOT WITH_VINS) ELSEIF(NOT WITH_VINS)
MESSAGE(STATUS " With VINS-Fusion = NO (WITH_VINS=OFF)") MESSAGE(STATUS " With VINS-Fusion = NO (WITH_VINS_FUSION=OFF)")
ELSE() ELSE()
MESSAGE(STATUS " With VINS-Fusion = NO (VINS-Fusion not found)") MESSAGE(STATUS " With VINS-Fusion = NO (VINS-Fusion not found)")
ENDIF() ENDIF()
IF(ov_msckf_FOUND) IF(OpenVINS_FOUND)
MESSAGE(STATUS " With OpenVINS = YES (License: GPLv3)") MESSAGE(STATUS " With OpenVINS = YES (License: GPLv3)")
ELSEIF(NOT WITH_OPENVINS) ELSEIF(NOT WITH_OPENVINS)
MESSAGE(STATUS " With OpenVINS = NO (WITH_OPENVINS=OFF)") MESSAGE(STATUS " With OpenVINS = NO (WITH_OPENVINS=OFF)")
@@ -1823,6 +1989,14 @@ ELSE()
MESSAGE(STATUS " With ORB_SLAM = NO (ORB_SLAM2 and ORB_SLAM3 not found, make sure environment variable ORB_SLAM_ROOT_DIR is set)") MESSAGE(STATUS " With ORB_SLAM = NO (ORB_SLAM2 and ORB_SLAM3 not found, make sure environment variable ORB_SLAM_ROOT_DIR is set)")
ENDIF() ENDIF()
IF(CUVSLAM_FOUND)
MESSAGE(STATUS " With cuVSLAM = YES (License: NVIDIA ISAAC ROS SOFTWARE LICENSE)")
ELSEIF(NOT WITH_CUVSLAM)
MESSAGE(STATUS " With cuVSLAM = NO (WITH_CUVSLAM=OFF)")
ELSE()
MESSAGE(STATUS " With cuVSLAM = NO (cuVSLAM not found, make sure cuVSLAM is installed)")
ENDIF()
MESSAGE(STATUS "Show all options with: cmake -LA | grep WITH_") MESSAGE(STATUS "Show all options with: cmake -LA | grep WITH_")
MESSAGE(STATUS "--------------------------------------------") MESSAGE(STATUS "--------------------------------------------")
+12 -9
View File
@@ -7,7 +7,7 @@ rtabmap
[![Downloads][downloads-image]][downloads] [![Downloads][downloads-image]][downloads]
[![License][license-image]][license] [![License][license-image]][license]
[release-image]: https://img.shields.io/badge/release-0.21.4-green.svg?style=flat [release-image]: https://img.shields.io/badge/release-0.23.1-green.svg?style=flat
[releases]: https://github.com/introlab/rtabmap/releases [releases]: https://github.com/introlab/rtabmap/releases
[downloads-image]: https://img.shields.io/github/downloads/introlab/rtabmap/total?label=downloads [downloads-image]: https://img.shields.io/github/downloads/introlab/rtabmap/total?label=downloads
@@ -35,13 +35,12 @@ This project is supported by [IntRoLab - Intelligent / Interactive / Integrated
<table> <table>
<tbody> <tbody>
<tr> <tr>
<td>Linux</td> <td>
<td><a href="https://github.com/introlab/rtabmap/actions/workflows/cmake.yml"><img src="https://github.com/introlab/rtabmap/actions/workflows/cmake.yml/badge.svg" alt="Build Status"/> <br> <a href="https://github.com/introlab/rtabmap/actions/workflows/cmake-ros.yml"><img src="https://github.com/introlab/rtabmap/actions/workflows/cmake-ros.yml/badge.svg" alt="Build Status"/> <br> <a href="https://github.com/introlab/rtabmap/actions/workflows/docker.yml"><img src="https://github.com/introlab/rtabmap/actions/workflows/docker.yml/badge.svg" alt="Build Status"/> <a href="https://github.com/introlab/rtabmap/actions/workflows/cmake-linux.yml"><img src="https://github.com/introlab/rtabmap/actions/workflows/cmake-linux.yml/badge.svg" alt="CMake Linux Build Status"/> <br>
</td> <a href="https://github.com/introlab/rtabmap/actions/workflows/cmake-windows.yml"><img src="https://github.com/introlab/rtabmap/actions/workflows/cmake-windows.yml/badge.svg" alt="CMake Windows Build Status"/> <br>
</tr> <a href="https://github.com/introlab/rtabmap/actions/workflows/cmake-macos.yml"><img src="https://github.com/introlab/rtabmap/actions/workflows/cmake-macos.yml/badge.svg" alt="CMake MaCOS Build Status"/> <br>
<tr> <a href="https://github.com/introlab/rtabmap/actions/workflows/cmake-ros.yml"><img src="https://github.com/introlab/rtabmap/actions/workflows/cmake-ros.yml/badge.svg" alt="CMake ROS Build Status"/> <br>
<td>Windows</td> <a href="https://github.com/introlab/rtabmap/actions/workflows/docker.yml"><img src="https://github.com/introlab/rtabmap/actions/workflows/docker.yml/badge.svg" alt="Docker Build Status"/>
<td><a href="https://ci.appveyor.com/project/matlabbe/rtabmap/branch/master"><img src="https://ci.appveyor.com/api/projects/status/hr73xspix9oqa26h/branch/master?svg=true" alt="Build Status"/>
</td> </td>
</tr> </tr>
</tbody> </tbody>
@@ -59,7 +58,7 @@ This project is supported by [IntRoLab - Intelligent / Interactive / Integrated
<td><a href="http://build.ros.org/job/Nbin_ufv8_uFv8__rtabmap__ubuntu_focal_arm64__binary/"><img src="http://build.ros.org/buildStatus/icon?job=Nbin_ufv8_uFv8__rtabmap__ubuntu_focal_arm64__binary" alt="Build Status"/></td> <td><a href="http://build.ros.org/job/Nbin_ufv8_uFv8__rtabmap__ubuntu_focal_arm64__binary/"><img src="http://build.ros.org/buildStatus/icon?job=Nbin_ufv8_uFv8__rtabmap__ubuntu_focal_arm64__binary" alt="Build Status"/></td>
</tr> </tr>
<tr> <tr>
<td rowspan="3">ROS 2</td> <td rowspan="4">ROS 2</td>
<td>Humble</td> <td>Humble</td>
<td><a href="http://build.ros2.org/job/Hbin_uJ64__rtabmap__ubuntu_jammy_amd64__binary/"><img src="http://build.ros2.org/buildStatus/icon?job=Hbin_uJ64__rtabmap__ubuntu_jammy_amd64__binary" alt="Build Status"/></td> <td><a href="http://build.ros2.org/job/Hbin_uJ64__rtabmap__ubuntu_jammy_amd64__binary/"><img src="http://build.ros2.org/buildStatus/icon?job=Hbin_uJ64__rtabmap__ubuntu_jammy_amd64__binary" alt="Build Status"/></td>
</tr> </tr>
@@ -67,6 +66,10 @@ This project is supported by [IntRoLab - Intelligent / Interactive / Integrated
<td>Jazzy</td> <td>Jazzy</td>
<td><a href="http://build.ros2.org/job/Jbin_uN64__rtabmap__ubuntu_noble_amd64__binary/"><img src="http://build.ros2.org/buildStatus/icon?job=Jbin_uN64__rtabmap__ubuntu_noble_amd64__binary" alt="Build Status"/></td> <td><a href="http://build.ros2.org/job/Jbin_uN64__rtabmap__ubuntu_noble_amd64__binary/"><img src="http://build.ros2.org/buildStatus/icon?job=Jbin_uN64__rtabmap__ubuntu_noble_amd64__binary" alt="Build Status"/></td>
</tr> </tr>
<tr>
<td>Kilted</td>
<td><a href="http://build.ros2.org/job/Kbin_uN64__rtabmap__ubuntu_noble_amd64__binary/"><img src="http://build.ros2.org/buildStatus/icon?job=Kbin_uN64__rtabmap__ubuntu_noble_amd64__binary" alt="Build Status"/></td>
</tr>
<tr> <tr>
<td>Rolling</td> <td>Rolling</td>
<td><a href="http://build.ros2.org/job/Rbin_uJ64__rtabmap__ubuntu_jammy_amd64__binary/"><img src="http://build.ros2.org/buildStatus/icon?job=Rbin_uJ64__rtabmap__ubuntu_jammy_amd64__binary" alt="Build Status"/></td> <td><a href="http://build.ros2.org/job/Rbin_uJ64__rtabmap__ubuntu_jammy_amd64__binary/"><img src="http://build.ros2.org/buildStatus/icon?job=Rbin_uJ64__rtabmap__ubuntu_jammy_amd64__binary" alt="Build Status"/></td>
+8 -2
View File
@@ -35,12 +35,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define RTABMAP_VERSION_MINOR @PROJECT_VERSION_MINOR@ #define RTABMAP_VERSION_MINOR @PROJECT_VERSION_MINOR@
#define RTABMAP_VERSION_PATCH @PROJECT_VERSION_PATCH@ #define RTABMAP_VERSION_PATCH @PROJECT_VERSION_PATCH@
#define RTABMAP_VERSION_COMPARE(major, minor, patch) (major>=@PROJECT_VERSION_MAJOR@ || (major==@PROJECT_VERSION_MAJOR@ && minor>=@PROJECT_VERSION_MINOR@) || (major==@PROJECT_VERSION_MAJOR@ && minor==@PROJECT_VERSION_MINOR@ && patch >=@PROJECT_VERSION_PATCH@)) #define RTABMAP_VERSION_COMPARE(OP, MAJOR, MINOR, PATCH) (RTABMAP_VERSION_MAJOR*10000+RTABMAP_VERSION_MINOR*100+RTABMAP_VERSION_PATCH OP MAJOR*10000+MINOR*100+PATCH)
@NONFREE@#define RTABMAP_NONFREE @NONFREE@#define RTABMAP_NONFREE
@TORO@#define RTABMAP_TORO @TORO@#define RTABMAP_TORO
@G2O@#define RTABMAP_G2O @G2O@#define RTABMAP_G2O
@G2O_CPP_CONF@#define RTABMAP_G2O_CPP11 @G2O_CPP11@ @G2O_CPP_CONF@#define RTABMAP_G2O_CPP11 @G2O_CPP11@
@G2O_WITH_SBA_UTILS_CONF@#define RTABMAP_G2O_WITH_SBA_UTILS
@GTSAM@#define RTABMAP_GTSAM @GTSAM@#define RTABMAP_GTSAM
@CERES@#define RTABMAP_CERES @CERES@#define RTABMAP_CERES
@MRPT@#define RTABMAP_MRPT @MRPT@#define RTABMAP_MRPT
@@ -62,6 +63,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@CUDASIFT@#define RTABMAP_CUDASIFT @CUDASIFT@#define RTABMAP_CUDASIFT
@LOAM@#define RTABMAP_LOAM @LOAM@#define RTABMAP_LOAM
@FLOAM@#define RTABMAP_FLOAM @FLOAM@#define RTABMAP_FLOAM
@LIOSAM@#define RTABMAP_LIOSAM
@DC1394@#define RTABMAP_DC1394 @DC1394@#define RTABMAP_DC1394
@FLYCAPTURE2@#define RTABMAP_FLYCAPTURE2 @FLYCAPTURE2@#define RTABMAP_FLYCAPTURE2
@ZED@#define RTABMAP_ZED @ZED@#define RTABMAP_ZED
@@ -72,6 +74,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@MYNTEYE@#define RTABMAP_MYNTEYE @MYNTEYE@#define RTABMAP_MYNTEYE
@DEPTHAI@#define RTABMAP_DEPTHAI @DEPTHAI@#define RTABMAP_DEPTHAI
@XVSDK@#define RTABMAP_XVSDK @XVSDK@#define RTABMAP_XVSDK
@ORBBEC_SDK@#define RTABMAP_ORBBEC_SDK
@OCTOMAP@#define RTABMAP_OCTOMAP @OCTOMAP@#define RTABMAP_OCTOMAP
@GRIDMAP@#define RTABMAP_GRIDMAP @GRIDMAP@#define RTABMAP_GRIDMAP
@CPUTSDF@#define RTABMAP_CPUTSDF @CPUTSDF@#define RTABMAP_CPUTSDF
@@ -82,13 +85,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@DVO@#define RTABMAP_DVO @DVO@#define RTABMAP_DVO
@OKVIS@#define RTABMAP_OKVIS @OKVIS@#define RTABMAP_OKVIS
@MSCKF_VIO@#define RTABMAP_MSCKF_VIO @MSCKF_VIO@#define RTABMAP_MSCKF_VIO
@VINS@#define RTABMAP_VINS @VINSFUSION@#define RTABMAP_VINS_FUSION
@OPENVINS@#define RTABMAP_OPENVINS @OPENVINS@#define RTABMAP_OPENVINS
@CUVSLAM@#define RTABMAP_CUVSLAM
@ORB_SLAM@#define RTABMAP_ORB_SLAM @ORB_SLAM_VERSION@ @ORB_SLAM@#define RTABMAP_ORB_SLAM @ORB_SLAM_VERSION@
@ORB_OCTREE@#define RTABMAP_ORB_OCTREE @ORB_OCTREE@#define RTABMAP_ORB_OCTREE
@TORCH@#define RTABMAP_TORCH @TORCH@#define RTABMAP_TORCH
@PYTHON@#define RTABMAP_PYTHON @PYTHON@#define RTABMAP_PYTHON
@MADGWICK@#define RTABMAP_MADGWICK @MADGWICK@#define RTABMAP_MADGWICK
@APRILTAG@#define RTABMAP_APRILTAG
@APRILTAG_ARUCO@#define RTABMAP_APRILTAG_WITH_ARUCO
#include <pcl/pcl_config.h> #include <pcl/pcl_config.h>
+1 -1
View File
@@ -3000,7 +3000,7 @@ void RTABMapApp::setTrajectoryMode(bool enabled)
void RTABMapApp::setGraphOptimization(bool enabled) void RTABMapApp::setGraphOptimization(bool enabled)
{ {
graphOptimization_ = enabled; graphOptimization_ = enabled;
if((sensorCaptureThread_ == 0) && rtabmap_ && rtabmap_->getMemory()->getLastWorkingSignature()!=0) if((sensorCaptureThread_ == 0) && rtabmap_ && rtabmap_->getMemory()->getLastWorkingSignature(false)!=0)
{ {
std::map<int, rtabmap::Transform> poses; std::map<int, rtabmap::Transform> poses;
std::multimap<int, rtabmap::Link> links; std::multimap<int, rtabmap::Link> links;
+4 -4
View File
@@ -1065,7 +1065,7 @@
"$(PROJECT_DIR)/RTABMapApp/Libraries/share/OpenCV/3rdparty/lib", "$(PROJECT_DIR)/RTABMapApp/Libraries/share/OpenCV/3rdparty/lib",
"$(PROJECT_DIR)/RTABMapApp/Libraries/lib/opencv4/3rdparty", "$(PROJECT_DIR)/RTABMapApp/Libraries/lib/opencv4/3rdparty",
); );
MARKETING_VERSION = 0.22.0; MARKETING_VERSION = 0.23.7;
OTHER_CFLAGS = ""; OTHER_CFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = com.introlab.rtabmap; PRODUCT_BUNDLE_IDENTIFIER = com.introlab.rtabmap;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1078,7 +1078,7 @@
"\"$(SRCROOT)/RTABMapApp/Libraries/include\"", "\"$(SRCROOT)/RTABMapApp/Libraries/include\"",
"\"$(SRCROOT)/RTABMapApp/Libraries/include/eigen3\"", "\"$(SRCROOT)/RTABMapApp/Libraries/include/eigen3\"",
"\"$(SRCROOT)/RTABMapApp/Libraries/include/pcl-1.15\"", "\"$(SRCROOT)/RTABMapApp/Libraries/include/pcl-1.15\"",
"\"$(SRCROOT)/RTABMapApp/Libraries/include/rtabmap-0.22\"", "\"$(SRCROOT)/RTABMapApp/Libraries/include/rtabmap-latest\"",
"\"$(SRCROOT)/../android/jni/tango-gl/include\"", "\"$(SRCROOT)/../android/jni/tango-gl/include\"",
"\"$(SRCROOT)/../android/jni/third-party/include\"", "\"$(SRCROOT)/../android/jni/third-party/include\"",
"\"$(SRCROOT)/RTABMapApp/Libraries/lib/vtk.framework/Headers\"", "\"$(SRCROOT)/RTABMapApp/Libraries/lib/vtk.framework/Headers\"",
@@ -1125,7 +1125,7 @@
"$(PROJECT_DIR)/RTABMapApp/Libraries/share/OpenCV/3rdparty/lib", "$(PROJECT_DIR)/RTABMapApp/Libraries/share/OpenCV/3rdparty/lib",
"$(PROJECT_DIR)/RTABMapApp/Libraries/lib/opencv4/3rdparty", "$(PROJECT_DIR)/RTABMapApp/Libraries/lib/opencv4/3rdparty",
); );
MARKETING_VERSION = 0.22.0; MARKETING_VERSION = 0.23.7;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = ""; OTHER_CFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = com.introlab.rtabmap; PRODUCT_BUNDLE_IDENTIFIER = com.introlab.rtabmap;
@@ -1139,7 +1139,7 @@
"\"$(SRCROOT)/RTABMapApp/Libraries/include\"", "\"$(SRCROOT)/RTABMapApp/Libraries/include\"",
"\"$(SRCROOT)/RTABMapApp/Libraries/include/eigen3\"", "\"$(SRCROOT)/RTABMapApp/Libraries/include/eigen3\"",
"\"$(SRCROOT)/RTABMapApp/Libraries/include/pcl-1.15\"", "\"$(SRCROOT)/RTABMapApp/Libraries/include/pcl-1.15\"",
"\"$(SRCROOT)/RTABMapApp/Libraries/include/rtabmap-0.22\"", "\"$(SRCROOT)/RTABMapApp/Libraries/include/rtabmap-latest\"",
"\"$(SRCROOT)/../android/jni/tango-gl/include\"", "\"$(SRCROOT)/../android/jni/tango-gl/include\"",
"\"$(SRCROOT)/../android/jni/third-party/include\"", "\"$(SRCROOT)/../android/jni/third-party/include\"",
"\"$(SRCROOT)/RTABMapApp/Libraries/lib/vtk.framework/Headers\"", "\"$(SRCROOT)/RTABMapApp/Libraries/lib/vtk.framework/Headers\"",
+23 -1
View File
@@ -175,6 +175,18 @@ cd $pwd
#rm -rf g2o #rm -rf g2o
fi fi
# g2o's installed CMake config hard-codes the absolute build-time prefix of its
# external dependencies (e.g. suitesparse) in INTERFACE_INCLUDE_DIRECTORIES. That
# path doesn't exist when the prebuilt Libraries archive is unpacked on another
# machine (CI), breaking find_package(g2o) with "includes non-existent path".
# Rewrite those absolute paths to be relocatable (relative to the config file).
# Run unconditionally (outside the build guard above) so it also fixes the prebuilt
# archive in CI, where the g2o build step is skipped.
find "$prefix/lib" -path '*/cmake/g2o/*.cmake' -print0 | while IFS= read -r -d '' f
do
sed -i '' -E 's#[^";]*/Libraries#${CMAKE_CURRENT_LIST_DIR}/../../..#g' "$f"
done
# VTK # VTK
if [ ! -e $prefix/lib/vtk.framework ] if [ ! -e $prefix/lib/vtk.framework ]
then then
@@ -288,6 +300,16 @@ cmake -DANDROID_PREBUILD=ON ../../../../..
cmake --build . --config Release cmake --build . --config Release
mkdir -p ios mkdir -p ios
cd ios cd ios
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DCMAKE_FIND_ROOT_PATH=$prefix -DWITH_QT=OFF -DBUILD_APP=OFF -DBUILD_TOOLS=OFF -DWITH_TORO=OFF -DWITH_VERTIGO=OFF -DWITH_MADGWICK=OFF -DWITH_ORB_OCTREE=ON -DBUILD_EXAMPLES=OFF -DWITH_LIBLAS=ON ../../../../../.. cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0 -DCMAKE_INSTALL_PREFIX=$prefix -DCMAKE_FIND_ROOT_PATH=$prefix -DWITH_QT=OFF -DBUILD_APP=OFF -DBUILD_TOOLS=OFF -DWITH_TORO=OFF -DWITH_VERTIGO=OFF -DWITH_MADGWICK=OFF -DWITH_ORB_OCTREE=ON -DBUILD_EXAMPLES=OFF -DWITH_LIBLAS=ON -DWITH_OPENGV=OFF ../../../../../..
cmake --build . --config Release cmake --build . --config Release
cmake --build . --config Release --target install cmake --build . --config Release --target install
# rtabmap installs its headers into a version-stamped "rtabmap-<major>.<minor>" directory.
# Create a version-agnostic "rtabmap-latest" symlink to the just-installed one (newest by
# modification time) so the Xcode project's header search path does not need updating on every
# rtabmap minor-version bump. ls -t is used instead of "sort -V" for BSD/macOS portability.
rtabmap_versioned=$(cd "$prefix/include" && ls -td rtabmap-[0-9]* 2>/dev/null | head -n1)
if [ -n "$rtabmap_versioned" ]; then
ln -sfn "$rtabmap_versioned" "$prefix/include/rtabmap-latest"
echo "Linked $prefix/include/rtabmap-latest -> $rtabmap_versioned"
fi
+264 -21
View File
@@ -33,6 +33,14 @@ ENDIF()
# Add binary # Add binary
IF(APPLE AND BUILD_AS_BUNDLE) IF(APPLE AND BUILD_AS_BUNDLE)
ADD_EXECUTABLE(rtabmap_app MACOSX_BUNDLE ${SRC_FILES}) ADD_EXECUTABLE(rtabmap_app MACOSX_BUNDLE ${SRC_FILES})
# Custom Info.plist providing NSCameraUsageDescription, required by macOS to
# grant the app access to USB/UVC cameras (e.g. Orbbec, RealSense). A bundle
# identifier is also set: macOS ties the camera (TCC) permission to it, so it
# must be non-empty for the permission to be granted/persisted.
SET_TARGET_PROPERTIES(rtabmap_app PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in
MACOSX_BUNDLE_GUI_IDENTIFIER "com.introlab.rtabmap"
MACOSX_BUNDLE_BUNDLE_NAME "${CMAKE_BUNDLE_NAME}")
ELSEIF(WIN32 AND BUILD_AS_BUNDLE) ELSEIF(WIN32 AND BUILD_AS_BUNDLE)
ADD_EXECUTABLE(rtabmap_app WIN32 ${SRC_FILES}) ADD_EXECUTABLE(rtabmap_app WIN32 ${SRC_FILES})
ELSE() ELSE()
@@ -95,40 +103,218 @@ IF(BUILD_AS_BUNDLE AND (APPLE OR WIN32))
DESTINATION ${thirdparty_dest_dir} DESTINATION ${thirdparty_dest_dir}
COMPONENT runtime COMPONENT runtime
REGEX ".*pdb" EXCLUDE) REGEX ".*pdb" EXCLUDE)
INSTALL(FILES "${OpenNI2_BIN_DIR}/OpenNI.ini" IF(NOT WIN32)
INSTALL(FILES "${OpenNI2_BIN_DIR}/OpenNI.ini"
DESTINATION ${thirdparty_dest_dir} DESTINATION ${thirdparty_dest_dir}
COMPONENT runtime) COMPONENT runtime)
ENDIF()
ENDIF(OpenNI2_FOUND) ENDIF(OpenNI2_FOUND)
IF(k4a_FOUND) IF(k4a_FOUND)
# Install needed depthengine_2_0.dll # Install needed depthengine_2_0.dll. Its location varies by K4A SDK version:
# v1.4.1 ships it under sdk/windows-desktop/amd64/release/bin, or fallback in tools/.
IF(WIN32) IF(WIN32)
file(TO_CMAKE_PATH "$ENV{K4A_ROOT_DIR}" ENV_K4A_ROOT_DIR) file(TO_CMAKE_PATH "$ENV{K4A_ROOT_DIR}" ENV_K4A_ROOT_DIR)
INSTALL(FILES "${ENV_K4A_ROOT_DIR}/tools/depthengine_2_0.dll" set(DEPTHENGINE_DLL "")
DESTINATION ${thirdparty_dest_dir} foreach(_depthengine_dir
COMPONENT runtime) "${ENV_K4A_ROOT_DIR}/sdk/windows-desktop/amd64/release/bin"
"${ENV_K4A_ROOT_DIR}/tools")
if(EXISTS "${_depthengine_dir}/depthengine_2_0.dll")
set(DEPTHENGINE_DLL "${_depthengine_dir}/depthengine_2_0.dll")
break()
endif()
endforeach()
IF(DEPTHENGINE_DLL)
INSTALL(FILES "${DEPTHENGINE_DLL}"
DESTINATION ${thirdparty_dest_dir}
COMPONENT runtime)
ELSE()
MESSAGE(WARNING "depthengine_2_0.dll not found under $ENV{K4A_ROOT_DIR} (sdk/windows-desktop/amd64/release/bin or tools); Kinect for Azure depth may not work at runtime.")
ENDIF()
ENDIF(WIN32) ENDIF(WIN32)
ENDIF(k4a_FOUND) ENDIF(k4a_FOUND)
IF(ZED_FOUND)
# Install needed zlibwapi.dll
IF(WIN32)
file(TO_CMAKE_PATH "$ENV{ZED_SDK_ROOT_DIR}" ENV_ZED_SDK_ROOT_DIR)
INSTALL(FILES "${ENV_ZED_SDK_ROOT_DIR}/bin/zlibwapi.dll"
DESTINATION ${thirdparty_dest_dir}
COMPONENT runtime)
ENDIF(WIN32)
ENDIF(ZED_FOUND)
IF(OrbbecSDK_FOUND)
# Install needed "extensions" folder
IF(WIN32)
find_path(OrbbecSDK_BIN_DIR NAMES OrbbecSDK.dll)
IF(NOT OrbbecSDK_BIN_DIR)
MESSAGE(FATAL_ERROR "OrbbecSDK.dll not found! Verify your PATH.")
ENDIF(NOT OrbbecSDK_BIN_DIR)
MESSAGE(STATUS "OrbbecSDK_BIN_DIR=${OrbbecSDK_BIN_DIR}")
INSTALL(DIRECTORY "${OrbbecSDK_BIN_DIR}/extensions"
DESTINATION ${thirdparty_dest_dir}
COMPONENT runtime
FILES_MATCHING
PATTERN "*.lib" EXCLUDE
PATTERN "*")
ELSEIF(APPLE)
# OrbbecSDK loads its extensions (frame processor, filters like
# FrameUnpacker) via dlopen relative to libOrbbecSDK. fixup_bundle puts
# libOrbbecSDK in Contents/Frameworks, so the extensions must sit next to
# it in Frameworks/extensions (they reference @rpath/libOrbbecSDK, which
# resolves via the app executable's @executable_path/../Frameworks rpath).
# Without this the camera is detected but frame processing fails.
get_filename_component(OrbbecSDK_LIB_DIR "${OrbbecSDK_DIR}/../.." ABSOLUTE)
INSTALL(DIRECTORY "${OrbbecSDK_LIB_DIR}/extensions"
DESTINATION Frameworks
COMPONENT runtime)
IF(EXISTS "${OrbbecSDK_LIB_DIR}/OrbbecSDKConfig.xml")
INSTALL(FILES "${OrbbecSDK_LIB_DIR}/OrbbecSDKConfig.xml"
DESTINATION Frameworks
COMPONENT runtime)
ENDIF()
ENDIF(WIN32)
ENDIF(OrbbecSDK_FOUND)
IF(Torch_FOUND) IF(Torch_FOUND)
# Install needed cudnn_ops_infer64_8.dll and cudnn_cnn_infer64_8.dll # Install needed cudnn dlls
# TODO: should be a more general way to include them if version is different
IF(WIN32 AND CUDA_FOUND) IF(WIN32 AND CUDA_FOUND)
find_file(CUDNN_OPS_DLL NAMES cudnn_ops_infer64_8.dll) find_path(cuDNN_BIN_DIR NAMES cudnn.dll cudnn64.dll cudnn64_9.dll)
find_file(CUDNN_CNN_DLL NAMES cudnn_cnn_infer64_8.dll) IF(NOT cuDNN_BIN_DIR)
IF(CUDNN_OPS_DLL AND CUDNN_CNN_DLL) MESSAGE(FATAL_ERROR "cudnn dlls not found! Make sure the dlls are in a directory on your PATH.")
MESSAGE(STATUS "Found ${CUDNN_OPS_DLL}") ENDIF(NOT cuDNN_BIN_DIR)
MESSAGE(STATUS "Found ${CUDNN_CNN_DLL}") MESSAGE(STATUS "cuDNN_BIN_DIR = ${cuDNN_BIN_DIR}")
INSTALL(FILES ${CUDNN_OPS_DLL} ${CUDNN_CNN_DLL} file(GLOB CUDNN_DLLS "${cuDNN_BIN_DIR}/cudnn*.dll")
DESTINATION ${thirdparty_dest_dir} IF(CUDNN_DLLS)
COMPONENT runtime) MESSAGE(STATUS "Found cuDNN DLLs: ${CUDNN_DLLS}")
ELSE() INSTALL(FILES ${CUDNN_DLLS}
MESSAGE(AUTHOR_WARNING "Using Torch with CUDA, but cudnn_ops_infer64_8.dll and cudnn_cnn_infer64_8.dll are not found on the PATH, so it won't be added to package.") DESTINATION ${thirdparty_dest_dir}
COMPONENT runtime)
ENDIF() ENDIF()
ENDIF(WIN32 AND CUDA_FOUND) ENDIF(WIN32 AND CUDA_FOUND)
ENDIF(Torch_FOUND) ENDIF(Torch_FOUND)
IF(Qt6_FOUND) set(python_pyd_dir "")
IF(Python3_FOUND)
# bundle python3
IF(WIN32)
set(python_pyd_dir "bin/Lib/site-packages")
set(PYTHON_ZIP_NAME "python${Python3_VERSION_MAJOR}${Python3_VERSION_MINOR}.zip")
get_filename_component(PYTHON_ROOT "${Python3_EXECUTABLE}" DIRECTORY)
file(TO_CMAKE_PATH "${Python3_STDLIB}" SANITIZED_STDLIB)
MESSAGE(STATUS "Python3_EXECUTABLE=${Python3_EXECUTABLE}")
MESSAGE(STATUS "Python3_STDLIB=${SANITIZED_STDLIB}")
install(FILES "${Python3_EXECUTABLE}" DESTINATION bin COMPONENT runtime)
# when using python-opencv, it expects python3.dll, not python312.dll
get_filename_component(VCPKG_TRIPLET_ROOT "${PYTHON_TOOLS_DIR}/../../" ABSOLUTE)
set(VCPKG_BIN_DIR "${VCPKG_TRIPLET_ROOT}/bin")
find_file(PYTHON3_STABLE_DLL
NAMES python3.dll
PATHS "${VCPKG_BIN_DIR}"
NO_DEFAULT_PATH
)
if(PYTHON3_STABLE_DLL)
message(STATUS "Found python3.dll at: ${PYTHON3_STABLE_DLL}")
install(FILES "${PYTHON3_STABLE_DLL}" DESTINATION bin COMPONENT runtime)
endif()
# install python Lib in python312.zip (without site-packages, which is installed separatly afterwards)
file(TO_CMAKE_PATH "${Python3_STDLIB}" SANITIZED_STDLIB)
file(GLOB LIB_CONTENTS RELATIVE "${SANITIZED_STDLIB}" "${SANITIZED_STDLIB}/*")
list(REMOVE_ITEM LIB_CONTENTS "site-packages")
install(CODE "
execute_process(
COMMAND \"${CMAKE_COMMAND}\" -E tar cf \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin/${PYTHON_ZIP_NAME}\" --format=zip -- ${LIB_CONTENTS}
WORKING_DIRECTORY \"${SANITIZED_STDLIB}\"
)
" COMPONENT runtime)
set(PYTHON_SITE_PACKAGES "${SANITIZED_STDLIB}/site-packages")
install(DIRECTORY "${PYTHON_SITE_PACKAGES}/"
DESTINATION "${thirdparty_dest_dir}/Lib/site-packages"
COMPONENT runtime
PATTERN "*.exe" EXCLUDE
PATTERN "*.lib" EXCLUDE
PATTERN "*.hpp" EXCLUDE
PATTERN "*.h" EXCLUDE
PATTERN "*/torch/*" EXCLUDE
)
if(EXISTS "${PYTHON_SITE_PACKAGES}/torch")
install(DIRECTORY "${PYTHON_SITE_PACKAGES}/torch"
DESTINATION "${thirdparty_dest_dir}/Lib/site-packages/"
COMPONENT runtime
PATTERN "*.exe" EXCLUDE
PATTERN "*.lib" EXCLUDE
PATTERN "*.hpp" EXCLUDE
PATTERN "*.h" EXCLUDE
PATTERN "*.dll" EXCLUDE
)
file(GLOB_RECURSE PY_DLL_FILES "${PYTHON_SITE_PACKAGES}/torch/*.dll")
if(PY_DLL_FILES)
install(FILES ${PY_DLL_FILES} DESTINATION bin COMPONENT runtime)
endif()
endif()
# install python DDLs
file(GLOB_RECURSE PY_DLL_FILES \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${python_pyd_dir}/*.dll\")
install(DIRECTORY "${PYTHON_ROOT}/DLLs"
DESTINATION "${thirdparty_dest_dir}/"
COMPONENT runtime
FILES_MATCHING
PATTERN "*.dll"
PATTERN "*.pyd"
)
# install our python scripts in share for convenience
install(DIRECTORY "${PROJECT_SOURCE_DIR}/corelib/src/python/"
DESTINATION share
COMPONENT runtime
FILES_MATCHING
PATTERN "*.py"
)
ENDIF(WIN32)
ENDIF(Python3_FOUND)
IF(Qt6_FOUND AND APPLE)
# On macOS we do NOT use qt_deploy_runtime_dependencies (macdeployqt):
# macdeployqt cannot deploy VTK 9.6+, whose libraries reference each other
# via @rpath relative to "@loader_path/../lib". Instead we install the Qt plugins
# manually and let fixup_bundle() below deploy all libraries.
IF(TARGET Qt6::QCocoaIntegrationPlugin)
get_target_property(_qt_plugin_loc Qt6::QCocoaIntegrationPlugin LOCATION)
get_filename_component(_qt_plugins_dir "${_qt_plugin_loc}" DIRECTORY) # .../plugins/platforms
get_filename_component(_qt_plugins_dir "${_qt_plugins_dir}" DIRECTORY) # .../plugins
FOREACH(_qt_plugin_type platforms styles imageformats iconengines)
IF(EXISTS "${_qt_plugins_dir}/${_qt_plugin_type}")
# Homebrew Qt plugins are symlinks into the Cellar; resolve them to the
# real files so they aren't installed as dangling symlinks (which would
# break fixup_bundle and codesign).
FILE(GLOB _qt_plugin_files "${_qt_plugins_dir}/${_qt_plugin_type}/*${CMAKE_SHARED_LIBRARY_SUFFIX}")
SET(_qt_plugin_real "")
FOREACH(_qt_plugin_file ${_qt_plugin_files})
GET_FILENAME_COMPONENT(_qt_plugin_file "${_qt_plugin_file}" REALPATH)
LIST(APPEND _qt_plugin_real "${_qt_plugin_file}")
ENDFOREACH()
IF(_qt_plugin_real)
INSTALL(FILES ${_qt_plugin_real}
DESTINATION ${plugin_dest_dir}/${_qt_plugin_type}
COMPONENT runtime)
ENDIF()
ENDIF()
ENDFOREACH()
ELSE()
MESSAGE(WARNING "Qt6::QCocoaIntegrationPlugin target not found: Qt plugins may be missing from the bundle")
ENDIF()
# qt.conf so Qt finds the bundled plugins (path is relative to Contents/)
SET(QT_CONF_FILE [Paths]\nPlugins=${plugin_dest_dir})
INSTALL(CODE "
file(WRITE \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"${QT_CONF_FILE}\")
" COMPONENT runtime)
ELSEIF(Qt6_FOUND)
# Reference: https://doc-snapshots.qt.io/qt6-6.4/qt-deploy-runtime-dependencies.html # Reference: https://doc-snapshots.qt.io/qt6-6.4/qt-deploy-runtime-dependencies.html
# The following script must only be executed at install time # The following script must only be executed at install time
set(deploy_script "${CMAKE_CURRENT_BINARY_DIR}/deploy_app$<CONFIG>.cmake") set(deploy_script "${CMAKE_CURRENT_BINARY_DIR}/deploy_app$<CONFIG>.cmake")
@@ -218,7 +404,10 @@ IF(BUILD_AS_BUNDLE AND (APPLE OR WIN32))
ENDIF() ENDIF()
# directories to look for dependencies # directories to look for dependencies
SET(DIRS "${QT_LIBRARY_DIRS}" "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/lib") # CMAKE_LIBRARY_OUTPUT_DIRECTORY is where rtabmap's own libraries (e.g.
# librtabmap_core) are built; fixup_bundle needs it to resolve the app's
# @rpath references to them (macdeployqt used to handle this via rpath).
SET(DIRS "${QT_LIBRARY_DIRS}" "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/lib")
IF(APPLE) IF(APPLE)
SET(DIRS ${DIRS} /usr/local /usr/local/lib /opt/homebrew /opt/homebrew/lib /opt/homebrew/lib/gcc/current) SET(DIRS ${DIRS} /usr/local /usr/local/lib /opt/homebrew /opt/homebrew/lib /opt/homebrew/lib/gcc/current)
ENDIF(APPLE) ENDIF(APPLE)
@@ -230,11 +419,65 @@ IF(BUILD_AS_BUNDLE AND (APPLE OR WIN32))
# over. # over.
# To find dependencies, cmake use "otool" on Apple and "dumpbin" on Windows (make sure you have one of them). # To find dependencies, cmake use "otool" on Apple and "dumpbin" on Windows (make sure you have one of them).
install(CODE " install(CODE "
file(GLOB_RECURSE QTPLUGINS \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/*${CMAKE_SHARED_LIBRARY_SUFFIX}\") # Glob Qt Plugins
file(GLOB_RECURSE ALL_LIBS \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
# OrbbecSDK loads its filter/frame-processor extensions via dlopen, and they
# link @rpath/libOrbbecSDK. Feed them to fixup_bundle so their reference is
# rewritten to the embedded libOrbbecSDK
file(GLOB ORBBEC_EXT_LIBS
\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/Frameworks/extensions/filters/*${CMAKE_SHARED_LIBRARY_SUFFIX}\"
\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/Frameworks/extensions/frameprocessor/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
if(ORBBEC_EXT_LIBS)
list(APPEND ALL_LIBS \${ORBBEC_EXT_LIBS})
endif()
if(NOT \"${python_pyd_dir}\" STREQUAL \"\")
file(GLOB_RECURSE PYD_FILES \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${python_pyd_dir}/*.pyd\")
if(PYD_FILES)
list(APPEND ALL_LIBS \${PYD_FILES})
endif()
if(WIN32)
file(GLOB_RECURSE DLL_FILES \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${python_pyd_dir}/torch/*.dll\")
if(DLL_FILES)
list(APPEND ALL_LIBS \${DLL_FILES})
endif()
endif()
endif()
set(BU_CHMOD_BUNDLE_ITEMS ON) set(BU_CHMOD_BUNDLE_ITEMS ON)
include(\"BundleUtilities\") include(\"BundleUtilities\")
fixup_bundle(\"${APPS}\" \"\${QTPLUGINS}\" \"${DIRS}\") # nvcuvid.dll (NVDEC) and nvEncodeAPI64.dll (NVENC), and the CUDA driver API
# nvcuda.dll, ship with the NVIDIA GPU driver (System32), not the CUDA toolkit,
# so they are absent on driver-less CI runners and must never be bundled (they
# are resolved at runtime from the end user's driver). Mark them 'system' so
# fixup_bundle skips them instead of failing to resolve them.
function(gp_resolved_file_type_override resolved_file type_var)
if(resolved_file MATCHES \"(nvcuvid|nvEncodeAPI64|nvcuda)\")
set(\${type_var} \"system\" PARENT_SCOPE)
endif()
endfunction()
fixup_bundle(\"${APPS}\" \"\${ALL_LIBS}\" \"${DIRS}\")
" COMPONENT runtime) " COMPONENT runtime)
IF(APPLE)
# Re-sign ad-hoc AFTER fixup_bundle has finished all its install_name_tool
# edits.
install(CODE "
set(_contents \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}\")
get_filename_component(_app \"\${_contents}\" DIRECTORY)
file(GLOB_RECURSE _nested \"\${_contents}/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
foreach(_f \${_nested})
execute_process(COMMAND codesign --force --sign - --timestamp=none \"\${_f}\")
endforeach()
file(GLOB _frameworks \"\${_contents}/Frameworks/*.framework\")
foreach(_f \${_frameworks})
execute_process(COMMAND codesign --force --sign - --timestamp=none \"\${_f}\")
endforeach()
message(STATUS \"Ad-hoc re-signing bundle: \${_app}\")
execute_process(COMMAND codesign --force --sign - --timestamp=none \"\${_app}\")
" COMPONENT runtime)
ENDIF(APPLE)
ENDIF(BUILD_AS_BUNDLE AND (APPLE OR WIN32)) ENDIF(BUILD_AS_BUNDLE AND (APPLE OR WIN32))
+40
View File
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSHighResolutionCapable</key>
<string>True</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
<key>CFBundleIconFile</key>
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
<key>CFBundleIdentifier</key>
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
<key>CFBundleName</key>
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>NSCameraUsageDescription</key>
<string>RTAB-Map needs access to the camera to capture images from connected RGB-D/stereo cameras (e.g. Orbbec, RealSense).</string>
</dict>
</plist>
+10
View File
@@ -52,6 +52,10 @@ int main(int argc, char* argv[])
ULogger::setLevel(ULogger::kWarning); ULogger::setLevel(ULogger::kWarning);
#ifdef WIN32 #ifdef WIN32
// STA (single-threaded apartment) is required for the native file dialogs / File Explorer
// (see commit d75cc04, "Fixed File Explorer hanging (Qt 5.12)"). Do NOT switch to MTA
// (CoInitializeEx COINIT_MULTITHREADED): it deadlocks the
// native file dialogs.
CoInitialize(nullptr); CoInitialize(nullptr);
#endif #endif
@@ -60,6 +64,12 @@ int main(int argc, char* argv[])
QSurfaceFormat::setDefaultFormat(QVTKRenderWidget::defaultFormat()); QSurfaceFormat::setDefaultFormat(QVTKRenderWidget::defaultFormat());
#endif #endif
// Recommended by VTK when using QVTKOpenGLNativeWidget (a QOpenGLWidget): let all VTK
// render widgets share a single OpenGL context, which is needed for correct rendering
// when render widgets live in / move across multiple top-level windows. Must be set
// before QApplication is constructed.
QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
/* Create tasks */ /* Create tasks */
QApplication * app = new QApplication(argc, argv); QApplication * app = new QApplication(argc, argv);
app->setStyleSheet("QMessageBox { messagebox-text-interaction-flags: 5; }"); // selectable message box app->setStyleSheet("QMessageBox { messagebox-text-interaction-flags: 5; }"); // selectable message box
@@ -15,7 +15,7 @@ RAMaddOverhead = 0;
% Inliers_ratio = 'Loop/Visual_inliers/' ./ 'Keypoint/Current_frame/words' % Inliers_ratio = 'Loop/Visual_inliers/' ./ 'Keypoint/Current_frame/words'
% Odometry_average = 'Memory/Distance_travelled/m'(2:end) - 'Memory/Distance_travelled/m'(1:end-1) % Odometry_average = 'Memory/Distance_travelled/m'(2:end) - 'Memory/Distance_travelled/m'(1:end-1)
statNames = {'Loop/Odom_correction_norm/m', 'Loop/Visual_inliers/', 'Inliers_ratio_%', 'Timing/Total/ms', 'Memory/RAM_usage/MB', 'Memory/RAM_estimated/MB', 'Keypoint/Current_frame/words', 'Loop/Map_id/', 'Memory/Local_graph_size/', 'Keypoint/Dictionary_size/words', 'Loop/Distance_since_last_loc/'}; % 'Odometry_average' statNames = {'Loop/Odom_correction_norm/m', 'Loop/Visual_inliers/', 'Inliers_ratio_%', 'Timing/Total/ms', 'Memory/RAM_usage/MB', 'Memory/RAM_estimated/MB', 'Keypoint/Current_frame/words', 'Loop/Map_id/', 'Memory/Local_graph_size/', 'Keypoint/Dictionary_size/words', 'Loop/Distance_since_last_loc/m'}; % 'Odometry_average'
datasets = [ 0 1 6 7 9 14 11 111 ]; % 0 1 6 7 9 12 14 11 datasets = [ 0 1 6 7 9 14 11 111 ]; % 0 1 6 7 9 12 14 11
@@ -26,7 +26,7 @@ if resultsToShow == 2
sep = [0, 1000, 3000, 5000, 7000, 9000]; sep = [0, 1000, 3000, 5000, 7000, 9000];
sepName = {'17:27', '17:54', '18:27', '18:56', '19:35'}; sepName = {'17:27', '17:54', '18:27', '18:56', '19:35'};
prefix = 'Consecutive'; prefix = 'Consecutive';
statNames = {'Loop/Distance_since_last_loc/', 'Distance_since_last_loc_under_50cm'}; statNames = {'Loop/Distance_since_last_loc/m', 'Distance_since_last_loc_under_50cm'};
endif endif
MapsN = length(sepName); MapsN = length(sepName);
@@ -52,7 +52,7 @@ if strcmp(statName,'Inliers_ratio_%')
elseif strcmp(statName, 'Odometry_average') elseif strcmp(statName, 'Odometry_average')
data = dlmread([dataDir '/' prefix num2str(datasets(d)) '-' 'Memory-Distance_travelled-m' '.txt'], '\t', 1, 0, "emptyvalue", 0); data = dlmread([dataDir '/' prefix num2str(datasets(d)) '-' 'Memory-Distance_travelled-m' '.txt'], '\t', 1, 0, "emptyvalue", 0);
elseif strcmp(statName, 'Distance_since_last_loc_under_50cm') elseif strcmp(statName, 'Distance_since_last_loc_under_50cm')
data = dlmread([dataDir '/' prefix num2str(datasets(d)) '-' 'Loop-Distance_since_last_loc-' '.txt'], '\t', 1, 0, "emptyvalue", 0); data = dlmread([dataDir '/' prefix num2str(datasets(d)) '-' 'Loop-Distance_since_last_loc-m' '.txt'], '\t', 1, 0, "emptyvalue", 0);
else else
data = dlmread([dataDir '/' prefix num2str(datasets(d)) '-' statName '.txt'], '\t', 1, 0, "emptyvalue", 0); data = dlmread([dataDir '/' prefix num2str(datasets(d)) '-' statName '.txt'], '\t', 1, 0, "emptyvalue", 0);
endif endif
@@ -13,7 +13,7 @@ source rtabmap_latest.bash
for d in "${DETECTOR[@]}" for d in "${DETECTOR[@]}"
do do
rtabmap-report --export --export_prefix "Stat$d" --loc 32 Loop/Odom_correction_norm/m Loop/Visual_inliers/ Timing/Total/ms Timing/Proximity_by_space_visual/ms Timing/Likelihood_computation/ms Timing/Posterior_computation/ms TimingMem/Keypoints_detection/ms TimingMem/Descriptors_extraction/ms TimingMem/Add_new_words/ms Loop/Map_id/ Keypoint/Current_frame/words Memory/RAM_usage/MB Memory/RAM_estimated/MB Memory/Distance_travelled/m Loop/Distance_since_last_loc/ Memory/Local_graph_size/ Keypoint/Dictionary_size/words "$DATA/$d/loc" rtabmap-report --export --export_prefix "Stat$d" --loc 32 Loop/Odom_correction_norm/m Loop/Visual_inliers/ Timing/Total/ms Timing/Proximity_by_space_visual/ms Timing/Likelihood_computation/ms Timing/Posterior_computation/ms TimingMem/Keypoints_detection/ms TimingMem/Descriptors_extraction/ms TimingMem/Add_new_words/ms Loop/Map_id/ Keypoint/Current_frame/words Memory/RAM_usage/MB Memory/RAM_estimated/MB Memory/Distance_travelled/m Loop/Distance_since_last_loc/m Memory/Local_graph_size/ Keypoint/Dictionary_size/words "$DATA/$d/loc"
rtabmap-report --export --export_prefix "Consecutive$d" --loc 32 Loop/Map_id/ Loop/Distance_since_last_loc/ "$DATA/$d/consecutive_loc" rtabmap-report --export --export_prefix "Consecutive$d" --loc 32 Loop/Map_id/ Loop/Distance_since_last_loc/m "$DATA/$d/consecutive_loc"
done done
+418
View File
@@ -0,0 +1,418 @@
@echo off
setlocal enabledelayedexpansion
:: --- CONFIGURATION ---
set "VCPKG_ROOT=%~dp0vcpkg"
set "EXPORT_DIR=%~dp0vcpkg_binaries"
:: All deps downloaded/built from source (git clones + the pinned CMake) live here.
set "SRC_DIR=%~dp0vcpkg_deps_from_source"
set "TRIPLET=x64-windows-release"
set "SEVENZIP_EXE=C:\Program Files\7-Zip\7z.exe"
set "VCPKG_JSON=%~dp0vcpkg.json"
for /f "usebackq tokens=*" %%a in (`powershell -NoProfile -Command "(Get-Content '%VCPKG_JSON%' -Raw | ConvertFrom-Json).'builtin-baseline'"` ) do set "VCPKG_COMMIT=%%a"
echo [+] Detected VCPKG baseline commit: %VCPKG_COMMIT%
if "%VCPKG_COMMIT%"=="" (
echo [X] Error: Could not find 'builtin-baseline' in %VCPKG_JSON%
pause
exit /b 1
)
set VCPKG_COMMIT_SHORT=%VCPKG_COMMIT:~0,8%
:: 1. Setup Local vcpkg
if not exist "%VCPKG_ROOT%" (
echo [+] Local vcpkg not found. Cloning...
git clone https://github.com/microsoft/vcpkg.git "%VCPKG_ROOT%"
)
pushd "%VCPKG_ROOT%"
git checkout %VCPKG_COMMIT%
call .\bootstrap-vcpkg.bat
popd
:: 2. Install vcpkg dependencies
echo [+] Installing dependencies via vcpkg manifest...
"%VCPKG_ROOT%\vcpkg.exe" install ^
--triplet=%TRIPLET% ^
--host-triplet=%TRIPLET% ^
--clean-after-build ^
--x-feature=tools ^
--x-feature=k4w2 ^
--x-feature=octomap ^
--x-feature=openmp ^
--x-feature=realsense2 ^
--x-feature=openni2 ^
--x-feature=gtsam-deps ^
--x-feature=python ^
--x-feature=libpointmatcher-deps ^
--x-feature=libfreenect2-deps || exit /b !errorlevel!
:: 3. Export
echo [+] Exporting built binaries to raw folder...
set "VS_LOCATOR=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
for /f "usebackq tokens=*" %%i in (`"%VS_LOCATOR%" -latest -property catalog_productLineVersion`) do set VS_YEAR=vs%%i
set TARGET_NAME=vcpkg-export-%VCPKG_COMMIT_SHORT%-x64-%VS_YEAR%
set TARGET_FULL_PATH=%EXPORT_DIR%\%TARGET_NAME%
if exist "%TARGET_FULL_PATH%" rd /s /q "%TARGET_FULL_PATH%"
"%VCPKG_ROOT%\vcpkg.exe" export --raw --output-dir="%EXPORT_DIR%" --output=%TARGET_NAME% --triplet=%TRIPLET% || exit /b !errorlevel!
set "FINAL_EXPORT_PATH=%TARGET_FULL_PATH%"
echo [+] Add numpy...
:: We install numpy<2 to be compatible with SuperPoint and SuperGlue scripts
%FINAL_EXPORT_PATH%/installed/%TRIPLET%/tools/python3/python.exe -m ensurepip --upgrade || exit /b %errorlevel%
%FINAL_EXPORT_PATH%/installed/%TRIPLET%/tools/python3/python.exe -m pip install --upgrade pip || exit /b !errorlevel!
%FINAL_EXPORT_PATH%/installed/%TRIPLET%/tools/python3/python.exe -m pip install "numpy<2" || exit /b !errorlevel!
:: 4. Other dependencies not in vcpkg
:: Everything cloned/downloaded below goes into %SRC_DIR% to keep the repo root clean.
if not exist "%SRC_DIR%" mkdir "%SRC_DIR%"
cd /d "%SRC_DIR%"
:: Kinect for Windows SDK v2 (k4w2): rtabmap's FindKinectSDK2.cmake expects the
:: Microsoft SDK layout (KINECTSDK20_DIR\inc and \Lib\x64), but vcpkg's kinectsdk2
:: port installs vcpkg-style (include\ and lib\). Mirror the bundled headers/lib into
:: the expected layout so it is found with KINECTSDK20_DIR pointing at the export.
if "%KINECTSDK20_DIR%"=="" (
echo Error: KINECTSDK20_DIR environment variable is not set! Install Kinect for Windows SDK v2: https://www.microsoft.com/en-us/download/details.aspx?id=44561
pause
exit /b 1
)
echo [+] Arranging Kinect SDK v2 layout for FindKinectSDK2...
set "K4W2_ROOT=%FINAL_EXPORT_PATH%\installed\%TRIPLET%"
robocopy "%K4W2_ROOT%\include" "%K4W2_ROOT%\inc" Kinect*.h Nui*.h /XO >nul
robocopy "%K4W2_ROOT%\lib" "%K4W2_ROOT%\Lib\x64" Kinect20*.lib /XO >nul
robocopy "%KINECTSDK20_DIR%\bin" "%K4W2_ROOT%\bin" Kinect20.dll /XO >nul
:: Robocopy exit codes under 8 mean successful copies/no changes; 8+ is a failure.
if !errorlevel! GEQ 8 (
echo Error: Robocopy failed with exit code !errorlevel!
pause
exit /b !errorlevel!
)
:: orbbec SDK2
echo [+] Building OrbbecSDK_v2...
if not exist OrbbecSDK_v2 (
echo [+] Downloading and applying patch...
git clone https://github.com/orbbec/OrbbecSDK_v2.git
cd OrbbecSDK_v2
git checkout v2.8.7
:: Install the CMake package config under lib/cmake/<pkg> so find_package(OrbbecSDK) works
git apply "%~dp0patches\orbbecsdk_2.8.7.patch"
cd ..
)
cd OrbbecSDK_v2
cmake -S . -B build -GNinja ^
-DVCPKG_MANIFEST_INSTALL=OFF ^
-DVCPKG_TARGET_TRIPLET=x64-windows-release ^
-DVCPKG_INSTALLED_DIR="%FINAL_EXPORT_PATH%\installed" ^
-DCMAKE_TOOLCHAIN_FILE="%FINAL_EXPORT_PATH%\scripts\buildsystems\vcpkg.cmake" ^
-DCMAKE_INSTALL_PREFIX="%FINAL_EXPORT_PATH%\installed\%TRIPLET%" ^
-DCMAKE_BUILD_TYPE=Release ^
-DOB_BUILD_DOCS=OFF ^
-DOB_BUILD_EXAMPLES=OFF ^
-DOB_BUILD_TOOLS=OFF ^
-DOB_INSTALL_EXAMPLES_SOURCE=OFF || exit /b !errorlevel!
cmake --build build --config Release --target install || exit /b !errorlevel!
cd ..
if "%K4A_ROOT_DIR%"=="" (
echo Error: K4A_ROOT_DIR environment variable is not set! Install K4A: https://github.com/microsoft/Azure-Kinect-Sensor-SDK/blob/develop/docs/usage.md
pause
exit /b 1
)
echo Copying Kinect For Azure components...
robocopy "%K4A_ROOT_DIR%\sdk" "%FINAL_EXPORT_PATH%\installed\%TRIPLET%\sdk" /E /XO
:: Robocopy exit codes under 8 mean successful copies/no changes.
:: 8 or higher means there was a failure.
if !errorlevel! GEQ 8 (
echo Error: Robocopy failed with exit code !errorlevel!
pause
exit /b !errorlevel!
)
:: libnabo
echo [+] Building libnabo...
if not exist libnabo (
echo [+] Downloading...
git clone https://github.com/ethz-asl/libnabo.git
cd libnabo
:: Jan 27, 2022
git checkout c925c47
git apply "%~dp0patches\libnabo_c925c47.patch"
cd ..
)
cd libnabo
cmake -S . -B build -GNinja ^
-DVCPKG_MANIFEST_INSTALL=OFF ^
-DVCPKG_TARGET_TRIPLET=x64-windows-release ^
-DVCPKG_INSTALLED_DIR="%FINAL_EXPORT_PATH%\installed" ^
-DCMAKE_TOOLCHAIN_FILE="%FINAL_EXPORT_PATH%\scripts\buildsystems\vcpkg.cmake" ^
-DCMAKE_INSTALL_PREFIX="%FINAL_EXPORT_PATH%\installed\%TRIPLET%" ^
-DCMAKE_BUILD_TYPE=Release ^
-DSHARED_LIBS=FALSE ^
-DLIBNABO_BUILD_DOXYGEN=OFF ^
-DLIBNABO_BUILD_EXAMPLES=OFF ^
-DLIBNABO_BUILD_PYTHON=OFF ^
-DLIBNABO_BUILD_TESTS=OFF || exit /b !errorlevel!
cmake --build build --config Release --target install || exit /b !errorlevel!
cd ..
:: libpointmatcher
echo [+] Building libpointmatcher...
if not exist libpointmatcher (
echo [+] Downloading and applying patch...
git clone https://github.com/ethz-asl/libpointmatcher.git
cd libpointmatcher
:: Mar 17, 2023
git checkout 7dc58e5
git apply "%~dp0patches\pointmatcher_7dc58e5.patch"
cd ..
)
cd libpointmatcher
cmake -S . -B build -GNinja ^
-DVCPKG_MANIFEST_INSTALL=OFF ^
-DVCPKG_TARGET_TRIPLET=x64-windows-release ^
-DVCPKG_INSTALLED_DIR="%FINAL_EXPORT_PATH%\installed" ^
-DCMAKE_TOOLCHAIN_FILE="%FINAL_EXPORT_PATH%\scripts\buildsystems\vcpkg.cmake" ^
-DCMAKE_INSTALL_PREFIX="%FINAL_EXPORT_PATH%\installed\%TRIPLET%" ^
-DCMAKE_BUILD_TYPE=Release ^
-DBUILD_TESTS=OFF ^
-DBUILD_SHARED_LIBS=ON ^
-DPOINTMATCHER_BUILD_EVALUATIONS=OFF ^
-DPOINTMATCHER_BUILD_EXAMPLES=OFF ^
-DCMAKE_CXX_FLAGS="-DBOOST_TIMER_ENABLE_DEPRECATED /EHsc -DBOOST_EXCEPTION_DISABLE" || exit /b !errorlevel!
cmake --build build --config Release --target install || exit /b !errorlevel!
cd ..
:: We remove the files in the top-level CMake directory to force use of share/libpointmatcher/cmake
if exist "%FINAL_EXPORT_PATH%\installed\%TRIPLET%\CMake\" (
rd /s /q "%FINAL_EXPORT_PATH%\installed\%TRIPLET%\CMake"
)
:: gtsam
echo [+] Building gtsam...
if not exist gtsam (
echo [+] Downloading and applying patch...
git clone https://github.com/borglab/gtsam.git
cd gtsam
:: June 18, 2025
git checkout 4.3a0-ros
git cherry-pick 18af4e6
git apply "%~dp0patches\gtsam_4_3a0-ros.patch"
cd ..
)
cd gtsam
cmake -S . -B build -GNinja ^
-DVCPKG_MANIFEST_INSTALL=OFF ^
-DVCPKG_TARGET_TRIPLET=x64-windows-release ^
-DVCPKG_INSTALLED_DIR="%FINAL_EXPORT_PATH%\installed" ^
-DCMAKE_TOOLCHAIN_FILE="%FINAL_EXPORT_PATH%\scripts\buildsystems\vcpkg.cmake" ^
-DCMAKE_INSTALL_PREFIX="%FINAL_EXPORT_PATH%\installed\%TRIPLET%" ^
-DCMAKE_BUILD_TYPE=Release ^
-DGTSAM_BUILD_EXAMPLES_ALWAYS=OFF ^
-DGTSAM_BUILD_TESTS=OFF ^
-DGTSAM_BUILD_UNSTABLE=OFF ^
-DGTSAM_USE_SYSTEM_EIGEN=ON ^
-DGTSAM_BUILD_WITH_PRECOMPILED_HEADERS=OFF ^
-DGTSAM_UNSTABLE_BUILD_PYTHON=OFF ^
-DGTSAM_WITH_EIGEN_MKL=OFF ^
-DGTSAM_WITH_EIGEN_MKL_OPENMP=OFF ^
-DCMAKE_CXX_FLAGS="-DBOOST_TIMER_ENABLE_DEPRECATED -DBOOST_BIND_GLOBAL_PLACEHOLDERS" || exit /b !errorlevel!
cmake --build build --config Release --target install || exit /b !errorlevel!
cd ..
:: opengv
echo [+] Building opengv...
if not exist opengv (
echo [+] Downloading and applying patch...
git clone https://github.com/laurentkneip/opengv.git
cd opengv
:: Aug 6, 2020
git checkout 91f4b19c73450833a40e463ad3648aae80b3a7f3
git apply "%~dp0patches\opengv_91f4b19c.patch"
cd ..
)
cd opengv
cmake -S . -B build -GNinja ^
-DVCPKG_MANIFEST_INSTALL=OFF ^
-DVCPKG_TARGET_TRIPLET=x64-windows-release ^
-DVCPKG_INSTALLED_DIR="%FINAL_EXPORT_PATH%\installed" ^
-DCMAKE_TOOLCHAIN_FILE="%FINAL_EXPORT_PATH%\scripts\buildsystems\vcpkg.cmake" ^
-DCMAKE_INSTALL_PREFIX="%FINAL_EXPORT_PATH%\installed\%TRIPLET%" ^
-DBUILD_TESTS=OFF ^
-DBUILD_SHARED_LIBS=ON || exit /b !errorlevel!
cmake --build build --config Release --target install || exit /b !errorlevel!
cd ..
:: libfreenect2
echo [+] Building libfreenect2...
if not exist libfreenect2 (
echo [+] Downloading and applying patch...
git clone https://github.com/OpenKinect/libfreenect2.git
cd libfreenect2
:: Aug 6, 2021
git checkout v0.2.1
:: Patch makes freenect2Config.cmake relocatable so the prebuilt bundle works
:: after being moved/unzipped, drops cudaDeviceProp::clockRate/computeMode
:: removed in CUDA 13 from the CUDA build, and renames a CL_ICDL_VERSION local
:: that collides with the OpenCL 3.0 macro.
git apply "%~dp0patches\libfreenect2_v0.2.1.patch"
cd ..
)
cd libfreenect2
:: libfreenect2's FindLibUSB.cmake locates libusb via pkg-config. It declares an
:: ancient cmake_minimum_required (2.8.12), which makes FindPkgConfig default
:: PKG_CONFIG_USE_CMAKE_PREFIX_PATH=OFF, so it ignores the vcpkg CMAKE_PREFIX_PATH.
:: Force it ON so the bundle's lib/pkgconfig (libusb-1.0.pc, libturbojpeg.pc) is
:: searched, use the vcpkg-bundled pkgconf, and also set PKG_CONFIG_PATH as a belt.
set "PKG_CONFIG_PATH=%FINAL_EXPORT_PATH%\installed\%TRIPLET%\lib\pkgconfig"
cmake -S . -B build -GNinja ^
-DVCPKG_MANIFEST_INSTALL=OFF ^
-DVCPKG_TARGET_TRIPLET=x64-windows-release ^
-DVCPKG_INSTALLED_DIR="%FINAL_EXPORT_PATH%\installed" ^
-DCMAKE_TOOLCHAIN_FILE="%FINAL_EXPORT_PATH%\scripts\buildsystems\vcpkg.cmake" ^
-DPKG_CONFIG_EXECUTABLE="%FINAL_EXPORT_PATH%\installed\%TRIPLET%\tools\pkgconf\pkgconf.exe" ^
-DPKG_CONFIG_USE_CMAKE_PREFIX_PATH=ON ^
-DCMAKE_BUILD_TYPE=Release ^
-DENABLE_CUDA=OFF ^
-DENABLE_OPENCL=OFF ^
-DBUILD_EXAMPLES=OFF ^
-DCMAKE_INSTALL_PREFIX="%FINAL_EXPORT_PATH%\installed\%TRIPLET%" ^
-DBUILD_SHARED_LIBS=ON || exit /b !errorlevel!
cmake --build build --config Release --target install || exit /b !errorlevel!
cd ..
:: depthai
echo [+] Building depthai...
if not exist depthai-core (
echo [+] Downloading...
git clone https://github.com/luxonis/depthai-core.git
cd depthai-core
:: depthai 2.32.0 (Hunter-based; v2 does NOT use vcpkg/CMake presets)
git checkout v2.32.0
git submodule update --init --recursive
cd ..
)
cd depthai-core
:: v2 and its old Hunter sub-deps declare cmake_minimum_required < 3.5, which
:: CMake 4.x rejects, and CMAKE_POLICY_VERSION_MINIMUM does not propagate into
:: Hunter's sub-builds. Use a pinned CMake 3.x just for depthai (Hunter reuses the
:: same cmake binary for its dependency sub-builds).
set "CMAKE3_VER=3.31.12"
set "CMAKE3_NAME=cmake-%CMAKE3_VER%-windows-x86_64"
set "CMAKE3_DIR=%SRC_DIR%\%CMAKE3_NAME%"
set "CMAKE3=%CMAKE3_DIR%\bin\cmake.exe"
if not exist "%CMAKE3_DIR%" (
echo [+] Downloading CMake %CMAKE3_VER% ...
curl -L -o "%SRC_DIR%\%CMAKE3_NAME%.zip" "https://github.com/Kitware/CMake/releases/download/v%CMAKE3_VER%/%CMAKE3_NAME%.zip" || exit /b !errorlevel!
"%SEVENZIP_EXE%" x "%SRC_DIR%\%CMAKE3_NAME%.zip" -o"%SRC_DIR%" -y || exit /b !errorlevel!
)
:: v2 is fully Hunter-managed (no vcpkg toolchain). depthaiDependencies.cmake
:: unconditionally does find_package(OpenCV 4 QUIET CONFIG) (not gated by
:: DEPTHAI_OPENCV_SUPPORT); if it finds the bundle's OpenCV, OpenCVModules does
:: find_dependency(TIFF) which collides with Hunter's config-less FindTIFF. We don't
:: need depthai's OpenCV at all (CameraDepthAI converts ImgFrame->cv::Mat itself), so
:: hard-disable the lookup. DEPTHAI_ENABLE_CURL=OFF avoids Hunter's old zlib/curl.
"%CMAKE3%" -S . -B build -GNinja ^
-DCMAKE_INSTALL_PREFIX="%FINAL_EXPORT_PATH%\installed\%TRIPLET%" ^
-DCMAKE_BUILD_TYPE=Release ^
-DBUILD_SHARED_LIBS=ON ^
-DDEPTHAI_OPENCV_SUPPORT=OFF ^
-DCMAKE_DISABLE_FIND_PACKAGE_OpenCV=ON ^
-DDEPTHAI_ENABLE_CURL=OFF ^
-DDEPTHAI_BUILD_EXAMPLES=OFF ^
-DDEPTHAI_BUILD_TESTS=OFF || exit /b !errorlevel!
"%CMAKE3%" --build build --config Release --target install || exit /b !errorlevel!
cd ..
:: CCCoreLib
echo [+] Building CCCoreLib...
if not exist CCCoreLib (
echo [+] Downloading...
git clone https://github.com/CloudCompare/CCCoreLib.git
cd CCCoreLib
:: June 20, 2026
git checkout 4095bea6552096cb528c3b8b5cb9505df2aa6002
git submodule update --init --recursive
:: nanoflann is an internal dep (only used in src/Kriging.cpp, no public header),
:: but CCCoreLib links it PUBLIC, leaking nanoflann::nanoflann into the exported
:: interface and breaking find_package(CCCoreLib). Link it PRIVATE instead.
git apply "%~dp0patches\cccorelib_4095bea.patch"
cd ..
)
cd CCCoreLib
cmake -S . -B build -GNinja ^
-DVCPKG_MANIFEST_INSTALL=OFF ^
-DVCPKG_TARGET_TRIPLET=x64-windows-release ^
-DVCPKG_INSTALLED_DIR="%FINAL_EXPORT_PATH%\installed" ^
-DCMAKE_TOOLCHAIN_FILE="%FINAL_EXPORT_PATH%\scripts\buildsystems\vcpkg.cmake" ^
-DCMAKE_INSTALL_PREFIX="%FINAL_EXPORT_PATH%\installed\%TRIPLET%" ^
-DCMAKE_BUILD_TYPE=Release ^
-DCCCORELIB_SHARED=ON ^
-DCCCORELIB_USE_CGAL=OFF ^
-DCCCORELIB_USE_TBB=ON ^
-DCCCORELIB_USE_QT_CONCURRENT=OFF || exit /b !errorlevel!
cmake --build build --config Release --target install || exit /b !errorlevel!
cd ..
:: 5. ZIP the folder
echo [+] Creating final package with 7-Zip...
:: Rip off pdb files
cd /d "%FINAL_EXPORT_PATH%"
del /s /q /f *.pdb >nul 2>&1
cd ..
set "FINAL_ZIP=%TARGET_NAME%.7z"
:: compress contents without the root folder
"%SEVENZIP_EXE%" u -t7z -mx9 "%FINAL_ZIP%" "%FINAL_EXPORT_PATH%\*" -up0q0
if !errorlevel! EQU 0 (
echo [!] Success! Package created at %FINAL_ZIP%
) else (
echo [X] 7-Zip failed with error code !errorlevel!
)
:: Example building rtabmap afterwards
goto :EndComment
:: The vcpkg export folder should not be in the rtabmap source directory
:: (otherwise we get some cmake errors about that)
set VCPKG_UNZIPPED_EXPORT_PATH=%USERPROFILE%\Downloads\vcpkg-export-########-x64-vs2022
set PATH=%VCPKG_UNZIPPED_EXPORT_PATH%\installed\x64-windows-release\bin;%PATH%
set PATH=%VCPKG_UNZIPPED_EXPORT_PATH%\installed\x64-windows-release\sdk\windows-desktop\amd64\release\bin;%PATH%
set PATH=%VCPKG_UNZIPPED_EXPORT_PATH%\installed\x64-windows-release\tools\python3\Lib\site-packages\numpy.libs;%PATH%
set K4A_ROOT_DIR=%VCPKG_UNZIPPED_EXPORT_PATH%\installed\x64-windows-release
set KINECTSDK20_DIR=%VCPKG_UNZIPPED_EXPORT_PATH%\installed\x64-windows-release
cmake -B build -GNinja ^
-DCMAKE_BUILD_TYPE=Release ^
-DBUILD_AS_BUNDLE=ON ^
-DWITH_PYTHON=ON ^
-DWITH_ZED=OFF ^
-DWITH_CERES=ON ^
-DWITH_ORBBEC_SDK=ON ^
-DWITH_FREENECT2=ON ^
-DWITH_K4W2=ON ^
-DWITH_K4A=ON ^
-DWITH_DEPTHAI=ON ^
-DWITH_REALSENSE2=ON ^
-DWITH_CCCORELIB=ON ^
-DWITH_PDAL=OFF ^
-DVCPKG_MANIFEST_INSTALL=OFF ^
-DVCPKG_TARGET_TRIPLET=x64-windows-release ^
-DVCPKG_INSTALLED_DIR="%VCPKG_UNZIPPED_EXPORT_PATH%/installed" ^
-DCMAKE_TOOLCHAIN_FILE=%VCPKG_UNZIPPED_EXPORT_PATH%/scripts/buildsystems/vcpkg.cmake ^
-DGTSAM_DIR=%VCPKG_UNZIPPED_EXPORT_PATH%\installed\x64-windows-release\CMake
cmake --build build --config Release --target package
:: To install CPU pytorch inside rtabmap package afterwards.
:: Note that python.exe is the one in the bin directory of the package, not the system one.
python.exe -m pip install torch torchvision opencv-python-headless "numpy<2"
:EndComment
+338
View File
@@ -0,0 +1,338 @@
@echo off
setlocal enabledelayedexpansion
IF NOT DEFINED CUDA_PATH (
echo [ERROR] CUDA_PATH is not set.
exit /b 1
)
set PATH=%CUDA_PATH%\bin;%PATH%
set PATH=%CUDA_PATH%\bin\x64;%PATH%
set PATH=%CUDA_PATH%\extras\CUPTI\lib64;%PATH%
:: CUDA Toolkit should be manually installed on the computer before running this script
:: We assume also that cuDNN is merged into CUDA installed directory.
where nvcc >nul 2>&1
if !errorlevel! neq 0 (
echo [ERROR] nvcc was not found in your PATH.
pause
exit /b
)
for /f "tokens=5" %%a in ('nvcc --version ^| findstr "release"') do (
set "RAW_VER=%%a"
:: This removes the trailing comma
set "CUDA_VER=!RAW_VER:,=!"
set "CUDA_VER_SHORT=!CUDA_VER:.=!"
)
if "!CUDA_VER!"=="" (
echo [ERROR] Could not parse CUDA version.
pause
exit /b
)
echo Installed CUDA Toolkit: %CUDA_VER%
:: --- CONFIGURATION ---
set "VCPKG_ROOT=%~dp0vcpkg"
set "EXPORT_DIR=%~dp0vcpkg_binaries"
:: All deps downloaded/built from source (pytorch, torchvision, opencv, libfreenect2, ...) live here.
set "SRC_DIR=%~dp0vcpkg_deps_from_source"
set "TRIPLET=x64-windows-release"
set "SEVENZIP_EXE=C:\Program Files\7-Zip\7z.exe"
set "VCPKG_JSON=%~dp0vcpkg.json"
for /f "usebackq tokens=*" %%a in (`powershell -NoProfile -Command "(Get-Content '%VCPKG_JSON%' -Raw | ConvertFrom-Json).'builtin-baseline'"` ) do set "VCPKG_COMMIT=%%a"
if "%VCPKG_COMMIT%"=="" (
echo [X] Error: Could not find 'builtin-baseline' in %VCPKG_JSON%
pause
exit /b 1
)
set VCPKG_COMMIT_SHORT=%VCPKG_COMMIT:~0,8%
set "VS_LOCATOR=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
for /f "usebackq tokens=*" %%i in (`"%VS_LOCATOR%" -latest -property catalog_productLineVersion`) do set VS_YEAR=vs%%i
set ORG_TARGET_NAME=vcpkg-export-%VCPKG_COMMIT_SHORT%-x64-%VS_YEAR%
set TARGET_NAME=%ORG_TARGET_NAME%-cuda%CUDA_VER_SHORT%
set VCPKG_EXPORT_PATH=%EXPORT_DIR%\%ORG_TARGET_NAME%
set FINAL_EXPORT_PATH=%EXPORT_DIR%\%TARGET_NAME%
if not exist "%FINAL_EXPORT_PATH%" (
if not exist "%VCPKG_EXPORT_PATH%" (
call bundle_windows_deps.bat || exit /b !errorlevel!
)
echo [+] Copying %VCPKG_EXPORT_PATH% to %FINAL_EXPORT_PATH%
xcopy "%VCPKG_EXPORT_PATH%" "%FINAL_EXPORT_PATH%\" /E /I /H /Y /Q || exit /b !errorlevel!
echo [+] Remove opencv built by vcpkg
rmdir /s /q "%FINAL_EXPORT_PATH%\installed\%TRIPLET%\include\opencv4" || exit /b !errorlevel!
rmdir /s /q "%FINAL_EXPORT_PATH%\installed\%TRIPLET%\share\opencv4" || exit /b !errorlevel!
rmdir /s /q "%FINAL_EXPORT_PATH%\installed\%TRIPLET%\share\opencv" || exit /b !errorlevel!
del "%FINAL_EXPORT_PATH%\installed\%TRIPLET%\bin\opencv*" || exit /b !errorlevel!
del "%FINAL_EXPORT_PATH%\installed\%TRIPLET%\lib\opencv*" || exit /b !errorlevel!
:: bundle cudnn runtime libraries
xcopy "%CUDA_PATH%\bin\x64\cudnn*.dll" "%FINAL_EXPORT_PATH%\installed\%TRIPLET%\bin\" /Y
)
:: ZED: copy the main library + the zed-config.cmake so find_package(ZED) resolves
:: it from the export (the config derives paths from ZED_SDK_ROOT_DIR/CMAKE_PREFIX_PATH).
if "%ZED_SDK_ROOT_DIR%"=="" (
echo Error: ZED_SDK_ROOT_DIR environment variable is not set!
pause
exit /b 1
)
echo Copying ZED main library only...
:: Only the core runtime goes into the bundle; the neural-depth/TensorRT DLLs are
:: shipped separately (see the zed-neural-extra archive below).
robocopy "%ZED_SDK_ROOT_DIR%\bin" "%FINAL_EXPORT_PATH%\installed\%TRIPLET%\bin" sl_zed64.dll zlibwapi.dll /XO
robocopy "%ZED_SDK_ROOT_DIR%\lib" "%FINAL_EXPORT_PATH%\installed\%TRIPLET%\lib" /E /XO
robocopy "%ZED_SDK_ROOT_DIR%\include" "%FINAL_EXPORT_PATH%\installed\%TRIPLET%\include" /E /XO
:: Install ZED's CMake config at the export prefix root so find_package(ZED 2) (config
:: mode, via the vcpkg toolchain CMAKE_PREFIX_PATH) finds it.
robocopy "%ZED_SDK_ROOT_DIR%" "%FINAL_EXPORT_PATH%\installed\%TRIPLET%" zed-config.cmake zed-config-version.cmake /XO
:: Robocopy exit codes under 8 mean successful copies/no changes.
:: 8 or higher means there was a failure.
if !errorlevel! GEQ 8 (
echo Error: Robocopy failed with exit code !errorlevel!
pause
exit /b !errorlevel!
)
:: Archive the remaining ZED runtime DLLs (neural-depth / TensorRT extras) as a
:: separate optional download, kept out of the main bundle to keep it small. Built
:: only once: skipped if the archive already exists. Staged with robocopy /XF
:: (excludes by name; avoids 7z's "!" exclude switch that delayed expansion mangles).
set "ZED_EXTRA_7Z=%EXPORT_DIR%\%TARGET_NAME%-zed-neural-extra.7z"
set "ZED_EXTRA_DIR=%SRC_DIR%\zed-neural-extra"
if not exist "%ZED_EXTRA_7Z%" (
echo [+] Creating ZED neural extra archive...
if exist "%ZED_EXTRA_DIR%" rd /s /q "%ZED_EXTRA_DIR%"
robocopy "%ZED_SDK_ROOT_DIR%\bin" "%ZED_EXTRA_DIR%" *.dll /XF sl_zed64.dll zlibwapi.dll >nul
"%SEVENZIP_EXE%" a -t7z -mx9 "%ZED_EXTRA_7Z%" "%ZED_EXTRA_DIR%\*" || exit /b !errorlevel!
)
:: pytorch deps
%FINAL_EXPORT_PATH%/installed/%TRIPLET%/tools/python3/python.exe -m pip install numpy packaging "setuptools<82" pyyaml typing_extensions
git config --global core.longpaths true
:: All deps cloned/built below go into %SRC_DIR% (incl. libfreenect2 built by
:: bundle_windows_deps.bat) to keep the repo root clean.
if not exist "%SRC_DIR%" mkdir "%SRC_DIR%"
cd /d "%SRC_DIR%"
:: pytorch, build with local cuda libraries to avoid duplicating them when we install rtabmap
echo [+] Building pytorch with cuda support...
if not exist pytorch (
echo [+] Downloading pytorch...
git clone https://github.com/pytorch/pytorch || exit /b !errorlevel!
cd pytorch
:: Jan 21, 2026
git checkout v2.10.0
git submodule update --init --recursive || exit /b !errorlevel!
cd ..
)
set "PYTHONHOME=%FINAL_EXPORT_PATH%\installed\%TRIPLET%\tools\python3"
set "Python_ROOT_DIR=%FINAL_EXPORT_PATH%\installed\%TRIPLET%"
set CMAKE_GENERATOR=Ninja
set BUILD_TEST=0
set ATEN_NO_TEST=1
set INSTALL_TEST=OFF
set "LIB=%FINAL_EXPORT_PATH%\installed\%TRIPLET%\lib;%LIB%"
set "%FINAL_EXPORT_PATH%\installed\%TRIPLET%\include;INCLUDE=%INCLUDE%"
:: check if torch is installed
%PYTHONHOME%/python.exe -m pip show torch >nul 2>&1
if !errorlevel! neq 0 (
cd pytorch
%PYTHONHOME%/python.exe setup.py install || exit /b !errorlevel!
cd ..
)
if exist "%PYTHONHOME%\Lib\site-packages\torch\test" rd /s /q %PYTHONHOME%\Lib\site-packages\torch\test"
del "%PYTHONHOME%\Lib\site-packages\torch\bin\test_*" || exit /b !errorlevel!
echo [+] Building torchvision...
if not exist torchvision (
echo [+] Downloading torchvision...
git clone https://github.com/pytorch/vision.git torchvision || exit /b !errorlevel!
cd torchvision
:: Jan 6, 2026
git checkout v0.25.0
git submodule update --init --recursive || exit /b !errorlevel!
cd ..
)
cd torchvision
set PATH=%FINAL_EXPORT_PATH%\installed\%TRIPLET%\bin;%PATH%
set DISTUTILS_USE_SDK=1
set TORCHVISION_INCLUDE=%FINAL_EXPORT_PATH%\installed\%TRIPLET%\include
set TORCHVISION_LIBRARY=%FINAL_EXPORT_PATH%\installed\%TRIPLET%\lib
%FINAL_EXPORT_PATH%/installed/%TRIPLET%/tools/python3/python.exe -m pip install . -v --no-build-isolation || exit /b !errorlevel!
cd ..
:: opencv_cuda
echo [+] Building opencv with cuda support...
if not exist opencv (
echo [+] Downloading opencv...
git clone https://github.com/opencv/opencv.git || exit /b !errorlevel!
cd opencv
:: 4.13.0 minimum required to be compatible with cuda 13
:: Dec 31, 2025
git checkout 4.13.0
cd ..
)
if not exist opencv_contrib (
echo [+] Downloading opencv_contrib...
git clone https://github.com/opencv/opencv_contrib.git || exit /b !errorlevel!
cd opencv_contrib
:: 4.13.0 minimum required to be compatible with cuda 13
:: Dec 31, 2025
git checkout 4.13.0
cd ..
)
cd opencv
cmake -S . -B build -GNinja ^
-DVCPKG_MANIFEST_INSTALL=OFF ^
-DVCPKG_TARGET_TRIPLET=%TRIPLET% ^
-DVCPKG_INSTALLED_DIR="%FINAL_EXPORT_PATH%\installed" ^
-DCMAKE_TOOLCHAIN_FILE="%FINAL_EXPORT_PATH%\scripts\buildsystems\vcpkg.cmake" ^
-DCMAKE_INSTALL_PREFIX="%FINAL_EXPORT_PATH%\installed\%TRIPLET%" ^
-DCMAKE_BUILD_TYPE=Release ^
-DOPENCV_BIN_INSTALL_PATH="bin" ^
-DOPENCV_LIB_INSTALL_PATH="lib" ^
-DOPENCV_CONFIG_INSTALL_PATH="share/opencv" ^
-DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules ^
-DBUILD_SHARED_LIBS=ON ^
-DBUILD_TESTS=OFF ^
-DBUILD_PERF_TESTS=OFF ^
-DOPENCV_ENABLE_NONFREE=ON ^
-DBUILD_opencv_apps=OFF ^
-DBUILD_opencv_cudacodec=OFF ^
-DBUILD_opencv_python3=OFF ^
-DBUILD_opencv_python_bindings_generator=OFF ^
-DBUILD_opencv_python_tests=OFF ^
-DBUILD_opencv_java_bindings_generator=OFF ^
-DWITH_CUDA=ON ^
-DWITH_VTK=OFF ^
-DWITH_TBB=ON || exit /b !errorlevel!
cmake --build build --config Release --target install || exit /b !errorlevel!
cd ..
:: freenect2 with cuda support
:: libfreenect2's CUDA processors include <helper_math.h>, which modern CUDA toolkits
:: no longer ship (it moved to the NVIDIA/cuda-samples repo). Fetch it and point
:: NVCUDASAMPLES_ROOT at it; libfreenect2 adds %NVCUDASAMPLES_ROOT%\common\inc to nvcc.
set "CUDA_SAMPLES_DIR=%SRC_DIR%\cuda-samples"
if not exist "%CUDA_SAMPLES_DIR%\common\inc\helper_math.h" (
mkdir "%CUDA_SAMPLES_DIR%\common\inc"
curl -L -o "%CUDA_SAMPLES_DIR%\common\inc\helper_math.h" "https://raw.githubusercontent.com/NVIDIA/cuda-samples/v12.5/Common/helper_math.h" || exit /b !errorlevel!
)
set "NVCUDASAMPLES_ROOT=%CUDA_SAMPLES_DIR%"
cd libfreenect2
cmake -S . -B build_cuda -GNinja ^
-DVCPKG_MANIFEST_INSTALL=OFF ^
-DVCPKG_TARGET_TRIPLET=x64-windows-release ^
-DVCPKG_INSTALLED_DIR="%FINAL_EXPORT_PATH%\installed" ^
-DCMAKE_TOOLCHAIN_FILE="%FINAL_EXPORT_PATH%\scripts\buildsystems\vcpkg.cmake" ^
-DPKG_CONFIG_EXECUTABLE="%FINAL_EXPORT_PATH%\installed\%TRIPLET%\tools\pkgconf\pkgconf.exe" ^
-DPKG_CONFIG_USE_CMAKE_PREFIX_PATH=ON ^
-DCMAKE_INSTALL_PREFIX="%FINAL_EXPORT_PATH%\installed\%TRIPLET%" ^
-DCMAKE_BUILD_TYPE=Release ^
-DENABLE_CUDA=ON ^
-DENABLE_OPENCL=ON ^
-DENABLE_OPENGL=ON ^
-DBUILD_EXAMPLES=OFF ^
-DBUILD_SHARED_LIBS=ON || exit /b !errorlevel!
cmake --build build_cuda --config Release --target install || exit /b !errorlevel!
cd ..
:: CudaSift (CUDA SIFT/SURF GPU features, matlabbe fork; needs CUDA)
echo [+] Building CudaSift...
if not exist CudaSift (
echo [+] Downloading...
git clone https://github.com/matlabbe/CudaSift.git
cd CudaSift
git checkout f764e14ae59ee78ff5b282d38790301d80faadc3
cd ..
)
cd CudaSift
cmake -S . -B build -GNinja ^
-DVCPKG_MANIFEST_INSTALL=OFF ^
-DVCPKG_TARGET_TRIPLET=%TRIPLET% ^
-DVCPKG_INSTALLED_DIR="%FINAL_EXPORT_PATH%\installed" ^
-DCMAKE_TOOLCHAIN_FILE="%FINAL_EXPORT_PATH%\scripts\buildsystems\vcpkg.cmake" ^
-DCMAKE_INSTALL_PREFIX="%FINAL_EXPORT_PATH%\installed\%TRIPLET%" ^
-DCMAKE_BUILD_TYPE=Release ^
-DVERBOSE=OFF ^
-DBUILD_SHARED_LIBS=ON || exit /b !errorlevel!
cmake --build build --config Release --target install || exit /b !errorlevel!
cd ..
:: 5. ZIP the folder
echo [+] Creating final package with 7-Zip...
:: Rip off pdb files
cd /d "%FINAL_EXPORT_PATH%"
del /s /q /f *.pdb >nul 2>&1
cd ..
set "FINAL_ZIP=%TARGET_NAME%.7z"
:: compress contents without the root folder
"%SEVENZIP_EXE%" u -t7z -mx9 "%FINAL_ZIP%" "%FINAL_EXPORT_PATH%\*" -up0q0 || exit /b !errorlevel!
if !errorlevel! EQU 0 (
echo [!] Success! Package created at %FINAL_ZIP%
) else (
echo [X] 7-Zip failed with error code !errorlevel!
)
:: Example building rtabmap with opencv cuda and libtorch afterwards
goto :EndComment
:: The vcpkg export folder should not be in the rtabmap source directory
:: (otherwise we get some cmake errors about that)
set VCPKG_UNZIPPED_EXPORT_PATH=%USERPROFILE%\Downloads\vcpkg-export-########-x64-vs2022
set TRIPLET=x64-windows-release
set PATH=%VCPKG_UNZIPPED_EXPORT_PATH%\installed\%TRIPLET%\bin;%PATH%
set PATH=%VCPKG_UNZIPPED_EXPORT_PATH%\installed\%TRIPLET%\tools\python3;%PATH%
set PATH=%CUDA_PATH%\bin;%PATH%
set PATH=%CUDA_PATH%\bin\x64;%PATH%
set PATH=%CUDA_PATH%\extras\CUPTI\lib64;%PATH%
set PATH=%VCPKG_UNZIPPED_EXPORT_PATH%\installed\%TRIPLET%\tools\python3\Lib\site-packages\torch\lib;%PATH%
set PATH=%VCPKG_UNZIPPED_EXPORT_PATH%\installed\%TRIPLET%\tools\python3\Lib\site-packages\numpy.libs;%PATH%
set PATH=%VCPKG_UNZIPPED_EXPORT_PATH%\installed\x64-windows-release\sdk\windows-desktop\amd64\release\bin;%PATH%
set K4A_ROOT_DIR=%VCPKG_UNZIPPED_EXPORT_PATH%\installed\%TRIPLET%
set KINECTSDK20_DIR=%VCPKG_UNZIPPED_EXPORT_PATH%\installed\%TRIPLET%
set ZED_SDK_ROOT_DIR=%VCPKG_UNZIPPED_EXPORT_PATH%\installed\%TRIPLET%
cmake -B build_cuda -GNinja ^
-DCMAKE_BUILD_TYPE=Release ^
-DBUILD_AS_BUNDLE=ON ^
-DWITH_PYTHON=ON ^
-DWITH_TORCH=ON ^
-DWITH_ZED=ON ^
-DWITH_CUDASIFT=ON ^
-DWITH_CERES=ON ^
-DWITH_ORBBEC_SDK=ON ^
-DWITH_FREENECT2=ON ^
-DWITH_K4W2=ON ^
-DWITH_K4A=ON ^
-DWITH_DEPTHAI=ON ^
-DWITH_REALSENSE2=ON ^
-DWITH_CCCORELIB=ON ^
-DWITH_PDAL=OFF ^
-DVCPKG_MANIFEST_INSTALL=OFF ^
-DVCPKG_TARGET_TRIPLET=%TRIPLET% ^
-DVCPKG_INSTALLED_DIR="%VCPKG_UNZIPPED_EXPORT_PATH%/installed" ^
-DCMAKE_TOOLCHAIN_FILE=%VCPKG_UNZIPPED_EXPORT_PATH%/scripts/buildsystems/vcpkg.cmake ^
-DGTSAM_DIR=%VCPKG_UNZIPPED_EXPORT_PATH%\installed\%TRIPLET%\CMake ^
-DTorch_DIR=%VCPKG_UNZIPPED_EXPORT_PATH%\installed\%TRIPLET%\tools\python3\Lib\site-packages\torch\share\cmake\Torch
cmake --build build_cuda --config Release --target package
:: Generate superpoint weights (from share directory of the installed package)
curl -L -O "https://raw.githubusercontent.com/magicleap/SuperPointPretrainedNetwork/master/demo_superpoint.py"
curl -L -O "https://github.com/magicleap/SuperPointPretrainedNetwork/raw/refs/heads/master/superpoint_v1.pth"
..\bin\python.exe rtabmap_trace_superpoint.py
:EndComment
+105
View File
@@ -0,0 +1,105 @@
# - Find cuVSLAM library (https://github.com/NVIDIA-ISAAC-ROS/isaac_ros_visual_slam)
#
# CUVSLAM_ROOT_DIR environment variable can be set to find the library.
#
# It sets the following variables:
# CUVSLAM_FOUND - Set to false, or undefined, if cuVSLAM isn't found.
# CUVSLAM_VERSION - The version of cuVSLAM found (e.g., "14.0.0").
# CUVSLAM_INCLUDE_DIRS - The cuVSLAM include directory.
# CUVSLAM_LIBRARIES - The cuVSLAM library to link against.
find_package(CUDA REQUIRED)
find_package(Eigen3 REQUIRED)
find_path(CUVSLAM_INCLUDE_DIRS
NAMES cuvslam.h
PATHS
/usr/include
/usr/local/include
/opt/cuvslam/include
/opt/ros/humble/share/isaac_ros_nitros/cuvslam/include
$ENV{CUVSLAM_ROOT}/include
$ENV{CUVSLAM_ROOT_DIR}/include
)
find_library(CUVSLAM_LIBRARY
NAMES cuvslam
PATHS
/usr/lib
/usr/local/lib
/opt/cuvslam/lib
/opt/ros/humble/share/isaac_ros_nitros/cuvslam/lib
$ENV{CUVSLAM_ROOT}/lib
$ENV{CUVSLAM_ROOT_DIR}/lib
)
if(CUVSLAM_INCLUDE_DIRS AND CUVSLAM_LIBRARY)
# Extract version from cuvslam.h header
file(STRINGS "${CUVSLAM_INCLUDE_DIRS}/cuvslam.h" CUVSLAM_VERSION_MAJOR_LINE
REGEX "^#define CUVSLAM_API_VERSION_MAJOR")
file(STRINGS "${CUVSLAM_INCLUDE_DIRS}/cuvslam.h" CUVSLAM_VERSION_MINOR_LINE
REGEX "^#define CUVSLAM_API_VERSION_MINOR")
if(CUVSLAM_VERSION_MAJOR_LINE AND CUVSLAM_VERSION_MINOR_LINE)
string(REGEX MATCH "[0-9]+" CUVSLAM_VERSION_MAJOR "${CUVSLAM_VERSION_MAJOR_LINE}")
string(REGEX MATCH "[0-9]+" CUVSLAM_VERSION_MINOR "${CUVSLAM_VERSION_MINOR_LINE}")
set(CUVSLAM_VERSION "${CUVSLAM_VERSION_MAJOR}.${CUVSLAM_VERSION_MINOR}.0")
endif()
set(CUVSLAM_LIBRARIES
${CUVSLAM_LIBRARY}
${CUDA_LIBRARIES}
# Eigen3 is header-only, so we don't need to link to it
)
set(CUVSLAM_INCLUDE_DIRS
${CUVSLAM_INCLUDE_DIRS}
${CUDA_INCLUDE_DIRS}
${EIGEN3_INCLUDE_DIR}
)
endif()
# Version compatibility check - cuVSLAM only guarantees API compatibility within the same major version
set(CUVSLAM_VERSION_MISMATCH_REASON "")
if(CuVSLAM_FIND_VERSION AND CUVSLAM_VERSION)
string(REGEX MATCH "^[0-9]+" REQUESTED_MAJOR_VERSION "${CuVSLAM_FIND_VERSION}")
if(NOT CUVSLAM_VERSION_MAJOR EQUAL REQUESTED_MAJOR_VERSION)
set(CUVSLAM_VERSION_MISMATCH_REASON "Major version mismatch: found ${CUVSLAM_VERSION_MAJOR}.x but requested ${REQUESTED_MAJOR_VERSION}.x.\ncuVSLAM only guarantees API compatibility within the same major version.\nPlease install cuVSLAM ${REQUESTED_MAJOR_VERSION}.x or update CMakeLists.txt to request version ${CUVSLAM_VERSION_MAJOR}.0.0")
if(CuVSLAM_FIND_REQUIRED)
message(FATAL_ERROR
"cuVSLAM major version mismatch: found version ${CUVSLAM_VERSION} but version ${CuVSLAM_FIND_VERSION} is required.\n"
"cuVSLAM only guarantees API compatibility within the same major version.\n"
"Found major version ${CUVSLAM_VERSION_MAJOR} is not compatible with requested major version ${REQUESTED_MAJOR_VERSION}.\n"
"Please install cuVSLAM ${REQUESTED_MAJOR_VERSION}.x or update CMakeLists.txt to request version ${CUVSLAM_VERSION_MAJOR}.x."
)
else()
# Clear the found variables to indicate incompatibility
unset(CUVSLAM_LIBRARIES)
unset(CUVSLAM_INCLUDE_DIRS)
endif()
endif()
endif()
# Handle the QUIET and REQUIRED arguments
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CuVSLAM
FOUND_VAR CUVSLAM_FOUND
REQUIRED_VARS CUVSLAM_LIBRARIES CUVSLAM_INCLUDE_DIRS
VERSION_VAR CUVSLAM_VERSION
REASON_FAILURE_MESSAGE "${CUVSLAM_VERSION_MISMATCH_REASON}"
HANDLE_COMPONENTS
)
if(CUVSLAM_FOUND)
# Create imported target for modern CMake usage
if(NOT TARGET cuvslam::cuvslam)
add_library(cuvslam::cuvslam UNKNOWN IMPORTED)
set_target_properties(cuvslam::cuvslam PROPERTIES
IMPORTED_LOCATION "${CUVSLAM_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${CUVSLAM_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${CUVSLAM_LIBRARIES};Eigen3::Eigen"
)
endif()
endif()
mark_as_advanced(CUVSLAM_INCLUDE_DIRS CUVSLAM_LIBRARY)
+9 -3
View File
@@ -27,10 +27,10 @@
if(NOT Eigen3_FIND_VERSION) if(NOT Eigen3_FIND_VERSION)
if(NOT Eigen3_FIND_VERSION_MAJOR) if(NOT Eigen3_FIND_VERSION_MAJOR)
set(Eigen3_FIND_VERSION_MAJOR 2) set(Eigen3_FIND_VERSION_MAJOR 3)
endif() endif()
if(NOT Eigen3_FIND_VERSION_MINOR) if(NOT Eigen3_FIND_VERSION_MINOR)
set(Eigen3_FIND_VERSION_MINOR 91) set(Eigen3_FIND_VERSION_MINOR 0)
endif() endif()
if(NOT Eigen3_FIND_VERSION_PATCH) if(NOT Eigen3_FIND_VERSION_PATCH)
set(Eigen3_FIND_VERSION_PATCH 0) set(Eigen3_FIND_VERSION_PATCH 0)
@@ -40,7 +40,13 @@ if(NOT Eigen3_FIND_VERSION)
endif() endif()
macro(_eigen3_check_version) macro(_eigen3_check_version)
file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header) # Since Eigen 5.0.0 the version macros moved from Eigen/src/Core/util/Macros.h
# to a dedicated Eigen/Version header, so check the new location first.
if(EXISTS "${EIGEN3_INCLUDE_DIR}/Eigen/Version")
file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/Version" _eigen3_version_header)
else()
file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header)
endif()
string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}") string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}")
set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}") set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}")
+27 -16
View File
@@ -26,6 +26,10 @@ FIND_FILE(G2O_FACTORY_FILE g2o/core/factory.h
PATHS ${G2O_INCLUDE_DIR} PATHS ${G2O_INCLUDE_DIR}
NO_DEFAULT_PATH) NO_DEFAULT_PATH)
FIND_FILE(G2O_SBA_UTILS_FILE g2o/types/sba/sba_utils.h
PATHS ${G2O_INCLUDE_DIR}
NO_DEFAULT_PATH)
#ifdef G2O_NUMBER_FORMAT_STR #ifdef G2O_NUMBER_FORMAT_STR
#define G2O_CPP11 // we assume that if G2O_NUMBER_FORMAT_STR is defined, this is the new g2o code with c++11 interface #define G2O_CPP11 // we assume that if G2O_NUMBER_FORMAT_STR is defined, this is the new g2o code with c++11 interface
#endif #endif
@@ -97,16 +101,16 @@ IF(G2O_STUFF_LIBRARY AND G2O_CORE_LIBRARY AND G2O_INCLUDE_DIR AND G2O_CONFIG_FIL
${G2O_TYPES_SBA} ${G2O_TYPES_SBA}
${G2O_STUFF_LIBRARY}) ${G2O_STUFF_LIBRARY})
IF(CSPARSE_FOUND) IF(CSPARSE_FOUND AND G2O_SOLVER_CSPARSE AND G2O_SOLVER_CSPARSE_EXTENSION)
SET(G2O_INCLUDE_DIRS SET(G2O_INCLUDE_DIRS
${G2O_INCLUDE_DIRS} ${G2O_INCLUDE_DIRS}
${CSPARSE_INCLUDE_DIR}) ${CSPARSE_INCLUDE_DIR})
SET(G2O_LIBRARIES SET(G2O_LIBRARIES
${G2O_LIBRARIES} ${G2O_LIBRARIES}
${G2O_SOLVER_CSPARSE} ${G2O_SOLVER_CSPARSE}
${G2O_SOLVER_CSPARSE_EXTENSION} ${G2O_SOLVER_CSPARSE_EXTENSION}
${CSPARSE_LIBRARY}) ${CSPARSE_LIBRARY})
ENDIF(CSPARSE_FOUND) ENDIF(CSPARSE_FOUND AND G2O_SOLVER_CSPARSE AND G2O_SOLVER_CSPARSE_EXTENSION)
IF(G2O_SOLVER_CHOLMOD) IF(G2O_SOLVER_CHOLMOD)
SET(G2O_INCLUDE_DIRS SET(G2O_INCLUDE_DIRS
@@ -118,22 +122,29 @@ IF(G2O_STUFF_LIBRARY AND G2O_CORE_LIBRARY AND G2O_INCLUDE_DIR AND G2O_CONFIG_FIL
${CHOLMOD_LIB}) ${CHOLMOD_LIB})
ENDIF(G2O_SOLVER_CHOLMOD) ENDIF(G2O_SOLVER_CHOLMOD)
FILE(READ ${G2O_CONFIG_FILE} TMPTXT) FILE(READ ${G2O_FACTORY_FILE} TMPTXT)
STRING(FIND "${TMPTXT}" "G2O_NUMBER_FORMAT_STR" matchres) STRING(FIND "${TMPTXT}" "shared_ptr" matchres)
IF(${matchres} EQUAL -1) IF(${matchres} EQUAL -1)
MESSAGE(STATUS "Old g2o version detected with c++03 interface (config file: ${G2O_CONFIG_FILE}).") FILE(READ ${G2O_CONFIG_FILE} TMPTXT)
SET(G2O_CPP11 0) STRING(FIND "${TMPTXT}" "G2O_NUMBER_FORMAT_STR" matchres)
ELSE()
MESSAGE(WARNING "Latest g2o version detected with c++11 interface (config file: ${G2O_CONFIG_FILE}). Make sure g2o is built with \"-DBUILD_WITH_MARCH_NATIVE=OFF\" to avoid segmentation faults caused by Eigen.")
FILE(READ ${G2O_FACTORY_FILE} TMPTXT)
STRING(FIND "${TMPTXT}" "shared_ptr" matchres)
IF(${matchres} EQUAL -1) IF(${matchres} EQUAL -1)
MESSAGE(STATUS "Old g2o version detected with c++03 interface (config file: ${G2O_CONFIG_FILE}).")
SET(G2O_CPP11 0)
ELSE()
MESSAGE(WARNING "Latest g2o version detected with c++11 interface (config file: ${G2O_CONFIG_FILE}). Make sure g2o is built with \"-DBUILD_WITH_MARCH_NATIVE=OFF\" to avoid segmentation faults caused by Eigen.")
MESSAGE(STATUS "Old g2o factory version detected without shared ptr (factory file: ${G2O_FACTORY_FILE}).") MESSAGE(STATUS "Old g2o factory version detected without shared ptr (factory file: ${G2O_FACTORY_FILE}).")
SET(G2O_CPP11 2) SET(G2O_CPP11 2)
ELSE()
MESSAGE(STATUS "Latest g2o factory version detected with shared ptr (factory file: ${G2O_FACTORY_FILE}).")
SET(G2O_CPP11 1)
ENDIF() ENDIF()
ELSE()
MESSAGE(WARNING "Latest g2o version detected with c++11 interface (config file: ${G2O_CONFIG_FILE}). Make sure g2o is built with \"-DBUILD_WITH_MARCH_NATIVE=OFF\" to avoid segmentation faults caused by Eigen.")
MESSAGE(STATUS "Latest g2o factory version detected with shared ptr (factory file: ${G2O_FACTORY_FILE}).")
SET(G2O_CPP11 1)
ENDIF()
IF(G2O_SBA_UTILS_FILE)
SET(G2O_WITH_SBA_UTILS 1)
ELSE()
SET(G2O_WITH_SBA_UTILS 0)
ENDIF() ENDIF()
SET(G2O_FOUND "YES") SET(G2O_FOUND "YES")
+4 -3
View File
@@ -11,6 +11,7 @@
find_path(ORB_SLAM_INCLUDE_DIR NAMES System.h PATHS $ENV{ORB_SLAM_ROOT_DIR}/include) find_path(ORB_SLAM_INCLUDE_DIR NAMES System.h PATHS $ENV{ORB_SLAM_ROOT_DIR}/include)
find_library(ORB_SLAM2_LIBRARY NAMES ORB_SLAM2 PATHS $ENV{ORB_SLAM_ROOT_DIR}/lib) find_library(ORB_SLAM2_LIBRARY NAMES ORB_SLAM2 PATHS $ENV{ORB_SLAM_ROOT_DIR}/lib)
find_library(ORB_SLAM3_LIBRARY NAMES ORB_SLAM3 PATHS $ENV{ORB_SLAM_ROOT_DIR}/lib) find_library(ORB_SLAM3_LIBRARY NAMES ORB_SLAM3 PATHS $ENV{ORB_SLAM_ROOT_DIR}/lib)
find_path(DBoW2_INCLUDE_DIR NAMES DBoW2/BowVector.h PATHS $ENV{ORB_SLAM_ROOT_DIR}/Thirdparty/DBoW2 NO_DEFAULT_PATH)
find_path(g2o_INCLUDE_DIR NAMES g2o/core/sparse_optimizer.h PATHS $ENV{ORB_SLAM_ROOT_DIR}/Thirdparty/g2o NO_DEFAULT_PATH) find_path(g2o_INCLUDE_DIR NAMES g2o/core/sparse_optimizer.h PATHS $ENV{ORB_SLAM_ROOT_DIR}/Thirdparty/g2o NO_DEFAULT_PATH)
find_path(sophus_INCLUDE_DIR NAMES sophus/se3.hpp PATHS $ENV{ORB_SLAM_ROOT_DIR}/Thirdparty/Sophus NO_DEFAULT_PATH) find_path(sophus_INCLUDE_DIR NAMES sophus/se3.hpp PATHS $ENV{ORB_SLAM_ROOT_DIR}/Thirdparty/Sophus NO_DEFAULT_PATH)
find_library(g2o_LIBRARY NAMES g2o PATHS $ENV{ORB_SLAM_ROOT_DIR}/Thirdparty/g2o/lib NO_DEFAULT_PATH) find_library(g2o_LIBRARY NAMES g2o PATHS $ENV{ORB_SLAM_ROOT_DIR}/Thirdparty/g2o/lib NO_DEFAULT_PATH)
@@ -22,9 +23,9 @@ IF(ORB_SLAM2_LIBRARY)
ELSEIF(ORB_SLAM3_LIBRARY) ELSEIF(ORB_SLAM3_LIBRARY)
SET(ORB_SLAM_VERSION 3) SET(ORB_SLAM_VERSION 3)
SET(ORB_SLAM_LIBRARY ${ORB_SLAM3_LIBRARY}) SET(ORB_SLAM_LIBRARY ${ORB_SLAM3_LIBRARY})
IF(g2o_INCLUDE_DIR AND sophus_INCLUDE_DIR) # ORB_SLAM3 v1 IF(g2o_INCLUDE_DIR AND sophus_INCLUDE_DIR AND DBoW2_INCLUDE_DIR) # ORB_SLAM3 v1
SET(g2o_INCLUDE_DIR ${g2o_INCLUDE_DIR} ${sophus_INCLUDE_DIR}) SET(g2o_INCLUDE_DIR ${g2o_INCLUDE_DIR} ${sophus_INCLUDE_DIR} ${DBoW2_INCLUDE_DIR} $ENV{ORB_SLAM_ROOT_DIR})
ENDIF(g2o_INCLUDE_DIR AND sophus_INCLUDE_DIR) ENDIF(g2o_INCLUDE_DIR AND sophus_INCLUDE_DIR AND DBoW2_INCLUDE_DIR)
ENDIF() ENDIF()
IF (ORB_SLAM_INCLUDE_DIR AND ORB_SLAM_LIBRARY AND DBoW2_LIBRARY AND g2o_INCLUDE_DIR AND g2o_LIBRARY) IF (ORB_SLAM_INCLUDE_DIR AND ORB_SLAM_LIBRARY AND DBoW2_LIBRARY AND g2o_INCLUDE_DIR AND g2o_LIBRARY)
+44
View File
@@ -0,0 +1,44 @@
# Find OpenVINS
#
# We search for a vins installation in ROS/ROS2 first, then fallback on
# ros-free library in common install paths
FIND_PACKAGE(ov_msckf QUIET)
IF(ov_msckf_FOUND)
# On ROS2, the indirect includes and libraries
# are not forwarded by ov_msckf target, append them manually
FIND_PACKAGE(ov_core)
FIND_PACKAGE(ov_init)
IF(ov_msckf_FOUND AND ov_core_FOUND AND ov_init_FOUND)
SET(OpenVINS_FOUND TRUE)
SET(OpenVINS_INCLUDE_DIRS
${ov_msckf_INCLUDE_DIRS}
${ov_core_INCLUDE_DIRS}
${ov_init_INCLUDE_DIRS})
SET(OpenVINS_LIBRARIES
${ov_msckf_LIBRARIES}
${ov_core_LIBRARIES}
${ov_init_LIBRARIES})
ENDIF()
ELSE()
find_path(OpenVINS_INCLUDE_DIR NAMES core/VioManager.h PATH_SUFFIXES open_vins)
find_library(OpenVINS_LIBRARY NAMES ov_msckf_lib)
IF (OpenVINS_INCLUDE_DIR AND OpenVINS_LIBRARY)
SET(OpenVINS_FOUND TRUE)
SET(OpenVINS_INCLUDE_DIRS ${OpenVINS_INCLUDE_DIR})
SET(OpenVINS_LIBRARIES ${OpenVINS_LIBRARY})
ENDIF()
ENDIF()
IF (OpenVINS_FOUND)
# show which OpenVINS was found only if not quiet
IF (NOT OpenVINS_FIND_QUIETLY)
MESSAGE(STATUS "Found OpenVINS: ${OpenVINS_LIBRARIES} ${OpenVINS_INCLUDE_DIRS}")
ENDIF (NOT OpenVINS_FIND_QUIETLY)
ELSE (OpenVINS_FOUND)
# fatal error if OpenVINS is required but not found
IF (OpenVINS_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find OpenVINS")
ENDIF (OpenVINS_FIND_REQUIRED)
ENDIF (OpenVINS_FOUND)
+8 -2
View File
@@ -10,8 +10,6 @@
<string>${MACOSX_BUNDLE_INFO_STRING}</string> <string>${MACOSX_BUNDLE_INFO_STRING}</string>
<key>CFBundleIconFile</key> <key>CFBundleIconFile</key>
<string>${MACOSX_BUNDLE_ICON_FILE}</string> <string>${MACOSX_BUNDLE_ICON_FILE}</string>
<key>CFBundleIdentifier</key>
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleLongVersionString</key> <key>CFBundleLongVersionString</key>
@@ -32,6 +30,14 @@
<true/> <true/>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string>${MACOSX_BUNDLE_COPYRIGHT}</string> <string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
<key>com.apple.security.files.downloads.read-only</key>
<false/>
<key>com.apple.security.device.camera</key>
<true/>
<!-- File type associations --> <!-- File type associations -->
<key>CFBundleDocumentTypes</key> <key>CFBundleDocumentTypes</key>
+2 -1
View File
@@ -48,7 +48,7 @@ public:
SensorData takeImage(SensorCaptureInfo * info = 0) {return takeData(info);} SensorData takeImage(SensorCaptureInfo * info = 0) {return takeData(info);}
float getImageRate() const {return getFrameRate();} float getImageRate() const {return getFrameRate();}
void setImageRate(float imageRate) {setFrameRate(imageRate);} void setImageRate(float imageRate) {setFrameRate(imageRate);}
void setInterIMUPublishing(bool enabled, IMUFilter * filter = 0); // Take ownership of filter void setInterIMUPublishing(bool enabled, IMUFilter * filter = 0, bool baseFrameConversion = false); // Take ownership of filter
bool isInterIMUPublishing() const {return publishInterIMU_;} bool isInterIMUPublishing() const {return publishInterIMU_;}
bool initFromFile(const std::string & calibrationPath); bool initFromFile(const std::string & calibrationPath);
@@ -73,6 +73,7 @@ private:
private: private:
IMUFilter * imuFilter_; IMUFilter * imuFilter_;
bool publishInterIMU_; bool publishInterIMU_;
bool imuBaseFrameConversion_;
}; };
+4 -2
View File
@@ -126,8 +126,10 @@ public:
double verticalFOV() const; // in degrees double verticalFOV() const; // in degrees
bool isFisheye() const {return D_.cols == 6;} bool isFisheye() const {return D_.cols == 6;}
bool load(const std::string & filePath); // Set initRectificationMaps=false to skip building the (potentially large)
bool load(const std::string & directory, const std::string & cameraName); // rectification maps when rectification won't be used (saves time and memory).
bool load(const std::string & filePath, bool initRectificationMaps = true);
bool load(const std::string & directory, const std::string & cameraName, bool initRectificationMaps = true);
bool save(const std::string & directory) const; bool save(const std::string & directory) const;
std::vector<unsigned char> serialize() const; std::vector<unsigned char> serialize() const;
unsigned int deserialize(const std::vector<unsigned char>& data); unsigned int deserialize(const std::vector<unsigned char>& data);
@@ -38,3 +38,4 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/core/camera/CameraRGBDImages.h> #include <rtabmap/core/camera/CameraRGBDImages.h>
#include <rtabmap/core/camera/CameraK4A.h> #include <rtabmap/core/camera/CameraK4A.h>
#include <rtabmap/core/camera/CameraSeerSense.h> #include <rtabmap/core/camera/CameraSeerSense.h>
#include <rtabmap/core/camera/CameraOrbbecSDK.h>
+21 -9
View File
@@ -72,6 +72,14 @@ public:
const std::string & getUrl() const {return _url;} const std::string & getUrl() const {return _url;}
const std::string & getTargetVersion() const {return _targetVersion;} const std::string & getTargetVersion() const {return _targetVersion;}
// Start recording changes made to the database until it is closed, then write a compact
// delta of those changes to outputUrl (empty disables). outputUrl MUST use the ".dbu"
// (db update) extension. Returns true if recording is active. Only the SQLite backend
// supports it (session extension + database version >= 0.24); other backends return false.
// NOTE: recorded changes are held in RAM until the database is closed, so only enable
// this when the expected set of changes is small.
virtual bool trackDatabaseChanges(const std::string & outputUrl) {(void)outputUrl; return false;}
void beginTransaction() const; void beginTransaction() const;
void commit() const; void commit() const;
@@ -129,11 +137,12 @@ public:
std::vector<std::vector<Eigen::Vector2f> > * texCoords = 0, std::vector<std::vector<Eigen::Vector2f> > * texCoords = 0,
#endif #endif
cv::Mat * textures = 0) const; cv::Mat * textures = 0) const;
void saveFlannIndex(const std::vector<unsigned char> & indexData) const;
public: public:
// Mutex-protected methods of abstract versions below // Mutex-protected methods of abstract versions below
bool openConnection(const std::string & url, bool overwritten = false); bool openConnection(const std::string & url, bool overwritten = false, bool readOnly = false);
void closeConnection(bool save = true, const std::string & outputUrl = ""); void closeConnection(bool save = true, const std::string & outputUrl = "");
bool isConnected() const; bool isConnected() const;
unsigned long getMemoryUsed() const; // In bytes unsigned long getMemoryUsed() const; // In bytes
@@ -161,19 +170,20 @@ public:
void executeNoResult(const std::string & sql) const; void executeNoResult(const std::string & sql) const;
// Load objects // Load objects
void load(VWDictionary * dictionary, bool lastStateOnly = true) const; void load(VWDictionary & dictionary, bool lastStateOnly = true) const;
void loadLastNodes(std::list<Signature *> & signatures) const; // returned signatures must be freed after usage void loadLastNodes(std::list<Signature *> & signatures, bool loadWordIdsOnly = false) const; // returned signatures must be freed after usage
Signature * loadSignature(int id, bool * loadedFromTrash = 0); // returned signature must be freed after usage, call loadSignatures() instead if more than one signature should be loaded Signature * loadSignature(int id, bool * loadedFromTrash = 0); // returned signature must be freed after usage, call loadSignatures() instead if more than one signature should be loaded
void loadSignatures(const std::list<int> & ids, std::list<Signature *> & signatures, std::set<int> * loadedFromTrash = 0); // returned signatures must be freed after usage void loadSignatures(const std::list<int> & ids, std::list<Signature *> & signatures, std::set<int> * loadedFromTrash = 0, bool loadWordIdsOnly = false); // returned signatures must be freed after usage
void loadWords(const std::set<int> & wordIds, std::list<VisualWord *> & vws); // returned words must be freed after usage void loadWords(const std::set<int> & wordIds, std::list<VisualWord *> & vws); // returned words must be freed after usage
// Specific queries... // Specific queries...
void loadNodeData(Signature * signature, bool images = true, bool scan = true, bool userData = true, bool occupancyGrid = true) const; void loadNodeData(Signature & signature, bool images = true, bool scan = true, bool userData = true, bool occupancyGrid = true) const;
void loadNodeData(std::list<Signature *> & signatures, bool images = true, bool scan = true, bool userData = true, bool occupancyGrid = true) const; void loadNodeData(std::list<Signature *> & signatures, bool images = true, bool scan = true, bool userData = true, bool occupancyGrid = true) const;
void getNodeData(int signatureId, SensorData & data, bool images = true, bool scan = true, bool userData = true, bool occupancyGrid = true) const; void getNodeData(int signatureId, SensorData & data, bool images = true, bool scan = true, bool userData = true, bool occupancyGrid = true) const;
bool getCalibration(int signatureId, std::vector<CameraModel> & models, std::vector<StereoCameraModel> & stereoModels) const; bool getCalibration(int signatureId, std::vector<CameraModel> & models, std::vector<StereoCameraModel> & stereoModels) const;
bool getLaserScanInfo(int signatureId, LaserScan & info) const; bool getLaserScanInfo(int signatureId, LaserScan & info) const;
bool getNodeInfo(int signatureId, Transform & pose, int & mapId, int & weight, std::string & label, double & stamp, Transform & groundTruthPose, std::vector<float> & velocity, GPS & gps, EnvSensors & sensors) const; bool getNodeInfo(int signatureId, Transform & pose, int & mapId, int & weight, std::string & label, double & stamp, Transform & groundTruthPose, std::vector<float> & velocity, GPS & gps, EnvSensors & sensors) const;
void getLocalFeatures(int signatureId, std::multimap<int, int> & words, std::vector<cv::KeyPoint> & keypoints, std::vector<cv::Point3f> & points, cv::Mat & descriptors) const;
void loadLinks(int signatureId, std::multimap<int, Link> & links, Link::Type type = Link::kUndef) const; void loadLinks(int signatureId, std::multimap<int, Link> & links, Link::Type type = Link::kUndef) const;
void getWeight(int signatureId, int & weight) const; void getWeight(int signatureId, int & weight) const;
void getLastNodeIds(std::set<int> & ids) const; void getLastNodeIds(std::set<int> & ids) const;
@@ -191,7 +201,7 @@ public:
protected: protected:
DBDriver(const ParametersMap & parameters = ParametersMap()); DBDriver(const ParametersMap & parameters = ParametersMap());
virtual bool connectDatabaseQuery(const std::string & url, bool overwritten = false) = 0; virtual bool connectDatabaseQuery(const std::string & url, bool overwritten = false, bool readOnly = false) = 0;
virtual void disconnectDatabaseQuery(bool save = true, const std::string & outputUrl = "") = 0; virtual void disconnectDatabaseQuery(bool save = true, const std::string & outputUrl = "") = 0;
virtual bool isConnectedQuery() const = 0; virtual bool isConnectedQuery() const = 0;
virtual unsigned long getMemoryUsedQuery() const = 0; // In bytes virtual unsigned long getMemoryUsedQuery() const = 0; // In bytes
@@ -274,11 +284,12 @@ protected:
std::vector<std::vector<Eigen::Vector2f> > * texCoords, std::vector<std::vector<Eigen::Vector2f> > * texCoords,
#endif #endif
cv::Mat * textures) const = 0; cv::Mat * textures) const = 0;
virtual void saveFlannIndexQuery(const std::vector<unsigned char> & indexData) const = 0;
// Load objects // Load objects
virtual void loadQuery(VWDictionary * dictionary, bool lastStateOnly = true) const = 0; virtual void loadQuery(VWDictionary & dictionary, bool lastStateOnly = true) const = 0;
virtual void loadLastNodesQuery(std::list<Signature *> & signatures) const = 0; virtual void loadLastNodesQuery(std::list<Signature *> & signatures, bool loadWordIdsOnly) const = 0;
virtual void loadSignaturesQuery(const std::list<int> & ids, std::list<Signature *> & signatures) const = 0; virtual void loadSignaturesQuery(const std::list<int> & ids, std::list<Signature *> & signatures, bool loadWordIdsOnly) const = 0;
virtual void loadWordsQuery(const std::set<int> & wordIds, std::list<VisualWord *> & vws) const = 0; virtual void loadWordsQuery(const std::set<int> & wordIds, std::list<VisualWord *> & vws) const = 0;
virtual void loadLinksQuery(int signatureId, std::multimap<int, Link> & links, Link::Type type = Link::kUndef) const = 0; virtual void loadLinksQuery(int signatureId, std::multimap<int, Link> & links, Link::Type type = Link::kUndef) const = 0;
@@ -286,6 +297,7 @@ protected:
virtual bool getCalibrationQuery(int signatureId, std::vector<CameraModel> & models, std::vector<StereoCameraModel> & stereoModels) const = 0; virtual bool getCalibrationQuery(int signatureId, std::vector<CameraModel> & models, std::vector<StereoCameraModel> & stereoModels) const = 0;
virtual bool getLaserScanInfoQuery(int signatureId, LaserScan & info) const = 0; virtual bool getLaserScanInfoQuery(int signatureId, LaserScan & info) const = 0;
virtual bool getNodeInfoQuery(int signatureId, Transform & pose, int & mapId, int & weight, std::string & label, double & stamp, Transform & groundTruthPose, std::vector<float> & velocity, GPS & gps, EnvSensors & sensors) const = 0; virtual bool getNodeInfoQuery(int signatureId, Transform & pose, int & mapId, int & weight, std::string & label, double & stamp, Transform & groundTruthPose, std::vector<float> & velocity, GPS & gps, EnvSensors & sensors) const = 0;
virtual void getLocalFeaturesQuery(int signatureId, std::multimap<int, int> & words, std::vector<cv::KeyPoint> & keypoints, std::vector<cv::Point3f> & points, cv::Mat & descriptors) const = 0;
virtual void getLastNodeIdsQuery(std::set<int> & ids) const = 0; virtual void getLastNodeIdsQuery(std::set<int> & ids) const = 0;
virtual void getAllNodeIdsQuery(std::set<int> & ids, bool ignoreChildren, bool ignoreBadSignatures, bool ignoreIntermediateNodes) const = 0; virtual void getAllNodeIdsQuery(std::set<int> & ids, bool ignoreChildren, bool ignoreBadSignatures, bool ignoreIntermediateNodes) const = 0;
virtual void getAllOdomPosesQuery(std::map<int, Transform> & poses, bool ignoreChildren, bool ignoreIntermediateNodes) const = 0; virtual void getAllOdomPosesQuery(std::map<int, Transform> & poses, bool ignoreChildren, bool ignoreIntermediateNodes) const = 0;
+40 -4
View File
@@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
typedef struct sqlite3_stmt sqlite3_stmt; typedef struct sqlite3_stmt sqlite3_stmt;
typedef struct sqlite3 sqlite3; typedef struct sqlite3 sqlite3;
typedef struct sqlite3_session sqlite3_session;
namespace rtabmap { namespace rtabmap {
@@ -49,9 +50,32 @@ public:
void setCacheSize(unsigned int cacheSize); void setCacheSize(unsigned int cacheSize);
void setSynchronous(int synchronous); void setSynchronous(int synchronous);
void setTempStore(int tempStore); void setTempStore(int tempStore);
// Start recording changes made to the database from now until it is closed, then write
// a compact changeset delta to outputUrl (empty disables). outputUrl MUST use the ".dbu"
// (db update) extension. Can be called before the connection is opened or on an already-open
// connection (e.g. after init(), so the baseline is the current content). Returns true if
// recording is active. Only effective if the build/runtime SQLite has the session extension
// and the database is version >= 0.24.
// NOTE: the SQLite session extension holds ALL recorded changes in RAM until the database
// is closed (there is no incremental spill to disk), so only enable this when the expected
// set of changes is small (e.g. appending a few sessions), not for rewriting a whole map.
virtual bool trackDatabaseChanges(const std::string & outputUrl);
// Apply a ".dbu" change delta previously written by trackDatabaseChanges() onto the database
// at databasePath. The file (which must have the ".dbu" extension) is decompressed (same codec
// as the other rtabmap blobs) then applied with the SQLite session extension. With rewind=false,
// databasePath must be at the same state the delta was recorded from; with rewind=true, the
// delta is inverted first to undo it, so databasePath must be at the post-update state. Returns
// true on success; on failure returns false and, if errorMsg is not null, sets a human-readable
// message. Requires a SQLite library built with the session extension (both build and runtime).
static bool applyChangesFromFile(
const std::string & databasePath,
const std::string & changesetPath,
bool rewind = false,
std::string * errorMsg = 0);
protected: protected:
virtual bool connectDatabaseQuery(const std::string & url, bool overwritten = false); virtual bool connectDatabaseQuery(const std::string & url, bool overwritten = false, bool readOnly = false);
virtual void disconnectDatabaseQuery(bool save = true, const std::string & outputUrl = ""); virtual void disconnectDatabaseQuery(bool save = true, const std::string & outputUrl = "");
virtual bool isConnectedQuery() const; virtual bool isConnectedQuery() const;
virtual unsigned long getMemoryUsedQuery() const; // In bytes virtual unsigned long getMemoryUsedQuery() const; // In bytes
@@ -135,10 +159,12 @@ protected:
#endif #endif
cv::Mat * textures) const; cv::Mat * textures) const;
virtual void saveFlannIndexQuery(const std::vector<unsigned char> & indexData) const;
// Load objects // Load objects
virtual void loadQuery(VWDictionary * dictionary, bool lastStateOnly = true) const; virtual void loadQuery(VWDictionary & dictionary, bool lastStateOnly = true) const;
virtual void loadLastNodesQuery(std::list<Signature *> & signatures) const; virtual void loadLastNodesQuery(std::list<Signature *> & signatures, bool loadWordIdsOnly) const;
virtual void loadSignaturesQuery(const std::list<int> & ids, std::list<Signature *> & signatures) const; virtual void loadSignaturesQuery(const std::list<int> & ids, std::list<Signature *> & signatures, bool loadWordIdsOnly) const;
virtual void loadWordsQuery(const std::set<int> & wordIds, std::list<VisualWord *> & vws) const; virtual void loadWordsQuery(const std::set<int> & wordIds, std::list<VisualWord *> & vws) const;
virtual void loadLinksQuery(int signatureId, std::multimap<int, Link> & links, Link::Type type = Link::kUndef) const; virtual void loadLinksQuery(int signatureId, std::multimap<int, Link> & links, Link::Type type = Link::kUndef) const;
@@ -146,6 +172,7 @@ protected:
virtual bool getCalibrationQuery(int signatureId, std::vector<CameraModel> & models, std::vector<StereoCameraModel> & stereoModels) const; virtual bool getCalibrationQuery(int signatureId, std::vector<CameraModel> & models, std::vector<StereoCameraModel> & stereoModels) const;
virtual bool getLaserScanInfoQuery(int signatureId, LaserScan & info) const; virtual bool getLaserScanInfoQuery(int signatureId, LaserScan & info) const;
virtual bool getNodeInfoQuery(int signatureId, Transform & pose, int & mapId, int & weight, std::string & label, double & stamp, Transform & groundTruthPose, std::vector<float> & velocity, GPS & gps, EnvSensors & sensors) const; virtual bool getNodeInfoQuery(int signatureId, Transform & pose, int & mapId, int & weight, std::string & label, double & stamp, Transform & groundTruthPose, std::vector<float> & velocity, GPS & gps, EnvSensors & sensors) const;
virtual void getLocalFeaturesQuery(int signatureId, std::multimap<int, int> & words, std::vector<cv::KeyPoint> & keypoints, std::vector<cv::Point3f> & points, cv::Mat & descriptors) const;
virtual void getLastNodeIdsQuery(std::set<int> & ids) const; virtual void getLastNodeIdsQuery(std::set<int> & ids) const;
virtual void getAllNodeIdsQuery(std::set<int> & ids, bool ignoreChildren, bool ignoreBadSignatures, bool ignoreIntermediateNodes) const; virtual void getAllNodeIdsQuery(std::set<int> & ids, bool ignoreChildren, bool ignoreBadSignatures, bool ignoreIntermediateNodes) const;
virtual void getAllOdomPosesQuery(std::map<int, Transform> & poses, bool ignoreChildren, bool ignoreIntermediateNodes) const; virtual void getAllOdomPosesQuery(std::map<int, Transform> & poses, bool ignoreChildren, bool ignoreIntermediateNodes) const;
@@ -190,8 +217,11 @@ private:
const cv::Point3f & viewpoint) const; const cv::Point3f & viewpoint) const;
private: private:
void loadWordsQuery(std::list<Signature *> & signatures) const;
void loadWordIdsQuery(std::list<Signature *> & signatures) const;
void loadLinksQuery(std::list<Signature *> & signatures) const; void loadLinksQuery(std::list<Signature *> & signatures) const;
int loadOrSaveDb(sqlite3 *pInMemory, const std::string & fileName, int isSave) const; int loadOrSaveDb(sqlite3 *pInMemory, const std::string & fileName, int isSave) const;
void startChangeTracking(); // attach the change-tracking session on the open connection
protected: protected:
sqlite3 * _ppDb; sqlite3 * _ppDb;
@@ -204,6 +234,12 @@ private:
int _journalMode; int _journalMode;
int _synchronous; int _synchronous;
int _tempStore; int _tempStore;
// DB change tracking (SQLite session extension). Members are always present to keep
// the class layout stable regardless of RTABMAP_WITH_SQLITE3_SESSION; the session is
// only created/used when the feature is compiled in and enabled.
sqlite3_session * _session;
std::string _trackChangesOutput;
}; };
} }
+6
View File
@@ -59,6 +59,8 @@ public:
int startMapId = 0, int startMapId = 0,
int stopMapId = -1, int stopMapId = -1,
bool priorsIgnored = false, bool priorsIgnored = false,
bool imuIgnored = false,
bool intermediateNodesAreNormalNodes = false,
const std::vector<Transform> & cameraLocalTransformOverrides = std::vector<Transform>()); const std::vector<Transform> & cameraLocalTransformOverrides = std::vector<Transform>());
DBReader(const std::list<std::string> & databasePaths, DBReader(const std::list<std::string> & databasePaths,
float frameRate = 0.0f, // -1 = use Database stamps, 0 = inf float frameRate = 0.0f, // -1 = use Database stamps, 0 = inf
@@ -74,6 +76,8 @@ public:
int startMapId = 0, int startMapId = 0,
int stopMapId = -1, int stopMapId = -1,
bool priorsIgnored = false, bool priorsIgnored = false,
bool imuIgnored = false,
bool intermediateNodesAreNormalNodes = false,
const std::vector<Transform> & cameraLocalTransformOverrides = std::vector<Transform>()); const std::vector<Transform> & cameraLocalTransformOverrides = std::vector<Transform>());
virtual ~DBReader(); virtual ~DBReader();
@@ -104,9 +108,11 @@ private:
int _stopId; int _stopId;
std::vector<unsigned int> _cameraIndices; std::vector<unsigned int> _cameraIndices;
bool _intermediateNodesIgnored; bool _intermediateNodesIgnored;
bool _intermediateNodesAreNormalNodes;
bool _landmarksIgnored; bool _landmarksIgnored;
bool _featuresIgnored; bool _featuresIgnored;
bool _priorsIgnored; bool _priorsIgnored;
bool _imuIgnored;
int _startMapId; int _startMapId;
int _stopMapId; int _stopMapId;
std::vector<Transform> _cameraLocalTransformOverrides; std::vector<Transform> _cameraLocalTransformOverrides;
+32 -2
View File
@@ -104,6 +104,7 @@ namespace rtabmap {
class ORBextractor; class ORBextractor;
class SPDetector; class SPDetector;
class SPDetectorRpautrat;
class Stereo; class Stereo;
#if CV_MAJOR_VERSION < 3 #if CV_MAJOR_VERSION < 3
@@ -129,7 +130,8 @@ public:
kFeatureSurfFreak=12, //new 0.20.4 kFeatureSurfFreak=12, //new 0.20.4
kFeatureGfttDaisy=13, //new 0.20.6 kFeatureGfttDaisy=13, //new 0.20.6
kFeatureSurfDaisy=14, //new 0.20.6 kFeatureSurfDaisy=14, //new 0.20.6
kFeaturePyDetector=15}; //new 0.20.8 kFeaturePyDetector=15, //new 0.20.8
kFeatureSuperPointRpautrat=16}; // new 0.23.3
static std::string typeName(Type type) static std::string typeName(Type type)
{ {
@@ -164,6 +166,8 @@ public:
return "GFTT+Daisy"; return "GFTT+Daisy";
case kFeatureSurfDaisy: case kFeatureSurfDaisy:
return "SURF+Daisy"; return "SURF+Daisy";
case kFeatureSuperPointRpautrat:
return "SUPERPOINT-RPAUTRAT";
default: default:
return "Unknown"; return "Unknown";
} }
@@ -305,7 +309,8 @@ private:
bool preciseUpscale_; bool preciseUpscale_;
bool rootSIFT_; bool rootSIFT_;
bool gpu_; bool gpu_;
float guaussianThreshold_; float gaussianThreshold_;
float maxGaussianThreshold_;
bool upscale_; bool upscale_;
cv::Ptr<CV_SIFT> sift_; cv::Ptr<CV_SIFT> sift_;
@@ -626,6 +631,31 @@ private:
bool cuda_; bool cuda_;
}; };
//SuperPointRpautrat
class RTABMAP_CORE_EXPORT SuperPointRpautrat : public Feature2D
{
public:
SuperPointRpautrat(const ParametersMap & parameters = ParametersMap());
virtual ~SuperPointRpautrat();
virtual void parseParameters(const ParametersMap & parameters);
virtual Feature2D::Type getType() const { return kFeatureSuperPointRpautrat; }
private:
virtual std::vector<cv::KeyPoint> generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask = cv::Mat());
virtual cv::Mat generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const;
cv::Ptr<SPDetectorRpautrat> superPoint_;
std::string superpointWeightsPath_;
std::string superpointModelPath_;
std::string outputDir_;
float threshold_;
bool nms_;
int minDistance_;
bool cuda_;
};
//GFTT_DAISY //GFTT_DAISY
class RTABMAP_CORE_EXPORT GFTT_DAISY : public GFTT class RTABMAP_CORE_EXPORT GFTT_DAISY : public GFTT
{ {
+30 -19
View File
@@ -37,37 +37,48 @@ namespace rtabmap {
class RTABMAP_CORE_EXPORT FlannIndex class RTABMAP_CORE_EXPORT FlannIndex
{ {
public: public:
// A forward of the internal enum, indexes should match. See src/rtflann/defines.h
enum flann_algorithm_t
{
FLANN_INDEX_LINEAR = 0,
FLANN_INDEX_KDTREE = 1,
FLANN_INDEX_KDTREE_SINGLE = 4,
FLANN_INDEX_LSH = 6,
};
FlannIndex(); FlannIndex();
virtual ~FlannIndex(); virtual ~FlannIndex();
void release(); void release();
std::vector<unsigned char> serializeIndex(bool computeChecksum = true) const;
size_t indexedFeatures() const; size_t indexedFeatures() const;
// return Bytes // return Bytes
size_t memoryUsed() const; size_t memoryUsed() const;
// Note that useDistanceL1 doesn't have any effect if LSH is used // Note that useDistanceL1 doesn't have any effect if LSH is used
void buildLinearIndex( void buildIndex(
flann_algorithm_t algorithm,
const cv::Mat & features, const cv::Mat & features,
bool useDistanceL1 = false, bool useDistanceL1 = false,
float rebalancingFactor = 2.0f); float rebalancingFactor = 2.0f);
void buildKDTreeIndex( // Return false if the indexData doesn't correspond to expected features used and parameters.
const cv::Mat & features, bool loadIndex(
int trees = 4, const std::vector<unsigned char> & indexData,
bool useDistanceL1 = false, flann_algorithm_t algorithm,
float rebalancingFactor = 2.0f); const cv::Mat & features,
void buildKDTreeSingleIndex( bool useDistanceL1 = false,
const cv::Mat & features, float rebalancingFactor = 2.0f,
int leafMaxSize = 10, std::string * errorMsg = NULL);
bool reorder = true, bool loadIndex(
bool useDistanceL1 = false, const unsigned char * indexData,
float rebalancingFactor = 2.0f); size_t indexDataSize,
void buildLSHIndex( flann_algorithm_t algorithm,
const cv::Mat & features, const cv::Mat & features,
unsigned int table_number = 12, bool useDistanceL1 = false,
unsigned int key_size = 20, float rebalancingFactor = 2.0f,
unsigned int multi_probe_level = 2, std::string * errorMsg = NULL);
float rebalancingFactor = 2.0f);
bool isBuilt(); bool isBuilt();
@@ -104,9 +115,9 @@ private:
unsigned int nextIndex_; unsigned int nextIndex_;
int featuresType_; int featuresType_;
int featuresDim_; int featuresDim_;
bool isLSH_;
bool useDistanceL1_; // true=EUCLEDIAN_L2 false=MANHATTAN_L1 bool useDistanceL1_; // true=EUCLEDIAN_L2 false=MANHATTAN_L1
float rebalancingFactor_; float rebalancingFactor_;
flann_algorithm_t algorithm_;
// keep feature in memory until the tree is rebuilt // keep feature in memory until the tree is rebuilt
// (in case the word is deleted when removed from the VWDictionary) // (in case the word is deleted when removed from the VWDictionary)
+1
View File
@@ -53,6 +53,7 @@ public:
public: public:
virtual ~GlobalMap(); virtual ~GlobalMap();
bool fullUpdateNeeded(const std::map<int, Transform> & poses) const;
bool update(const std::map<int, Transform> & poses); // return true if map has changed bool update(const std::map<int, Transform> & poses); // return true if map has changed
virtual void clear(); virtual void clear();
+14 -12
View File
@@ -56,7 +56,7 @@ bool RTABMAP_CORE_EXPORT exportPoses(
bool RTABMAP_CORE_EXPORT importPoses( bool RTABMAP_CORE_EXPORT importPoses(
const std::string & filePath, const std::string & filePath,
int format, // 0=Raw, 1=RGBD-SLAM motion capture (10=without change of coordinate frame, 11=10+ID), 2=KITTI, 3=TORO, 4=g2o, 5=NewCollege(t,x,y), 6=Malaga Urban GPS, 7=St Lucia INS, 8=Karlsruhe, 9=EuRoC MAV int format, // 0=Raw, 1=RGBD-SLAM motion capture (10=without change of coordinate frame, 11=10+ID), 2=KITTI, 3=TORO, 4=g2o, 5=NewCollege(t,x,y), 6=Malaga Urban GPS, 7=St Lucia INS, 8=Karlsruhe, 9=EuRoC MAV, 12=rgbd_bonn
std::map<int, Transform> & poses, std::map<int, Transform> & poses,
std::multimap<int, Link> * constraints = 0, // optional for formats 3 and 4 std::multimap<int, Link> * constraints = 0, // optional for formats 3 and 4
std::map<int, double> * stamps = 0); // optional for format 1 and 9 std::map<int, double> * stamps = 0); // optional for format 1 and 9
@@ -118,15 +118,18 @@ Transform RTABMAP_CORE_EXPORT calcRMSE(
float & rotational_max, float & rotational_max,
bool align2D = false); bool align2D = false);
void RTABMAP_CORE_EXPORT computeMaxGraphErrors( struct MaxGraphErrors
{
float linear=-1.0f; // absolute error (m) of the link with maximum linear error
float angular=-1.0f; // absolute error (rad) of the link with maximum angular error
float linearRatio=-1.0f; // Ratio = absolute error (m) / linear std (m), of the link with maximum linear error
float angularRatio=-1.0f; // Ratio = absolute error (rad) / angular std (rad), of the link with maximum angular error
Link linearLink; // link with maximum linear error
Link angularLink; // link with maximum angular error
};
MaxGraphErrors RTABMAP_CORE_EXPORT computeMaxGraphErrors(
const std::map<int, Transform> & poses, const std::map<int, Transform> & poses,
const std::multimap<int, Link> & links, const std::multimap<int, Link> & links,
float & maxLinearErrorRatio,
float & maxAngularErrorRatio,
float & maxLinearError,
float & maxAngularError,
const Link ** maxLinearErrorLink = 0,
const Link ** maxAngularErrorLink = 0,
bool for3DoF = false); bool for3DoF = false);
std::vector<double> RTABMAP_CORE_EXPORT getMaxOdomInf(const std::multimap<int, Link> & links); std::vector<double> RTABMAP_CORE_EXPORT getMaxOdomInf(const std::multimap<int, Link> & links);
@@ -277,7 +280,8 @@ std::list<std::pair<int, Transform> > RTABMAP_CORE_EXPORT computePath(
bool lookInDatabase = true, bool lookInDatabase = true,
bool updateNewCosts = false, bool updateNewCosts = false,
float linearVelocity = 0.0f, // m/sec float linearVelocity = 0.0f, // m/sec
float angularVelocity = 0.0f); // rad/sec float angularVelocity = 0.0f, // rad/sec
bool ignoreDirectLinks = false);
/** /**
* Find the nearest node of the target pose * Find the nearest node of the target pose
@@ -336,9 +340,7 @@ RTABMAP_DEPRECATED std::map<int, Transform> RTABMAP_CORE_EXPORT getPosesInRadius
RTABMAP_DEPRECATED std::map<int, Transform> RTABMAP_CORE_EXPORT getPosesInRadius(const Transform & targetPose, const std::map<int, Transform> & nodes, float radius, float angle = 0.0f); RTABMAP_DEPRECATED std::map<int, Transform> RTABMAP_CORE_EXPORT getPosesInRadius(const Transform & targetPose, const std::map<int, Transform> & nodes, float radius, float angle = 0.0f);
float RTABMAP_CORE_EXPORT computePathLength( float RTABMAP_CORE_EXPORT computePathLength(
const std::vector<std::pair<int, Transform> > & path, const std::vector<std::pair<int, Transform> > & path);
unsigned int fromIndex = 0,
unsigned int toIndex = 0);
// assuming they are all linked in map order // assuming they are all linked in map order
float RTABMAP_CORE_EXPORT computePathLength( float RTABMAP_CORE_EXPORT computePathLength(
+6 -2
View File
@@ -48,7 +48,8 @@ public:
kXYZNormal=8, kXYZNormal=8,
kXYZINormal=9, kXYZINormal=9,
kXYZRGBNormal=10, kXYZRGBNormal=10,
kXYZIT=11}; kXYZIT=11,
kXYZIRT=12};
static std::string formatName(const Format & format); static std::string formatName(const Format & format);
static int channels(const Format & format); static int channels(const Format & format);
@@ -57,6 +58,7 @@ public:
static bool isScanHasRGB(const Format & format); static bool isScanHasRGB(const Format & format);
static bool isScanHasIntensity(const Format & format); static bool isScanHasIntensity(const Format & format);
static bool isScanHasTime(const Format & format); static bool isScanHasTime(const Format & format);
static bool isScanHasRing(const Format & format);
static LaserScan backwardCompatibility( static LaserScan backwardCompatibility(
const cv::Mat & oldScanFormat, const cv::Mat & oldScanFormat,
int maxPoints = 0, int maxPoints = 0,
@@ -135,6 +137,7 @@ public:
bool hasRGB() const {return isScanHasRGB(format_);} bool hasRGB() const {return isScanHasRGB(format_);}
bool hasIntensity() const {return isScanHasIntensity(format_);} bool hasIntensity() const {return isScanHasIntensity(format_);}
bool hasTime() const {return isScanHasTime(format_);} bool hasTime() const {return isScanHasTime(format_);}
bool hasRing() const {return isScanHasRing(format_);}
bool isCompressed() const {return !data_.empty() && data_.type()==CV_8UC1;} bool isCompressed() const {return !data_.empty() && data_.type()==CV_8UC1;}
bool isOrganized() const {return data_.rows > 1;} bool isOrganized() const {return data_.rows > 1;}
LaserScan clone() const; LaserScan clone() const;
@@ -143,7 +146,8 @@ public:
int getIntensityOffset() const {return hasIntensity()?(is2d()?2:3):-1;} int getIntensityOffset() const {return hasIntensity()?(is2d()?2:3):-1;}
int getRGBOffset() const {return hasRGB()?(is2d()?2:3):-1;} int getRGBOffset() const {return hasRGB()?(is2d()?2:3):-1;}
int getNormalsOffset() const {return hasNormals()?(2 + (is2d()?0:1) + ((hasRGB() || hasIntensity())?1:0)):-1;} int getNormalsOffset() const {return hasNormals()?(2 + (is2d()?0:1) + ((hasRGB() || hasIntensity())?1:0)):-1;}
int getTimeOffset() const {return hasTime()?4:-1;} int getRingOffset() const {return format_==kXYZIRT?4:-1;}
int getTimeOffset() const {return format_==kXYZIT?4:(format_==kXYZIRT?5:-1);}
float & field(unsigned int pointIndex, unsigned int channelOffset); float & field(unsigned int pointIndex, unsigned int channelOffset);
+13 -3
View File
@@ -58,6 +58,12 @@ private:
class RTABMAP_CORE_EXPORT MarkerDetector { class RTABMAP_CORE_EXPORT MarkerDetector {
public:
enum Strategy {
kStrategyOpencv,
kStrategyApriltag
};
public: public:
MarkerDetector(const ParametersMap & parameters = ParametersMap()); MarkerDetector(const ParametersMap & parameters = ParametersMap());
virtual ~MarkerDetector(); virtual ~MarkerDetector();
@@ -84,15 +90,19 @@ public:
cv::Mat * imageWithDetections = 0); cv::Mat * imageWithDetections = 0);
private: private:
#ifdef HAVE_OPENCV_ARUCO Strategy strategy_;
cv::Ptr<cv::aruco::DetectorParameters> detectorParams_; float markerLength_;
float markerLength_; std::map<int, float> markerLengths_;
float maxDepthError_; float maxDepthError_;
float maxRange_; float maxRange_;
float minRange_; float minRange_;
int dictionaryId_; int dictionaryId_;
#ifdef HAVE_OPENCV_ARUCO
cv::Ptr<cv::aruco::DetectorParameters> detectorParams_;
cv::Ptr<cv::aruco::Dictionary> dictionary_; cv::Ptr<cv::aruco::Dictionary> dictionary_;
#endif #endif
void * apriltagLibDetector_;
void * apriltagLibFamily_;
}; };
} /* namespace rtabmap */ } /* namespace rtabmap */
+15 -2
View File
@@ -140,10 +140,12 @@ public:
float radius, float radius,
const std::map<int, Transform> & optimizedPoses, const std::map<int, Transform> & optimizedPoses,
int maxGraphDepth) const; int maxGraphDepth) const;
void convertToIntermediate(int locationId);
void deleteLocation(int locationId, std::list<int> * deletedWords = 0); void deleteLocation(int locationId, std::list<int> * deletedWords = 0);
void saveLocationData(int locationId); void saveLocationData(int locationId);
void removeLink(int idA, int idB); void removeLink(int idA, int idB);
void removeRawData(int id, bool image = true, bool scan = true, bool userData = true); void removeRawData(int id, bool image = true, bool scan = true, bool userData = true, bool occupancyGrid = true);
int reduceNode(int id, float maxDistance = 0.0f, bool keepLinkedInDb = false, int direction = 0);
//getters //getters
const std::map<int, double> & getWorkingMem() const {return _workingMem;} const std::map<int, double> & getWorkingMem() const {return _workingMem;}
@@ -161,7 +163,7 @@ public:
float getSimilarityThreshold() const {return _similarityThreshold;} float getSimilarityThreshold() const {return _similarityThreshold;}
std::map<int, int> getWeights() const; std::map<int, int> getWeights() const;
int getLastSignatureId() const; int getLastSignatureId() const;
const Signature * getLastWorkingSignature() const; const Signature * getLastWorkingSignature(bool ignoreIntermediateNodes) const;
std::map<int, Link> getNodesObservingLandmark(int landmarkId, bool lookInDatabase) const; std::map<int, Link> getNodesObservingLandmark(int landmarkId, bool lookInDatabase) const;
int getSignatureIdByLabel(const std::string & label, bool lookInDatabase = true) const; int getSignatureIdByLabel(const std::string & label, bool lookInDatabase = true) const;
bool labelSignature(int id, const std::string & label); bool labelSignature(int id, const std::string & label);
@@ -180,6 +182,10 @@ public:
int getDatabaseMemoryUsed() const; // in bytes int getDatabaseMemoryUsed() const; // in bytes
std::string getDatabaseVersion() const; std::string getDatabaseVersion() const;
std::string getDatabaseUrl() const; std::string getDatabaseUrl() const;
// Record changes made to the database until it is closed, then write a compact delta
// to outputUrl (empty disables). outputUrl MUST use the ".dbu" (db update) extension.
// Returns true if recording started. See DBDriver.
bool trackDatabaseChanges(const std::string & outputUrl);
double getDbSavingTime() const; double getDbSavingTime() const;
int getMapId(int id, bool lookInDatabase = false) const; int getMapId(int id, bool lookInDatabase = false) const;
Transform getOdomPose(int signatureId, bool lookInDatabase = false) const; Transform getOdomPose(int signatureId, bool lookInDatabase = false) const;
@@ -211,6 +217,7 @@ public:
std::set<int> getAllSignatureIds(bool ignoreChildren = true) const; std::set<int> getAllSignatureIds(bool ignoreChildren = true) const;
bool memoryChanged() const {return _memoryChanged;} bool memoryChanged() const {return _memoryChanged;}
bool isIncremental() const {return _incrementalMemory;} bool isIncremental() const {return _incrementalMemory;}
bool isReadOnly() const {return !_incrementalMemory && _localizationReadOnly;}
bool isLocalizationDataSaved() const {return _localizationDataSaved;} bool isLocalizationDataSaved() const {return _localizationDataSaved;}
const Signature * getSignature(int id) const; const Signature * getSignature(int id) const;
bool isInSTM(int signatureId) const {return _stMem.find(signatureId) != _stMem.end();} bool isInSTM(int signatureId) const {return _stMem.find(signatureId) != _stMem.end();}
@@ -264,6 +271,7 @@ private:
void addSignatureToStm(Signature * signature, const cv::Mat & covariance); void addSignatureToStm(Signature * signature, const cv::Mat & covariance);
void clear(); void clear();
void loadDataFromDb(bool postInitClosingEvents); void loadDataFromDb(bool postInitClosingEvents);
void saveFlannIndex(bool postInitClosingEvents);
void moveToTrash(Signature * s, bool keepLinkedToGraph = true, std::list<int> * deletedWords = 0); void moveToTrash(Signature * s, bool keepLinkedToGraph = true, std::list<int> * deletedWords = 0);
void moveSignatureToWMFromSTM(int id, int * reducedTo = 0); void moveSignatureToWMFromSTM(int id, int * reducedTo = 0);
@@ -275,6 +283,7 @@ private:
void initCountId(); void initCountId();
void rehearsal(Signature * signature, Statistics * stats = 0); void rehearsal(Signature * signature, Statistics * stats = 0);
bool rehearsalMerge(int oldId, int newId); bool rehearsalMerge(int oldId, int newId);
bool canBeReduced(const Link & link, float maxDistance, int direction);
const std::map<int, Signature*> & getSignatures() const {return _signatures;} const std::map<int, Signature*> & getSignatures() const {return _signatures;}
@@ -299,13 +308,16 @@ private:
float _similarityThreshold; float _similarityThreshold;
bool _binDataKept; bool _binDataKept;
bool _rawDescriptorsKept; bool _rawDescriptorsKept;
bool _loadVisualLocalFeaturesOnInit;
bool _saveDepth16Format; bool _saveDepth16Format;
bool _notLinkedNodesKeptInDb; bool _notLinkedNodesKeptInDb;
bool _saveIntermediateNodeData; bool _saveIntermediateNodeData;
std::string _rgbCompressionFormat; std::string _rgbCompressionFormat;
std::string _depthCompressionFormat; std::string _depthCompressionFormat;
bool _incrementalMemory; bool _incrementalMemory;
bool _localizationReadOnly;
bool _localizationDataSaved; bool _localizationDataSaved;
bool _flannIndexSaved;
bool _reduceGraph; bool _reduceGraph;
int _maxStMemSize; int _maxStMemSize;
float _recentWmRatio; float _recentWmRatio;
@@ -353,6 +365,7 @@ private:
bool _linksChanged; // False by default, become true when links are modified. bool _linksChanged; // False by default, become true when links are modified.
int _signaturesAdded; int _signaturesAdded;
bool _allNodesInWM; bool _allNodesInWM;
bool _receivingOdometryFeatures;
GPS _gpsOrigin; GPS _gpsOrigin;
std::vector<CameraModel> _rectCameraModels; std::vector<CameraModel> _rectCameraModels;
std::vector<StereoCameraModel> _rectStereoCameraModels; std::vector<StereoCameraModel> _rectStereoCameraModels;
+4 -2
View File
@@ -53,10 +53,12 @@ public:
kTypeOkvis = 6, kTypeOkvis = 6,
kTypeLOAM = 7, kTypeLOAM = 7,
kTypeMSCKF = 8, kTypeMSCKF = 8,
kTypeVINS = 9, kTypeVINSFusion = 9,
kTypeOpenVINS = 10, kTypeOpenVINS = 10,
kTypeFLOAM = 11, kTypeFLOAM = 11,
kTypeOpen3D = 12 kTypeOpen3D = 12,
kTypeCuVSLAM = 13,
kTypeLIOSAM = 14
}; };
public: public:
@@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define ODOMETRYTHREAD_H_ #define ODOMETRYTHREAD_H_
#include <rtabmap/core/rtabmap_core_export.h> #include <rtabmap/core/rtabmap_core_export.h>
#include <rtabmap/core/SensorEvent.h>
#include <rtabmap/core/SensorData.h> #include <rtabmap/core/SensorData.h>
#include <rtabmap/utilite/UThread.h> #include <rtabmap/utilite/UThread.h>
#include <rtabmap/utilite/UEventsHandler.h> #include <rtabmap/utilite/UEventsHandler.h>
@@ -55,18 +56,19 @@ private:
// MAIN LOOP // MAIN LOOP
//============================================================ //============================================================
virtual void mainLoop(); virtual void mainLoop();
void addData(const SensorData & data); void addData(const SensorEvent & data);
bool getData(SensorData & data); bool getData(SensorEvent & data);
private: private:
USemaphore _dataAdded; USemaphore _dataAdded;
UMutex _dataMutex; UMutex _dataMutex;
std::list<SensorData> _dataBuffer; std::list<SensorEvent> _dataBuffer;
std::list<SensorData> _imuBuffer; std::list<SensorData> _imuBuffer;
Odometry * _odometry; Odometry * _odometry;
unsigned int _dataBufferMaxSize; unsigned int _dataBufferMaxSize;
bool _resetOdometry; bool _resetOdometry;
Transform _resetPose; Transform _resetPose;
Transform _previousGuessPose;
double _oldestAsyncImuStamp; double _oldestAsyncImuStamp;
double _newestAsyncImuStamp; double _newestAsyncImuStamp;
}; };
+131 -83
View File
@@ -204,6 +204,7 @@ class RTABMAP_CORE_EXPORT Parameters
RTABMAP_PARAM(Mem, ImageKept, bool, false, "Keep raw images in RAM."); RTABMAP_PARAM(Mem, ImageKept, bool, false, "Keep raw images in RAM.");
RTABMAP_PARAM(Mem, BinDataKept, bool, true, "Keep binary data in db."); RTABMAP_PARAM(Mem, BinDataKept, bool, true, "Keep binary data in db.");
RTABMAP_PARAM(Mem, RawDescriptorsKept, bool, true, "Raw descriptors kept in memory."); RTABMAP_PARAM(Mem, RawDescriptorsKept, bool, true, "Raw descriptors kept in memory.");
RTABMAP_PARAM(Mem, LoadVisualLocalFeaturesOnInit, bool, true, "Load all local visual features (keypoints, descriptors and 3D points) in RAM when loading an existing database. This can add significant time to initialize the memory but the features will be already loaded before computing loop closure transforms. If false, the features are loaded on-demand from the database when a loop closure transformation should be estimated.");
RTABMAP_PARAM(Mem, MapLabelsAdded, bool, true, "Create map labels. The first node of a map will be labeled as \"map#\" where # is the map ID."); RTABMAP_PARAM(Mem, MapLabelsAdded, bool, true, "Create map labels. The first node of a map will be labeled as \"map#\" where # is the map ID.");
RTABMAP_PARAM(Mem, SaveDepth16Format, bool, false, "Save depth image into 16 bits format to reduce memory used. Warning: values over ~65 meters are ignored (maximum 65535 millimeters)."); RTABMAP_PARAM(Mem, SaveDepth16Format, bool, false, "Save depth image into 16 bits format to reduce memory used. Warning: values over ~65 meters are ignored (maximum 65535 millimeters).");
RTABMAP_PARAM(Mem, NotLinkedNodesKept, bool, true, "Keep not linked nodes in db (rehearsed nodes and deleted nodes)."); RTABMAP_PARAM(Mem, NotLinkedNodesKept, bool, true, "Keep not linked nodes in db (rehearsed nodes and deleted nodes).");
@@ -212,17 +213,18 @@ class RTABMAP_CORE_EXPORT Parameters
RTABMAP_PARAM_STR(Mem, DepthCompressionFormat, ".rvl", "Depth image compression format for 16UC1 depth type. It should be \".png\" or \".rvl\". If depth type is 32FC1, \".png\" is used."); RTABMAP_PARAM_STR(Mem, DepthCompressionFormat, ".rvl", "Depth image compression format for 16UC1 depth type. It should be \".png\" or \".rvl\". If depth type is 32FC1, \".png\" is used.");
RTABMAP_PARAM(Mem, STMSize, unsigned int, 10, "Short-term memory size."); RTABMAP_PARAM(Mem, STMSize, unsigned int, 10, "Short-term memory size.");
RTABMAP_PARAM(Mem, IncrementalMemory, bool, true, "SLAM mode, otherwise it is Localization mode."); RTABMAP_PARAM(Mem, IncrementalMemory, bool, true, "SLAM mode, otherwise it is Localization mode.");
RTABMAP_PARAM(Mem, LocalizationDataSaved, bool, false, uFormat("Save localization data during localization session (when %s=false). When enabled, the database will then also grow in localization mode. This mode would be used only for debugging purpose.", kMemIncrementalMemory().c_str()).c_str()); RTABMAP_PARAM(Mem, LocalizationReadOnly, bool, false, uFormat("In localization mode, open the database in read-only mode (ignored if %s=true). Currrenty incompatible with memory management (%s and %s cannot be used) and if there are disjoint sessions in working memory. Last localization pose won't be saved back in the database at the end of the session, so the robot will always restart to original last localization pose, unless %s is used or an external initial pose is provided on initialization.", kMemIncrementalMemory().c_str(), kRtabmapLoopThr().c_str(), kRtabmapMemoryThr().c_str(), kRGBDStartAtOrigin().c_str()).c_str());
RTABMAP_PARAM(Mem, ReduceGraph, bool, false, "Reduce graph. Merge nodes when loop closures are added (ignoring those with user data set)."); RTABMAP_PARAM(Mem, LocalizationDataSaved, bool, false, uFormat("Save localization data during localization session (when %s=false). When enabled, the database will then also grow in localization mode. This mode would be used only for debugging purpose.", kMemIncrementalMemory().c_str()).c_str());
RTABMAP_PARAM(Mem, ReduceGraph, bool, false, uFormat("Reduce graph. Merge nodes when loop closures are added (ignoring those with user data). Note that this approach assumes that 100%% of the loop closures accepted are good, so it is highly recommended to enable \"%s\" at the same time.", kRGBDOptimizeMaxError().c_str()));
RTABMAP_PARAM(Mem, RecentWmRatio, float, 0.2, "Ratio of locations after the last loop closure in WM that cannot be transferred."); RTABMAP_PARAM(Mem, RecentWmRatio, float, 0.2, "Ratio of locations after the last loop closure in WM that cannot be transferred.");
RTABMAP_PARAM(Mem, TransferSortingByWeightId, bool, false, "On transfer, signatures are sorted by weight->ID only (i.e. the oldest of the lowest weighted signatures are transferred first). If false, the signatures are sorted by weight->Age->ID (i.e. the oldest inserted in WM of the lowest weighted signatures are transferred first). Note that retrieval updates the age, not the ID."); RTABMAP_PARAM(Mem, TransferSortingByWeightId, bool, false, "On transfer, signatures are sorted by weight->ID only (i.e. the oldest of the lowest weighted signatures are transferred first). If false, the signatures are sorted by weight->Age->ID (i.e. the oldest inserted in WM of the lowest weighted signatures are transferred first). Note that retrieval updates the age, not the ID.");
RTABMAP_PARAM(Mem, RehearsalIdUpdatedToNewOne, bool, false, "On merge, update to new id. When false, no copy."); RTABMAP_PARAM(Mem, RehearsalIdUpdatedToNewOne, bool, false, uFormat("On merge, update to new id. When false, no copy. Keep this disable if %s=true.", kRtabmapCreateIntermediateNodes().c_str()));
RTABMAP_PARAM(Mem, RehearsalWeightIgnoredWhileMoving, bool, false, "When the robot is moving, weights are not updated on rehearsal."); RTABMAP_PARAM(Mem, RehearsalWeightIgnoredWhileMoving, bool, false, "When the robot is moving, weights are not updated on rehearsal.");
RTABMAP_PARAM(Mem, GenerateIds, bool, true, "True=Generate location IDs, False=use input image IDs."); RTABMAP_PARAM(Mem, GenerateIds, bool, true, "True=Generate location IDs, False=use input image IDs.");
RTABMAP_PARAM(Mem, BadSignaturesIgnored, bool, false, "Bad signatures are ignored."); RTABMAP_PARAM(Mem, BadSignaturesIgnored, bool, false, "Bad signatures are ignored.");
RTABMAP_PARAM(Mem, InitWMWithAllNodes, bool, false, "Initialize the Working Memory with all nodes in Long-Term Memory. When false, it is initialized with nodes of the previous session."); RTABMAP_PARAM(Mem, InitWMWithAllNodes, bool, false, "Initialize the Working Memory with all nodes in Long-Term Memory. When false, it is initialized with nodes of the previous session.");
RTABMAP_PARAM(Mem, DepthAsMask, bool, true, "Use depth image as mask when extracting features for vocabulary."); RTABMAP_PARAM(Mem, DepthAsMask, bool, true, "Use depth image as mask when extracting features for vocabulary.");
RTABMAP_PARAM(Mem, DepthMaskFloorThr, float, 0.0, uFormat("Filter floor from depth mask below specified threshold (m) before extracting features. 0 means disabled, negative means remove all objects above the floor threshold instead. Ignored if %s is false.", kMemDepthAsMask().c_str())); RTABMAP_PARAM(Mem, DepthMaskFloorThr, float, 0.0, uFormat("Filter floor from depth mask below specified threshold (m) before extracting features. 0 means disabled. Ignored if %s is false.", kMemDepthAsMask().c_str()));
RTABMAP_PARAM(Mem, StereoFromMotion, bool, false, uFormat("Triangulate features without depth using stereo from motion (odometry). It would be ignored if %s is true and the feature detector used supports masking.", kMemDepthAsMask().c_str())); RTABMAP_PARAM(Mem, StereoFromMotion, bool, false, uFormat("Triangulate features without depth using stereo from motion (odometry). It would be ignored if %s is true and the feature detector used supports masking.", kMemDepthAsMask().c_str()));
RTABMAP_PARAM(Mem, ImagePreDecimation, unsigned int, 1, uFormat("Decimation of the RGB image before visual feature detection. If depth size is larger than decimated RGB size, depth is decimated to be always at most equal to RGB size. If %s is true and if depth is smaller than decimated RGB, depth may be interpolated to match RGB size for feature detection.",kMemDepthAsMask().c_str())); RTABMAP_PARAM(Mem, ImagePreDecimation, unsigned int, 1, uFormat("Decimation of the RGB image before visual feature detection. If depth size is larger than decimated RGB size, depth is decimated to be always at most equal to RGB size. If %s is true and if depth is smaller than decimated RGB, depth may be interpolated to match RGB size for feature detection.",kMemDepthAsMask().c_str()));
RTABMAP_PARAM(Mem, ImagePostDecimation, unsigned int, 1, uFormat("Decimation of the RGB image before saving it to database. If depth size is larger than decimated RGB size, depth is decimated to be always at most equal to RGB size. Decimation is done from the original image. If set to same value than %s, data already decimated is saved (no need to re-decimate the image).", kMemImagePreDecimation().c_str())); RTABMAP_PARAM(Mem, ImagePostDecimation, unsigned int, 1, uFormat("Decimation of the RGB image before saving it to database. If depth size is larger than decimated RGB size, depth is decimated to be always at most equal to RGB size. Decimation is done from the original image. If set to same value than %s, data already decimated is saved (no need to re-decimate the image).", kMemImagePreDecimation().c_str()));
@@ -247,19 +249,21 @@ class RTABMAP_CORE_EXPORT Parameters
RTABMAP_PARAM(Kp, MinDepth, float, 0, "Filter extracted keypoints by depth."); RTABMAP_PARAM(Kp, MinDepth, float, 0, "Filter extracted keypoints by depth.");
RTABMAP_PARAM(Kp, MaxFeatures, int, 500, "Maximum features extracted from the images (0 means not bounded, <0 means no extraction)."); RTABMAP_PARAM(Kp, MaxFeatures, int, 500, "Maximum features extracted from the images (0 means not bounded, <0 means no extraction).");
RTABMAP_PARAM(Kp, SSC, bool, false, "If true, SSC (Suppression via Square Covering) is applied to limit keypoints."); RTABMAP_PARAM(Kp, SSC, bool, false, "If true, SSC (Suppression via Square Covering) is applied to limit keypoints.");
RTABMAP_PARAM(Kp, BadSignRatio, float, 0.5, "Bad signature ratio (less than Ratio x AverageWordsPerImage = bad)."); RTABMAP_PARAM(Kp, BadSignRatio, float, 0.5, uFormat("Bad signature ratio. If %s=0, the ratio is computed from the average number of words per signature (less than Ratio x AverageWordsPerImage = bad).", kKpMaxFeatures().c_str()));
RTABMAP_PARAM(Kp, NndrRatio, float, 0.8, "NNDR ratio (A matching pair is detected, if its distance is closer than X times the distance of the second nearest neighbor.)"); RTABMAP_PARAM(Kp, NndrRatio, float, 0.8, "NNDR ratio (A matching pair is detected, if its distance is closer than X times the distance of the second nearest neighbor.)");
#if CV_MAJOR_VERSION > 2 && !defined(HAVE_OPENCV_XFEATURES2D) #if CV_MAJOR_VERSION > 2 && !defined(HAVE_OPENCV_XFEATURES2D)
// OpenCV>2 without xFeatures2D module doesn't have BRIEF // OpenCV>2 without xFeatures2D module doesn't have BRIEF
RTABMAP_PARAM(Kp, DetectorStrategy, int, 8, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE 10=ORB-OCTREE 11=SuperPoint 12=SURF/FREAK 13=GFTT/DAISY 14=SURF/DAISY 15=PyDetector"); RTABMAP_PARAM(Kp, DetectorStrategy, int, 8, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE 10=ORB-OCTREE 11=SuperPoint 12=SURF/FREAK 13=GFTT/DAISY 14=SURF/DAISY 15=PyDetector 16=SuperPoint-Rpautrat");
#else #else
RTABMAP_PARAM(Kp, DetectorStrategy, int, 6, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE 10=ORB-OCTREE 11=SuperPoint 12=SURF/FREAK 13=GFTT/DAISY 14=SURF/DAISY 15=PyDetector"); RTABMAP_PARAM(Kp, DetectorStrategy, int, 6, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE 10=ORB-OCTREE 11=SuperPoint 12=SURF/FREAK 13=GFTT/DAISY 14=SURF/DAISY 15=PyDetector 16=SuperPoint-Rpautrat");
#endif #endif
RTABMAP_PARAM(Kp, TfIdfLikelihoodUsed, bool, true, "Use of the td-idf strategy to compute the likelihood."); RTABMAP_PARAM(Kp, TfIdfLikelihoodUsed, bool, true, "Use of the td-idf strategy to compute the likelihood.");
RTABMAP_PARAM(Kp, Parallelized, bool, true, "If the dictionary update and signature creation were parallelized."); RTABMAP_PARAM(Kp, Parallelized, bool, true, "If the dictionary update and signature creation were parallelized.");
RTABMAP_PARAM_STR(Kp, RoiRatios, "0.0 0.0 0.0 0.0", "Region of interest ratios [left, right, top, bottom]."); RTABMAP_PARAM_STR(Kp, RoiRatios, "0.0 0.0 0.0 0.0", "Region of interest ratios [left, right, top, bottom].");
RTABMAP_PARAM_STR(Kp, DictionaryPath, "", "Path of the pre-computed dictionary"); RTABMAP_PARAM_STR(Kp, DictionaryPath, "", "Path of the pre-computed dictionary");
RTABMAP_PARAM(Kp, NewWordsComparedTogether, bool, true, "When adding new words to dictionary, they are compared also with each other (to detect same words in the same signature)."); RTABMAP_PARAM(Kp, NewWordsComparedTogether, bool, true, "When adding new words to dictionary, they are compared also with each other (to detect same words in the same signature).");
RTABMAP_PARAM(Kp, FlannIndexSaved, bool, false, uFormat("Save FLANN index during localization session (when %s=false). The FLANN index will be saved to database after the first time localization mode is used, then on next sessions, the index is reloaded from the database instead of being rebuilt again. This can save significant loading time when the visual word dictionary is big (>1M words). Note that if the dictionary is modified (parameters or data), the index will be rebuilt and saved again on the next session. Ignored on initialization if %s is enabled.", kMemIncrementalMemory().c_str(), kMemInitWMWithAllNodes().c_str()).c_str());
RTABMAP_PARAM(Kp, SerializeWithChecksum, bool, true, "On serialization of the FLANN index, compute checksum of the data used by the FLANN index. This adds a slight overhead on serialization/deserialization to make sure that the dictionary data correspond to same data used when the index was built.");
RTABMAP_PARAM(Kp, SubPixWinSize, int, 3, "See cv::cornerSubPix()."); RTABMAP_PARAM(Kp, SubPixWinSize, int, 3, "See cv::cornerSubPix().");
RTABMAP_PARAM(Kp, SubPixIterations, int, 0, "See cv::cornerSubPix(). 0 disables sub pixel refining."); RTABMAP_PARAM(Kp, SubPixIterations, int, 0, "See cv::cornerSubPix(). 0 disables sub pixel refining.");
RTABMAP_PARAM(Kp, SubPixEps, double, 0.02, "See cv::cornerSubPix()."); RTABMAP_PARAM(Kp, SubPixEps, double, 0.02, "See cv::cornerSubPix().");
@@ -290,7 +294,8 @@ class RTABMAP_CORE_EXPORT Parameters
RTABMAP_PARAM(SIFT, PreciseUpscale, bool, false, "Whether to enable precise upscaling in the scale pyramid (OpenCV >= 4.8)."); RTABMAP_PARAM(SIFT, PreciseUpscale, bool, false, "Whether to enable precise upscaling in the scale pyramid (OpenCV >= 4.8).");
RTABMAP_PARAM(SIFT, RootSIFT, bool, false, "Apply RootSIFT normalization of the descriptors."); RTABMAP_PARAM(SIFT, RootSIFT, bool, false, "Apply RootSIFT normalization of the descriptors.");
RTABMAP_PARAM(SIFT, Gpu, bool, false, "CudaSift: Use GPU version of SIFT. This option is enabled only if RTAB-Map is built with CudaSift dependency and GPUs are detected."); RTABMAP_PARAM(SIFT, Gpu, bool, false, "CudaSift: Use GPU version of SIFT. This option is enabled only if RTAB-Map is built with CudaSift dependency and GPUs are detected.");
RTABMAP_PARAM(SIFT, GaussianThreshold, float, 2.0, "CudaSift: Threshold on difference of Gaussians for feature pruning. The higher the threshold, the less features are produced by the detector."); RTABMAP_PARAM(SIFT, GaussianThreshold, float, 2.0, "CudaSift: Threshold on difference of Gaussians for feature pruning. The higher the threshold, the less features with low response/hessian are produced by the detector.");
RTABMAP_PARAM(SIFT, MaxGaussianThreshold, float, 0.0, uFormat("CudaSift: Maximum threshold on difference of Gaussians for feature pruning (ignored if smaller or equal than %s). The lower the threshold, the less features with high response/hessian are produced by the detector.", kSIFTGaussianThreshold().c_str()));
RTABMAP_PARAM(SIFT, Upscale, bool, false, "CudaSift: Whether to enable upscaling."); RTABMAP_PARAM(SIFT, Upscale, bool, false, "CudaSift: Whether to enable upscaling.");
RTABMAP_PARAM(BRIEF, Bytes, int, 32, "Bytes is a length of descriptor in bytes. It can be equal 16, 32 or 64 bytes."); RTABMAP_PARAM(BRIEF, Bytes, int, 32, "Bytes is a length of descriptor in bytes. It can be equal 16, 32 or 64 bytes.");
@@ -343,6 +348,13 @@ class RTABMAP_CORE_EXPORT Parameters
RTABMAP_PARAM(SuperPoint, NMSRadius, int, 4, uFormat("[%s=true] Minimum distance (pixels) between keypoints.", kSuperPointNMS().c_str())); RTABMAP_PARAM(SuperPoint, NMSRadius, int, 4, uFormat("[%s=true] Minimum distance (pixels) between keypoints.", kSuperPointNMS().c_str()));
RTABMAP_PARAM(SuperPoint, Cuda, bool, true, "Use Cuda device for Torch, otherwise CPU device is used by default."); RTABMAP_PARAM(SuperPoint, Cuda, bool, true, "Use Cuda device for Torch, otherwise CPU device is used by default.");
RTABMAP_PARAM_STR(SuperPointRpautrat, WeightsPath, "", "[Required] SuperPoint weights file (*.pth).");
RTABMAP_PARAM_STR(SuperPointRpautrat, ModelPath, "", "[Required] SuperPoint python model file (superpoint_pytorch.py).");
RTABMAP_PARAM(SuperPointRpautrat, Threshold, float, 0.005, "Detector response threshold to accept keypoint.");
RTABMAP_PARAM(SuperPointRpautrat, NMS, bool, true, "If true, non-maximum suppression is applied to detected keypoints.");
RTABMAP_PARAM(SuperPointRpautrat, NMSRadius, int, 4, uFormat("[%s=true] Minimum distance (pixels) between keypoints.", kSuperPointRpautratNMS().c_str()));
RTABMAP_PARAM(SuperPointRpautrat, Cuda, bool, true, "Use Cuda device for Torch, otherwise CPU device is used by default.");
RTABMAP_PARAM_STR(PyDetector, Path, "", "Path to python script file (see available ones in rtabmap/corelib/src/python/*). See the header to see where the script should be copied."); RTABMAP_PARAM_STR(PyDetector, Path, "", "Path to python script file (see available ones in rtabmap/corelib/src/python/*). See the header to see where the script should be copied.");
RTABMAP_PARAM(PyDetector, Cuda, bool, true, "Use cuda."); RTABMAP_PARAM(PyDetector, Cuda, bool, true, "Use cuda.");
@@ -359,14 +371,15 @@ class RTABMAP_CORE_EXPORT Parameters
// RGB-D SLAM // RGB-D SLAM
RTABMAP_PARAM(RGBD, Enabled, bool, true, "Activate metric SLAM. If set to false, classic RTAB-Map loop closure detection is done using only images and without any metric information."); RTABMAP_PARAM(RGBD, Enabled, bool, true, "Activate metric SLAM. If set to false, classic RTAB-Map loop closure detection is done using only images and without any metric information.");
RTABMAP_PARAM(RGBD, LinearUpdate, float, 0.1, "Minimum linear displacement (m) to update the map. Rehearsal is done prior to this, so weights are still updated."); RTABMAP_PARAM(RGBD, LinearUpdate, float, 0.1, uFormat("Minimum linear displacement (m) to update the map. Rehearsal is done prior to this, so weights are still updated. To update the map when not moving, both %s and %s should be set to 0.", Parameters::kRGBDLinearUpdate().c_str(), Parameters::kRGBDAngularUpdate().c_str()));
RTABMAP_PARAM(RGBD, AngularUpdate, float, 0.1, "Minimum angular displacement (rad) to update the map. Rehearsal is done prior to this, so weights are still updated."); RTABMAP_PARAM(RGBD, AngularUpdate, float, 0.1, uFormat("Minimum angular displacement (rad) to update the map. Rehearsal is done prior to this, so weights are still updated. To update the map when not moving, both %s and %s should be set to 0.", Parameters::kRGBDLinearUpdate().c_str(), Parameters::kRGBDAngularUpdate().c_str()));
RTABMAP_PARAM(RGBD, LinearSpeedUpdate, float, 0.0, "Maximum linear speed (m/s) to update the map (0 means not limit)."); RTABMAP_PARAM(RGBD, LinearSpeedUpdate, float, 0.0, "Maximum linear speed (m/s) to update the map (0 means not limit).");
RTABMAP_PARAM(RGBD, AngularSpeedUpdate, float, 0.0, "Maximum angular speed (rad/s) to update the map (0 means not limit)."); RTABMAP_PARAM(RGBD, AngularSpeedUpdate, float, 0.0, "Maximum angular speed (rad/s) to update the map (0 means not limit).");
RTABMAP_PARAM(RGBD, AggressiveLoopThr, float, 0.05, uFormat("Loop closure threshold used (overriding %s) when a new mapping session is not yet linked to a map of the highest loop closure hypothesis. In localization mode, this threshold is used when there are no loop closure constraints with any map in the cache (%s). In all cases, the goal is to aggressively loop on a previous map in the database. Only used when %s is enabled. Set 1 to disable.", kRtabmapLoopThr().c_str(), kRGBDMaxOdomCacheSize().c_str(), kRGBDEnabled().c_str())); RTABMAP_PARAM(RGBD, AggressiveLoopThr, float, 0.05, uFormat("Loop closure threshold used (overriding %s) when a new mapping session is not yet linked to a map of the highest loop closure hypothesis. In localization mode, this threshold is used when there are no loop closure constraints with any map in the cache (%s). In all cases, the goal is to aggressively loop on a previous map in the database. Only used when %s is enabled. Set 1 to disable.", kRtabmapLoopThr().c_str(), kRGBDMaxOdomCacheSize().c_str(), kRGBDEnabled().c_str()));
RTABMAP_PARAM(RGBD, NewMapOdomChangeDistance, float, 0, "A new map is created if a change of odometry translation greater than X m is detected (0 m = disabled)."); RTABMAP_PARAM(RGBD, NewMapOdomChangeDistance, float, 0, "A new map is created if a change of odometry translation greater than X m is detected (0 m = disabled).");
RTABMAP_PARAM(RGBD, OptimizeFromGraphEnd, bool, false, "Optimize graph from the newest node. If false, the graph is optimized from the oldest node of the current graph (this adds an overhead computation to detect to oldest node of the current graph, but it can be useful to preserve the map referential from the oldest node). Warning when set to false: when some nodes are transferred, the first referential of the local map may change, resulting in momentary changes in robot/map position (which are annoying in teleoperation)."); RTABMAP_PARAM(RGBD, OptimizeFromGraphEnd, bool, false, "Optimize graph from the newest node. If false, the graph is optimized from the oldest node of the current graph (this adds an overhead computation to detect to oldest node of the current graph, but it can be useful to preserve the map referential from the oldest node). Warning when set to false: when some nodes are transferred, the first referential of the local map may change, resulting in momentary changes in robot/map position (which are annoying in teleoperation).");
RTABMAP_PARAM(RGBD, OptimizeMaxError, float, 3.0, uFormat("Reject loop closures if optimization error ratio is greater than this value (0=disabled). Ratio is computed as absolute error over standard deviation of each link. This will help to detect when a wrong loop closure is added to the graph. Not compatible with \"%s\" if enabled.", kOptimizerRobust().c_str())); RTABMAP_PARAM(RGBD, OptimizeMaxError, float, 3.0, uFormat("Reject loop closures if optimization error ratio is greater than this value (0=disabled). Ratio is computed as absolute error over standard deviation of each link. This will help to detect when a wrong loop closure is added to the graph. If used with \"%s\", the disabled loop closure links will be removed.", kOptimizerRobust().c_str()));
RTABMAP_PARAM(RGBD, OptimizeMaxErrorRepairRadius, float, 0.0, uFormat("If two consecutive loop closures are rejected by %s on the same old loop closure link, we will remove that old link, and other old links under that radius if necessary, until optimization is accepted. When optimization is accepted, the old loop closure links are removed from the graph. This feature is useful to reject bad loop closures that were accepted previously. Set to 0 to disable this feature.", kRGBDOptimizeMaxError().c_str()));
RTABMAP_PARAM(RGBD, MaxLoopClosureDistance, float, 0.0, "Reject loop closures/localizations if the distance from the map is over this distance (0=disabled)."); RTABMAP_PARAM(RGBD, MaxLoopClosureDistance, float, 0.0, "Reject loop closures/localizations if the distance from the map is over this distance (0=disabled).");
RTABMAP_PARAM(RGBD, ForceOdom3DoF, bool, true, uFormat("Force odometry pose to be 3DoF if %s=true.", kRegForce3DoF().c_str())); RTABMAP_PARAM(RGBD, ForceOdom3DoF, bool, true, uFormat("Force odometry pose to be 3DoF if %s=true.", kRegForce3DoF().c_str()));
RTABMAP_PARAM(RGBD, StartAtOrigin, bool, false, uFormat("If true, rtabmap will assume the robot is starting from origin of the map. If false, rtabmap will assume the robot is restarting from the last saved localization pose from previous session (the place where it shut down previously). Used only in localization mode (%s=false).", kMemIncrementalMemory().c_str())); RTABMAP_PARAM(RGBD, StartAtOrigin, bool, false, uFormat("If true, rtabmap will assume the robot is starting from origin of the map. If false, rtabmap will assume the robot is restarting from the last saved localization pose from previous session (the place where it shut down previously). Used only in localization mode (%s=false).", kMemIncrementalMemory().c_str()));
@@ -428,7 +441,7 @@ class RTABMAP_CORE_EXPORT Parameters
#endif #endif
#endif #endif
RTABMAP_PARAM(Optimizer, VarianceIgnored, bool, false, "Ignore constraints' variance. If checked, identity information matrix is used for each constraint. Otherwise, an information matrix is generated from the variance saved in the links."); RTABMAP_PARAM(Optimizer, VarianceIgnored, bool, false, "Ignore constraints' variance. If checked, identity information matrix is used for each constraint. Otherwise, an information matrix is generated from the variance saved in the links.");
RTABMAP_PARAM(Optimizer, Robust, bool, false, uFormat("Robust graph optimization using Vertigo (only work for g2o and GTSAM optimization strategies). Not compatible with \"%s\" if enabled.", kRGBDOptimizeMaxError().c_str())); RTABMAP_PARAM(Optimizer, Robust, bool, false, "Robust graph optimization using Vertigo (only work for g2o and GTSAM optimization strategies).");
RTABMAP_PARAM(Optimizer, PriorsIgnored, bool, true, "Ignore prior constraints (global pose or GPS) while optimizing. Currently only g2o and gtsam optimization supports this."); RTABMAP_PARAM(Optimizer, PriorsIgnored, bool, true, "Ignore prior constraints (global pose or GPS) while optimizing. Currently only g2o and gtsam optimization supports this.");
RTABMAP_PARAM(Optimizer, LandmarksIgnored, bool, false, "Ignore landmark constraints while optimizing. Currently only g2o and gtsam optimization supports this."); RTABMAP_PARAM(Optimizer, LandmarksIgnored, bool, false, "Ignore landmark constraints while optimizing. Currently only g2o and gtsam optimization supports this.");
#if defined(RTABMAP_G2O) || defined(RTABMAP_GTSAM) #if defined(RTABMAP_G2O) || defined(RTABMAP_GTSAM)
@@ -453,8 +466,8 @@ class RTABMAP_CORE_EXPORT Parameters
RTABMAP_PARAM(GTSAM, IncRelinearizeSkip, int, 1, "Only relinearize any variables every X calls to ISAM2::update(). See GTSAM::ISAM2 doc for more info."); RTABMAP_PARAM(GTSAM, IncRelinearizeSkip, int, 1, "Only relinearize any variables every X calls to ISAM2::update(). See GTSAM::ISAM2 doc for more info.");
// Odometry // Odometry
RTABMAP_PARAM(Odom, Strategy, int, 0, "0=Frame-to-Map (F2M) 1=Frame-to-Frame (F2F) 2=Fovis 3=viso2 4=DVO-SLAM 5=ORB_SLAM2 6=OKVIS 7=LOAM 8=MSCKF_VIO 9=VINS-Fusion 10=OpenVINS 11=FLOAM 12=Open3D"); RTABMAP_PARAM(Odom, Strategy, int, 0, "0=Frame-to-Map (F2M) 1=Frame-to-Frame (F2F) 2=Fovis 3=viso2 4=DVO-SLAM 5=ORB_SLAM 6=OKVIS 7=LOAM 8=MSCKF_VIO 9=VINS-Fusion 10=OpenVINS 11=FLOAM 12=Open3D 13=cuVSLAM 14=LIO-SAM");
RTABMAP_PARAM(Odom, ResetCountdown, int, 0, "Automatically reset odometry after X consecutive images on which odometry cannot be computed (value=0 disables auto-reset)."); RTABMAP_PARAM(Odom, ResetCountdown, int, 0, "Automatically reset odometry after X consecutive images where odometry cannot be computed (a value of 0 disables auto-reset). When a reset occurs, odometry resumes from the last successfully computed pose with large covariance to trigger a new map. If external odometry is used, it will also be reset based on the motion estimated relative to the last computed pose but no large covariance will be received, so that a new map won't be triggered.");
RTABMAP_PARAM(Odom, Holonomic, bool, true, "If the robot is holonomic (strafing commands can be issued). If not, y value will be estimated from x and yaw values (y=x*tan(yaw))."); RTABMAP_PARAM(Odom, Holonomic, bool, true, "If the robot is holonomic (strafing commands can be issued). If not, y value will be estimated from x and yaw values (y=x*tan(yaw)).");
RTABMAP_PARAM(Odom, FillInfoData, bool, true, "Fill info with data (inliers/outliers features)."); RTABMAP_PARAM(Odom, FillInfoData, bool, true, "Fill info with data (inliers/outliers features).");
RTABMAP_PARAM(Odom, ImageBufferSize, unsigned int, 1, "Data buffer size (0 min inf)."); RTABMAP_PARAM(Odom, ImageBufferSize, unsigned int, 1, "Data buffer size (0 min inf).");
@@ -548,7 +561,7 @@ class RTABMAP_CORE_EXPORT Parameters
RTABMAP_PARAM(OdomViso2, BucketWidth, double, 50, "Width of bucket."); RTABMAP_PARAM(OdomViso2, BucketWidth, double, 50, "Width of bucket.");
RTABMAP_PARAM(OdomViso2, BucketHeight, double, 50, "Height of bucket."); RTABMAP_PARAM(OdomViso2, BucketHeight, double, 50, "Height of bucket.");
// Odometry ORB_SLAM2 // Odometry ORB_SLAM
RTABMAP_PARAM_STR(OdomORBSLAM, VocPath, "", "Path to ORB vocabulary (*.txt)."); RTABMAP_PARAM_STR(OdomORBSLAM, VocPath, "", "Path to ORB vocabulary (*.txt).");
RTABMAP_PARAM(OdomORBSLAM, Bf, double, 0.076, "Fake IR projector baseline (m) used only when stereo is not used."); RTABMAP_PARAM(OdomORBSLAM, Bf, double, 0.076, "Fake IR projector baseline (m) used only when stereo is not used.");
RTABMAP_PARAM(OdomORBSLAM, ThDepth, double, 40.0, "Close/Far threshold. Baseline times."); RTABMAP_PARAM(OdomORBSLAM, ThDepth, double, 40.0, "Close/Far threshold. Baseline times.");
@@ -603,75 +616,94 @@ class RTABMAP_CORE_EXPORT Parameters
RTABMAP_PARAM(OdomMSCKF, InitCovExTrans, double, 0.000025, ""); RTABMAP_PARAM(OdomMSCKF, InitCovExTrans, double, 0.000025, "");
RTABMAP_PARAM(OdomMSCKF, MaxCamStateSize, int, 20, ""); RTABMAP_PARAM(OdomMSCKF, MaxCamStateSize, int, 20, "");
// Odometry VINS // Odometry VINS-Fusion
RTABMAP_PARAM_STR(OdomVINS, ConfigPath, "", "Path of VINS config file."); RTABMAP_PARAM_STR(OdomVINSFusion, ConfigPath, "", "Path of VINS-Fusion config file.");
// Odometry OpenVINS // Odometry OpenVINS
RTABMAP_PARAM(OdomOpenVINS, UseStereo, bool, true, "If we have more than 1 camera, if we should try to track stereo constraints between pairs"); RTABMAP_PARAM_STR(OdomOpenVINS, ConfigPath, "", "Path of OpenVINS config file (*.yaml). Same format used than OpenVINS library. Note that any parameter from that config file will overwrite the same parameter in OdomOpenVINS group.");
RTABMAP_PARAM(OdomOpenVINS, UseKLT, bool, true, "If true we will use KLT, otherwise use a ORB descriptor + robust matching"); RTABMAP_PARAM(OdomOpenVINS, UseStereo, bool, true, "If we have more than 1 camera, if we should try to track stereo constraints between pairs.");
RTABMAP_PARAM(OdomOpenVINS, NumPts, int, 200, "Number of points (per camera) we will extract and try to track"); RTABMAP_PARAM(OdomOpenVINS, UseKLT, bool, true, "If true we will use KLT, otherwise use a ORB descriptor + robust matching.");
RTABMAP_PARAM(OdomOpenVINS, MinPxDist, int, 15, "Eistance between features (features near each other provide less information)"); RTABMAP_PARAM(OdomOpenVINS, NumPts, int, 200, "Number of points (per camera) we will extract and try to track.");
RTABMAP_PARAM(OdomOpenVINS, FiTriangulate1d, bool, false, "If we should perform 1d triangulation instead of 3d"); RTABMAP_PARAM(OdomOpenVINS, MinPxDist, int, 15, "Eistance between features (features near each other provide less information).");
RTABMAP_PARAM(OdomOpenVINS, FiRefineFeatures, bool, true, "If we should perform Levenberg-Marquardt refinement"); RTABMAP_PARAM(OdomOpenVINS, FiTriangulate1d, bool, false, "If we should perform 1d triangulation instead of 3d.");
RTABMAP_PARAM(OdomOpenVINS, FiMaxRuns, int, 5, "Max runs for Levenberg-Marquardt"); RTABMAP_PARAM(OdomOpenVINS, FiRefineFeatures, bool, true, "If we should perform Levenberg-Marquardt refinement.");
RTABMAP_PARAM(OdomOpenVINS, FiMaxBaseline, double, 40, "Max baseline ratio to accept triangulated features"); RTABMAP_PARAM(OdomOpenVINS, FiMaxRuns, int, 5, "Max runs for Levenberg-Marquardt.");
RTABMAP_PARAM(OdomOpenVINS, FiMaxCondNumber, double, 10000, "Max condition number of linear triangulation matrix accept triangulated features"); RTABMAP_PARAM(OdomOpenVINS, FiMaxBaseline, double, 40, "Max baseline ratio to accept triangulated features.");
RTABMAP_PARAM(OdomOpenVINS, FiMaxCondNumber, double, 10000, "Max condition number of linear triangulation matrix accept triangulated features.");
RTABMAP_PARAM(OdomOpenVINS, UseFEJ, bool, true, "If first-estimate Jacobians should be used (enable for good consistency)"); RTABMAP_PARAM(OdomOpenVINS, UseFEJ, bool, true, "If first-estimate Jacobians should be used (enable for good consistency).");
RTABMAP_PARAM(OdomOpenVINS, Integration, int, 1, "0=discrete, 1=rk4, 2=analytical (if rk4 or analytical used then analytical covariance propagation is used)"); RTABMAP_PARAM(OdomOpenVINS, Integration, int, 1, "0=discrete, 1=rk4, 2=analytical (if rk4 or analytical used then analytical covariance propagation is used).");
RTABMAP_PARAM(OdomOpenVINS, CalibCamExtrinsics, bool, false, "Bool to determine whether or not to calibrate imu-to-camera pose"); RTABMAP_PARAM(OdomOpenVINS, CalibCamExtrinsics, bool, false, "Bool to determine whether or not to calibrate imu-to-camera pose.");
RTABMAP_PARAM(OdomOpenVINS, CalibCamIntrinsics, bool, false, "Bool to determine whether or not to calibrate camera intrinsics"); RTABMAP_PARAM(OdomOpenVINS, CalibCamIntrinsics, bool, false, "Bool to determine whether or not to calibrate camera intrinsics.");
RTABMAP_PARAM(OdomOpenVINS, CalibCamTimeoffset, bool, false, "Bool to determine whether or not to calibrate camera to IMU time offset"); RTABMAP_PARAM(OdomOpenVINS, CalibCamTimeoffset, bool, false, "Bool to determine whether or not to calibrate camera to IMU time offset.");
RTABMAP_PARAM(OdomOpenVINS, CalibIMUIntrinsics, bool, false, "Bool to determine whether or not to calibrate the IMU intrinsics"); RTABMAP_PARAM(OdomOpenVINS, CalibIMUIntrinsics, bool, false, "Bool to determine whether or not to calibrate the IMU intrinsics.");
RTABMAP_PARAM(OdomOpenVINS, CalibIMUGSensitivity, bool, false, "Bool to determine whether or not to calibrate the Gravity sensitivity"); RTABMAP_PARAM(OdomOpenVINS, CalibIMUGSensitivity, bool, false, "Bool to determine whether or not to calibrate the Gravity sensitivity.");
RTABMAP_PARAM(OdomOpenVINS, MaxClones, int, 11, "Max clone size of sliding window"); RTABMAP_PARAM(OdomOpenVINS, MaxClones, int, 11, "Max clone size of sliding window.");
RTABMAP_PARAM(OdomOpenVINS, MaxSLAM, int, 50, "Max number of estimated SLAM features"); RTABMAP_PARAM(OdomOpenVINS, MaxSLAM, int, 50, "Max number of estimated SLAM features.");
RTABMAP_PARAM(OdomOpenVINS, MaxSLAMInUpdate, int, 25, "Max number of SLAM features we allow to be included in a single EKF update."); RTABMAP_PARAM(OdomOpenVINS, MaxSLAMInUpdate, int, 25, "Max number of SLAM features we allow to be included in a single EKF update..");
RTABMAP_PARAM(OdomOpenVINS, MaxMSCKFInUpdate, int, 50, "Max number of MSCKF features we will use at a given image timestep."); RTABMAP_PARAM(OdomOpenVINS, MaxMSCKFInUpdate, int, 50, "Max number of MSCKF features we will use at a given image timestep..");
RTABMAP_PARAM(OdomOpenVINS, FeatRepMSCKF, int, 0, "What representation our features are in (msckf features)"); RTABMAP_PARAM(OdomOpenVINS, FeatRepMSCKF, int, 0, "What representation our features are in (msckf features).");
RTABMAP_PARAM(OdomOpenVINS, FeatRepSLAM, int, 4, "What representation our features are in (slam features)"); RTABMAP_PARAM(OdomOpenVINS, FeatRepSLAM, int, 4, "What representation our features are in (slam features).");
RTABMAP_PARAM(OdomOpenVINS, DtSLAMDelay, double, 0.0, "Delay, in seconds, that we should wait from init before we start estimating SLAM features"); RTABMAP_PARAM(OdomOpenVINS, DtSLAMDelay, double, 0.0, "Delay, in seconds, that we should wait from init before we start estimating SLAM features.");
RTABMAP_PARAM(OdomOpenVINS, GravityMag, double, 9.81, "Gravity magnitude in the global frame (i.e. should be 9.81 typically)"); RTABMAP_PARAM(OdomOpenVINS, GravityMag, double, 9.81, "Gravity magnitude in the global frame (i.e. should be 9.81 typically).");
RTABMAP_PARAM_STR(OdomOpenVINS, LeftMaskPath, "", "Mask for left image"); RTABMAP_PARAM_STR(OdomOpenVINS, LeftMaskPath, "", "Mask for left image.");
RTABMAP_PARAM_STR(OdomOpenVINS, RightMaskPath, "", "Mask for right image"); RTABMAP_PARAM_STR(OdomOpenVINS, RightMaskPath, "", "Mask for right image.");
RTABMAP_PARAM(OdomOpenVINS, InitWindowTime, double, 2.0, "Amount of time we will initialize over (seconds)"); RTABMAP_PARAM(OdomOpenVINS, InitWindowTime, double, 2.0, "Amount of time we will initialize over (seconds).");
RTABMAP_PARAM(OdomOpenVINS, InitIMUThresh, double, 1.0, "Variance threshold on our acceleration to be classified as moving"); RTABMAP_PARAM(OdomOpenVINS, InitIMUThresh, double, 1.0, "Variance threshold on our acceleration to be classified as moving.");
RTABMAP_PARAM(OdomOpenVINS, InitMaxDisparity, double, 10.0, "Max disparity to consider the platform stationary (dependent on resolution)"); RTABMAP_PARAM(OdomOpenVINS, InitMaxDisparity, double, 10.0, "Max disparity to consider the platform stationary (dependent on resolution).");
RTABMAP_PARAM(OdomOpenVINS, InitMaxFeatures, int, 50, "How many features to track during initialization (saves on computation)"); RTABMAP_PARAM(OdomOpenVINS, InitMaxFeatures, int, 50, "How many features to track during initialization (saves on computation).");
RTABMAP_PARAM(OdomOpenVINS, InitDynUse, bool, false, "If dynamic initialization should be used"); RTABMAP_PARAM(OdomOpenVINS, InitDynUse, bool, false, "If dynamic initialization should be used.");
RTABMAP_PARAM(OdomOpenVINS, InitDynMLEOptCalib, bool, false, "If we should optimize calibration during intialization (not recommended)"); RTABMAP_PARAM(OdomOpenVINS, InitDynMLEOptCalib, bool, false, "If we should optimize calibration during intialization (not recommended).");
RTABMAP_PARAM(OdomOpenVINS, InitDynMLEMaxIter, int, 50, "How many iterations the MLE refinement should use (zero to skip the MLE)"); RTABMAP_PARAM(OdomOpenVINS, InitDynMLEMaxIter, int, 50, "How many iterations the MLE refinement should use (zero to skip the MLE).");
RTABMAP_PARAM(OdomOpenVINS, InitDynMLEMaxTime, double, 0.05, "How many seconds the MLE should be completed in"); RTABMAP_PARAM(OdomOpenVINS, InitDynMLEMaxTime, double, 0.05, "How many seconds the MLE should be completed in.");
RTABMAP_PARAM(OdomOpenVINS, InitDynMLEMaxThreads, int, 6, "How many threads the MLE should use"); RTABMAP_PARAM(OdomOpenVINS, InitDynMLEMaxThreads, int, 6, "How many threads the MLE should use.");
RTABMAP_PARAM(OdomOpenVINS, InitDynNumPose, int, 6, "Number of poses to use within our window time (evenly spaced)"); RTABMAP_PARAM(OdomOpenVINS, InitDynNumPose, int, 6, "Number of poses to use within our window time (evenly spaced).");
RTABMAP_PARAM(OdomOpenVINS, InitDynMinDeg, double, 10.0, "Orientation change needed to try to init"); RTABMAP_PARAM(OdomOpenVINS, InitDynMinDeg, double, 10.0, "Orientation change needed to try to init.");
RTABMAP_PARAM(OdomOpenVINS, InitDynInflationOri, double, 10.0, "What to inflate the recovered q_GtoI covariance by"); RTABMAP_PARAM(OdomOpenVINS, InitDynInflationOri, double, 10.0, "What to inflate the recovered q_GtoI covariance by.");
RTABMAP_PARAM(OdomOpenVINS, InitDynInflationVel, double, 100.0, "What to inflate the recovered v_IinG covariance by"); RTABMAP_PARAM(OdomOpenVINS, InitDynInflationVel, double, 100.0, "What to inflate the recovered v_IinG covariance by.");
RTABMAP_PARAM(OdomOpenVINS, InitDynInflationBg, double, 10.0, "What to inflate the recovered bias_g covariance by"); RTABMAP_PARAM(OdomOpenVINS, InitDynInflationBg, double, 10.0, "What to inflate the recovered bias_g covariance by.");
RTABMAP_PARAM(OdomOpenVINS, InitDynInflationBa, double, 100.0, "What to inflate the recovered bias_a covariance by"); RTABMAP_PARAM(OdomOpenVINS, InitDynInflationBa, double, 100.0, "What to inflate the recovered bias_a covariance by.");
RTABMAP_PARAM(OdomOpenVINS, InitDynMinRecCond, double, 1e-15, "Reciprocal condition number thresh for info inversion"); RTABMAP_PARAM(OdomOpenVINS, InitDynMinRecCond, double, 1e-15, "Reciprocal condition number thresh for info inversion.");
RTABMAP_PARAM(OdomOpenVINS, TryZUPT, bool, true, "If we should try to use zero velocity update"); RTABMAP_PARAM(OdomOpenVINS, TryZUPT, bool, true, "If we should try to use zero velocity update.");
RTABMAP_PARAM(OdomOpenVINS, ZUPTChi2Multiplier, double, 0.0, "Chi2 multiplier for zero velocity"); RTABMAP_PARAM(OdomOpenVINS, ZUPTChi2Multiplier, double, 0.0, "Chi2 multiplier for zero velocity.");
RTABMAP_PARAM(OdomOpenVINS, ZUPTMaxVelodicy, double, 0.1, "Max velocity we will consider to try to do a zupt (i.e. if above this, don't do zupt)"); RTABMAP_PARAM(OdomOpenVINS, ZUPTMaxVelodicy, double, 0.1, "Max velocity we will consider to try to do a zupt (i.e. if above this, don't do zupt).");
RTABMAP_PARAM(OdomOpenVINS, ZUPTNoiseMultiplier, double, 10.0, "Multiplier of our zupt measurement IMU noise matrix (default should be 1.0)"); RTABMAP_PARAM(OdomOpenVINS, ZUPTNoiseMultiplier, double, 10.0, "Multiplier of our zupt measurement IMU noise matrix (default should be 1.0).");
RTABMAP_PARAM(OdomOpenVINS, ZUPTMaxDisparity, double, 0.5, "Max disparity we will consider to try to do a zupt (i.e. if above this, don't do zupt)"); RTABMAP_PARAM(OdomOpenVINS, ZUPTMaxDisparity, double, 0.5, "Max disparity we will consider to try to do a zupt (i.e. if above this, don't do zupt).");
RTABMAP_PARAM(OdomOpenVINS, ZUPTOnlyAtBeginning, bool, false, "If we should only use the zupt at the very beginning static initialization phase"); RTABMAP_PARAM(OdomOpenVINS, ZUPTOnlyAtBeginning, bool, false, "If we should only use the zupt at the very beginning static initialization phase.");
RTABMAP_PARAM(OdomOpenVINS, AccelerometerNoiseDensity, double, 0.01, "[m/s^2/sqrt(Hz)] (accel \"white noise\")"); RTABMAP_PARAM(OdomOpenVINS, AccelerometerNoiseDensity, double, 0.01, "[m/s^2/sqrt(Hz)] (accel \"white noise\").");
RTABMAP_PARAM(OdomOpenVINS, AccelerometerRandomWalk, double, 0.001, "[m/s^3/sqrt(Hz)] (accel bias diffusion)"); RTABMAP_PARAM(OdomOpenVINS, AccelerometerRandomWalk, double, 0.001, "[m/s^3/sqrt(Hz)] (accel bias diffusion).");
RTABMAP_PARAM(OdomOpenVINS, GyroscopeNoiseDensity, double, 0.001, "[rad/s/sqrt(Hz)] (gyro \"white noise\")"); RTABMAP_PARAM(OdomOpenVINS, GyroscopeNoiseDensity, double, 0.001, "[rad/s/sqrt(Hz)] (gyro \"white noise\").");
RTABMAP_PARAM(OdomOpenVINS, GyroscopeRandomWalk, double, 0.0001, "[rad/s^2/sqrt(Hz)] (gyro bias diffusion)"); RTABMAP_PARAM(OdomOpenVINS, GyroscopeRandomWalk, double, 0.0001, "[rad/s^2/sqrt(Hz)] (gyro bias diffusion).");
RTABMAP_PARAM(OdomOpenVINS, UpMSCKFSigmaPx, double, 1.0, "Pixel noise for MSCKF features"); RTABMAP_PARAM(OdomOpenVINS, UpMSCKFSigmaPx, double, 1.0, "Pixel noise for MSCKF features.");
RTABMAP_PARAM(OdomOpenVINS, UpMSCKFChi2Multiplier, double, 1.0, "Chi2 multiplier for MSCKF features"); RTABMAP_PARAM(OdomOpenVINS, UpMSCKFChi2Multiplier, double, 1.0, "Chi2 multiplier for MSCKF features.");
RTABMAP_PARAM(OdomOpenVINS, UpSLAMSigmaPx, double, 1.0, "Pixel noise for SLAM features"); RTABMAP_PARAM(OdomOpenVINS, UpSLAMSigmaPx, double, 1.0, "Pixel noise for SLAM features.");
RTABMAP_PARAM(OdomOpenVINS, UpSLAMChi2Multiplier, double, 1.0, "Chi2 multiplier for SLAM features"); RTABMAP_PARAM(OdomOpenVINS, UpSLAMChi2Multiplier, double, 1.0, "Chi2 multiplier for SLAM features.");
// Odometry Open3D // Odometry Open3D
RTABMAP_PARAM(OdomOpen3D, MaxDepth, float, 3.0, "Maximum depth."); RTABMAP_PARAM(OdomOpen3D, MaxDepth, float, 3.0, "Maximum depth.");
RTABMAP_PARAM(OdomOpen3D, Method, int, 0, "Registration method: 0=PointToPlane, 1=Intensity, 2=Hybrid."); RTABMAP_PARAM(OdomOpen3D, Method, int, 0, "Registration method: 0=PointToPlane, 1=Intensity, 2=Hybrid.");
// Odometry cuVSLAM
RTABMAP_PARAM(OdomCuVSLAM, MulticamMode, int, 0, "cuVSLAM multicam_mode setting: 0=moderate, 1=performance, 2=precision.");
// Odometry LIO-SAM
RTABMAP_PARAM_STR(OdomLIOSAM, ConfigPath, "", "Path to LIO-SAM params.yaml config file. When set, sensor/IMU/feature parameters are loaded from the file and the individual parameters below are ignored.");
RTABMAP_PARAM(OdomLIOSAM, Sensor, int, 0, "LiDAR sensor: 0=Velodyne, 1=Ouster, 2=Livox");
RTABMAP_PARAM(OdomLIOSAM, NScan, int, 16, "Number of LiDAR channels (16, 32, 64, 128).");
RTABMAP_PARAM(OdomLIOSAM, HorizonScan, int, 1800, "Horizontal resolution (Velodyne:1800, Ouster:512/1024/2048).");
RTABMAP_PARAM(OdomLIOSAM, ImuAccNoise, float, 0.01, "IMU accelerometer white noise.");
RTABMAP_PARAM(OdomLIOSAM, ImuGyrNoise, float, 0.001, "IMU gyroscope white noise.");
RTABMAP_PARAM(OdomLIOSAM, ImuAccBiasN, float, 0.0002,"IMU accelerometer bias noise.");
RTABMAP_PARAM(OdomLIOSAM, ImuGyrBiasN, float, 0.00003,"IMU gyroscope bias noise.");
RTABMAP_PARAM(OdomLIOSAM, ImuGravity, float, 9.80511,"Gravity magnitude.");
RTABMAP_PARAM(OdomLIOSAM, EdgeThreshold,float, 1.0, "Edge feature curvature threshold.");
RTABMAP_PARAM(OdomLIOSAM, SurfThreshold,float, 0.1, "Surface feature curvature threshold.");
RTABMAP_PARAM(OdomLIOSAM, LinVar, float, 0.01, "Linear output variance.");
RTABMAP_PARAM(OdomLIOSAM, AngVar, float, 0.01, "Angular output variance.");
// Common registration parameters // Common registration parameters
RTABMAP_PARAM(Reg, RepeatOnce, bool, true, "Do a second registration with the output of the first registration as guess. Only done if no guess was provided for the first registration (like on loop closure). It can be useful if the registration approach used can use a guess to get better matches."); RTABMAP_PARAM(Reg, RepeatOnce, bool, true, "Do a second registration with the output of the first registration as guess. Only done if no guess was provided for the first registration (like on loop closure). It can be useful if the registration approach used can use a guess to get better matches.");
RTABMAP_PARAM(Reg, Strategy, int, 0, "0=Vis, 1=Icp, 2=VisIcp"); RTABMAP_PARAM(Reg, Strategy, int, 0, "0=Vis, 1=Icp, 2=VisIcp");
@@ -701,16 +733,16 @@ class RTABMAP_CORE_EXPORT Parameters
RTABMAP_PARAM(Vis, Iterations, int, 300, "Maximum iterations to compute the transform."); RTABMAP_PARAM(Vis, Iterations, int, 300, "Maximum iterations to compute the transform.");
#if CV_MAJOR_VERSION > 2 && !defined(HAVE_OPENCV_XFEATURES2D) #if CV_MAJOR_VERSION > 2 && !defined(HAVE_OPENCV_XFEATURES2D)
// OpenCV>2 without xFeatures2D module doesn't have BRIEF // OpenCV>2 without xFeatures2D module doesn't have BRIEF
RTABMAP_PARAM(Vis, FeatureType, int, 8, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE 10=ORB-OCTREE 11=SuperPoint 12=SURF/FREAK 13=GFTT/DAISY 14=SURF/DAISY 15=PyDetector"); RTABMAP_PARAM(Vis, FeatureType, int, 8, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE 10=ORB-OCTREE 11=SuperPoint 12=SURF/FREAK 13=GFTT/DAISY 14=SURF/DAISY 15=PyDetector 16=SuperPoint-Rpautrat");
#else #else
RTABMAP_PARAM(Vis, FeatureType, int, 6, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE 10=ORB-OCTREE 11=SuperPoint 12=SURF/FREAK 13=GFTT/DAISY 14=SURF/DAISY 15=PyDetector"); RTABMAP_PARAM(Vis, FeatureType, int, 6, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE 10=ORB-OCTREE 11=SuperPoint 12=SURF/FREAK 13=GFTT/DAISY 14=SURF/DAISY 15=PyDetector 16=SuperPoint-Rpautrat");
#endif #endif
RTABMAP_PARAM(Vis, MaxFeatures, int, 1000, "0 no limits."); RTABMAP_PARAM(Vis, MaxFeatures, int, 1000, "0 no limits.");
RTABMAP_PARAM(Vis, SSC, bool, false, "If true, SSC (Suppression via Square Covering) is applied to limit keypoints."); RTABMAP_PARAM(Vis, SSC, bool, false, "If true, SSC (Suppression via Square Covering) is applied to limit keypoints.");
RTABMAP_PARAM(Vis, MaxDepth, float, 0, "Max depth of the features (0 means no limit)."); RTABMAP_PARAM(Vis, MaxDepth, float, 0, "Max depth of the features (0 means no limit).");
RTABMAP_PARAM(Vis, MinDepth, float, 0, "Min depth of the features (0 means no limit)."); RTABMAP_PARAM(Vis, MinDepth, float, 0, "Min depth of the features (0 means no limit).");
RTABMAP_PARAM(Vis, DepthAsMask, bool, true, "Use depth image as mask when extracting features."); RTABMAP_PARAM(Vis, DepthAsMask, bool, true, "Use depth image as mask when extracting features.");
RTABMAP_PARAM(Vis, DepthMaskFloorThr, float, 0.0, uFormat("Filter floor from depth mask below specified threshold (m) before extracting features. 0 means disabled, negative means remove all objects above the floor threshold instead. Ignored if %s is false.", kVisDepthAsMask().c_str())); RTABMAP_PARAM(Vis, DepthMaskFloorThr, float, 0.0, uFormat("Filter floor from depth mask below specified threshold (m) before extracting features. 0 means disabled. Ignored if %s is false.", kVisDepthAsMask().c_str()));
RTABMAP_PARAM_STR(Vis, RoiRatios, "0.0 0.0 0.0 0.0", "Region of interest ratios [left, right, top, bottom]."); RTABMAP_PARAM_STR(Vis, RoiRatios, "0.0 0.0 0.0 0.0", "Region of interest ratios [left, right, top, bottom].");
RTABMAP_PARAM(Vis, SubPixWinSize, int, 3, "See cv::cornerSubPix()."); RTABMAP_PARAM(Vis, SubPixWinSize, int, 3, "See cv::cornerSubPix().");
RTABMAP_PARAM(Vis, SubPixIterations, int, 0, "See cv::cornerSubPix(). 0 disables sub pixel refining."); RTABMAP_PARAM(Vis, SubPixIterations, int, 0, "See cv::cornerSubPix(). 0 disables sub pixel refining.");
@@ -726,8 +758,11 @@ class RTABMAP_CORE_EXPORT Parameters
RTABMAP_PARAM(Vis, CorFlowIterations, int, 30, uFormat("[%s=1] See cv::calcOpticalFlowPyrLK(). Used for optical flow approach.", kVisCorType().c_str())); RTABMAP_PARAM(Vis, CorFlowIterations, int, 30, uFormat("[%s=1] See cv::calcOpticalFlowPyrLK(). Used for optical flow approach.", kVisCorType().c_str()));
RTABMAP_PARAM(Vis, CorFlowEps, float, 0.01, uFormat("[%s=1] See cv::calcOpticalFlowPyrLK(). Used for optical flow approach.", kVisCorType().c_str())); RTABMAP_PARAM(Vis, CorFlowEps, float, 0.01, uFormat("[%s=1] See cv::calcOpticalFlowPyrLK(). Used for optical flow approach.", kVisCorType().c_str()));
RTABMAP_PARAM(Vis, CorFlowMaxLevel, int, 3, uFormat("[%s=1] See cv::calcOpticalFlowPyrLK(). Used for optical flow approach.", kVisCorType().c_str())); RTABMAP_PARAM(Vis, CorFlowMaxLevel, int, 3, uFormat("[%s=1] See cv::calcOpticalFlowPyrLK(). Used for optical flow approach.", kVisCorType().c_str()));
RTABMAP_PARAM(Vis, CorFlowGpu, bool, false, uFormat("[%s=1] Enable GPU version of the optical flow approach (only available if OpenCV is built with CUDA).", kVisCorType().c_str())); RTABMAP_PARAM(Vis, CorFlowUseMinEigenVals, bool, true, uFormat("[%s=1] See cv::calcOpticalFlowPyrLK(). Used for optical flow approach. Use minimum eigen values as an error measure, otherwise L1 distance between patches is used as an error measure.", kVisCorType().c_str()));
#if defined(RTABMAP_G2O) || defined(RTABMAP_ORB_SLAM) RTABMAP_PARAM(Vis, CorFlowMinEigThreshold, float, 1e-4, uFormat("[%s=true] If the minimum eigenvalue of a feature's spatial gradient matrix is less than this threshold, then the feature is filtered out.", kVisCorFlowUseMinEigenVals().c_str()));
RTABMAP_PARAM(Vis, CorFlowErrorThreshold, float, 20, uFormat("[%s=false] Filter out features with error greater than this threshold.", kVisCorFlowUseMinEigenVals().c_str()));
RTABMAP_PARAM(Vis, CorFlowGpu, bool, false, uFormat("[%s=1] Enable GPU version of the optical flow approach (only available if OpenCV is built with CUDA). Note that %s is not used in the GPU implementation.", kVisCorType().c_str(), kVisCorFlowUseMinEigenVals().c_str()));
#if defined(RTABMAP_G2O) || defined(RTABMAP_ORB_SLAM)
RTABMAP_PARAM(Vis, BundleAdjustment, int, 1, "Optimization with bundle adjustment: 0=disabled, 1=g2o, 2=cvsba, 3=Ceres."); RTABMAP_PARAM(Vis, BundleAdjustment, int, 1, "Optimization with bundle adjustment: 0=disabled, 1=g2o, 2=cvsba, 3=Ceres.");
#else #else
RTABMAP_PARAM(Vis, BundleAdjustment, int, 0, "Optimization with bundle adjustment: 0=disabled, 1=g2o, 2=cvsba, 3=Ceres."); RTABMAP_PARAM(Vis, BundleAdjustment, int, 0, "Optimization with bundle adjustment: 0=disabled, 1=g2o, 2=cvsba, 3=Ceres.");
@@ -804,7 +839,10 @@ class RTABMAP_CORE_EXPORT Parameters
RTABMAP_PARAM(Stereo, OpticalFlow, bool, true, "Use optical flow to find stereo correspondences, otherwise a simple block matching approach is used."); RTABMAP_PARAM(Stereo, OpticalFlow, bool, true, "Use optical flow to find stereo correspondences, otherwise a simple block matching approach is used.");
RTABMAP_PARAM(Stereo, SSD, bool, true, uFormat("[%s=false] Use Sum of Squared Differences (SSD) window, otherwise Sum of Absolute Differences (SAD) window is used.", kStereoOpticalFlow().c_str())); RTABMAP_PARAM(Stereo, SSD, bool, true, uFormat("[%s=false] Use Sum of Squared Differences (SSD) window, otherwise Sum of Absolute Differences (SAD) window is used.", kStereoOpticalFlow().c_str()));
RTABMAP_PARAM(Stereo, Eps, double, 0.01, uFormat("[%s=true] Epsilon stop criterion.", kStereoOpticalFlow().c_str())); RTABMAP_PARAM(Stereo, Eps, double, 0.01, uFormat("[%s=true] Epsilon stop criterion.", kStereoOpticalFlow().c_str()));
RTABMAP_PARAM(Stereo, Gpu, bool, false, uFormat("[%s=true] Enable GPU version of the optical flow approach (only available if OpenCV is built with CUDA).", kStereoOpticalFlow().c_str())); RTABMAP_PARAM(Stereo, UseMinEigenVals, bool, true, uFormat("[%s=true] Use minimum eigen values as an error measure, otherwise L1 distance between patches is used as an error measure.", kStereoOpticalFlow().c_str()));
RTABMAP_PARAM(Stereo, MinEigThreshold, double, 1e-4, uFormat("[%s=true] If the minimum eigenvalue of a feature's spatial gradient matrix is less than this threshold, then the feature is filtered out.", kStereoUseMinEigenVals().c_str()));
RTABMAP_PARAM(Stereo, ErrorThreshold, double, 50, uFormat("[%s=false] Filter out features with error greater than this threshold.", kStereoUseMinEigenVals().c_str()));
RTABMAP_PARAM(Stereo, Gpu, bool, false, uFormat("[%s=true] Enable GPU version of the optical flow approach (only available if OpenCV is built with CUDA). Note that %s is not used in the GPU implementation.", kStereoOpticalFlow().c_str(), kStereoUseMinEigenVals().c_str()));
RTABMAP_PARAM(Stereo, DenseStrategy, int, 0, "0=cv::StereoBM, 1=cv::StereoSGBM"); RTABMAP_PARAM(Stereo, DenseStrategy, int, 0, "0=cv::StereoBM, 1=cv::StereoSGBM");
@@ -880,19 +918,29 @@ class RTABMAP_CORE_EXPORT Parameters
RTABMAP_PARAM(GridGlobal, ProbClampingMax, float, 0.971, "Probability clamping maximum (value between 0 and 1)."); RTABMAP_PARAM(GridGlobal, ProbClampingMax, float, 0.971, "Probability clamping maximum (value between 0 and 1).");
RTABMAP_PARAM(GridGlobal, FloodFillDepth, unsigned int, 0, "Flood fill filter (0=disabled), used to remove empty cells outside the map. The flood fill is done at the specified depth (between 1 and 16) of the OctoMap."); RTABMAP_PARAM(GridGlobal, FloodFillDepth, unsigned int, 0, "Flood fill filter (0=disabled), used to remove empty cells outside the map. The flood fill is done at the specified depth (between 1 and 16) of the OctoMap.");
RTABMAP_PARAM(Marker, Dictionary, int, 0, "Dictionary to use: DICT_ARUCO_4X4_50=0, DICT_ARUCO_4X4_100=1, DICT_ARUCO_4X4_250=2, DICT_ARUCO_4X4_1000=3, DICT_ARUCO_5X5_50=4, DICT_ARUCO_5X5_100=5, DICT_ARUCO_5X5_250=6, DICT_ARUCO_5X5_1000=7, DICT_ARUCO_6X6_50=8, DICT_ARUCO_6X6_100=9, DICT_ARUCO_6X6_250=10, DICT_ARUCO_6X6_1000=11, DICT_ARUCO_7X7_50=12, DICT_ARUCO_7X7_100=13, DICT_ARUCO_7X7_250=14, DICT_ARUCO_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16, DICT_APRILTAG_16h5=17, DICT_APRILTAG_25h9=18, DICT_APRILTAG_36h10=19, DICT_APRILTAG_36h11=20"); RTABMAP_PARAM(Marker, Strategy, int, 0, "Marker detection implementation: 0=OpenCV, 1=AprilTag");
RTABMAP_PARAM(Marker, Length, float, 0, "The length (m) of the markers' side. 0 means automatic marker length estimation using the depth image (the camera should look at the marker perpendicularly for initialization)."); RTABMAP_PARAM(Marker, Dictionary, int, 0, "Dictionary to use: DICT_ARUCO_4X4_50=0, DICT_ARUCO_4X4_100=1, DICT_ARUCO_4X4_250=2, DICT_ARUCO_4X4_1000=3, DICT_ARUCO_5X5_50=4, DICT_ARUCO_5X5_100=5, DICT_ARUCO_5X5_250=6, DICT_ARUCO_5X5_1000=7, DICT_ARUCO_6X6_50=8, DICT_ARUCO_6X6_100=9, DICT_ARUCO_6X6_250=10, DICT_ARUCO_6X6_1000=11, DICT_ARUCO_7X7_50=12, DICT_ARUCO_7X7_100=13, DICT_ARUCO_7X7_250=14, DICT_ARUCO_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16, DICT_APRILTAG_16h5=17, DICT_APRILTAG_25h9=18, DICT_APRILTAG_36h10=19, DICT_APRILTAG_36h11=20, DICT_ARUCO_MIP_36H12=21");
RTABMAP_PARAM(Marker, Length, float, 0, "The length (m) of the markers' side. Value <=0 means automatic marker length estimation using the depth image (the camera should look at the marker perpendicularly for initialization). If 0, the length is estimated only on the first marker detected, then re-used for all next detections (i.e., this assumes that markers have all the same length). With <0, the length is estimated once for each unique marker, then re-used for next detections with the same marker ID.");
RTABMAP_PARAM_STR(Marker, Lengths, "", uFormat("List of markers to detect. Format is the marker's ID followed by its length (in meters), multiple markers are separated by a vertical line (\"id1 length|id2 length\"). We can also define a range of markers with \"id1:id2 length\" (id2 included). If empty, all markers of the chosen dictionary can be detected and their length is set/estimated based on %s. For example, to detect markers 12 and 14 with lengths of 8 and 15 cm respectively, and all markers between 30 and 40 with a length of 10 cm, set \"12 0.08|14 0.15|30:40 0.1\".", kMarkerLength().c_str()).c_str());
RTABMAP_PARAM(Marker, MaxDepthError, float, 0.01, uFormat("Maximum depth error between all corners of a marker when estimating the marker length (when %s is 0). The smaller it is, the more perpendicular the camera should be toward the marker to initialize the length.", kMarkerLength().c_str())); RTABMAP_PARAM(Marker, MaxDepthError, float, 0.01, uFormat("Maximum depth error between all corners of a marker when estimating the marker length (when %s is 0). The smaller it is, the more perpendicular the camera should be toward the marker to initialize the length.", kMarkerLength().c_str()));
RTABMAP_PARAM(Marker, VarianceLinear, float, 0.001, uFormat("Linear variance to set on marker detections. If %s is enabled and %s=2 (GTSAM): it is the variance of the range factor, with 9999 to disable range factor and to do only bearing.", kMarkerVarianceOrientationIgnored().c_str(), kOptimizerStrategy().c_str())); RTABMAP_PARAM(Marker, VarianceLinear, float, 0.001, uFormat("Linear variance to set on marker detections. If %s is enabled and %s=2 (GTSAM): it is the variance of the range factor, with 9999 to disable range factor and to do only bearing.", kMarkerVarianceOrientationIgnored().c_str(), kOptimizerStrategy().c_str()));
RTABMAP_PARAM(Marker, VarianceAngular, float, 0.01, uFormat("Angular variance to set on marker detections. If %s is enabled, it is ignored with %s=1 (g2o) and it corresponds to bearing variance with %s=2 (GTSAM).", kMarkerVarianceOrientationIgnored().c_str(), kOptimizerStrategy().c_str(), kOptimizerStrategy().c_str())); RTABMAP_PARAM(Marker, VarianceAngular, float, 0.01, uFormat("Angular variance to set on marker detections. If %s is enabled, it is ignored with %s=1 (g2o) and it corresponds to bearing variance with %s=2 (GTSAM).", kMarkerVarianceOrientationIgnored().c_str(), kOptimizerStrategy().c_str(), kOptimizerStrategy().c_str()));
RTABMAP_PARAM(Marker, VarianceOrientationIgnored, bool, false, uFormat("When this setting is false, the landmark's orientation is optimized during graph optimization. When this setting is true, only the position of the landmark is optimized. This can be useful when the landmark's orientation estimation is not reliable. Note that for %s=1 (g2o), only %s needs be set if we ignore orientation. For %s=2 (GTSAM), instead of optimizing the landmark's position directly, a bearing/range factor is used, with %s as the variance of the range factor (with 9999 to optimize the position with only a bearing factor) and %s as the variance of the bearing factor (pitch/yaw).", kOptimizerStrategy().c_str(), kMarkerVarianceLinear().c_str(), kOptimizerStrategy().c_str(), kMarkerVarianceLinear().c_str(), kMarkerVarianceAngular().c_str())); RTABMAP_PARAM(Marker, VarianceOrientationIgnored, bool, false, uFormat("When this setting is false, the landmark's orientation is optimized during graph optimization. When this setting is true, only the position of the landmark is optimized. This can be useful when the landmark's orientation estimation is not reliable. Note that for %s=1 (g2o), only %s needs be set if we ignore orientation. For %s=2 (GTSAM), instead of optimizing the landmark's position directly, a bearing/range factor is used, with %s as the variance of the range factor (with 9999 to optimize the position with only a bearing factor) and %s as the variance of the bearing factor (pitch/yaw).", kOptimizerStrategy().c_str(), kMarkerVarianceLinear().c_str(), kOptimizerStrategy().c_str(), kMarkerVarianceLinear().c_str(), kMarkerVarianceAngular().c_str()));
RTABMAP_PARAM(Marker, CornerRefinementMethod, int, 0, "Corner refinement method (0: None, 1: Subpixel, 2:contour, 3: AprilTag2). For OpenCV <3.3.0, this is \"doCornerRefinement\" parameter: set 0 for false and 1 for true.");
RTABMAP_PARAM(Marker, MaxRange, float, 0.0, "Maximum range in which markers will be detected. <=0 for unlimited range."); RTABMAP_PARAM(Marker, MaxRange, float, 0.0, "Maximum range in which markers will be detected. <=0 for unlimited range.");
RTABMAP_PARAM(Marker, MinRange, float, 0.0, "Miniminum range in which markers will be detected. <=0 for unlimited range."); RTABMAP_PARAM(Marker, MinRange, float, 0.0, "Miniminum range in which markers will be detected. <=0 for unlimited range.");
RTABMAP_PARAM_STR(Marker, Priors, "", "World prior locations of the markers. The map will be transformed in marker's world frame when a tag is detected. Format is the marker's ID followed by its position (angles in rad), markers are separated by vertical line (\"id1 x y z roll pitch yaw|id2 x y z roll pitch yaw\"). Example: \"1 0 0 1 0 0 0|2 1 0 1 0 0 1.57\" (marker 2 is 1 meter forward than marker 1 with 90 deg yaw rotation)."); RTABMAP_PARAM_STR(Marker, Priors, "", "World prior locations of the markers. The map will be transformed in marker's world frame when a tag is detected. Format is the marker's ID followed by its position (angles in rad), multiple markers are separated by vertical line (\"id1 x y z roll pitch yaw|id2 x y z roll pitch yaw\"). Example: \"1 0 0 1 0 0 0|2 1 0 1 0 0 1.57\" (marker 2 is 1 meter forward than marker 1 with 90 deg yaw rotation).");
RTABMAP_PARAM(Marker, PriorsVarianceLinear, float, 0.001, "Linear variance to set on marker priors."); RTABMAP_PARAM(Marker, PriorsVarianceLinear, float, 0.001, "Linear variance to set on marker priors.");
RTABMAP_PARAM(Marker, PriorsVarianceAngular, float, 0.001, "Angular variance to set on marker priors."); RTABMAP_PARAM(Marker, PriorsVarianceAngular, float, 0.001, "Angular variance to set on marker priors.");
RTABMAP_PARAM(MarkerAprilTag, NThreads, int, 1, "How many threads should be used?");
RTABMAP_PARAM(MarkerAprilTag, QuadDecimate, float, 1.0, "Detection of quads can be done on a lower-resolution image, improving speed at a cost of pose accuracy and a slight decrease in detection rate. Decoding the binary payload is still done at full resolution.");
RTABMAP_PARAM(MarkerAprilTag, QuadSigma, float, 0.0, "What Gaussian blur should be applied to the segmented image (used for quad detection?) Parameter is the standard deviation in pixels. Very noisy images benefit from non-zero values (e.g. 0.8).");
RTABMAP_PARAM(MarkerAprilTag, RefineEdges, bool, true, uFormat("When true, the edges of the each quad are adjusted to \"snap to\" strong gradients nearby. This is useful when decimation is employed, as it can increase the quality of the initial quad estimate substantially. Generally recommended to be on (true). Very computationally inexpensive. Option is ignored if %s = 1.", kMarkerAprilTagQuadDecimate().c_str()));
RTABMAP_PARAM(MarkerAprilTag, DecodeSharpening, double, 0.25, "How much sharpening should be done to decoded images? This can help decode small tags but may or may not help in odd lighting conditions or low light conditions.");
RTABMAP_PARAM(MarkerAprilTag, Debug, bool, false, uFormat("When true, write a variety of debugging images to the working directory where the app started (not %s) at various stages through the detection process. (Somewhat slow).", kRtabmapWorkingDirectory().c_str()));
RTABMAP_PARAM(MarkerOpenCV, CornerRefinementMethod, int, 0, "Corner refinement method for OpenCV strategy (0: None, 1: Subpixel, 2:contour, 3: AprilTag2). For OpenCV <3.3.0, this is \"doCornerRefinement\" parameter: set 0 for false and 1 for true.");
RTABMAP_PARAM(ImuFilter, MadgwickGain, double, 0.1, "Gain of the filter. Higher values lead to faster convergence but more noise. Lower values lead to slower convergence but smoother signal, belongs in [0, 1]."); RTABMAP_PARAM(ImuFilter, MadgwickGain, double, 0.1, "Gain of the filter. Higher values lead to faster convergence but more noise. Lower values lead to slower convergence but smoother signal, belongs in [0, 1].");
RTABMAP_PARAM(ImuFilter, MadgwickZeta, double, 0.0, "Gyro drift gain (approx. rad/s), belongs in [-1, 1]."); RTABMAP_PARAM(ImuFilter, MadgwickZeta, double, 0.0, "Gyro drift gain (approx. rad/s), belongs in [-1, 1].");
@@ -8,6 +8,7 @@
#ifndef CORELIB_SRC_PYTHON_PYTHONINTERFACE_H_ #ifndef CORELIB_SRC_PYTHON_PYTHONINTERFACE_H_
#define CORELIB_SRC_PYTHON_PYTHONINTERFACE_H_ #define CORELIB_SRC_PYTHON_PYTHONINTERFACE_H_
#include "rtabmap/core/rtabmap_core_export.h" // DLL export/import defines
#include <string> #include <string>
#include <rtabmap/utilite/UMutex.h> #include <rtabmap/utilite/UMutex.h>
@@ -23,7 +24,7 @@ namespace rtabmap {
* Create a single PythonInterface on main thread at * Create a single PythonInterface on main thread at
* global scope before any Python classes. * global scope before any Python classes.
*/ */
class PythonInterface class RTABMAP_CORE_EXPORT PythonInterface
{ {
public: public:
PythonInterface(); PythonInterface();
@@ -34,7 +35,7 @@ private:
pybind11::gil_scoped_release* release_; pybind11::gil_scoped_release* release_;
}; };
std::string getPythonTraceback(); std::string RTABMAP_CORE_EXPORT getPythonTraceback();
} }
@@ -41,6 +41,7 @@ public:
inliersMeanDistance(0.0f), inliersMeanDistance(0.0f),
inliersDistribution(0.0f), inliersDistribution(0.0f),
matches(0), matches(0),
variance(0.0f),
icpInliersRatio(0), icpInliersRatio(0),
icpTranslation(0.0f), icpTranslation(0.0f),
icpRotation(0.0f), icpRotation(0.0f),
@@ -64,6 +65,7 @@ public:
output.inliersDistribution = inliersDistribution; output.inliersDistribution = inliersDistribution;
output.matches = matches; output.matches = matches;
output.matchesPerCam = matchesPerCam; output.matchesPerCam = matchesPerCam;
output.variance = variance;
output.icpInliersRatio = icpInliersRatio; output.icpInliersRatio = icpInliersRatio;
output.icpTranslation = icpTranslation; output.icpTranslation = icpTranslation;
output.icpRotation = icpRotation; output.icpRotation = icpRotation;
@@ -85,6 +87,7 @@ public:
float inliersDistribution; float inliersDistribution;
std::vector<int> inliersIDs; std::vector<int> inliersIDs;
int matches; int matches;
float variance;
std::vector<int> matchesIDs; std::vector<int> matchesIDs;
std::vector<int> projectedIDs; // "From" IDs std::vector<int> projectedIDs; // "From" IDs
std::vector<int> inliersPerCam; std::vector<int> inliersPerCam;
@@ -91,6 +91,9 @@ private:
float _flowEps; float _flowEps;
int _flowMaxLevel; int _flowMaxLevel;
bool _flowGpu; bool _flowGpu;
bool _flowUseMinEigenVals;
float _flowMinEigThreshold;
float _flowErrorThreshold;
float _nndr; float _nndr;
int _nnType; int _nnType;
bool _gmsWithRotation; bool _gmsWithRotation;
+20 -1
View File
@@ -35,6 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/core/Statistics.h" #include "rtabmap/core/Statistics.h"
#include "rtabmap/core/Link.h" #include "rtabmap/core/Link.h"
#include "rtabmap/core/ProgressState.h" #include "rtabmap/core/ProgressState.h"
#include "rtabmap/core/Graph.h"
#include <opencv2/core/core.hpp> #include <opencv2/core/core.hpp>
#include <list> #include <list>
@@ -145,6 +146,14 @@ public:
Transform getPose(int locationId) const; Transform getPose(int locationId) const;
Transform getMapCorrection() const {return _mapCorrection;} Transform getMapCorrection() const {return _mapCorrection;}
const Memory * getMemory() const {return _memory;} const Memory * getMemory() const {return _memory;}
// Record changes made to the working database from now until it is closed, then write a
// compact delta to outputUrl (empty disables). outputUrl MUST use the ".dbu" (db update)
// extension. Call after init(), so the delta reflects only what is added/modified afterwards.
// Returns true if recording started (requires the SQLite session extension and a database
// version >= 0.24). See DBDriver.
// NOTE: recorded changes are held in RAM until the database is closed, so only enable this
// when the expected set of changes is small (e.g. appending a few sessions).
bool trackDatabaseChanges(const std::string & outputUrl);
float getGoalReachedRadius() const {return _goalReachedRadius;} float getGoalReachedRadius() const {return _goalReachedRadius;}
float getLocalRadius() const {return _localRadius;} float getLocalRadius() const {return _localRadius;}
const Transform & getLastLocalizationPose() const {return _lastLocalizationPose;} const Transform & getLastLocalizationPose() const {return _lastLocalizationPose;}
@@ -209,7 +218,8 @@ public:
bool intraSession = true, bool intraSession = true,
bool interSession = true, bool interSession = true,
const ProgressState * state = 0, const ProgressState * state = 0,
float clusterRadiusMin = 0.0f); float clusterRadiusMin = 0.0f,
int toFromMapId = -1);
bool globalBundleAdjustment( bool globalBundleAdjustment(
int optimizerType = 1 /*g2o*/, int optimizerType = 1 /*g2o*/,
bool rematchFeatures = true, bool rematchFeatures = true,
@@ -263,6 +273,13 @@ private:
std::multimap<int, Link> * constraints = 0, std::multimap<int, Link> * constraints = 0,
double * error = 0, double * error = 0,
int * iterationsDone = 0) const; int * iterationsDone = 0) const;
std::list<std::pair<int, int> > repairGraph(
graph::MaxGraphErrors & maxGraphErrors,
std::map<int, Transform> & poses,
std::multimap<int, Link> & constraints,
double & optimizationError,
int & optimizationIterations,
cv::Mat & optimizationCovariance);
void updateGoalIndex(); void updateGoalIndex();
bool computePath(int targetNode, std::map<int, Transform> nodes, const std::multimap<int, rtabmap::Link> & constraints); bool computePath(int targetNode, std::map<int, Transform> nodes, const std::multimap<int, rtabmap::Link> & constraints);
@@ -319,6 +336,7 @@ private:
std::string _databasePath; std::string _databasePath;
bool _optimizeFromGraphEnd; bool _optimizeFromGraphEnd;
float _optimizationMaxError; float _optimizationMaxError;
float _optimizationMaxErrorRepairRadius;
bool _startNewMapOnLoopClosure; bool _startNewMapOnLoopClosure;
bool _startNewMapOnGoodSignature; bool _startNewMapOnGoodSignature;
float _goalReachedRadius; // meters float _goalReachedRadius; // meters
@@ -378,6 +396,7 @@ private:
std::map<int, Transform> _odomCachePoses; // used in localization mode to reject loop closures std::map<int, Transform> _odomCachePoses; // used in localization mode to reject loop closures
std::multimap<int, Link> _odomCacheConstraints; // used in localization mode to reject loop closures std::multimap<int, Link> _odomCacheConstraints; // used in localization mode to reject loop closures
std::map<int, Transform> _markerPriors; std::map<int, Transform> _markerPriors;
std::pair<int, int> _lastRejectedLoopClosureIds;
std::set<int> _nodesToRepublish; std::set<int> _nodesToRepublish;
@@ -106,7 +106,6 @@ private:
unsigned int _dataBufferMaxSize; unsigned int _dataBufferMaxSize;
float _rate; float _rate;
bool _createIntermediateNodes; bool _createIntermediateNodes;
UTimer * _frameRateTimer;
double _previousStamp; double _previousStamp;
Rtabmap * _rtabmap; Rtabmap * _rtabmap;
+9 -5
View File
@@ -212,6 +212,12 @@ public:
_userDataCompressed.empty() && _userDataCompressed.empty() &&
_keypoints.size() == 0 && _keypoints.size() == 0 &&
_descriptors.empty() && _descriptors.empty() &&
_groundCellsRaw.empty() &&
_groundCellsCompressed.empty() &&
_obstacleCellsRaw.empty() &&
_obstacleCellsCompressed.empty() &&
_emptyCellsRaw.empty() &&
_emptyCellsCompressed.empty() &&
imu_.empty()); imu_.empty());
} }
@@ -309,8 +315,6 @@ public:
const cv::Mat & empty, const cv::Mat & empty,
float cellSize, float cellSize,
const cv::Point3f & viewPoint); const cv::Point3f & viewPoint);
// remove raw occupancy grids
void clearOccupancyGridRaw() {_groundCellsRaw = cv::Mat(); _obstacleCellsRaw = cv::Mat();}
const cv::Mat & gridGroundCellsRaw() const {return _groundCellsRaw;} const cv::Mat & gridGroundCellsRaw() const {return _groundCellsRaw;}
const cv::Mat & gridGroundCellsCompressed() const {return _groundCellsCompressed;} const cv::Mat & gridGroundCellsCompressed() const {return _groundCellsCompressed;}
const cv::Mat & gridObstacleCellsRaw() const {return _obstacleCellsRaw;} const cv::Mat & gridObstacleCellsRaw() const {return _obstacleCellsRaw;}
@@ -340,7 +344,7 @@ public:
void setGPS(const GPS & gps) {gps_ = gps;} void setGPS(const GPS & gps) {gps_ = gps;}
const GPS & gps() const {return gps_;} const GPS & gps() const {return gps_;}
void setIMU(const IMU & imu) {imu_ = imu; } void setIMU(const IMU & imu);
const IMU & imu() const {return imu_;} const IMU & imu() const {return imu_;}
void setEnvSensors(const EnvSensors & sensors) {_envSensors = sensors;} void setEnvSensors(const EnvSensors & sensors) {_envSensors = sensors;}
@@ -355,12 +359,12 @@ public:
* Clear compressed rgb/depth (left/right) images, compressed laser scan and compressed user data. * Clear compressed rgb/depth (left/right) images, compressed laser scan and compressed user data.
* Raw data are kept is set. * Raw data are kept is set.
*/ */
void clearCompressedData(bool images = true, bool scan = true, bool userData = true); void clearCompressedData(bool images = true, bool scan = true, bool userData = true, bool occupancyGrid = true);
/** /**
* Clear raw rgb/depth (left/right) images, raw laser scan and raw user data. * Clear raw rgb/depth (left/right) images, raw laser scan and raw user data.
* Compressed data are kept is set. * Compressed data are kept is set.
*/ */
void clearRawData(bool images = true, bool scan = true, bool userData = true); void clearRawData(bool images = true, bool scan = true, bool userData = true, bool occupancyGrid = true);
bool isPointVisibleFromCameras(const cv::Point3f & pt) const; // assuming point is in robot frame bool isPointVisibleFromCameras(const cv::Point3f & pt) const; // assuming point is in robot frame
@@ -67,6 +67,7 @@ class RTABMAP_CORE_EXPORT Statistics
RTABMAP_STATS(Loop, Visual_inliers,); RTABMAP_STATS(Loop, Visual_inliers,);
RTABMAP_STATS(Loop, Visual_inliers_ratio,); RTABMAP_STATS(Loop, Visual_inliers_ratio,);
RTABMAP_STATS(Loop, Visual_matches,); RTABMAP_STATS(Loop, Visual_matches,);
RTABMAP_STATS(Loop, Visual_variance,);
RTABMAP_STATS(Loop, Distance_since_last_loc, m); RTABMAP_STATS(Loop, Distance_since_last_loc, m);
RTABMAP_STATS(Loop, Last_id,); RTABMAP_STATS(Loop, Last_id,);
RTABMAP_STATS(Loop, Optimization_max_error, m); RTABMAP_STATS(Loop, Optimization_max_error, m);
@@ -75,6 +76,13 @@ class RTABMAP_CORE_EXPORT Statistics
RTABMAP_STATS(Loop, Optimization_max_ang_error_ratio, ); RTABMAP_STATS(Loop, Optimization_max_ang_error_ratio, );
RTABMAP_STATS(Loop, Optimization_error, ); RTABMAP_STATS(Loop, Optimization_error, );
RTABMAP_STATS(Loop, Optimization_iterations, ); RTABMAP_STATS(Loop, Optimization_iterations, );
RTABMAP_STATS(Loop, Optimization_max_error_from_id, );
RTABMAP_STATS(Loop, Optimization_max_error_to_id, );
RTABMAP_STATS(Loop, Optimization_max_ang_error_from_id, );
RTABMAP_STATS(Loop, Optimization_max_ang_error_to_id, );
RTABMAP_STATS(Loop, Optimization_max_error_removed_from_id, );
RTABMAP_STATS(Loop, Optimization_max_error_removed_to_id, );
RTABMAP_STATS(Loop, Optimization_max_error_removed_count, );
RTABMAP_STATS(Loop, Linear_variance,); RTABMAP_STATS(Loop, Linear_variance,);
RTABMAP_STATS(Loop, Angular_variance,); RTABMAP_STATS(Loop, Angular_variance,);
RTABMAP_STATS(Loop, Landmark_detected,); RTABMAP_STATS(Loop, Landmark_detected,);
+8 -1
View File
@@ -96,16 +96,23 @@ public:
#endif #endif
float epsilon() const {return epsilon_;} float epsilon() const {return epsilon_;}
bool usingMinEigenVals() const {return useMinEigenVals_;}
float minEigThreshold() const {return minEigThreshold_;}
float errorThreshold() const {return errorThreshold_;}
virtual bool isGpuEnabled() const; virtual bool isGpuEnabled() const;
private: private:
void updateStatus( void updateStatus(
const std::vector<cv::Point2f> & leftCorners, const std::vector<cv::Point2f> & leftCorners,
const std::vector<cv::Point2f> & rightCorners, const std::vector<cv::Point2f> & rightCorners,
std::vector<unsigned char> & status) const; std::vector<unsigned char> & status,
std::vector<float> err = {}) const;
private: private:
float epsilon_; float epsilon_;
bool useMinEigenVals_;
float minEigThreshold_;
float errorThreshold_;
bool gpu_; bool gpu_;
}; };
@@ -94,7 +94,9 @@ public:
// backward compatibility // backward compatibility
void setImageSize(const cv::Size & size) {left_.setImageSize(size); right_.setImageSize(size);} void setImageSize(const cv::Size & size) {left_.setImageSize(size); right_.setImageSize(size);}
bool load(const std::string & directory, const std::string & cameraName, bool ignoreStereoTransform = true); // Set initRectificationMaps=false to skip building the (potentially large) left/right
// rectification maps when rectification won't be used (saves time and memory).
bool load(const std::string & directory, const std::string & cameraName, bool ignoreStereoTransform = true, bool initRectificationMaps = true);
bool save(const std::string & directory, bool ignoreStereoTransform = true) const; bool save(const std::string & directory, bool ignoreStereoTransform = true) const;
bool saveStereoTransform(const std::string & directory) const; bool saveStereoTransform(const std::string & directory) const;
std::vector<unsigned char> serialize() const; std::vector<unsigned char> serialize() const;
+7 -1
View File
@@ -89,7 +89,7 @@ public:
std::vector<int> findNN(const std::list<VisualWord *> & vws) const; std::vector<int> findNN(const std::list<VisualWord *> & vws) const;
std::vector<int> findNN(const cv::Mat & descriptors) const; std::vector<int> findNN(const cv::Mat & descriptors) const;
void addWordRef(int wordId, int signatureId); bool addWordRef(int wordId, int signatureId);
void removeAllWordRef(int wordId, int signatureId); void removeAllWordRef(int wordId, int signatureId);
const VisualWord * getWord(int id) const; const VisualWord * getWord(int id) const;
VisualWord * getUnusedWord(int id) const; VisualWord * getUnusedWord(int id) const;
@@ -107,7 +107,11 @@ public:
bool isIncrementalFlann() const {return _incrementalFlann;} bool isIncrementalFlann() const {return _incrementalFlann;}
void setIncrementalDictionary(); void setIncrementalDictionary();
void setFixedDictionary(const std::string & dictionaryPath); void setFixedDictionary(const std::string & dictionaryPath);
bool isModified() const;
std::vector<unsigned char> serializeIndex() const;
void deserializeIndex(const std::vector<unsigned char> & data);
void deserializeIndex(const unsigned char * data, size_t size);
void exportDictionary(const char * fileNameReferences, const char * fileNameDescriptors) const; void exportDictionary(const char * fileNameReferences, const char * fileNameDescriptors) const;
void clear(bool printWarningsIfNotEmpty = true); void clear(bool printWarningsIfNotEmpty = true);
@@ -137,10 +141,12 @@ private:
std::string _dictionaryPath; // a pre-computed dictionary (.txt or .db) std::string _dictionaryPath; // a pre-computed dictionary (.txt or .db)
std::string _newDictionaryPath; // a pre-computed dictionary (.txt or .db) std::string _newDictionaryPath; // a pre-computed dictionary (.txt or .db)
bool _newWordsComparedTogether; bool _newWordsComparedTogether;
bool _serializeWithChecksum;
int _lastWordId; int _lastWordId;
bool useDistanceL1_; bool useDistanceL1_;
FlannIndex * _flannIndex; FlannIndex * _flannIndex;
cv::Mat _dataTree; cv::Mat _dataTree;
bool _modified;
NNStrategy _strategy; NNStrategy _strategy;
std::map<int ,int> _mapIndexId; std::map<int ,int> _mapIndexId;
std::map<int ,int> _mapIdIndex; std::map<int ,int> _mapIdIndex;
@@ -76,6 +76,28 @@ public:
{ {
_hasConfigForEachFrame = value; _hasConfigForEachFrame = value;
} }
bool isConfigForEachFrame() const {return _hasConfigForEachFrame;}
// Enable multi-camera mode. Each image in the folder is expected to be the
// horizontal concatenation of N sub-camera images of a rig, sharing the same
// base name (timestamp or node id), e.g. "1780687370.031791.jpg" or "1.jpg".
// One calibration file per sub-camera must exist in the calibrationFolder
// passed to init(), named "<prefix>_<index>.yaml" with index starting at 0
// (e.g. "1_0.yaml", "1_1.yaml", ...). The number of cameras is auto-detected.
// Each sub-image width is taken from the corresponding model's calibrated image
// size; if a model has no size, a uniform split (stackedWidth / N) is assumed.
// If setConfigForEachFrame() is enabled, one calibration set is loaded per frame
// using each image's base name as prefix. Otherwise a single calibration set is
// loaded and reused for all frames, using the cameraName passed to init() as
// prefix (it may differ from any image name), falling back to the first image's
// base name when cameraName is empty.
// Note that it is not recommended to use setConfigForEachFrame() if images have
// to be rectified, a rectification matrix would need to be re-initilaized for
// each frame.
void setMultiCameraCalibration(bool enabled)
{
_multiCameraCalib = enabled;
}
void setScanPath( void setScanPath(
const std::string & dir, const std::string & dir,
@@ -94,18 +116,19 @@ public:
_depthFromScanFillHolesFromBorder = fillHolesFromBorder; _depthFromScanFillHolesFromBorder = fillHolesFromBorder;
} }
// Format: 0=Raw, 1=RGBD-SLAM, 2=KITTI, 3=TORO, 4=g2o, 5=NewCollege(t,x,y), 6=Malaga Urban GPS, 7=St Lucia INS, 8=Karlsruhe // 0=Raw, 1=RGBD-SLAM motion capture (10=without change of coordinate frame, 11=10+ID), 2=KITTI, 3=TORO, 4=g2o, 5=NewCollege(t,x,y), 6=Malaga Urban GPS, 7=St Lucia INS, 8=Karlsruhe, 9=EuRoC MAV, 12=rgbd_bonn
void setOdometryPath(const std::string & filePath, int format = 0) void setOdometryPath(const std::string & filePath, int format = 0)
{ {
_odometryPath = filePath; _odometryPath = filePath;
_odometryFormat = format; _odometryFormat = format;
} }
// Format: 0=Raw, 1=RGBD-SLAM, 2=KITTI, 3=TORO, 4=g2o, 5=NewCollege(t,x,y), 6=Malaga Urban GPS, 7=St Lucia INS, 8=Karlsruhe // 0=Raw, 1=RGBD-SLAM motion capture (10=without change of coordinate frame, 11=10+ID), 2=KITTI, 3=TORO, 4=g2o, 5=NewCollege(t,x,y), 6=Malaga Urban GPS, 7=St Lucia INS, 8=Karlsruhe, 9=EuRoC MAV, 12=rgbd_bonn
void setGroundTruthPath(const std::string & filePath, int format = 0) void setGroundTruthPath(const std::string & filePath, int format = 0, const Transform & localTransform = Transform::getIdentity())
{ {
_groundTruthPath = filePath; _groundTruthPath = filePath;
_groundTruthFormat = format; _groundTruthFormat = format;
_groundTruthLocalTransform = localTransform;
} }
void setMaxPoseTimeDiff(double diff) {_maxPoseTimeDiff = diff;} void setMaxPoseTimeDiff(double diff) {_maxPoseTimeDiff = diff;}
@@ -120,6 +143,22 @@ public:
protected: protected:
virtual SensorData captureImage(SensorCaptureInfo * info = 0); virtual SensorData captureImage(SensorCaptureInfo * info = 0);
// File name (with extension, no directory) of the image returned by the last
// captureImage() call. Used by subclasses (e.g. stereo) to key per-frame
// calibration loaded on demand. Empty if no image was read.
const std::string & lastImageFileName() const {return _lastImageFileName;}
// Calibration folder passed to init(), kept to load per-frame calibration on
// demand. Shared with subclasses (e.g. stereo) that load calibration themselves.
std::string _calibrationFolder;
// Multi-camera mode state, shared with subclasses (e.g. stereo) that layer their
// own multi-camera handling over the base reader. Such subclasses temporarily set
// _multiCameraCalib to false while delegating to base init()/captureImage() so the
// base returns the raw stacked image instead of doing its own split, then restore it.
bool _multiCameraCalib;
int _multiCameraCount; // number of sub-cameras detected in multi-camera mode
private: private:
bool readPoses( bool readPoses(
std::list<Transform> & outputPoses, std::list<Transform> & outputPoses,
@@ -128,6 +167,16 @@ private:
int format, int format,
double maxTimeDiff) const; double maxTimeDiff) const;
// Load the sub-camera models of a multi-camera rig from calibration files named
// "<baseName>_<index>.yaml" (index 0.._multiCameraCount-1) in _calibrationFolder.
// Returns an empty vector (and logs an error) if any model is missing or invalid.
std::vector<CameraModel> loadMultiCameraModels(const std::string & baseName) const;
// Load the single-camera model for one frame from a per-frame config file (RTAB-Map
// calibration or 3DScannerApp format). Returns an invalid model (and logs an error)
// on failure.
CameraModel loadConfigModel(const std::string & filePath);
private: private:
std::string _path; std::string _path;
int _startAt; int _startAt;
@@ -143,6 +192,7 @@ private:
int _framesPublished; int _framesPublished;
UDirectory * _dir; UDirectory * _dir;
std::string _lastFileName; std::string _lastFileName;
std::string _lastImageFileName; // file name of the image returned by the last captureImage()
int _countScan; int _countScan;
UDirectory * _scanDir; UDirectory * _scanDir;
@@ -164,6 +214,7 @@ private:
int _odometryFormat; int _odometryFormat;
std::string _groundTruthPath; std::string _groundTruthPath;
int _groundTruthFormat; int _groundTruthFormat;
Transform _groundTruthLocalTransform;
double _maxPoseTimeDiff; double _maxPoseTimeDiff;
std::list<double> _stamps; std::list<double> _stamps;
@@ -171,7 +222,9 @@ private:
std::list<cv::Mat> covariances_; std::list<cv::Mat> covariances_;
std::list<Transform> groundTruth_; std::list<Transform> groundTruth_;
CameraModel _model; CameraModel _model;
std::list<CameraModel> _models; std::list<std::string> _modelFileNames; // per-frame single-camera config file paths (config-for-each-frame)
bool _configLocalTransformWarned; // warn only once when a per-frame config has no local_transform
std::vector<CameraModel> _multiModels; // sub-camera models, shared by all frames (multi-camera mode); empty when loaded per-frame
UTimer _captureTimer; UTimer _captureTimer;
double _captureDelay; double _captureDelay;
@@ -0,0 +1,105 @@
/*
Copyright (c) 2010-2025, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "rtabmap/core/CameraModel.h"
#include "rtabmap/core/Camera.h"
#include "rtabmap/core/Version.h"
#ifdef RTABMAP_ORBBEC_SDK
namespace ob
{
class Pipeline;
class Align;
}
#endif
namespace rtabmap
{
class RTABMAP_CORE_EXPORT CameraOrbbecSDK :
public Camera
{
public:
static bool available();
public:
// deviceId can be either an index (e.g., "0"), an UID (e.g, "2-1-2" or "gmsl-1") or a serial ("AAA6454S")
CameraOrbbecSDK(
std::string deviceId = "",
unsigned int colorWidth = 800,
unsigned int colorHeight = 600,
unsigned int depthWidth = 800,
unsigned int depthHeight = 600,
float imageRate = 0.0f,
const Transform & localTransform = Transform::getIdentity());
virtual ~CameraOrbbecSDK();
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
virtual bool isCalibrated() const;
virtual std::string getSerial() const;
void close();
// Should be set before initializing
void enableColorRectification(bool enabled);
void enableImu(bool enabled);
void enableDepthMM(bool enabled);
protected:
virtual SensorData captureImage(SensorCaptureInfo * info = 0);
private:
#ifdef RTABMAP_ORBBEC_SDK
std::string deviceId_;
unsigned int colorWidth_;
unsigned int colorHeight_;
unsigned int depthWidth_;
unsigned int depthHeight_;
ob::Pipeline * pipeline_;
ob::Pipeline * imuPipeline_;
ob::Align * alignFilter_;
CameraModel model_;
Transform imuLocalTransform_;
bool imuLocalTransformInitialized_;
uint64_t lastAccStamp_;
uint64_t lastImageStamp_;
bool globalTimestampAvailable_;
bool rectifyColor_;
bool convertDepthToMM_;
bool imuPublished_;
std::map<double, cv::Vec6f> imuBuffer_;
UMutex imuMutex_;
#endif
};
} // namespace rtabmap
@@ -146,6 +146,7 @@ private:
Transform dualExtrinsics_; Transform dualExtrinsics_;
std::string jsonConfig_; std::string jsonConfig_;
bool closing_; bool closing_;
bool playback_;
static Transform realsense2PoseRotation_; static Transform realsense2PoseRotation_;
static Transform realsense2PoseRotationInv_; static Transform realsense2PoseRotationInv_;
@@ -58,6 +58,24 @@ public:
void setRightGrayScale(bool enabled = true) {rightGrayScale_ = enabled;} void setRightGrayScale(bool enabled = true) {rightGrayScale_ = enabled;}
// Enable multi-camera stereo mode. Each left/right image in the folders is
// expected to be the horizontal concatenation of N sub-camera images of a
// stereo rig, all sharing the same base name (timestamp or node id), e.g.
// "1779318290.502227.jpg". Two calibration files per sub-camera must exist in
// the calibrationFolder passed to init(), named "<prefix>_<index>_left.yaml"
// and "<prefix>_<index>_right.yaml" with index starting at 0. The number of
// cameras is auto-detected. Sub-images are split using a uniform width
// (stackedWidth / N).
// If setConfigForEachFrame() is enabled, one calibration set is loaded per frame
// using each image's base name as prefix. Otherwise a single calibration set is
// loaded and reused for all frames, using the cameraName passed to init() as
// prefix (it may differ from any image name), falling back to the first image's
// base name when cameraName is empty.
// Note that it is not recommended to use setConfigForEachFrame() if images have
// to be rectified, a rectification matrix would need to be re-initilaized for each
// frame.
void setMultiCameraCalibration(bool enabled) {CameraImages::setMultiCameraCalibration(enabled);}
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = ""); virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
virtual bool isCalibrated() const; virtual bool isCalibrated() const;
virtual std::string getSerial() const; virtual std::string getSerial() const;
@@ -68,10 +86,17 @@ public:
protected: protected:
virtual SensorData captureImage(SensorCaptureInfo * info = 0); virtual SensorData captureImage(SensorCaptureInfo * info = 0);
private:
// Load the sub-camera stereo models of a frame from calibration files named
// "<baseName>_<index>_{left,right}.yaml" (index 0.._multiCameraCount-1) in
// _calibrationFolder. Returns an empty vector (and logs an error) on failure.
std::vector<StereoCameraModel> loadStereoCameraModels(const std::string & baseName, bool rectify) const;
private: private:
CameraImages * camera2_; CameraImages * camera2_;
StereoCameraModel stereoModel_; StereoCameraModel stereoModel_;
bool rightGrayScale_; bool rightGrayScale_;
std::vector<StereoCameraModel> multiStereoModels_; // sub-camera stereo models shared by all frames (multi-camera mode); empty when loaded per-frame
}; };
@@ -49,8 +49,8 @@ public:
public: public:
CameraStereoZed( CameraStereoZed(
int deviceId, int deviceId,
int resolution = -1, // -1 = AUTO, 0=HD4K 1=HD2K 2=HD1080 3=HD1200 4=HD720 5=SVGA 6=VGA int resolution = -1, // -1 = AUTO, 0=HD4K 1=QHDPLUS 2=HD2K 3=HD1536 4=HD1080 5=HD1200 6=HD720 7=SVGA 8=VGA 9=XVGA 10=TXVGA
int quality = 1, // 0=NONE, 1=PERFORMANCE, 2=QUALITY int quality = 1, // 0=NONE, 1=PERFORMANCE, 2=QUALITY, 3=ULTRA, 4=NEURAL_LIGHT, 5=NEURAL, 6=NEURAL_ULTRA
int sensingMode = 0,// 0=STANDARD, 1=FILL int sensingMode = 0,// 0=STANDARD, 1=FILL
int confidenceThr = 100, int confidenceThr = 100,
bool computeOdometry = false, bool computeOdometry = false,
@@ -61,7 +61,7 @@ public:
int texturenessConfidenceThr = 90); // introduced with ZED SDK 3 int texturenessConfidenceThr = 90); // introduced with ZED SDK 3
CameraStereoZed( CameraStereoZed(
const std::string & svoFilePath, const std::string & svoFilePath,
int quality = 1, // 0=NONE, 1=PERFORMANCE, 2=QUALITY, 3=NEURAL int quality = 1, // 0=NONE, 1=PERFORMANCE, 2=QUALITY, 3=ULTRA, 4=NEURAL_LIGHT, 5=NEURAL, 6=NEURAL_ULTRA
int sensingMode = 0,// 0=STANDARD, 1=FILL int sensingMode = 0,// 0=STANDARD, 1=FILL
int confidenceThr = 100, int confidenceThr = 100,
bool computeOdometry = false, bool computeOdometry = false,
@@ -81,6 +81,15 @@ public:
void postInterIMUPublic(const IMU & imu, double stamp); void postInterIMUPublic(const IMU & imu, double stamp);
void setRightGrayScale(bool enabled = true); void setRightGrayScale(bool enabled = true);
/**
* If the given ZED depth mode (quality: same encoding as the constructor) is a NEURAL mode
* whose AI model isn't yet downloaded/optimized for the GPU, returns a human-readable warning
* that the first start will be slower (the ZED SDK downloads/optimizes the model during
* init()). Returns an empty string when the model is ready, the mode isn't neural, or the
* SDK/build doesn't support the check.
*/
static std::string getNeuralModelWarning(int quality);
protected: protected:
virtual SensorData captureImage(SensorCaptureInfo * info = 0); virtual SensorData captureImage(SensorCaptureInfo * info = 0);
@@ -57,7 +57,6 @@ protected:
private: private:
cv::Mat map_; cv::Mat map_;
cv::Mat mapInfo_; cv::Mat mapInfo_;
std::map<int, std::pair<int, int> > cellCount_; //<node Id, cells>
float minMapSize_; float minMapSize_;
bool erode_; bool erode_;
+84 -15
View File
@@ -41,11 +41,11 @@ LaserScan laserScanFromPointCloud(const PointCloud2T & cloud, bool filterNaNs, b
return LaserScan(); return LaserScan();
} }
//determine the output type //determine the output type
int fieldStates[8] = {0}; // x,y,z,normal_x,normal_y,normal_z,rgb,intensity int fieldStates[10] = {0}; // x,y,z,normal_x,normal_y,normal_z,rgb,intensity,time,ring
#if PCL_VERSION_COMPARE(>=, 1, 10, 0) #if PCL_VERSION_COMPARE(>=, 1, 10, 0)
std::uint32_t fieldOffsets[8] = {0}; std::uint32_t fieldOffsets[10] = {0};
#else #else
pcl::uint32_t fieldOffsets[8] = {0}; pcl::uint32_t fieldOffsets[10] = {0};
#endif #endif
for(unsigned int i=0; i<cloud.fields.size(); ++i) for(unsigned int i=0; i<cloud.fields.size(); ++i)
{ {
@@ -102,6 +102,42 @@ LaserScan laserScanFromPointCloud(const PointCloud2T & cloud, bool filterNaNs, b
fieldStates[7] = 1; fieldStates[7] = 1;
fieldOffsets[7] = cloud.fields[i].offset; fieldOffsets[7] = cloud.fields[i].offset;
} }
else if(cloud.fields[i].name.compare("time") == 0)
{
if(cloud.fields[i].datatype != pcl::PCLPointField::FLOAT32)
{
static bool warningShown = false;
if(!warningShown)
{
UWARN("The input scan cloud has an \"time\" field "
"but the datatype (%d) is not supported. Time will be ignored. "
"This message is only shown once.", cloud.fields[i].datatype);
warningShown = true;
}
continue;
}
fieldStates[8] = 1;
fieldOffsets[8] = cloud.fields[i].offset;
}
else if(cloud.fields[i].name.compare("ring") == 0)
{
if(cloud.fields[i].datatype != pcl::PCLPointField::UINT16)
{
static bool warningShown = false;
if(!warningShown)
{
UWARN("The input scan cloud has an \"ring\" field "
"but the datatype (%d) is not supported. Ring will be ignored. "
"This message is only shown once.", cloud.fields[i].datatype);
warningShown = true;
}
continue;
}
fieldStates[9] = 1;
fieldOffsets[9] = cloud.fields[i].offset;
}
else else
{ {
UDEBUG("Ignoring \"%s\" field", cloud.fields[i].name.c_str()); UDEBUG("Ignoring \"%s\" field", cloud.fields[i].name.c_str());
@@ -117,6 +153,8 @@ LaserScan laserScanFromPointCloud(const PointCloud2T & cloud, bool filterNaNs, b
bool hasNormals = fieldStates[3] || fieldStates[4] || fieldStates[5]; bool hasNormals = fieldStates[3] || fieldStates[4] || fieldStates[5];
bool hasIntensity = fieldStates[7]; bool hasIntensity = fieldStates[7];
bool hasRGB = !hasIntensity&&fieldStates[6]; bool hasRGB = !hasIntensity&&fieldStates[6];
bool hasTime = hasIntensity&&fieldStates[8];
bool hasRing = hasIntensity&&fieldStates[9];
bool is3D = fieldStates[0] && fieldStates[1] && fieldStates[2]; bool is3D = fieldStates[0] && fieldStates[1] && fieldStates[2];
LaserScan::Format format; LaserScan::Format format;
@@ -140,7 +178,18 @@ LaserScan laserScanFromPointCloud(const PointCloud2T & cloud, bool filterNaNs, b
} }
else if(!hasNormals && hasIntensity) else if(!hasNormals && hasIntensity)
{ {
format = LaserScan::kXYZI; if(hasTime && hasRing)
{
format = LaserScan::kXYZIRT;
}
else if(hasTime)
{
format = LaserScan::kXYZIT;
}
else
{
format = LaserScan::kXYZI;
}
} }
else if(!hasNormals && hasRGB) else if(!hasNormals && hasRGB)
{ {
@@ -183,6 +232,7 @@ LaserScan laserScanFromPointCloud(const PointCloud2T & cloud, bool filterNaNs, b
transformRot = transform.rotation(); transformRot = transform.rotation();
} }
int oi=0; int oi=0;
UASSERT(cloud.height == 1 || cloud.row_step != 0);
for (uint32_t row = 0; row < (uint32_t)cloud.height; ++row) for (uint32_t row = 0; row < (uint32_t)cloud.height; ++row)
{ {
const uint8_t* row_data = &cloud.data[row * cloud.row_step]; const uint8_t* row_data = &cloud.data[row * cloud.row_step];
@@ -242,26 +292,45 @@ LaserScan laserScanFromPointCloud(const PointCloud2T & cloud, bool filterNaNs, b
{ {
ptr[0] = *(float*)(msg_data + fieldOffsets[0]); ptr[0] = *(float*)(msg_data + fieldOffsets[0]);
ptr[1] = *(float*)(msg_data + fieldOffsets[1]); ptr[1] = *(float*)(msg_data + fieldOffsets[1]);
ptr[2] = *(float*)(msg_data + fieldOffsets[3]); if(format == LaserScan::kXYZIT)
ptr[3] = *(float*)(msg_data + fieldOffsets[4]); {
ptr[4] = *(float*)(msg_data + fieldOffsets[5]); ptr[2] = *(float*)(msg_data + fieldOffsets[2]);
ptr[3] = *(float*)(msg_data + fieldOffsets[7]);
ptr[4] = *(float*)(msg_data + fieldOffsets[8]);
}
else // kXYNormal
{
ptr[2] = *(float*)(msg_data + fieldOffsets[3]);
ptr[3] = *(float*)(msg_data + fieldOffsets[4]);
ptr[4] = *(float*)(msg_data + fieldOffsets[5]);
}
valid = uIsFinite(ptr[0]) && uIsFinite(ptr[1]) && uIsFinite(ptr[2]) && uIsFinite(ptr[3]) && uIsFinite(ptr[4]); valid = uIsFinite(ptr[0]) && uIsFinite(ptr[1]) && uIsFinite(ptr[2]) && uIsFinite(ptr[3]) && uIsFinite(ptr[4]);
} }
else if(laserScan.channels() == 6) else if(laserScan.channels() == 6)
{ {
ptr[0] = *(float*)(msg_data + fieldOffsets[0]); ptr[0] = *(float*)(msg_data + fieldOffsets[0]);
ptr[1] = *(float*)(msg_data + fieldOffsets[1]); ptr[1] = *(float*)(msg_data + fieldOffsets[1]);
if(format == LaserScan::kXYINormal) if(format == LaserScan::kXYZIRT)
{
ptr[2] = *(float*)(msg_data + fieldOffsets[7]);
}
else // XYZNormal
{ {
ptr[2] = *(float*)(msg_data + fieldOffsets[2]); ptr[2] = *(float*)(msg_data + fieldOffsets[2]);
ptr[3] = *(float*)(msg_data + fieldOffsets[7]);
ptr[4] = float(*(unsigned short*)(msg_data + fieldOffsets[9])); // Convert 16U to float
ptr[5] = *(float*)(msg_data + fieldOffsets[8]);
}
else // with normal
{
if(format == LaserScan::kXYINormal)
{
ptr[2] = *(float*)(msg_data + fieldOffsets[7]);
}
else // XYZNormal
{
ptr[2] = *(float*)(msg_data + fieldOffsets[2]);
}
ptr[3] = *(float*)(msg_data + fieldOffsets[3]);
ptr[4] = *(float*)(msg_data + fieldOffsets[4]);
ptr[5] = *(float*)(msg_data + fieldOffsets[5]);
} }
ptr[3] = *(float*)(msg_data + fieldOffsets[3]);
ptr[4] = *(float*)(msg_data + fieldOffsets[4]);
ptr[5] = *(float*)(msg_data + fieldOffsets[5]);
valid = uIsFinite(ptr[0]) && uIsFinite(ptr[1]) && uIsFinite(ptr[2]) && uIsFinite(ptr[3]) && uIsFinite(ptr[4]) && uIsFinite(ptr[5]); valid = uIsFinite(ptr[0]) && uIsFinite(ptr[1]) && uIsFinite(ptr[2]) && uIsFinite(ptr[3]) && uIsFinite(ptr[4]) && uIsFinite(ptr[5]);
} }
else if(laserScan.channels() == 7) else if(laserScan.channels() == 7)
@@ -29,10 +29,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Should be first on windows to avoid "WinSock.h has already been included" error // Should be first on windows to avoid "WinSock.h has already been included" error
#include <pcl/io/vlp_grabber.h> #include <pcl/io/vlp_grabber.h>
#include <boost/version.hpp> #include <boost/version.hpp>
#include <boost/asio.hpp>
#include <rtabmap/core/Lidar.h> #include <rtabmap/core/Lidar.h>
#include <rtabmap/utilite/USemaphore.h> #include <rtabmap/utilite/USemaphore.h>
#include <thread>
#include <atomic>
// On Apple, closing pcl::HDLGrabber's UDP socket while its read thread is blocked
// in receive_from returns EBADF, which pcl::HDLGrabber::readPacketsFromSocket()
// rethrows uncaught in its own thread, aborting the process on shutdown. There we
// run our own single-threaded UDP receive loop and own the socket lifecycle.
// Other platforms use the base pcl::VLPGrabber path (which also avoids needing
// boost::asio::io_context, absent from the Boost 1.65 on e.g. Ubuntu Bionic).
// Comment this out to force the base path everywhere (e.g. A/B testing on macOS).
#if defined(__APPLE__)
#define RTABMAP_VLP16_USE_CUSTOM_SOCKET
#endif
namespace rtabmap { namespace rtabmap {
struct PointXYZIT { struct PointXYZIT {
@@ -68,9 +83,28 @@ public:
void setOrganized(bool enable); void setOrganized(bool enable);
#ifdef RTABMAP_VLP16_USE_CUSTOM_SOCKET
// Overridden only on Apple: in network mode we run our own UDP receive loop
// instead of pcl::HDLGrabber's, because on macOS/BSD closing the grabber's
// socket while its read thread is blocked in receive_from returns EBADF, a
// code that pcl::HDLGrabber::readPacketsFromSocket() rethrows uncaught (in
// its own thread), aborting the process on shutdown. Owning the socket lets
// us tear it down with the non-throwing receive_from overload. Like
// pcl::HDLGrabber, we bind to the given LOCAL interface address (to scope
// reception on a multi-homed host) and fall back to all interfaces (0.0.0.0)
// when it is unspecified or not a local address. In PCAP mode we delegate to
// the base grabber. On other platforms we inherit pcl::VLPGrabber directly.
virtual void start() override;
virtual void stop() override;
virtual bool isRunning() const override;
#endif
private: private:
void buildTimings(bool dualMode); void buildTimings(bool dualMode);
virtual void toPointClouds (HDLDataPacket *dataPacket) override; virtual void toPointClouds (HDLDataPacket *dataPacket) override;
#ifdef RTABMAP_VLP16_USE_CUSTOM_SOCKET
void readPackets();
#endif
protected: protected:
virtual SensorData captureData(SensorCaptureInfo * info = 0) override; virtual SensorData captureData(SensorCaptureInfo * info = 0) override;
@@ -88,6 +122,18 @@ private:
std::vector<std::vector<PointXYZIT> > accumulatedScans_; std::vector<std::vector<PointXYZIT> > accumulatedScans_;
USemaphore scanReady_; USemaphore scanReady_;
UMutex lastScanMutex_; UMutex lastScanMutex_;
// Own UDP receive path (network mode only).
bool networkMode_;
boost::asio::ip::address ipAddress_;
std::uint16_t port_;
bool receivedScan_; // set once the first scan is received
#ifdef RTABMAP_VLP16_USE_CUSTOM_SOCKET
boost::asio::io_context ioContext_;
boost::asio::ip::udp::socket * socket_;
std::thread * readThread_;
std::atomic<bool> terminate_;
#endif
}; };
} /* namespace rtabmap */ } /* namespace rtabmap */
@@ -0,0 +1,101 @@
/*
Copyright (c) 2025 Felix Toft
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ODOMETRYCUVSLAM_H_
#define ODOMETRYCUVSLAM_H_
#include <rtabmap/core/Odometry.h>
#include <memory>
#include <deque>
#include <array>
#ifdef RTABMAP_CUVSLAM
#include <cuvslam.h>
#include <ground_constraint.h>
#include <cuda_runtime.h>
#endif
namespace rtabmap {
class RTABMAP_CORE_EXPORT OdometryCuVSLAM : public Odometry
{
public:
OdometryCuVSLAM(const rtabmap::ParametersMap & parameters = rtabmap::ParametersMap());
virtual ~OdometryCuVSLAM();
virtual void reset(const Transform & initialPose = Transform::getIdentity());
virtual Odometry::Type getType() {return Odometry::kTypeCuVSLAM;}
private:
virtual Transform computeTransform(SensorData & image, const Transform & guess = Transform(), OdometryInfo * info = 0);
virtual void cleanupCuVSLAMResources();
private:
#ifdef RTABMAP_CUVSLAM
CUVSLAM_TrackerHandle cuvslam_handle_;
CUVSLAM_GroundConstraintHandle ground_constraint_handle_;
std::vector<CUVSLAM_Camera> cuvslam_cameras_;
std::vector<std::array<float, 12>> intrinsics_;
// State tracking
bool initialized_;
bool lost_;
bool tracking_;
bool planar_constraints_;
int multicam_mode_;
Transform previous_pose_;
double last_timestamp_;
// Configuration Thresholds
double velocity_ratio_threshold_high_ = 1.5; // The maximum velocity ratio of guess / estimated velocity needed to detect lost state.
double velocity_ratio_threshold_low_ = 0.5; // The minimum velocity ratio of guess / estimated velocity needed to detect lost state.
double velocity_difference_threshold_ = 0.1; // The maximum velocity difference between the guess and the estimated velocity needed to detect lost state.
double zero_estimated_velocity_threshold_ = 0.00001; // The minimum cuVSLAM estimated velocity needed to detect lost state.
double min_landmarks_threshold_ = 30; // The minimum number of landmarks needed to start tracking after an initialization.
// Forward cuVLSAM covariance directly to RTAB-Map.
// When true this disables covariance based lost detection.
bool use_raw_covariance_ = false;
//visualization
std::vector<CUVSLAM_Observation> observations_;
std::vector<CUVSLAM_Landmark> landmarks_;
// GPU memory management
std::vector<uint8_t *> gpu_left_image_data_; // pointers to all gpu images
std::vector<uint8_t *> gpu_right_image_data_;
std::vector<size_t> gpu_left_image_sizes_; // size of one image
std::vector<size_t> gpu_right_image_sizes_;
cudaStream_t cuda_stream_;
#endif
};
}
#endif /* ODOMETRYCUVSLAM_H_ */
@@ -0,0 +1,82 @@
/*
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ODOMETRYLIOSAM_H_
#define ODOMETRYLIOSAM_H_
#include <rtabmap/core/Odometry.h>
#ifdef RTABMAP_LIOSAM
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <vector>
namespace lio_sam { class LioSamCore; }
#endif
namespace rtabmap {
class RTABMAP_CORE_EXPORT OdometryLIOSAM : public Odometry
{
public:
OdometryLIOSAM(const rtabmap::ParametersMap & parameters = rtabmap::ParametersMap());
virtual ~OdometryLIOSAM();
virtual void reset(const Transform & initialPose = Transform::getIdentity());
virtual Odometry::Type getType() {return Odometry::kTypeLIOSAM;}
virtual bool canProcessAsyncIMU() const {return true;}
private:
virtual Transform computeTransform(SensorData & data, const Transform & guess = Transform(), OdometryInfo * info = 0);
#ifdef RTABMAP_LIOSAM
bool init(const Transform & imuLocalTransform, const Transform & lidarLocalTransform);
#endif
private:
#ifdef RTABMAP_LIOSAM
lio_sam::LioSamCore * lioSam_;
Transform lastPose_;
bool lost_;
float linVar_;
float angVar_;
ParametersMap parameters_;
Transform imuLocalTransform_; // base_link -> imu_link (cached for deferred init)
// Buffered IMU samples received before initialization
struct ImuSample {
double stamp;
Eigen::Vector3d acc;
Eigen::Vector3d gyro;
Eigen::Quaterniond orientation;
};
std::vector<ImuSample> imuBuffer_;
#endif
};
}
#endif /* ODOMETRYLIOSAM_H_ */
@@ -25,39 +25,7 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef ODOMETRYVINS_H_ #pragma once
#define ODOMETRYVINS_H_ #pragma message("Warning: OdometryVINS.h is deprecated. Please use OdometryVINSFusion.h instead.")
#include <rtabmap/core/Odometry.h> #include "rtabmap/core/odometry/OdometryVINSFusion.h"
namespace rtabmap {
class VinsEstimator;
class RTABMAP_CORE_EXPORT OdometryVINS : public Odometry
{
public:
OdometryVINS(const rtabmap::ParametersMap & parameters = rtabmap::ParametersMap());
virtual ~OdometryVINS();
virtual void reset(const Transform & initialPose = Transform::getIdentity());
virtual Odometry::Type getType() {return Odometry::kTypeVINS;}
virtual bool canProcessRawImages() const {return true;}
virtual bool canProcessAsyncIMU() const {return true;}
private:
virtual Transform computeTransform(SensorData & image, const Transform & guess = Transform(), OdometryInfo * info = 0);
private:
#ifdef RTABMAP_VINS
VinsEstimator * vinsEstimator_;
bool initGravity_;
Transform previousPose_;
Transform previousLocalTransform_;
IMU lastImu_;
#endif
};
}
#endif /* ODOMETRYVINS_H_ */
@@ -0,0 +1,64 @@
/*
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ODOMETRYVINSFUSION_H_
#define ODOMETRYVINSFUSION_H_
#include <rtabmap/core/Odometry.h>
namespace rtabmap {
class VinsFusionEstimator;
class RTABMAP_CORE_EXPORT OdometryVINSFusion : public Odometry
{
public:
OdometryVINSFusion(const rtabmap::ParametersMap & parameters = rtabmap::ParametersMap());
virtual ~OdometryVINSFusion();
virtual void reset(const Transform & initialPose = Transform::getIdentity());
virtual Odometry::Type getType() {return Odometry::kTypeVINSFusion;}
virtual bool canProcessRawImages() const {return true;}
virtual bool canProcessAsyncIMU() const {return true;}
private:
virtual Transform computeTransform(SensorData & image, const Transform & guess = Transform(), OdometryInfo * info = 0);
private:
#ifdef RTABMAP_VINS_FUSION
VinsFusionEstimator * vinsEstimator_;
bool initGravity_;
Transform previousPose_;
Transform previousLocalTransform_;
IMU lastImu_;
double lastImuStamp_;
#endif
};
}
#endif /* ODOMETRYVINSFUSION_H_ */
@@ -41,6 +41,12 @@ public:
static bool isCSparseAvailable(); static bool isCSparseAvailable();
static bool isCholmodAvailable(); static bool isCholmodAvailable();
public:
static bool loadGraph(
const std::string & fileName,
std::map<int, Transform> & poses,
std::multimap<int, Link> & edgeConstraints);
public: public:
OptimizerG2O(const ParametersMap & parameters = ParametersMap()); OptimizerG2O(const ParametersMap & parameters = ParametersMap());
virtual ~OptimizerG2O() {} virtual ~OptimizerG2O() {}
@@ -77,6 +77,7 @@ private:
std::vector<ConstraintToFactor> lastAddedConstraints_; std::vector<ConstraintToFactor> lastAddedConstraints_;
int lastSwitchId_; int lastSwitchId_;
std::set<int> addedPoses_; std::set<int> addedPoses_;
std::map<int, bool> isLandmarkWithRotation_; // persists across iSAM2 incremental calls
std::pair<int, std::uint64_t> lastRootFactorIndex_; std::pair<int, std::uint64_t> lastRootFactorIndex_;
}; };
+26
View File
@@ -39,12 +39,26 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/core/Parameters.h> #include <rtabmap/core/Parameters.h>
#include <opencv2/core/core.hpp> #include <opencv2/core/core.hpp>
#include <rtabmap/core/ProgressState.h> #include <rtabmap/core/ProgressState.h>
#include <cstdint>
#include <map> #include <map>
#include <list> #include <list>
namespace rtabmap namespace rtabmap
{ {
// Point type carrying xyz + intensity + ring (laser line index) + time
// (per-point acquisition offset, seconds from the scan start). Matches the
// layout expected by LIO-SAM's Velodyne feature extractor so it can be fed
// directly via util3d::laserScanFromPointCloud().
struct EIGEN_ALIGN16 PointXYZIRT
{
PCL_ADD_POINT4D;
float intensity;
std::uint16_t ring;
float time;
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
namespace util3d namespace util3d
{ {
@@ -297,6 +311,9 @@ LaserScan RTABMAP_CORE_EXPORT laserScanFromPointCloud(const pcl::PointCloud<pcl:
// return CV_32FC4 (x,y,z,I) // return CV_32FC4 (x,y,z,I)
LaserScan RTABMAP_CORE_EXPORT laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZI> & cloud, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_CORE_EXPORT laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZI> & cloud, const Transform & transform = Transform(), bool filterNaNs = true);
LaserScan RTABMAP_CORE_EXPORT laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZI> & cloud, const pcl::IndicesPtr & indices, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_CORE_EXPORT laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZI> & cloud, const pcl::IndicesPtr & indices, const Transform & transform = Transform(), bool filterNaNs = true);
// return CV_32FC6 (x,y,z,I,ring,time)
LaserScan RTABMAP_CORE_EXPORT laserScanFromPointCloud(const pcl::PointCloud<rtabmap::PointXYZIRT> & cloud, const Transform & transform = Transform(), bool filterNaNs = true);
LaserScan RTABMAP_CORE_EXPORT laserScanFromPointCloud(const pcl::PointCloud<rtabmap::PointXYZIRT> & cloud, const pcl::IndicesPtr & indices, const Transform & transform = Transform(), bool filterNaNs = true);
// return CV_32FC7 (x,y,z,rgb,normal_x,normal_y,normal_z) // return CV_32FC7 (x,y,z,rgb,normal_x,normal_y,normal_z)
LaserScan RTABMAP_CORE_EXPORT laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGB> & cloud, const pcl::PointCloud<pcl::Normal> & normals, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_CORE_EXPORT laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGB> & cloud, const pcl::PointCloud<pcl::Normal> & normals, const Transform & transform = Transform(), bool filterNaNs = true);
LaserScan RTABMAP_CORE_EXPORT laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGBNormal> & cloud, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_CORE_EXPORT laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGBNormal> & cloud, const Transform & transform = Transform(), bool filterNaNs = true);
@@ -512,6 +529,15 @@ LaserScan RTABMAP_CORE_EXPORT deskew(
} // namespace util3d } // namespace util3d
} // namespace rtabmap } // namespace rtabmap
POINT_CLOUD_REGISTER_POINT_STRUCT(rtabmap::PointXYZIRT,
(float, x, x)
(float, y, y)
(float, z, z)
(float, intensity, intensity)
(std::uint16_t, ring, ring)
(float, time, time)
)
#include "rtabmap/core/impl/util3d.hpp" #include "rtabmap/core/impl/util3d.hpp"
#endif /* UTIL3D_H_ */ #endif /* UTIL3D_H_ */
@@ -80,6 +80,7 @@ std::map<int, cv::Point3f> RTABMAP_CORE_EXPORT generateWords3DMono(
Transform & cameraTransform, Transform & cameraTransform,
float ransacReprojThreshold = 3.0f, float ransacReprojThreshold = 3.0f,
float ransacConfidence = 0.99f, float ransacConfidence = 0.99f,
int varianceMedianRatio = 4,
const std::map<int, cv::Point3f> & refGuess3D = std::map<int, cv::Point3f>(), const std::map<int, cv::Point3f> & refGuess3D = std::map<int, cv::Point3f>(),
double * variance = 0, double * variance = 0,
std::vector<int> * matchesOut = 0); std::vector<int> * matchesOut = 0);
+113 -41
View File
@@ -41,6 +41,7 @@ SET(SRC_FILES
camera/CameraMyntEye.cpp camera/CameraMyntEye.cpp
camera/CameraDepthAI.cpp camera/CameraDepthAI.cpp
camera/CameraSeerSense.cpp camera/CameraSeerSense.cpp
camera/CameraOrbbecSDK.cpp
EpipolarGeometry.cpp EpipolarGeometry.cpp
VisualWord.cpp VisualWord.cpp
@@ -97,10 +98,12 @@ SET(SRC_FILES
odometry/OdometryORBSLAM3.cpp odometry/OdometryORBSLAM3.cpp
odometry/OdometryLOAM.cpp odometry/OdometryLOAM.cpp
odometry/OdometryFLOAM.cpp odometry/OdometryFLOAM.cpp
odometry/OdometryLIOSAM.cpp
odometry/OdometryMSCKF.cpp odometry/OdometryMSCKF.cpp
odometry/OdometryVINS.cpp odometry/OdometryVINSFusion.cpp
odometry/OdometryOpenVINS.cpp odometry/OdometryOpenVINS.cpp
odometry/OdometryOpen3D.cpp odometry/OdometryOpen3D.cpp
odometry/OdometryCuVSLAM.cpp
IMU.cpp IMU.cpp
IMUThread.cpp IMUThread.cpp
@@ -163,10 +166,6 @@ IF(MSVC)
ENDIF(MSVC) ENDIF(MSVC)
SET(INCLUDE_DIRS SET(INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../include
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}/include
${ZLIB_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS}
) )
@@ -197,6 +196,33 @@ IF(SQLite3_FOUND)
${LIBRARIES} ${LIBRARIES}
${SQLite3_LIBRARIES} ${SQLite3_LIBRARIES}
) )
# The SQLite session extension (used to track DB changes) needs a SQLite built with
# SQLITE_ENABLE_SESSION. Check if sqlite is built with it.
INCLUDE(CheckCXXSourceCompiles)
SET(CMAKE_REQUIRED_INCLUDES ${SQLite3_INCLUDE_DIRS})
SET(CMAKE_REQUIRED_LIBRARIES ${SQLite3_LIBRARIES})
SET(CMAKE_REQUIRED_DEFINITIONS -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK)
CHECK_CXX_SOURCE_COMPILES("
#include <sqlite3.h>
int main() {
sqlite3_session * s = 0;
sqlite3session_create((sqlite3*)0, \"main\", &s);
sqlite3session_attach(s, 0);
int n = 0; void * p = 0;
sqlite3session_changeset(s, &n, &p);
sqlite3changeset_invert(n, p, &n, &p);
sqlite3session_delete(s);
return 0;
}" RTABMAP_SQLITE3_SESSION_AVAILABLE)
UNSET(CMAKE_REQUIRED_INCLUDES)
UNSET(CMAKE_REQUIRED_LIBRARIES)
UNSET(CMAKE_REQUIRED_DEFINITIONS)
IF(RTABMAP_SQLITE3_SESSION_AVAILABLE)
SET(SQLITE3_SESSION_DEFINITIONS SQLITE_ENABLE_SESSION SQLITE_ENABLE_PREUPDATE_HOOK RTABMAP_WITH_SQLITE3_SESSION)
MESSAGE(STATUS " With SQLite3 session ext = YES (system SQLite3 ${SQLite3_VERSION})")
ELSE()
MESSAGE(STATUS " With SQLite3 session ext = NO (system SQLite3 ${SQLite3_VERSION} has no session extension)")
ENDIF()
ELSE() ELSE()
SET(SRC_FILES SET(SRC_FILES
${SRC_FILES} ${SRC_FILES}
@@ -206,6 +232,17 @@ ELSE()
${CMAKE_CURRENT_SOURCE_DIR}/sqlite3 ${CMAKE_CURRENT_SOURCE_DIR}/sqlite3
${INCLUDE_DIRS} ${INCLUDE_DIRS}
) )
FILE(READ ${CMAKE_CURRENT_SOURCE_DIR}/sqlite3/sqlite3.h RTABMAP_BUNDLED_SQLITE3_HEADER)
IF(RTABMAP_BUNDLED_SQLITE3_HEADER MATCHES "sqlite3session_create")
SET(SQLITE3_SESSION_DEFINITIONS SQLITE_ENABLE_SESSION SQLITE_ENABLE_PREUPDATE_HOOK RTABMAP_WITH_SQLITE3_SESSION)
MESSAGE(STATUS " With SQLite3 session ext = YES (bundled SQLite3)")
ELSE()
MESSAGE(FATAL_ERROR "The bundled SQLite amalgamation (corelib/src/sqlite3/sqlite3.h) does not contain "
"the session extension (sqlite3session_create not found). It must be a session-enabled "
"amalgamation, as the standard sqlite.org amalgamation does NOT include the session extension "
"by default. Please vendor a session-enabled SQLite amalgamation.")
ENDIF()
UNSET(RTABMAP_BUNDLED_SQLITE3_HEADER)
ENDIF() ENDIF()
IF(TORCH_FOUND) IF(TORCH_FOUND)
@@ -217,11 +254,21 @@ IF(TORCH_FOUND)
${SRC_FILES} ${SRC_FILES}
superpoint_torch/SuperPoint.cc superpoint_torch/SuperPoint.cc
) )
SET(INCLUDE_DIRS SET(INCLUDE_DIRS
${TORCH_INCLUDE_DIRS} ${TORCH_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}/superpoint_torch ${CMAKE_CURRENT_SOURCE_DIR}/superpoint_torch
${INCLUDE_DIRS} ${INCLUDE_DIRS}
) )
IF(WITH_PYTHON AND Python3_FOUND)
SET(SRC_FILES
${SRC_FILES}
superpoint_rpautrat/SuperpointRpautrat.cpp
)
SET(INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/superpoint_rpautrat
${INCLUDE_DIRS}
)
ENDIF(WITH_PYTHON AND Python3_FOUND)
ENDIF(TORCH_FOUND) ENDIF(TORCH_FOUND)
IF(WITH_PYTHON AND Python3_FOUND) IF(WITH_PYTHON AND Python3_FOUND)
@@ -383,7 +430,6 @@ IF(depthai_FOUND)
SET(PUBLIC_LIBRARIES SET(PUBLIC_LIBRARIES
${PUBLIC_LIBRARIES} ${PUBLIC_LIBRARIES}
depthai::core depthai::core
depthai::opencv
) )
ENDIF(depthai_FOUND) ENDIF(depthai_FOUND)
@@ -394,6 +440,13 @@ IF(xvsdk_FOUND)
) )
ENDIF(xvsdk_FOUND) ENDIF(xvsdk_FOUND)
IF(OrbbecSDK_FOUND)
SET(LIBRARIES
${LIBRARIES}
ob::OrbbecSDK
)
ENDIF(OrbbecSDK_FOUND)
IF(TARGET OpenMP::OpenMP_CXX) IF(TARGET OpenMP::OpenMP_CXX)
SET(LIBRARIES SET(LIBRARIES
${LIBRARIES} ${LIBRARIES}
@@ -517,6 +570,13 @@ IF(FastCV_FOUND)
) )
ENDIF(FastCV_FOUND) ENDIF(FastCV_FOUND)
IF(apriltag_FOUND)
SET(LIBRARIES
apriltag::apriltag
${LIBRARIES}
)
ENDIF(apriltag_FOUND)
IF(opengv_FOUND) IF(opengv_FOUND)
SET(LIBRARIES SET(LIBRARIES
${LIBRARIES} ${LIBRARIES}
@@ -589,6 +649,18 @@ IF(floam_FOUND)
) )
ENDIF(floam_FOUND) ENDIF(floam_FOUND)
IF(lio_sam_FOUND)
SET(INCLUDE_DIRS
${INCLUDE_DIRS}
${lio_sam_INCLUDE_DIRS}
)
link_directories(${lio_sam_LIBRARY_DIRS})
SET(LIBRARIES
${LIBRARIES}
lio_sam_core
)
ENDIF(lio_sam_FOUND)
IF(ZED_FOUND) IF(ZED_FOUND)
SET(INCLUDE_DIRS SET(INCLUDE_DIRS
${INCLUDE_DIRS} ${INCLUDE_DIRS}
@@ -746,16 +818,16 @@ IF(vins_FOUND)
) )
ENDIF(vins_FOUND) ENDIF(vins_FOUND)
IF(ov_msckf_FOUND) IF(OpenVINS_FOUND)
SET(INCLUDE_DIRS SET(INCLUDE_DIRS
${ov_msckf_INCLUDE_DIRS} ${OpenVINS_INCLUDE_DIRS}
${INCLUDE_DIRS} ${INCLUDE_DIRS}
) )
SET(LIBRARIES SET(LIBRARIES
${ov_msckf_LIBRARIES} ${OpenVINS_LIBRARIES}
${LIBRARIES} ${LIBRARIES}
) )
ENDIF(ov_msckf_FOUND) ENDIF(OpenVINS_FOUND)
IF(ORB_SLAM_FOUND) IF(ORB_SLAM_FOUND)
SET(INCLUDE_DIRS SET(INCLUDE_DIRS
@@ -768,38 +840,18 @@ IF(ORB_SLAM_FOUND)
) )
ENDIF(ORB_SLAM_FOUND) ENDIF(ORB_SLAM_FOUND)
IF(GTSAM_FOUND) IF(CUVSLAM_FOUND)
# Make sure GTSAM is built with system Eigen, not the included one in its package SET(LIBRARIES
IF(GTSAM_INCLUDE_DIR) ${LIBRARIES}
SET(INCLUDE_DIRS cuvslam::cuvslam
${INCLUDE_DIRS}
${GTSAM_INCLUDE_DIR}
)
ELSE()
SET(INCLUDE_DIRS
${INCLUDE_DIRS}
${GTSAM_INCLUDE_DIRS}
)
ENDIF()
SET(SRC_FILES
${SRC_FILES}
optimizer/gtsam/GravityFactor.cpp
) )
IF(WIN32) ENDIF(CUVSLAM_FOUND)
# GTSAM should be built in STATIC on Windows to avoid "error C2338: THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS" when building GTSAM
add_definitions("-DGTSAM_IMPORT_STATIC") IF(GTSAM_FOUND)
ENDIF(WIN32)
SET(LIBRARIES SET(LIBRARIES
${LIBRARIES} ${LIBRARIES}
gtsam # Windows: Place static libs at the end gtsam
) )
IF(WIN32)
#explicitly add metis target on windows (after gtsam target)
SET(LIBRARIES
${LIBRARIES}
metis
)
ENDIF(WIN32)
ENDIF(GTSAM_FOUND) ENDIF(GTSAM_FOUND)
IF(WITH_MADGWICK) IF(WITH_MADGWICK)
@@ -816,6 +868,8 @@ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/resources/DatabaseSchema.sql.in ${CMA
SET(RESOURCES SET(RESOURCES
${CMAKE_CURRENT_SOURCE_DIR}/resources/DatabaseSchema.sql ${CMAKE_CURRENT_SOURCE_DIR}/resources/DatabaseSchema.sql
${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_23_0.sql
${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_22_0.sql
${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_20_0.sql ${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_20_0.sql
${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_18_3.sql ${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_18_3.sql
${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_18_0.sql ${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_18_0.sql
@@ -825,6 +879,13 @@ SET(RESOURCES
${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_16_0.sql ${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_16_0.sql
) )
IF(TORCH_FOUND AND WITH_PYTHON AND Python3_FOUND)
SET(RESOURCES
${RESOURCES}
${CMAKE_CURRENT_SOURCE_DIR}/superpoint_rpautrat/superpoint_to_torchscript.py
)
ENDIF()
foreach(arg ${RESOURCES}) foreach(arg ${RESOURCES})
get_filename_component(filename ${arg} NAME) get_filename_component(filename ${arg} NAME)
string(REPLACE "." "_" output ${filename}) string(REPLACE "." "_" output ${filename})
@@ -857,8 +918,12 @@ generate_export_header(rtabmap_core
DEPRECATED_MACRO_NAME RTABMAP_DEPRECATED) DEPRECATED_MACRO_NAME RTABMAP_DEPRECATED)
target_include_directories(rtabmap_core PUBLIC target_include_directories(rtabmap_core PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include;${CMAKE_CURRENT_BINARY_DIR}/include;${PUBLIC_INCLUDE_DIRS};${INCLUDE_DIRS}>" "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/../include;${CMAKE_CURRENT_BINARY_DIR};${CMAKE_CURRENT_BINARY_DIR}/include>"
"$<INSTALL_INTERFACE:${INSTALL_INCLUDE_DIR};${PUBLIC_INCLUDE_DIRS}>") "$<INSTALL_INTERFACE:${INSTALL_INCLUDE_DIR}>")
target_include_directories(rtabmap_core SYSTEM PUBLIC
"$<BUILD_INTERFACE:${PUBLIC_INCLUDE_DIRS};${INCLUDE_DIRS}>"
"$<INSTALL_INTERFACE:${PUBLIC_INCLUDE_DIRS}>")
TARGET_LINK_LIBRARIES(rtabmap_core TARGET_LINK_LIBRARIES(rtabmap_core
PUBLIC PUBLIC
@@ -867,6 +932,13 @@ TARGET_LINK_LIBRARIES(rtabmap_core
PRIVATE PRIVATE
${LIBRARIES}) ${LIBRARIES})
# Enable the SQLite session extension for the core sources (bundled sqlite3.c and
# DBDriverSqlite3.cpp). Kept PRIVATE so it only affects rtabmap_core's own TUs and
# never changes the public header layout for downstream consumers.
IF(SQLITE3_SESSION_DEFINITIONS)
target_compile_definitions(rtabmap_core PRIVATE ${SQLITE3_SESSION_DEFINITIONS})
ENDIF()
SET_TARGET_PROPERTIES( SET_TARGET_PROPERTIES(
rtabmap_core rtabmap_core
PROPERTIES PROPERTIES
+12 -3
View File
@@ -39,7 +39,8 @@ namespace rtabmap
Camera::Camera(float imageRate, const Transform & localTransform) : Camera::Camera(float imageRate, const Transform & localTransform) :
SensorCapture(imageRate, localTransform*CameraModel::opticalRotation()), SensorCapture(imageRate, localTransform*CameraModel::opticalRotation()),
imuFilter_(0), imuFilter_(0),
publishInterIMU_(false) publishInterIMU_(false),
imuBaseFrameConversion_(false)
{} {}
Camera::~Camera() Camera::~Camera()
@@ -52,15 +53,23 @@ bool Camera::initFromFile(const std::string & calibrationPath)
return init(UDirectory::getDir(calibrationPath), uSplit(UFile::getName(calibrationPath), '.').front()); return init(UDirectory::getDir(calibrationPath), uSplit(UFile::getName(calibrationPath), '.').front());
} }
void Camera::setInterIMUPublishing(bool enabled, IMUFilter * filter) void Camera::setInterIMUPublishing(bool enabled, IMUFilter * filter, bool baseFrameConversion)
{ {
publishInterIMU_ = enabled; publishInterIMU_ = enabled;
delete imuFilter_; delete imuFilter_;
imuFilter_ = filter; imuFilter_ = filter;
imuBaseFrameConversion_ = baseFrameConversion;
} }
void Camera::postInterIMU(const IMU & imu, double stamp) void Camera::postInterIMU(const IMU & imu_in, double stamp)
{ {
IMU imu = imu_in;
if(imuBaseFrameConversion_)
{
UASSERT(!imu.localTransform().isNull());
imu.convertToBaseFrame();
}
if(imuFilter_) if(imuFilter_)
{ {
imuFilter_->update( imuFilter_->update(
+21 -5
View File
@@ -212,7 +212,7 @@ void CameraModel::setImageSize(const cv::Size & size)
} }
} }
bool CameraModel::load(const std::string & filePath) bool CameraModel::load(const std::string & filePath, bool initRectificationMaps)
{ {
K_ = cv::Mat(); K_ = cv::Mat();
D_ = cv::Mat(); D_ = cv::Mat();
@@ -353,6 +353,22 @@ bool CameraModel::load(const std::string & filePath)
data[0], data[1], data[2], data[3], data[0], data[1], data[2], data[3],
data[4], data[5], data[6], data[7], data[4], data[5], data[6], data[7],
data[8], data[9], data[10], data[11]); data[8], data[9], data[10], data[11]);
Transform detCheck = localTransform_.clone();
localTransform_.normalizeRotation(); /// Normalize by default
float det = detCheck.toEigen3f().linear().determinant();
if(fabs(det - 1.0f) > 0.0001)
{
std::stringstream streamBefore, streamAfter;
streamBefore << detCheck << std::endl;
streamAfter << localTransform_ << std::endl;
UWARN("The camera model's local_transform from \"%s\" doesn't "
"have a normalized rotation matrix (dertminant=%f). We will normalize "
"it for convenience.\nWas:\n%sNow\n%s",
filePath.c_str(),
det,
streamBefore.str().c_str(),
streamAfter.str().c_str());
}
} }
else else
{ {
@@ -361,7 +377,7 @@ bool CameraModel::load(const std::string & filePath)
fs.release(); fs.release();
if(isValidForRectification()) if(initRectificationMaps && isValidForRectification())
{ {
initRectificationMap(); initRectificationMap();
} }
@@ -380,9 +396,9 @@ bool CameraModel::load(const std::string & filePath)
return false; return false;
} }
bool CameraModel::load(const std::string & directory, const std::string & cameraName) bool CameraModel::load(const std::string & directory, const std::string & cameraName, bool initRectificationMaps)
{ {
return load(directory+"/"+cameraName+".yaml"); return load(directory+"/"+cameraName+".yaml", initRectificationMaps);
} }
bool CameraModel::save(const std::string & directory) const bool CameraModel::save(const std::string & directory) const
@@ -554,7 +570,7 @@ unsigned int CameraModel::deserialize(const unsigned char * data, unsigned int d
int iR = 8; int iR = 8;
int iP = 9; int iP = 9;
int iL = 10; int iL = 10;
UDEBUG("Header: %d %d %d %d %d %d %d %d %d %d %d", header[0],header[1],header[2],header[3],header[4],header[5],header[6],header[7],header[8],header[9],header[10]); //UDEBUG("Header: %d %d %d %d %d %d %d %d %d %d %d", header[0],header[1],header[2],header[3],header[4],header[5],header[6],header[7],header[8],header[9],header[10]);
unsigned int requiredDataSize = sizeof(int)*headerSize + unsigned int requiredDataSize = sizeof(int)*headerSize +
sizeof(double)*(header[iK]+header[iD]+header[iR]+header[iP]) + sizeof(double)*(header[iK]+header[iD]+header[iR]+header[iP]) +
sizeof(float)*header[iL]; sizeof(float)*header[iL];
+66 -11
View File
@@ -45,7 +45,7 @@ DBDriver * DBDriver::create(const ParametersMap & parameters)
DBDriver::DBDriver(const ParametersMap & parameters) : DBDriver::DBDriver(const ParametersMap & parameters) :
_emptyTrashesTime(0), _emptyTrashesTime(0),
_timestampUpdate(true) _timestampUpdate(false)
{ {
this->parseParameters(parameters); this->parseParameters(parameters);
} }
@@ -73,7 +73,15 @@ void DBDriver::closeConnection(bool save, const std::string & outputUrl)
else else
{ {
_trashesMutex.lock(); _trashesMutex.lock();
for(auto & iter: _trashSignatures)
{
delete iter.second;
}
_trashSignatures.clear(); _trashSignatures.clear();
for(auto & iter: _trashVisualWords)
{
delete iter.second;
}
_trashVisualWords.clear(); _trashVisualWords.clear();
_trashesMutex.unlock(); _trashesMutex.unlock();
} }
@@ -83,12 +91,12 @@ void DBDriver::closeConnection(bool save, const std::string & outputUrl)
UDEBUG(""); UDEBUG("");
} }
bool DBDriver::openConnection(const std::string & url, bool overwritten) bool DBDriver::openConnection(const std::string & url, bool overwritten, bool readOnly)
{ {
UDEBUG(""); UDEBUG("");
_url = url; _url = url;
_dbSafeAccessMutex.lock(); _dbSafeAccessMutex.lock();
if(this->connectDatabaseQuery(url, overwritten)) if(this->connectDatabaseQuery(url, overwritten, readOnly))
{ {
_dbSafeAccessMutex.unlock(); _dbSafeAccessMutex.unlock();
return true; return true;
@@ -383,7 +391,7 @@ void DBDriver::asyncSave(Signature * s)
{ {
if(s) if(s)
{ {
UDEBUG("s=%d", s->id()); //UDEBUG("s=%d", s->id());
_trashesMutex.lock(); _trashesMutex.lock();
{ {
_trashSignatures.insert(std::pair<int, Signature*>(s->id(), s)); _trashSignatures.insert(std::pair<int, Signature*>(s->id(), s));
@@ -531,17 +539,17 @@ void DBDriver::updateLaserScan(int nodeId, const LaserScan & scan)
_dbSafeAccessMutex.unlock(); _dbSafeAccessMutex.unlock();
} }
void DBDriver::load(VWDictionary * dictionary, bool lastStateOnly) const void DBDriver::load(VWDictionary & dictionary, bool lastStateOnly) const
{ {
_dbSafeAccessMutex.lock(); _dbSafeAccessMutex.lock();
this->loadQuery(dictionary, lastStateOnly); this->loadQuery(dictionary, lastStateOnly);
_dbSafeAccessMutex.unlock(); _dbSafeAccessMutex.unlock();
} }
void DBDriver::loadLastNodes(std::list<Signature *> & signatures) const void DBDriver::loadLastNodes(std::list<Signature *> & signatures, bool loadWordIdsOnly) const
{ {
_dbSafeAccessMutex.lock(); _dbSafeAccessMutex.lock();
this->loadLastNodesQuery(signatures); this->loadLastNodesQuery(signatures, loadWordIdsOnly);
_dbSafeAccessMutex.unlock(); _dbSafeAccessMutex.unlock();
} }
@@ -564,7 +572,8 @@ Signature * DBDriver::loadSignature(int id, bool * loadedFromTrash)
} }
void DBDriver::loadSignatures(const std::list<int> & signIds, void DBDriver::loadSignatures(const std::list<int> & signIds,
std::list<Signature *> & signatures, std::list<Signature *> & signatures,
std::set<int> * loadedFromTrash) std::set<int> * loadedFromTrash,
bool loadWordIdsOnly)
{ {
UDEBUG(""); UDEBUG("");
// look up in the trash before the database // look up in the trash before the database
@@ -609,7 +618,7 @@ void DBDriver::loadSignatures(const std::list<int> & signIds,
if(ids.size()) if(ids.size())
{ {
_dbSafeAccessMutex.lock(); _dbSafeAccessMutex.lock();
this->loadSignaturesQuery(ids, signatures); this->loadSignaturesQuery(ids, signatures, loadWordIdsOnly);
_dbSafeAccessMutex.unlock(); _dbSafeAccessMutex.unlock();
} }
} }
@@ -656,10 +665,10 @@ void DBDriver::loadWords(const std::set<int> & wordIds, std::list<VisualWord *>
} }
} }
void DBDriver::loadNodeData(Signature * signature, bool images, bool scan, bool userData, bool occupancyGrid) const void DBDriver::loadNodeData(Signature & signature, bool images, bool scan, bool userData, bool occupancyGrid) const
{ {
std::list<Signature *> signatures; std::list<Signature *> signatures;
signatures.push_back(signature); signatures.push_back(&signature);
this->loadNodeData(signatures, images, scan, userData, occupancyGrid); this->loadNodeData(signatures, images, scan, userData, occupancyGrid);
} }
@@ -823,6 +832,45 @@ bool DBDriver::getNodeInfo(
return found; return found;
} }
void DBDriver::getLocalFeatures(
int signatureId,
std::multimap<int, int> & words,
std::vector<cv::KeyPoint> & keypoints,
std::vector<cv::Point3f> & points,
cv::Mat & descriptors) const
{
bool found = false;
// look in the trash
_trashesMutex.lock();
if(uContains(_trashSignatures, signatureId))
{
const Signature * s = _trashSignatures.at(signatureId);
UASSERT(s != 0);
found = true;
if(!s->getWords().empty())
{
words = s->getWords();
if(s->getWordsKpts().empty()){
found = false; // Force checking the database in case the local features were not loaded in RAM
}
else
{
words = s->getWords();
keypoints = s->getWordsKpts();
points = s->getWords3();
descriptors = s->getWordsDescriptors().clone();
}
}
}
_trashesMutex.unlock();
if(!found)
{
UScopeMutex lock(_dbSafeAccessMutex);
getLocalFeaturesQuery(signatureId, words, keypoints, points, descriptors);
}
}
void DBDriver::loadLinks(int signatureId, std::multimap<int, Link> & links, Link::Type type) const void DBDriver::loadLinks(int signatureId, std::multimap<int, Link> & links, Link::Type type) const
{ {
bool found = false; bool found = false;
@@ -1287,6 +1335,13 @@ cv::Mat DBDriver::loadOptimizedMesh(
return cloud; return cloud;
} }
void DBDriver::saveFlannIndex(const std::vector<unsigned char> & indexData) const
{
_dbSafeAccessMutex.lock();
saveFlannIndexQuery(indexData);
_dbSafeAccessMutex.unlock();
}
void DBDriver::generateGraph( void DBDriver::generateGraph(
const std::string & fileName, const std::string & fileName,
const std::set<int> & idsInput, const std::set<int> & idsInput,
File diff suppressed because it is too large Load Diff
+54 -23
View File
@@ -56,6 +56,8 @@ DBReader::DBReader(const std::string & databasePath,
int startMapId, int startMapId,
int stopMapId, int stopMapId,
bool priorsIgnored, bool priorsIgnored,
bool imuIgnored,
bool intermediateNodesAreNormalNodes,
const std::vector<Transform> & cameraLocalTransformOverrides) : const std::vector<Transform> & cameraLocalTransformOverrides) :
Camera(frameRate), Camera(frameRate),
_paths(uSplit(databasePath, ';')), _paths(uSplit(databasePath, ';')),
@@ -66,9 +68,11 @@ DBReader::DBReader(const std::string & databasePath,
_stopId(stopId), _stopId(stopId),
_cameraIndices(cameraIndices), _cameraIndices(cameraIndices),
_intermediateNodesIgnored(intermediateNodesIgnored), _intermediateNodesIgnored(intermediateNodesIgnored),
_intermediateNodesAreNormalNodes(intermediateNodesAreNormalNodes),
_landmarksIgnored(landmarksIgnored), _landmarksIgnored(landmarksIgnored),
_featuresIgnored(featuresIgnored), _featuresIgnored(featuresIgnored),
_priorsIgnored(priorsIgnored), _priorsIgnored(priorsIgnored),
_imuIgnored(imuIgnored),
_startMapId(startMapId), _startMapId(startMapId),
_stopMapId(stopMapId), _stopMapId(stopMapId),
_cameraLocalTransformOverrides(cameraLocalTransformOverrides), _cameraLocalTransformOverrides(cameraLocalTransformOverrides),
@@ -96,6 +100,8 @@ DBReader::DBReader(const std::list<std::string> & databasePaths,
int startMapId, int startMapId,
int stopMapId, int stopMapId,
bool priorsIgnored, bool priorsIgnored,
bool imuIgnored,
bool intermediateNodesAreNormalNodes,
const std::vector<Transform> & cameraLocalTransformOverrides) : const std::vector<Transform> & cameraLocalTransformOverrides) :
Camera(frameRate), Camera(frameRate),
_paths(databasePaths), _paths(databasePaths),
@@ -106,9 +112,11 @@ DBReader::DBReader(const std::list<std::string> & databasePaths,
_stopId(stopId), _stopId(stopId),
_cameraIndices(cameraIndices), _cameraIndices(cameraIndices),
_intermediateNodesIgnored(intermediateNodesIgnored), _intermediateNodesIgnored(intermediateNodesIgnored),
_intermediateNodesAreNormalNodes(intermediateNodesAreNormalNodes),
_landmarksIgnored(landmarksIgnored), _landmarksIgnored(landmarksIgnored),
_featuresIgnored(featuresIgnored), _featuresIgnored(featuresIgnored),
_priorsIgnored(priorsIgnored), _priorsIgnored(priorsIgnored),
_imuIgnored(imuIgnored),
_startMapId(startMapId), _startMapId(startMapId),
_stopMapId(stopMapId), _stopMapId(stopMapId),
_cameraLocalTransformOverrides(cameraLocalTransformOverrides), _cameraLocalTransformOverrides(cameraLocalTransformOverrides),
@@ -260,7 +268,7 @@ bool DBReader::init(
else else
{ {
Signature * s = _dbDriver->loadSignature(*_ids.begin()); Signature * s = _dbDriver->loadSignature(*_ids.begin());
_dbDriver->loadNodeData(s); _dbDriver->loadNodeData(*s);
if( s->sensorData().imageCompressed().empty() && if( s->sensorData().imageCompressed().empty() &&
s->getWords().empty() && s->getWords().empty() &&
!s->sensorData().laserScanCompressed().empty()) !s->sensorData().laserScanCompressed().empty())
@@ -463,14 +471,17 @@ SensorData DBReader::getNextData(SensorCaptureInfo * info)
} }
Transform gravityTransform; Transform gravityTransform;
std::multimap<int, Link> gravityLinks; if(!_imuIgnored)
_dbDriver->loadLinks(*_currentId, gravityLinks, Link::kGravity);
if( gravityLinks.size() &&
!gravityLinks.begin()->second.transform().isNull() &&
gravityLinks.begin()->second.infMatrix().cols == 6 &&
gravityLinks.begin()->second.infMatrix().rows == 6)
{ {
gravityTransform = gravityLinks.begin()->second.transform(); std::multimap<int, Link> gravityLinks;
_dbDriver->loadLinks(*_currentId, gravityLinks, Link::kGravity);
if( gravityLinks.size() &&
!gravityLinks.begin()->second.transform().isNull() &&
gravityLinks.begin()->second.infMatrix().cols == 6 &&
gravityLinks.begin()->second.infMatrix().rows == 6)
{
gravityTransform = gravityLinks.begin()->second.transform();
}
} }
Landmarks landmarks; Landmarks landmarks;
@@ -510,22 +521,41 @@ SensorData DBReader::getNextData(SensorCaptureInfo * info)
} }
else else
{ {
// if localization data saved in database, covariance will be set in a prior link // In case the graph was reduced, look for forward neighbor link from previous id
_dbDriver->loadLinks(*_currentId, links, Link::kPosePrior); bool covAdded = false;
if(links.size()) if(_currentId != _ids.begin()) {
{ std::set<int>::iterator previousId = _currentId;
// assume the first is the backward neighbor, take its variance --previousId;
infMatrix = links.begin()->second.infMatrix(); std::multimap<int, Link> previousLinks;
_previousInfMatrix = infMatrix; _dbDriver->loadLinks(*previousId, previousLinks, Link::kNeighbor);
} if(previousLinks.size() && previousLinks.rbegin()->first == *_currentId)
else
{
if(_previousInfMatrix.empty())
{ {
_previousInfMatrix = cv::Mat::eye(6,6,CV_64FC1); // assume the last is the forward neighbor pointing to current ID, take its covariance
infMatrix = previousLinks.rbegin()->second.infMatrix();
_previousInfMatrix = infMatrix;
covAdded = true;
}
}
if(!covAdded) {
// if localization data saved in database, covariance will be set in a prior link
_dbDriver->loadLinks(*_currentId, links, Link::kPosePrior);
if(links.size())
{
// assume the first is the backward neighbor, take its variance
infMatrix = links.begin()->second.infMatrix();
_previousInfMatrix = infMatrix;
}
else
{
if(_previousInfMatrix.empty())
{
_previousInfMatrix = cv::Mat::eye(6,6,CV_64FC1);
}
// we have a node not linked to map, use last variance
UWARN("The node loaded (%d) doesn't have neighbor, re-using the covariance of the previous link for odometry.", s->id());
infMatrix = _previousInfMatrix;
} }
// we have a node not linked to map, use last variance
infMatrix = _previousInfMatrix;
} }
} }
} }
@@ -723,7 +753,7 @@ SensorData DBReader::getNextData(SensorCaptureInfo * info)
data.setStereoCameraModels(combinedStereoModels); data.setStereoCameraModels(combinedStereoModels);
} }
} }
data.setId(seq); data.setId(!_intermediateNodesAreNormalNodes && s->getWeight()==-1 ? -1 : seq);
data.setStamp(s->getStamp()); data.setStamp(s->getStamp());
data.setGroundTruth(s->getGroundTruthPose()); data.setGroundTruth(s->getGroundTruthPose());
if(!globalPose.isNull()) if(!globalPose.isNull())
@@ -837,6 +867,7 @@ SensorData DBReader::getNextData(SensorCaptureInfo * info)
if(info) if(info)
{ {
info->odomPose = pose; info->odomPose = pose;
UASSERT(!infMatrix.empty());
info->odomCovariance = infMatrix.inv(); info->odomCovariance = infMatrix.inv();
info->odomVelocity = s->getVelocity(); info->odomVelocity = s->getVelocity();
UDEBUG("odom variance = %f/%f", info->odomCovariance.at<double>(0,0), info->odomCovariance.at<double>(5,5)); UDEBUG("odom variance = %f/%f", info->odomCovariance.at<double>(0,0), info->odomCovariance.at<double>(5,5));
+232 -50
View File
@@ -47,6 +47,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifdef RTABMAP_TORCH #ifdef RTABMAP_TORCH
#include "superpoint_torch/SuperPoint.h" #include "superpoint_torch/SuperPoint.h"
#endif #endif
#if defined(RTABMAP_TORCH) && defined(RTABMAP_PYTHON)
#include "superpoint_rpautrat/SuperpointRpautrat.h"
#endif
#ifdef RTABMAP_PYTHON #ifdef RTABMAP_PYTHON
#include "python/PyDetector.h" #include "python/PyDetector.h"
@@ -300,7 +303,7 @@ void Feature2D::limitKeypoints(std::vector<cv::KeyPoint> & keypoints, std::vecto
cv::Mat descriptorsTmp; cv::Mat descriptorsTmp;
if(ssc) if(ssc)
{ {
ULOGGER_DEBUG("too much words (%d), removing words with SSC", keypoints.size()); ULOGGER_DEBUG("too many words (%d), removing words with SSC", keypoints.size());
// Sorting keypoints by deacreasing order of strength // Sorting keypoints by deacreasing order of strength
std::vector<float> responseVector; std::vector<float> responseVector;
@@ -416,7 +419,7 @@ void Feature2D::limitKeypoints(const std::vector<cv::KeyPoint> & keypoints, std:
inliers.resize(keypoints.size(), false); inliers.resize(keypoints.size(), false);
if(ssc) if(ssc)
{ {
ULOGGER_DEBUG("too much words (%d), removing words with SSC", keypoints.size()); ULOGGER_DEBUG("too many words (%d), removing words with SSC", keypoints.size());
// Sorting keypoints by deacreasing order of strength // Sorting keypoints by deacreasing order of strength
std::vector<float> responseVector; std::vector<float> responseVector;
@@ -463,7 +466,7 @@ void Feature2D::limitKeypoints(const std::vector<cv::KeyPoint> & keypoints, std:
minimumHessian = iter->first; minimumHessian = iter->first;
} }
} }
ULOGGER_DEBUG("%d keypoints removed, (kept %d), minimum response=%f", removed, maxKeypoints, minimumHessian); ULOGGER_DEBUG("%d keypoints removed, (kept %d), minimum response=%f", removed, keypoints.size()-removed, minimumHessian);
ULOGGER_DEBUG("filter keypoints time = %f s", timer.ticks()); ULOGGER_DEBUG("filter keypoints time = %f s", timer.ticks());
} }
else else
@@ -730,9 +733,14 @@ Feature2D * Feature2D::create(Feature2D::Type type, const ParametersMap & parame
feature2D = new ORBOctree(parameters); feature2D = new ORBOctree(parameters);
break; break;
#ifdef RTABMAP_TORCH #ifdef RTABMAP_TORCH
case Feature2D::kFeatureSuperPointTorch: case Feature2D::kFeatureSuperPointTorch:
feature2D = new SuperPointTorch(parameters); feature2D = new SuperPointTorch(parameters);
break; break;
#endif
#if defined(RTABMAP_TORCH) && defined(RTABMAP_PYTHON)
case Feature2D::kFeatureSuperPointRpautrat:
feature2D = new SuperPointRpautrat(parameters);
break;
#endif #endif
case Feature2D::kFeatureSurfFreak: case Feature2D::kFeatureSurfFreak:
feature2D = new SURF_FREAK(parameters); feature2D = new SURF_FREAK(parameters);
@@ -831,7 +839,7 @@ std::vector<cv::KeyPoint> Feature2D::generateKeypoints(const cv::Mat & image, co
cv::Rect roi(globalRoi.x + j*colSize, globalRoi.y + i*rowSize, colSize, rowSize); cv::Rect roi(globalRoi.x + j*colSize, globalRoi.y + i*rowSize, colSize, rowSize);
std::vector<cv::KeyPoint> subKeypoints; std::vector<cv::KeyPoint> subKeypoints;
subKeypoints = this->generateKeypointsImpl(image, roi, mask); subKeypoints = this->generateKeypointsImpl(image, roi, mask);
if (this->getType() != Feature2D::Type::kFeaturePyDetector) if (this->getType() != Feature2D::Type::kFeaturePyDetector && this->getType() != Feature2D::Type::kFeatureSuperPointRpautrat)
{ {
limitKeypoints(subKeypoints, maxFeatures, roi.size(), this->getSSC()); limitKeypoints(subKeypoints, maxFeatures, roi.size(), this->getSSC());
} }
@@ -879,8 +887,17 @@ cv::Mat Feature2D::generateDescriptors(
UASSERT(!image.empty()); UASSERT(!image.empty());
UASSERT(image.type() == CV_8UC1); UASSERT(image.type() == CV_8UC1);
descriptors = generateDescriptorsImpl(image, keypoints); descriptors = generateDescriptorsImpl(image, keypoints);
UASSERT_MSG(descriptors.rows == (int)keypoints.size(), uFormat("descriptors=%d, keypoints=%d", descriptors.rows, (int)keypoints.size()).c_str()); if(descriptors.rows != (int)keypoints.size())
UDEBUG("Descriptors extracted = %d, remaining kpts=%d", descriptors.rows, (int)keypoints.size()); {
UWARN("Descriptor extraction returned %d rows for %d keypoints — "
"clearing keypoints to keep them in sync.",
descriptors.rows, (int)keypoints.size());
keypoints.clear();
descriptors = cv::Mat();
}
else {
UDEBUG("Descriptors extracted = %d, remaining kpts=%d", descriptors.rows, (int)keypoints.size());
}
} }
return descriptors; return descriptors;
} }
@@ -1243,7 +1260,8 @@ SIFT::SIFT(const ParametersMap & parameters) :
preciseUpscale_(Parameters::defaultSIFTPreciseUpscale()), preciseUpscale_(Parameters::defaultSIFTPreciseUpscale()),
rootSIFT_(Parameters::defaultSIFTRootSIFT()), rootSIFT_(Parameters::defaultSIFTRootSIFT()),
gpu_(Parameters::defaultSIFTGpu()), gpu_(Parameters::defaultSIFTGpu()),
guaussianThreshold_(Parameters::defaultSIFTGaussianThreshold()), gaussianThreshold_(Parameters::defaultSIFTGaussianThreshold()),
maxGaussianThreshold_(Parameters::defaultSIFTMaxGaussianThreshold()),
upscale_(Parameters::defaultSIFTUpscale()), upscale_(Parameters::defaultSIFTUpscale()),
cudaSiftData_(0), cudaSiftData_(0),
cudaSiftMemory_(0), cudaSiftMemory_(0),
@@ -1276,23 +1294,25 @@ void SIFT::parseParameters(const ParametersMap & parameters)
Parameters::parse(parameters, Parameters::kSIFTPreciseUpscale(), preciseUpscale_); Parameters::parse(parameters, Parameters::kSIFTPreciseUpscale(), preciseUpscale_);
Parameters::parse(parameters, Parameters::kSIFTRootSIFT(), rootSIFT_); Parameters::parse(parameters, Parameters::kSIFTRootSIFT(), rootSIFT_);
Parameters::parse(parameters, Parameters::kSIFTGpu(), gpu_); Parameters::parse(parameters, Parameters::kSIFTGpu(), gpu_);
Parameters::parse(parameters, Parameters::kSIFTGaussianThreshold(), guaussianThreshold_); Parameters::parse(parameters, Parameters::kSIFTGaussianThreshold(), gaussianThreshold_);
Parameters::parse(parameters, Parameters::kSIFTMaxGaussianThreshold(), maxGaussianThreshold_);
Parameters::parse(parameters, Parameters::kSIFTUpscale(), upscale_); Parameters::parse(parameters, Parameters::kSIFTUpscale(), upscale_);
if(gpu_) if(gpu_)
{ {
#ifdef RTABMAP_CUDASIFT #ifdef RTABMAP_CUDASIFT
// Check if there is a cuda device // Check if there is a cuda device
if(InitCuda(0, ULogger::level() == ULogger::kDebug)) { if(cudaSiftData_==0)
UDEBUG("Init SiftData"); {
if(cudaSiftData_ == 0) { if(InitCuda(0, ULogger::level() == ULogger::kDebug)) {
UDEBUG("Init SiftData");
cudaSiftData_ = new SiftData(); cudaSiftData_ = new SiftData();
InitSiftData(*cudaSiftData_, 8192, true, true); InitSiftData(*cudaSiftData_, 8192, true, true);
} }
} else{
else{ UWARN("No cuda device(s) detected, CudaSift is not available! Using SIFT CPU version instead.");
UWARN("No cuda device(s) detected, CudaSift is not available! Using SIFT CPU version instead."); gpu_ = false;
gpu_ = false; }
} }
#else #else
UWARN("RTAB-Map is not built with CudaSift so %s cannot be used!", Parameters::kSIFTGpu().c_str()); UWARN("RTAB-Map is not built with CudaSift so %s cannot be used!", Parameters::kSIFTGpu().c_str());
@@ -1355,7 +1375,7 @@ std::vector<cv::KeyPoint> SIFT::generateKeypointsImpl(const cv::Mat & image, con
numOctaves = 7; // hard-coded limit in CudaSift numOctaves = 7; // hard-coded limit in CudaSift
} }
float initBlur = sigma_; /* Amount of initial Gaussian blurring in standard deviations */ float initBlur = sigma_; /* Amount of initial Gaussian blurring in standard deviations */
float thresh = guaussianThreshold_; /* Threshold on difference of Gaussians for feature pruning */ float thresh = gaussianThreshold_; /* Threshold on difference of Gaussians for feature pruning */
float edgeLimit = edgeThreshold_; float edgeLimit = edgeThreshold_;
float minScale = 0.0f; /* Minimum acceptable scale to remove fine-scale features */ float minScale = 0.0f; /* Minimum acceptable scale to remove fine-scale features */
UDEBUG("numOctaves=%d initBlur=%f thresh=%f edgeLimit=%f minScale=%f upScale=%s w=%d h=%d", numOctaves, initBlur, thresh, edgeLimit, minScale, upscale_?"true":"false", w, h); UDEBUG("numOctaves=%d initBlur=%f thresh=%f edgeLimit=%f minScale=%f upScale=%s w=%d h=%d", numOctaves, initBlur, thresh, edgeLimit, minScale, upscale_?"true":"false", w, h);
@@ -1380,15 +1400,9 @@ std::vector<cv::KeyPoint> SIFT::generateKeypointsImpl(const cv::Mat & image, con
cudaSiftDescriptors_ = cv::Mat(); cudaSiftDescriptors_ = cv::Mat();
if(cudaSiftData_->numPts) if(cudaSiftData_->numPts)
{ {
int maxKeypoints = this->getMaxFeatures(); keypoints.resize(cudaSiftData_->numPts);
if(maxKeypoints == 0 || maxKeypoints > cudaSiftData_->numPts) cudaSiftDescriptors_ = cv::Mat(cudaSiftData_->numPts, 128, CV_32FC1);
{ size_t k=0;
maxKeypoints = cudaSiftData_->numPts;
}
// Re-using same implementation of limitKeypoints() directly here to avoid doubling memory copies
// Sort words by hessian
std::multimap<float, int> hessianMap; // <hessian,id>
for(int i=0; i<cudaSiftData_->numPts; ++i) for(int i=0; i<cudaSiftData_->numPts; ++i)
{ {
// Ignore keypoints with invalid descriptors // Ignore keypoints with invalid descriptors
@@ -1405,29 +1419,40 @@ std::vector<cv::KeyPoint> SIFT::generateKeypointsImpl(const cv::Mat & image, con
continue; continue;
} }
//Keep track of the data, to be easier to manage the data in the next step if(i>0 &&
hessianMap.insert(std::pair<float, int>(cudaSiftData_->h_data[i].sharpness, i)); cudaSiftData_->h_data[i].subsampling == cudaSiftData_->h_data[i-1].subsampling &&
} fabs(cudaSiftData_->h_data[i].xpos-cudaSiftData_->h_data[i-1].xpos) +
fabs(cudaSiftData_->h_data[i].xpos-cudaSiftData_->h_data[i-1].ypos) < 0.1f)
{
// Same feature, skip doubles
continue;
}
if((int)hessianMap.size() < maxKeypoints) float response = abs(cudaSiftData_->h_data[i].sharpness);
{ if(maxGaussianThreshold_>gaussianThreshold_ && response > maxGaussianThreshold_)
maxKeypoints = hessianMap.size(); {
} continue;
}
std::multimap<float, int>::reverse_iterator iter = hessianMap.rbegin();
keypoints.resize(maxKeypoints);
cudaSiftDescriptors_ = cv::Mat(maxKeypoints, 128, CV_32FC1);
for(unsigned int k=0; k<keypoints.size() && iter!=hessianMap.rend(); ++k, ++iter)
{
int i = iter->second;
float *desc = cudaSiftData_->h_data[i].data;
cv::Mat(1, 128, CV_32FC1, desc).copyTo(cudaSiftDescriptors_.row(k)); cv::Mat(1, 128, CV_32FC1, desc).copyTo(cudaSiftDescriptors_.row(k));
keypoints[k].pt.x = cudaSiftData_->h_data[i].xpos; keypoints[k].pt.x = cudaSiftData_->h_data[i].xpos;
keypoints[k].pt.y = cudaSiftData_->h_data[i].ypos; keypoints[k].pt.y = cudaSiftData_->h_data[i].ypos;
keypoints[k].size = 2.0f*cudaSiftData_->h_data[i].scale; // x2 because the scale is more like a radius than a diameter, see CudaSift's ExtractSiftDescriptors function to see how they convert scale to patch size keypoints[k].size = 2.0f*cudaSiftData_->h_data[i].scale; // x2 because the scale is more like a radius than a diameter, see CudaSift's ExtractSiftDescriptors function to see how they convert scale to patch size
keypoints[k].angle = cudaSiftData_->h_data[i].orientation; keypoints[k].angle = cudaSiftData_->h_data[i].orientation;
keypoints[k].response = cudaSiftData_->h_data[i].sharpness; keypoints[k].response = response;
keypoints[k].octave = log2(cudaSiftData_->h_data[i].subsampling)-(upscale_?1:0); keypoints[k].octave = log2(cudaSiftData_->h_data[i].subsampling)-(upscale_?1:0);
++k;
}
if(k < keypoints.size())
{
UDEBUG("keypoints extracted = %d, valid=%d", keypoints.size(), k);
keypoints.resize(k);
cudaSiftDescriptors_.resize(k);
}
if(this->getMaxFeatures() != 0 && this->getMaxFeatures() < (int)keypoints.size())
{
// Call limitKeypoints() now to filter the descriptors.
this->limitKeypoints(keypoints, cudaSiftDescriptors_, this->getMaxFeatures(), cv::Size(w,h), this->getSSC());
} }
} }
} }
@@ -1449,12 +1474,13 @@ std::vector<cv::KeyPoint> SIFT::generateKeypointsImpl(const cv::Mat & image, con
cv::Mat SIFT::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const cv::Mat SIFT::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const
{ {
cv::Mat descriptors;
#ifdef RTABMAP_CUDASIFT #ifdef RTABMAP_CUDASIFT
if(gpu_) if(gpu_)
{ {
if((int)keypoints.size() == cudaSiftDescriptors_.rows) if((int)keypoints.size() == cudaSiftDescriptors_.rows)
{ {
return cudaSiftDescriptors_.clone(); descriptors = cudaSiftDescriptors_.clone();
} }
else else
{ {
@@ -1462,19 +1488,25 @@ cv::Mat SIFT::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::Key
return cv::Mat(); return cv::Mat();
} }
} }
else
{
#endif #endif
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U); UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
cv::Mat descriptors;
#if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <= 3) || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION < 4 || (CV_MINOR_VERSION==4 && CV_SUBMINOR_VERSION<11))) #if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 4 && CV_MINOR_VERSION <= 3) || (CV_MAJOR_VERSION == 3 && (CV_MINOR_VERSION < 4 || (CV_MINOR_VERSION==4 && CV_SUBMINOR_VERSION<11)))
#ifdef RTABMAP_NONFREE #ifdef RTABMAP_NONFREE
sift_->compute(image, keypoints, descriptors); sift_->compute(image, keypoints, descriptors);
#else #else
UWARN("RTAB-Map is not built with OpenCV nonfree module so SIFT cannot be used!"); UWARN("RTAB-Map is not built with OpenCV nonfree module so SIFT cannot be used!");
#endif #endif
#else // >=4.4, >=3.4.11 #else // >=4.4, >=3.4.11
sift_->compute(image, keypoints, descriptors); sift_->compute(image, keypoints, descriptors);
#endif #endif
#ifdef RTABMAP_CUDASIFT
}
#endif
if( rootSIFT_ && !descriptors.empty()) if( rootSIFT_ && !descriptors.empty())
{ {
UDEBUG("Performing RootSIFT..."); UDEBUG("Performing RootSIFT...");
@@ -2607,7 +2639,31 @@ cv::Mat SuperPointTorch::generateDescriptorsImpl(const cv::Mat & image, std::vec
{ {
#ifdef RTABMAP_TORCH #ifdef RTABMAP_TORCH
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U); UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
return superPoint_->compute(keypoints); cv::Mat descriptors;
if(!keypoints.empty())
{
descriptors = superPoint_->compute(keypoints);
if(descriptors.empty())
{
// superpoint may have been reset between keypoint detection and now,
// re-detect features to re-inialize the descriptors matrix, then
// re-extract descriptors with original keypoints.
UWARN("Re-initializing superpoint on that image to extract descriptors");
if(!superPoint_->detect(image).empty())
{
descriptors = superPoint_->compute(keypoints);
if(descriptors.rows == (int)keypoints.size())
{
UWARN("Sucessfully re-initialized superpoint, returning %d descriptors.", descriptors.rows);
}
}
else
{
UWARN("Failed to re-initialize superpoint on that image, returning empty descriptors.");
}
}
}
return descriptors;
#else #else
UWARN("RTAB-Map is not built with Torch support so SuperPoint Torch feature cannot be used!"); UWARN("RTAB-Map is not built with Torch support so SuperPoint Torch feature cannot be used!");
return cv::Mat(); return cv::Mat();
@@ -2615,6 +2671,132 @@ cv::Mat SuperPointTorch::generateDescriptorsImpl(const cv::Mat & image, std::vec
} }
//////////////////////////
//SuperPointRpautrat
//////////////////////////
SuperPointRpautrat::SuperPointRpautrat(const ParametersMap & parameters) :
superpointWeightsPath_(Parameters::defaultSuperPointRpautratWeightsPath()),
superpointModelPath_(Parameters::defaultSuperPointRpautratModelPath()),
outputDir_(""),
threshold_(Parameters::defaultSuperPointRpautratThreshold()),
nms_(Parameters::defaultSuperPointRpautratNMS()),
minDistance_(Parameters::defaultSuperPointRpautratNMSRadius()),
cuda_(Parameters::defaultSuperPointRpautratCuda())
{
parseParameters(parameters);
}
SuperPointRpautrat::~SuperPointRpautrat()
{
}
void SuperPointRpautrat::parseParameters(const ParametersMap & parameters)
{
Feature2D::parseParameters(parameters);
#if defined(RTABMAP_TORCH) && defined(RTABMAP_PYTHON)
std::string previousWeightsPath = superpointWeightsPath_;
std::string previousModelPath = superpointModelPath_;
bool previousCuda = cuda_;
float previousThreshold = threshold_;
bool previousNms = nms_;
int previousMinDistance = minDistance_;
Parameters::parse(parameters, Parameters::kSuperPointRpautratWeightsPath(), superpointWeightsPath_);
Parameters::parse(parameters, Parameters::kSuperPointRpautratModelPath(), superpointModelPath_);
Parameters::parse(parameters, Parameters::kSuperPointRpautratThreshold(), threshold_);
Parameters::parse(parameters, Parameters::kSuperPointRpautratNMS(), nms_);
Parameters::parse(parameters, Parameters::kSuperPointRpautratNMSRadius(), minDistance_);
Parameters::parse(parameters, Parameters::kSuperPointRpautratCuda(), cuda_);
Parameters::parse(parameters, Parameters::kRtabmapWorkingDirectory(), outputDir_);
// If working directory is not set, use the default
if(outputDir_.empty())
{
outputDir_ = Parameters::createDefaultWorkingDirectory();
}
// Reinitialize detector if model-affecting parameters changed
if(superPoint_.get() == 0 ||
superpointWeightsPath_.compare(previousWeightsPath) != 0 ||
superpointModelPath_.compare(previousModelPath) != 0 ||
previousCuda != cuda_ ||
previousThreshold != threshold_ ||
previousNms != nms_ ||
previousMinDistance != minDistance_)
{
superPoint_ = cv::Ptr<SPDetectorRpautrat>(new SPDetectorRpautrat(superpointWeightsPath_, superpointModelPath_, outputDir_, threshold_, nms_, minDistance_, cuda_, this->getMaxFeatures(), this->getSSC()));
}
else if(superPoint_.get() != 0)
{
// Update post-processing parameters without reinitializing
superPoint_->setMaxFeatures(this->getMaxFeatures());
superPoint_->setSSC(this->getSSC());
}
#else
UWARN("RTAB-Map is not built with Torch support so SuperPoint Rpautrat feature cannot be used!");
#endif
}
std::vector<cv::KeyPoint> SuperPointRpautrat::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask)
{
#if defined(RTABMAP_TORCH) && defined(RTABMAP_PYTHON)
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
if(roi.x!=0 || roi.y !=0)
{
UERROR("SuperPoint Rpautrat: Not supporting ROI (%d,%d,%d,%d). Make sure %s, %s, %s, %s, %s, %s are all set to default values.",
roi.x, roi.y, roi.width, roi.height,
Parameters::kKpRoiRatios().c_str(),
Parameters::kVisRoiRatios().c_str(),
Parameters::kVisGridRows().c_str(),
Parameters::kVisGridCols().c_str(),
Parameters::kKpGridRows().c_str(),
Parameters::kKpGridCols().c_str());
return std::vector<cv::KeyPoint>();
}
return superPoint_->detect(image, mask);
#else
UWARN("RTAB-Map is not built with Torch support so SuperPoint Rpautrat feature cannot be used!");
return std::vector<cv::KeyPoint>();
#endif
}
cv::Mat SuperPointRpautrat::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const
{
#if defined(RTABMAP_TORCH) && defined(RTABMAP_PYTHON)
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
cv::Mat descriptors;
if(!keypoints.empty())
{
descriptors = superPoint_->compute(keypoints);
if(descriptors.empty())
{
// superpoint may have been reset between keypoint detection and now,
// re-detect features to re-inialize the descriptors matrix, then
// re-extract descriptors with original keypoints.
UWARN("Re-initializing superpoint on that image to extract descriptors");
if(!superPoint_->detect(image).empty())
{
descriptors = superPoint_->compute(keypoints);
if(descriptors.rows == (int)keypoints.size())
{
UWARN("Sucessfully re-initialized superpoint, returning %d descriptors.", descriptors.rows);
}
}
else
{
UWARN("Failed to re-initialize superpoint on that image, returning empty descriptors.");
}
}
}
return descriptors;
#else
UWARN("RTAB-Map is not built with Torch support so SuperPoint Rpautrat feature cannot be used!");
return cv::Mat();
#endif
}
////////////////////////// //////////////////////////
//GFTT-DAISY //GFTT-DAISY
////////////////////////// //////////////////////////
+330 -119
View File
@@ -27,8 +27,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/core/FlannIndex.h> #include <rtabmap/core/FlannIndex.h>
#include <rtabmap/utilite/ULogger.h> #include <rtabmap/utilite/ULogger.h>
#include <rtabmap/utilite/UTimer.h>
#include <rtabmap/utilite/UConversion.h>
#include <rtabmap/core/Compression.h>
#include <rtabmap/core/Version.h>
#ifdef WIN32
#include <rtabmap/core/Parameters.h>
#endif
#include "rtflann/flann.hpp" #include "rtflann/flann.hpp"
#include <boost/crc.hpp>
namespace rtabmap { namespace rtabmap {
@@ -37,7 +45,6 @@ FlannIndex::FlannIndex():
nextIndex_(0), nextIndex_(0),
featuresType_(0), featuresType_(0),
featuresDim_(0), featuresDim_(0),
isLSH_(false),
useDistanceL1_(false), useDistanceL1_(false),
rebalancingFactor_(2.0f) rebalancingFactor_(2.0f)
{ {
@@ -49,9 +56,9 @@ FlannIndex::~FlannIndex()
void FlannIndex::release() void FlannIndex::release()
{ {
UDEBUG("");
if(index_) if(index_)
{ {
UDEBUG("Clearing flann index...");
if(featuresType_ == CV_8UC1) if(featuresType_ == CV_8UC1)
{ {
delete (rtflann::Index<rtflann::Hamming<unsigned char> >*)index_; delete (rtflann::Index<rtflann::Hamming<unsigned char> >*)index_;
@@ -72,12 +79,139 @@ void FlannIndex::release()
} }
} }
index_ = 0; index_ = 0;
UDEBUG("Clearing flann index... done!");
} }
nextIndex_ = 0; nextIndex_ = 0;
isLSH_ = false;
addedDescriptors_.clear(); addedDescriptors_.clear();
removedIndexes_.clear(); removedIndexes_.clear();
UDEBUG(""); }
#define FLANN_INDEX_HEADER_SIZE 12
std::vector<unsigned char> FlannIndex::serializeIndex(bool computeChecksum) const {
if(index_ && !addedDescriptors_.empty())
{
#ifdef WIN32
UERROR("FLANN index serialization is not yet implemented on Windows. Parameter \"%s\" cannot be used.", Parameters::kKpFlannIndexSaved().c_str());
#else
UTimer timer;
const int headerSizeBytes = sizeof(int)*FLANN_INDEX_HEADER_SIZE;
std::vector<unsigned char> indexData(1024*1024*1024 + headerSizeBytes); // Max 1 GB
FILE* indexDataPtr = fmemopen(indexData.data()+headerSizeBytes, indexData.size() - headerSizeBytes, "wb");
long bytes_written = 0;
if (indexDataPtr) {
if(featuresType_ == CV_8UC1)
{
((rtflann::Index<rtflann::Hamming<unsigned char> >*)index_)->save(indexDataPtr);
}
else
{
if(useDistanceL1_)
{
((rtflann::Index<rtflann::L1<float> >*)index_)->save(indexDataPtr);;
}
else if(featuresDim_ <= 3)
{
((rtflann::Index<rtflann::L2_Simple<float> >*)index_)->save(indexDataPtr);;
}
else
{
((rtflann::Index<rtflann::L2<float> >*)index_)->save(indexDataPtr);;
}
}
bytes_written = ftell(indexDataPtr);
fclose(indexDataPtr);
}
if(bytes_written < long(indexData.size()-headerSizeBytes))
{
//Expected data size and type
int dataRows = 0;
int dataCols = 0;
int dataType = -1;
cv::Mat dataset;
std::set<int> removedDescriptors;
if(computeChecksum){
removedDescriptors.insert(removedIndexes_.begin(), removedIndexes_.end());
}
for(const auto & iter: addedDescriptors_)
{
UASSERT(!iter.second.empty());
dataRows += iter.second.rows;
if(dataCols <= 0) {
dataCols = iter.second.cols;
}
else {
UASSERT(dataCols == iter.second.cols);
}
if(dataType < 0) {
dataType = iter.second.type();
}
else {
UASSERT(dataType == iter.second.type());
}
if(computeChecksum){
if(removedDescriptors.find(iter.first) == removedDescriptors.end()) {
if(dataset.empty()) {
dataset = iter.second.clone();
}
else {
dataset.push_back(iter.second);
}
}
else {
dataRows -= iter.second.rows;
}
}
}
if(!computeChecksum) {
for(const auto & index: removedIndexes_)
{
dataRows -= addedDescriptors_.at(index).rows;
}
}
unsigned int crcValue = 0;
if(computeChecksum) {
boost::crc_32_type result;
result.process_bytes(dataset.data, dataset.total()*dataset.elemSize());
crcValue = result.checksum();
}
indexData.resize(bytes_written+headerSizeBytes);
indexData.shrink_to_fit();
int rebalancingFactorAsInt;
memcpy(&rebalancingFactorAsInt, &rebalancingFactor_, sizeof(rebalancingFactor_));
int crcValueAsInt;
memcpy(&crcValueAsInt, &crcValue, sizeof(crcValue));
int header[FLANN_INDEX_HEADER_SIZE] = {
RTABMAP_VERSION_MAJOR, RTABMAP_VERSION_MINOR, RTABMAP_VERSION_PATCH, // 0,1,2
algorithm_, // 3,
featuresDim_, // 4,
useDistanceL1_?1:0, // 5,
rebalancingFactorAsInt, // 6,
dataRows, // 7,
dataCols, // 8,
dataType, // 9,
crcValueAsInt, // 10
(int)bytes_written}; // 11
UDEBUG("Header: \"%d.%d.%d\" alg=%d dim=%d L1=%d factor=%f data(%dx%d type=%d, crc=%X) %d",
header[0],header[1],header[2],
header[3],
header[4],
header[5],
rebalancingFactor_,
header[7], header[8], header[9], crcValueAsInt,
header[11]);
memcpy(indexData.data(), header, headerSizeBytes);
return indexData;
}
else {
UERROR("Target buffer too small to serialize index, aborting.");
}
UDEBUG("Flann serialization: %fs", timer.ticks());
#endif
}
return std::vector<unsigned char>();
} }
size_t FlannIndex::indexedFeatures() const size_t FlannIndex::indexedFeatures() const
@@ -139,12 +273,13 @@ size_t FlannIndex::memoryUsed() const
return memoryUsage; return memoryUsage;
} }
void FlannIndex::buildLinearIndex( void FlannIndex::buildIndex(
flann_algorithm_t algorithm,
const cv::Mat & features, const cv::Mat & features,
bool useDistanceL1, bool useDistanceL1,
float rebalancingFactor) float rebalancingFactor)
{ {
UDEBUG(""); UDEBUG("algorithm=%d", (int)algorithm);
this->release(); this->release();
UASSERT(index_ == 0); UASSERT(index_ == 0);
UASSERT(features.type() == CV_32FC1 || features.type() == CV_8UC1); UASSERT(features.type() == CV_32FC1 || features.type() == CV_8UC1);
@@ -152,8 +287,29 @@ void FlannIndex::buildLinearIndex(
featuresDim_ = features.cols; featuresDim_ = features.cols;
useDistanceL1_ = useDistanceL1; useDistanceL1_ = useDistanceL1;
rebalancingFactor_ = rebalancingFactor; rebalancingFactor_ = rebalancingFactor;
algorithm_ = algorithm;
rtflann::LinearIndexParams params; rtflann::IndexParams params;
switch (algorithm)
{
case FLANN_INDEX_LINEAR:
params = rtflann::LinearIndexParams();
break;
case FLANN_INDEX_KDTREE:
params = rtflann::KDTreeIndexParams(4);
break;
case FLANN_INDEX_KDTREE_SINGLE:
params = rtflann::KDTreeSingleIndexParams(10, true);
break;
case FLANN_INDEX_LSH:
UASSERT(features.type() == CV_8UC1);
params = rtflann::LshIndexParams(12, 20, 2);
break;
default:
UFATAL("The flann algorithm type %d is not supported!", (int)algorithm);
break;
}
if(featuresType_ == CV_8UC1) if(featuresType_ == CV_8UC1)
{ {
@@ -199,13 +355,140 @@ void FlannIndex::buildLinearIndex(
UDEBUG(""); UDEBUG("");
} }
void FlannIndex::buildKDTreeIndex( bool FlannIndex::loadIndex(
const cv::Mat & features, const std::vector<unsigned char> & indexData,
int trees, flann_algorithm_t algorithm,
bool useDistanceL1, const cv::Mat & features,
float rebalancingFactor) bool useDistanceL1,
float rebalancingFactor,
std::string * error)
{ {
UDEBUG(""); return loadIndex(
indexData.data(),
indexData.size(),
algorithm,
features,
useDistanceL1,
rebalancingFactor),
error;
}
bool FlannIndex::loadIndex(
const unsigned char * indexData,
size_t indexDataSize,
flann_algorithm_t algorithm,
const cv::Mat & features,
bool useDistanceL1,
float rebalancingFactor,
std::string * error)
{
UASSERT(indexData!=NULL);
if(indexDataSize == 0) {
UWARN("Trying to load empty index....");
return false;
}
#ifdef WIN32
UERROR("FLANN index deserialization is not yet implemented on Windows. Index cannot be loaded from memory buffer.");
return false;
#else
// Check if the features match the expected data from the index
size_t headerSizeBytes = sizeof(int)*FLANN_INDEX_HEADER_SIZE;
if(indexDataSize < headerSizeBytes) {
if(error) {
*error = uFormat("Wrong header size detected (%ld vs expected %ld).", indexDataSize, headerSizeBytes);
}
return false;
}
const int * header = (const int *)indexData;
int savedAlgorithm = header[3];
int savedDim = header[4];
bool savedDistanceL1 = header[5]==1;
float savedRebalancingFactor;
memcpy(&savedRebalancingFactor, &header[6], sizeof(header[6]));
int savedRows = header[7];
int savedCols = header[8];
int savedType = header[9];
unsigned int savedCrc;
memcpy(&savedCrc, &header[10], sizeof(header[10]));
int savedIndexSize = header[11];
UDEBUG("Header: \"%d.%d.%d\" alg=%d dim=%d L1=%d factor=%f data(%dx%d type=%d, crc=%X) %d",
header[0],header[1],header[2],
header[3],
header[4],
header[5],
savedRebalancingFactor,
header[7], header[8], header[9], savedCrc,
header[11]);
if(savedAlgorithm != algorithm) {
if(error) {
*error = uFormat("Serialized flann algorithm (%d) doesn't match the expected one (%d).", savedAlgorithm, algorithm);
}
return false;
}
if(savedDim != features.cols) {
if(error) {
*error = uFormat("Serialized feature dimension (%d) doesn't match the expected one (%d).", savedDim, features.cols);
}
return false;
}
if(savedDistanceL1 != useDistanceL1) {
if(error) {
*error = uFormat("Serialized \"use distance L1\" (%s) doesn't match the expected one (%s).", savedDistanceL1?"true":"false", useDistanceL1?"true":"false");
}
return false;
}
if(savedRebalancingFactor != rebalancingFactor) {
if(error) {
*error = uFormat("Serialized \"rebalancing factor\" (%f) doesn't match the expected one (%f).", savedRebalancingFactor, rebalancingFactor);
}
return false;
}
if(savedRows != features.rows) {
if(error) {
*error = uFormat("Serialized feature count (%d) doesn't match the expected one (%d).", savedRows, features.rows);
}
return false;
}
if(savedCols != features.cols) {
if(error) {
*error = uFormat("Serialized feature dimension (%d) doesn't match the expected one (%d).", savedCols, features.cols);
}
return false;
}
if(savedType != features.type()) {
if(error) {
*error = uFormat("Serialized feature type (%d) doesn't match the expected one (%d).", savedType, features.type());
}
return false;
}
if(savedCrc != 0) {
// Compute checksum and compare
boost::crc_32_type result;
result.process_bytes(features.data, features.total()*features.elemSize());
if(savedCrc != result.checksum()) {
if(error) {
*error = uFormat("Serialized feature crc (%X) doesn't match the expected one (%X).", savedCrc, result.checksum());
}
return false;
}
}
if(savedIndexSize != int(indexDataSize - headerSizeBytes)) {
if(error) {
*error = uFormat("Serialized flann index size (%ld) doesn't match the expected one (%ld).", savedIndexSize, indexDataSize - headerSizeBytes);
}
return false;
}
if(savedIndexSize == 0) {
if(error) {
*error = "Serialized flann index is empty.";
}
return false;
}
this->release(); this->release();
UASSERT(index_ == 0); UASSERT(index_ == 0);
UASSERT(features.type() == CV_32FC1 || features.type() == CV_8UC1); UASSERT(features.type() == CV_32FC1 || features.type() == CV_8UC1);
@@ -213,14 +496,39 @@ void FlannIndex::buildKDTreeIndex(
featuresDim_ = features.cols; featuresDim_ = features.cols;
useDistanceL1_ = useDistanceL1; useDistanceL1_ = useDistanceL1;
rebalancingFactor_ = rebalancingFactor; rebalancingFactor_ = rebalancingFactor;
algorithm_ = algorithm;
rtflann::KDTreeIndexParams params(trees); UDEBUG("algorithm=%d", (int)algorithm);
rtflann::IndexParams params;
switch (algorithm)
{
case FLANN_INDEX_LINEAR:
params = rtflann::LinearIndexParams();
break;
case FLANN_INDEX_KDTREE:
params = rtflann::KDTreeIndexParams(4);
break;
case FLANN_INDEX_KDTREE_SINGLE:
params = rtflann::KDTreeSingleIndexParams(10, true);
break;
case FLANN_INDEX_LSH:
UASSERT(features.type() == CV_8UC1);
params = rtflann::LshIndexParams(12, 20, 2);
break;
default:
UFATAL("The flann algorithm type %d is not supported!", (int)algorithm);
break;
}
FILE* indexDataPtr = fmemopen((void*)(indexData+headerSizeBytes), indexDataSize - headerSizeBytes, "r");
if(featuresType_ == CV_8UC1) if(featuresType_ == CV_8UC1)
{ {
rtflann::Matrix<unsigned char> dataset(features.data, features.rows, features.cols); rtflann::Matrix<unsigned char> dataset(features.data, features.rows, features.cols);
index_ = new rtflann::Index<rtflann::Hamming<unsigned char> >(dataset, params); index_ = new rtflann::Index<rtflann::Hamming<unsigned char> >(dataset, params);
((rtflann::Index<rtflann::Hamming<unsigned char> >*)index_)->buildIndex(); ((rtflann::Index<rtflann::Hamming<unsigned char> >*)index_)->load_saved_index(indexDataPtr);
} }
else else
{ {
@@ -228,22 +536,24 @@ void FlannIndex::buildKDTreeIndex(
if(useDistanceL1_) if(useDistanceL1_)
{ {
index_ = new rtflann::Index<rtflann::L1<float> >(dataset, params); index_ = new rtflann::Index<rtflann::L1<float> >(dataset, params);
((rtflann::Index<rtflann::L1<float> >*)index_)->buildIndex(); ((rtflann::Index<rtflann::L1<float> >*)index_)->load_saved_index(indexDataPtr);
} }
else if(featuresDim_ <=3) else if(featuresDim_ <=3)
{ {
index_ = new rtflann::Index<rtflann::L2_Simple<float> >(dataset, params); index_ = new rtflann::Index<rtflann::L2_Simple<float> >(dataset, params);
((rtflann::Index<rtflann::L2_Simple<float> >*)index_)->buildIndex(); ((rtflann::Index<rtflann::L2_Simple<float> >*)index_)->load_saved_index(indexDataPtr);
} }
else else
{ {
index_ = new rtflann::Index<rtflann::L2<float> >(dataset, params); index_ = new rtflann::Index<rtflann::L2<float> >(dataset, params);
((rtflann::Index<rtflann::L2<float> >*)index_)->buildIndex(); ((rtflann::Index<rtflann::L2<float> >*)index_)->load_saved_index(indexDataPtr);
} }
} }
fclose(indexDataPtr);
// incremental FLANN: we should add all headers separately in case we remove // incremental FLANN: we should add all headers separately in case we remove
// some indexes (to keep underlying matrix data allocated) // some indexes (to keep underlying matrix data allocated)
if(rebalancingFactor_ > 1.0f) if(rebalancingFactor_ > 1.0f)
{ {
for(int i=0; i<features.rows; ++i) for(int i=0; i<features.rows; ++i)
@@ -257,107 +567,8 @@ void FlannIndex::buildKDTreeIndex(
addedDescriptors_.insert(std::make_pair(nextIndex_, features)); addedDescriptors_.insert(std::make_pair(nextIndex_, features));
nextIndex_ += features.rows; nextIndex_ += features.rows;
} }
UDEBUG(""); return true;
} #endif
void FlannIndex::buildKDTreeSingleIndex(
const cv::Mat & features,
int leafMaxSize,
bool reorder,
bool useDistanceL1,
float rebalancingFactor)
{
UDEBUG("");
this->release();
UASSERT(index_ == 0);
UASSERT(features.type() == CV_32FC1 || features.type() == CV_8UC1);
featuresType_ = features.type();
featuresDim_ = features.cols;
useDistanceL1_ = useDistanceL1;
rebalancingFactor_ = rebalancingFactor;
rtflann::KDTreeSingleIndexParams params(leafMaxSize, reorder);
if(featuresType_ == CV_8UC1)
{
rtflann::Matrix<unsigned char> dataset(features.data, features.rows, features.cols);
index_ = new rtflann::Index<rtflann::Hamming<unsigned char> >(dataset, params);
((rtflann::Index<rtflann::Hamming<unsigned char> >*)index_)->buildIndex();
}
else
{
rtflann::Matrix<float> dataset((float*)features.data, features.rows, features.cols);
if(useDistanceL1_)
{
index_ = new rtflann::Index<rtflann::L1<float> >(dataset, params);
((rtflann::Index<rtflann::L1<float> >*)index_)->buildIndex();
}
else if(featuresDim_ <=3)
{
index_ = new rtflann::Index<rtflann::L2_Simple<float> >(dataset, params);
((rtflann::Index<rtflann::L2_Simple<float> >*)index_)->buildIndex();
}
else
{
index_ = new rtflann::Index<rtflann::L2<float> >(dataset, params);
((rtflann::Index<rtflann::L2<float> >*)index_)->buildIndex();
}
}
// incremental FLANN: we should add all headers separately in case we remove
// some indexes (to keep underlying matrix data allocated)
if(rebalancingFactor_ > 1.0f)
{
for(int i=0; i<features.rows; ++i)
{
addedDescriptors_.insert(std::make_pair(nextIndex_++, features.row(i)));
}
}
else
{
// tree won't ever be rebalanced, so just keep only one header for the data
addedDescriptors_.insert(std::make_pair(nextIndex_, features));
nextIndex_ += features.rows;
}
UDEBUG("");
}
void FlannIndex::buildLSHIndex(
const cv::Mat & features,
unsigned int table_number,
unsigned int key_size,
unsigned int multi_probe_level,
float rebalancingFactor)
{
UDEBUG("");
this->release();
UASSERT(index_ == 0);
UASSERT(features.type() == CV_8UC1);
featuresType_ = features.type();
featuresDim_ = features.cols;
useDistanceL1_ = true;
rebalancingFactor_ = rebalancingFactor;
rtflann::Matrix<unsigned char> dataset(features.data, features.rows, features.cols);
index_ = new rtflann::Index<rtflann::Hamming<unsigned char> >(dataset, rtflann::LshIndexParams(12, 20, 2));
((rtflann::Index<rtflann::Hamming<unsigned char> >*)index_)->buildIndex();
// incremental FLANN: we should add all headers separately in case we remove
// some indexes (to keep underlying matrix data allocated)
if(rebalancingFactor_ > 1.0f)
{
for(int i=0; i<features.rows; ++i)
{
addedDescriptors_.insert(std::make_pair(nextIndex_++, features.row(i)));
}
}
else
{
// tree won't ever be rebalanced, so just keep only one header for the data
addedDescriptors_.insert(std::make_pair(nextIndex_, features));
nextIndex_ += features.rows;
}
UDEBUG("");
} }
bool FlannIndex::isBuilt() bool FlannIndex::isBuilt()

Some files were not shown because too many files have changed in this diff Show More