Compare commits

..
75 Commits
Author SHA1 Message Date
matlabbe a58ec494d1 icpCC: when force3DoF is true, set z to 0 in data conversion 2021-03-28 09:28:55 -04:00
matlabbe 69735b6271 Added removeNaNFromPointCloud for PCLPointCloud2 type 2021-03-28 00:15:47 -04:00
matlabbe d002711f21 reprocess tool: Updated usage description to upgrade db version 2021-03-27 16:21:52 -04:00
matlabbe 06e85e140c Refactored RegistrationIcp: libpointmatcher yaml config usage / integrated CCCoreLib (#704)
* Refactored RegistrationIcp so that libpointmatcher yaml can work with icp odometry (we can then avoid refiltering data with local map of F2M). All data filtering (including libpointmatcher DataFilters) are done at the beginning of the function.

* ICP: Restored ref and data scans order for libpointmatcher (seems more stable this way).

* Fixed compilation error without libpointmatcher

* CCCoreLib integration (Icp/Strategy=2). Icp/PMForce4DoF is now Icp/Force4DoF. Icp/PM is now Icp/Strategy. Icp/PMOutlierRatio is now Icp/OutlierRatio.

* Fixed build without CCCoreLib

* Cleanup RegistrationIcp from third party functions.

* Preferences: disable libpointmatcher and cccorlib options if not available
2021-03-27 15:11:20 -04:00
matlabbe c4d127cae4 Export: added more options for pose format and image file name. 2021-03-21 19:05:24 -04:00
matlabbe 21737f9937 Added description fo RGBD/Enabled parameter 2021-03-17 23:58:12 -04:00
matlabbe ccc519ec58 Export: added --output name option. 2021-03-13 20:58:10 -05:00
matlabbe 1e4b172a7d Export: added poisson polygon size option 2021-03-13 19:01:09 -05:00
matlabbe 752509fb15 Rtabmap::detectMoreLoopClosures: added clusterRadiusMin parameter and update optimized poses after each accepted loop closure (also in MainWindow) like in DbViewer. Added graph::computeMinMax(poses). OdometryInfo: added guess transform. Export: added min/max axis ranges to filter nodes before expoting clouds. 2021-03-13 18:42:13 -05:00
matlabbe f6e17be2b4 Added ViewPlane XY, XZ and YZ options to GraphViewer
Parameter RGBD/SavedLocalizationIgnored now called RGBD/StartAtOrigin (updated description, used only in localization mode)
IcpReg: if Force4DoF, set lower covariance values for roll and pitch
DbViewer: updated detectMoreLoopClosures with new minRadius option and update optimized poses between each new accepted loop closures.
MainWindow: suppressed warning if depth image is not found in current node data (when rgb is).
3D Map view: changed default map point size to 1 (was 2)
2021-03-12 17:47:36 -05:00
matlabbe da2e2f810c Updated images 2021-03-09 17:48:40 -05:00
matlabbe 5b44c557b3 Update README.md 2021-03-09 17:44:39 -05:00
matlabbe 600d68932d updated images 2021-03-09 17:43:27 -05:00
matlabbe 800d087b07 Added archive directory to put paper related scripts 2021-03-09 17:08:42 -05:00
matlabbe db43479e44 Added ORB_SLAM3 support. IMU Filter: added base frame conversion option. (#698)
Referred issues:
#655
https://github.com/introlab/rtabmap_ros/issues/492

Note: IMU not supported yet with ORB_SLAM3.

Commits:
* Added orbslam3 support. UI-Source->IMU filtering: Added base frame conversion option of IMU data to uniformize yaw initialization. Madgwick: fixed yaw initialization accordingly to Z acc.

* fixed regression build error with ORB_SLAM2

* Renamed OdometryORBSLAM2 to OdometryORBSLAM (can be 2 or 3 now)
2021-03-09 16:00:41 -05:00
matlabbe 736c8aceae Export tool: show an error if file doesn't exist 2021-03-09 14:06:33 -05:00
matlabbe 351c659beb Integrated DepthAI (gen2) (#696)
* Added OAK-D camera support (DepthAI)

* Fixed build without DepthAI dependency

* Added minimum version 2 for depthai

* fixed trusty build
2021-03-07 12:27:21 -05:00
matlabbe ab8f0e2b34 Fixed #695 (footprint not cleared correctly when GridGlobal/OccupancyThr>0) 2021-03-05 18:35:49 -05:00
matlabbe 4f46d8e904 Updated some RGBD/Proximity**** parameter descriptions. Added parameter RGBD/LoopClosureIdentityGuess. Fixed local map cleared in localization when RGBD/SavedLocalizationIgnored is true (should then assume it is starting from origin). 2021-03-04 11:26:35 -05:00
matlabbe 98c69c4578 Fixed Force4DoF param not used exception on older libpointmatcher versions 2021-03-02 17:27:25 -05:00
matlabbe 4e4207a6dd CMake: updated to support latest g2oConfig.cmake (using targets) 2021-03-02 18:17:09 +00:00
matlabbe ea4cc7cb6c Refactored how IMU is used in odometry (if guess is not set, use imu orientation for guess). Changed canProcessIMU() to canProcessAsynIMU() to make it more clear for odometry approaches able to process IMU between image frames (VIO approaches). ZedOC: fixed device closed if imu is not detected. 2021-03-01 19:27:24 -05:00
matlabbe f7bc47572b Parameters: Icp/VoxelSize default updated from 0 to 0.05 2021-03-01 11:22:40 -05:00
matlabbe d119487dd7 Coloring scan (camera projection on point cloud) (#693)
* ExportClouds: Added camera projection options

* ExportClouds: fixed ceiling/floor filtering options not saved in config

* ExportClouds: fixed colorless scan points still exported when option is unchecked.

* Export tool: added --bin, --poses, --images, --las and --cam_projection options; export with intensity with --scan option. PDALWriter: added binary option (only used for PLY an PCD formats). Rtabmap: Do graph optimization if neighbor link refined and Mem/UseOdomGravity is used.
2021-03-01 09:56:37 -05:00
matlabbe 967c57d165 Added CameraStereoZedOC (Zed Open Capture driver).
* Added CameraStereoZedOC (Zed Open Capture driver). Calibration: added stereo baseline option, show warning if fx is very different after stereo calibration.

* Fixed build without Zed Open Capture. Fixed "any" prefix added to all tools when WITH_ZEDOC=ON. UI: fixed Zed Open Capture action not disabled when not built with it.
2021-02-28 10:31:18 -05:00
matlabbe 862eb0a90a CameraStereoVideo: added resolution options for usb camera 2021-02-25 22:22:44 -05:00
matlabbe cad184e82b Added Icp/PMForce4DoF parameter (works only with libpointmatcher > April 2020). Fixed some deprecated warnings. 2021-02-24 09:43:22 -05:00
matlabbe d61e463595 Updated About dialog with opencv license 2021-02-21 13:59:36 -05:00
matlabbe 5cdb346a35 Updated opencv license to Apache2 when version >= 4.5 2021-02-21 13:03:19 -05:00
matlabbe 8696a38343 Added parameter GridGlobal/AltitudeDelta 2021-02-21 13:00:16 -05:00
matlabbe e59aad03ed Fixed android build with latest laserScanFromPointCloud changes 2021-02-19 14:25:34 +00:00
matlabbe 9bf12742b1 fixed #688 2021-02-18 21:04:00 -05:00
matlabbe bb7e9edb9b Fixed create2DMap assert on 32FC2 when subscribing 2D scans with intensity. LaserScan: fixed assert when angle_min > angle_max (with angle_increment < 0) 2021-02-16 10:47:31 -05:00
matlabbe f871e4359d Fixed optimized map cleared when optimized graph is smaller than WM (poses should still refer to nodes in WM). Removed warning about max scan points smaller than actual scan (this can happen when assembling scans for proximity detection). Lowering default Icp/PMOutlierRatio to 0.85. 2021-02-12 18:40:40 -05:00
matlabbe 03cfaf2063 DBViewer: Added option to export odometry poses 2021-02-12 11:22:02 -05:00
matlabbe 089441a496 Fixed loadScan return 2D cloud for organized PCD 2021-02-10 21:35:09 -05:00
matlabbe 481a140f84 util3d: Refactored laserScanFromPointCloud() functions to return LaserScan with correct format instead of cv::Mat. 2021-02-07 17:27:55 -05:00
matlabbe c42a4e3d7e Fixed assert when loading database having optimized poses different from the working memory (force re-update graph in this case). 2021-02-06 15:10:18 -05:00
matlabbe c1a22609f3 Extract images: added timestamp.jpg/.png filname options (to match RGBD-SLAM pose format). Fixed wrong calibration file when first node is an intermdediate node. Export poses: ignore intermediate nodes when output frame is camera or scan. 2021-02-02 09:36:12 -05:00
matlabbe b759b1b4d1 DBReader: set calibrated true when only scans in db. RegIcp: added intensity matching option when complexity is low. OdomF2M: accept first key frame on low complexity if a guess is provided. DbViewer: added gravity visualization in 3D view. 2021-02-01 11:31:45 -05:00
matlabbe 6b119c1f90 Camera test view: show intensity/rgb/normals if input scans have them 2021-01-25 17:16:46 -05:00
matlabbe 7e298e1999 CameraImages: timestamp file is optional for pose format containing stamp 2021-01-25 13:21:39 -05:00
matlabbe c9472962d7 bumpt 0.20.9 version 2021-01-24 13:48:05 -05:00
matlabbe 4d75361fe0 CameraImages: support scan only dataset. 2021-01-24 13:21:30 -05:00
matlabbe e99c658276 fixed scan-only nodes wrongly set as intermediate nodes by default 2021-01-24 11:35:48 -05:00
matlabbe 57326214f1 Fixed texture projection when fx!=fy, cx!=w/2 or cy!=h/2 2021-01-24 10:39:36 -05:00
matlabbe 47e40ef34d MainWindow: add fake frustum when only lidar is received 2021-01-22 12:51:47 -05:00
matlabbe aa31a900fb fixed trusty build (#682)
* fixed trusty build (g2o backward compatibility)
2021-01-20 22:54:48 -05:00
matlabbe 28e624e6b2 fixed g2o build with c++14 #681 2021-01-20 10:45:45 -05:00
matlabbe 731b073ed8 Cleanup ObjDeletionHandler not used. Zed: fixed assert "qual >= sl::DEPTH_MODE::NONE && qual < sl::DEPTH_MODE::LAST" with latest sdk. 2021-01-19 17:24:38 -05:00
matlabbe 5d777469ff CameraRealSense2: refactored for freezing/crash issues on stop 2021-01-18 14:58:33 -05:00
matlabbe 70e9dff7da L515: downscale depth image if it has been upscaled during registration, fixed depth not correctly scaled in IR mode 2021-01-18 11:33:10 -05:00
matlabbe 814a243693 Add boost link dir on Windows #678 2021-01-17 15:06:47 -05:00
matlabbe c49785061f Added PyDetector (#677)
* Added PyDetector. Refactored PyMatcher.

* Fixed python freezing with multi-threading
2021-01-17 01:56:27 -05:00
matlabbe 0bc483b6d3 Added pdal optional dependency (export to LAS, E57, ...) 2021-01-14 15:49:18 -05:00
matlabbe eae5f2b428 fixed #674 2021-01-11 11:38:31 -05:00
matlabbe 94cf1dfd32 Fixed zero-ed 3D words when receiving odometry's 2D keypoints > Kp/MaxFeatures and empty 3D points 2021-01-09 20:52:34 -05:00
matlabbe 1a967127d9 Bump 0.20.8 version. Parameters: updated default of Vis/CorGuessWinSize=40 (was 20), GFTT/MinDistance=7 (was 3), Optimizer/GravitySigma=0.3 if built with g2o or gtsam. Those parameters help for smooth tracking on latest sensors with higher resolution and use IMU by default if available. Updated docker jfr2018 to use original parameters. CameraStereoZed: wait for imu to be available before sending frames (Zed-m and Zed2). 2021-01-08 13:04:24 -05:00
matlabbe 792c967d46 MainWindow: added driver options to differentiate between cameras having IMU or not (D400 vs D435i, ZED vs Zedm and Zed2). Enabled imu filtering by default for Freenect driver (Kinect XBOX360). 2021-01-08 01:10:23 -05:00
matlabbe a67dbc26f2 L515 refactoring (realsense v2.41.0, firmware 1.5.3): added IR-only mode support, fixed support with latest firmware, T265+L515 working, related to #574 #614 #629. MainWindow: Selecting RealSense2, ZED sdk, K4A, Mynteye drivers automatically enable gravity optimization (with IMU filtering). 2021-01-08 00:01:08 -05:00
matlabbe f1993d9cd7 android: fixed z-fighting on some android devices 2021-01-02 18:14:55 -05:00
matlabbe da99d7e4a0 disabled osx travis build (too long to do) 2020-12-20 00:07:34 -05:00
matlabbe e896ffb5c0 Update .travis.yml 2020-12-19 23:16:28 -05:00
matlabbe 04cbf56cc0 Update .travis.yml 2020-12-19 22:37:13 -05:00
matlabbe c5051bf82a Update .travis.yml 2020-12-19 21:38:13 -05:00
matlabbe 7a9f01b9a3 Update .travis.yml 2020-12-19 12:55:12 -05:00
matlabbe 70094edb75 Update .travis.yml 2020-12-19 12:38:36 -05:00
matlabbe eb2af19a89 Update .travis.yml 2020-12-19 12:28:02 -05:00
matlabbe af227bad51 Update .travis.yml 2020-12-19 12:21:25 -05:00
matlabbe ee63ce338a Update .travis.yml 2020-12-19 12:11:19 -05:00
matlabbe 1b3a6abb82 Update .travis.yml 2020-12-19 11:48:06 -05:00
matlabbe 4a8a20c7d1 Update .travis.yml 2020-12-19 11:24:19 -05:00
matlabbe a125797e50 Update .travis.yml
Added osx
2020-12-19 11:18:20 -05:00
matlabbe a6f0877045 Parameters: added Rtabmap/ImagesAlreadyRectified to odometry parameters (to be shown with --params) 2020-12-18 17:57:43 -05:00
matlabbe b5cae38eb9 Fixed -lBoost:timer not defined when building with latest GTSAM binaries 2020-12-18 17:01:11 -05:00
166 changed files with 12509 additions and 4630 deletions
+33 -26
View File
@@ -1,14 +1,19 @@
sudo: true
language: cpp language: cpp
group: deprecated-2017Q3
compiler: jobs:
- gcc
matrix:
include: include:
# - name: osx
# compiler: clang
# os: osx
# install:
# - brew install sqlite
# - brew install pcl
# - brew install opencv@3
- dist: trusty - name: linux-trusty
compiler: gcc
os: linux
dist: trusty
install: install:
- sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu trusty main" > /etc/apt/sources.list.d/ros-latest.list' - sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu trusty main" > /etc/apt/sources.list.d/ros-latest.list'
- wget http://packages.ros.org/ros.key -O - | sudo apt-key add - - wget http://packages.ros.org/ros.key -O - | sudo apt-key add -
@@ -17,13 +22,13 @@ matrix:
- sudo apt-get -y install ros-indigo-rtabmap-ros - sudo apt-get -y install ros-indigo-rtabmap-ros
- sudo apt-get -y remove ros-indigo-rtabmap - sudo apt-get -y remove ros-indigo-rtabmap
script: before_script:
- source /opt/ros/indigo/setup.bash - source /opt/ros/indigo/setup.bash
- mkdir -p build && cd build
- cmake ..
- make
- dist: xenial - name: linux-xenial
compiler: gcc
os: linux
dist: xenial
install: install:
- sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu xenial main" > /etc/apt/sources.list.d/ros-latest.list' - sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu xenial main" > /etc/apt/sources.list.d/ros-latest.list'
- wget http://packages.ros.org/ros.key -O - | sudo apt-key add - - wget http://packages.ros.org/ros.key -O - | sudo apt-key add -
@@ -32,13 +37,13 @@ matrix:
- sudo apt-get -y install ros-kinetic-rtabmap-ros - sudo apt-get -y install ros-kinetic-rtabmap-ros
- sudo apt-get -y remove ros-kinetic-rtabmap - sudo apt-get -y remove ros-kinetic-rtabmap
script: before_script:
- source /opt/ros/kinetic/setup.bash - source /opt/ros/kinetic/setup.bash
- mkdir -p build && cd build
- cmake ..
- make
- dist: bionic - name: linux-bionic
compiler: gcc
os: linux
dist: bionic
install: install:
- sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu bionic main" > /etc/apt/sources.list.d/ros-latest.list' - sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu bionic main" > /etc/apt/sources.list.d/ros-latest.list'
- wget http://packages.ros.org/ros.key -O - | sudo apt-key add - - wget http://packages.ros.org/ros.key -O - | sudo apt-key add -
@@ -47,13 +52,13 @@ matrix:
- sudo apt-get -y install ros-melodic-rtabmap-ros - sudo apt-get -y install ros-melodic-rtabmap-ros
- sudo apt-get -y remove ros-melodic-rtabmap - sudo apt-get -y remove ros-melodic-rtabmap
script: before_script:
- source /opt/ros/melodic/setup.bash - source /opt/ros/melodic/setup.bash
- mkdir -p build && cd build
- cmake ..
- make
- dist: focal - name: linux-focal
compiler: gcc
os: linux
dist: focal
install: install:
- sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu focal main" > /etc/apt/sources.list.d/ros-latest.list' - sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu focal main" > /etc/apt/sources.list.d/ros-latest.list'
- wget http://packages.ros.org/ros.key -O - | sudo apt-key add - - wget http://packages.ros.org/ros.key -O - | sudo apt-key add -
@@ -62,11 +67,13 @@ matrix:
- sudo apt-get -y install ros-noetic-rtabmap-ros - sudo apt-get -y install ros-noetic-rtabmap-ros
- sudo apt-get -y remove ros-noetic-rtabmap - sudo apt-get -y remove ros-noetic-rtabmap
script: before_script:
- source /opt/ros/noetic/setup.bash - source /opt/ros/noetic/setup.bash
- mkdir -p build && cd build
- cmake .. script:
- make - mkdir -p build && cd build
- cmake ..
- make
notifications: notifications:
email: email:
+186 -84
View File
@@ -21,7 +21,7 @@ SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
####################### #######################
SET(RTABMAP_MAJOR_VERSION 0) SET(RTABMAP_MAJOR_VERSION 0)
SET(RTABMAP_MINOR_VERSION 20) SET(RTABMAP_MINOR_VERSION 20)
SET(RTABMAP_PATCH_VERSION 7) SET(RTABMAP_PATCH_VERSION 9)
SET(RTABMAP_VERSION SET(RTABMAP_VERSION
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION}) ${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})
@@ -163,8 +163,10 @@ ELSE()
option(WITH_QT "Include Qt support" ON) option(WITH_QT "Include Qt support" ON)
ENDIF() ENDIF()
option(WITH_ORB_OCTREE "Include ORB Octree feature support" ON) option(WITH_ORB_OCTREE "Include ORB Octree feature support" ON)
option(WITH_SUPERPOINT_TORCH "Include SuperPoint Torch feature support" ON) option(WITH_TORCH "Include Torch support (SuperPoint)" OFF)
option(WITH_PYMATCHER "Include Python3 matchers support" OFF) option(WITH_PYTHON "Include Python3 support (PyMatcher, PyDetector)" OFF)
option(WITH_PYTHON_THREADING "Use more than one Python interpreter." OFF)
option(WITH_PDAL "Include PDAL support" ON)
option(WITH_FREENECT "Include Freenect support" ON) option(WITH_FREENECT "Include Freenect support" ON)
option(WITH_FREENECT2 "Include Freenect2 support" ON) option(WITH_FREENECT2 "Include Freenect2 support" ON)
option(WITH_K4W2 "Include Kinect for Windows v2 support" ON) option(WITH_K4W2 "Include Kinect for Windows v2 support" ON)
@@ -178,13 +180,16 @@ option(WITH_CERES "Include Ceres support" ON)
option(WITH_VERTIGO "Include Vertigo support" ON) option(WITH_VERTIGO "Include Vertigo support" ON)
option(WITH_CVSBA "Include cvsba support" ON) option(WITH_CVSBA "Include cvsba support" ON)
option(WITH_POINTMATCHER "Include libpointmatcher support" ON) option(WITH_POINTMATCHER "Include libpointmatcher support" ON)
option(WITH_CCCORELIB "Include CCCoreLib support" ON)
option(WITH_LOAM "Include LOAM support" ON) option(WITH_LOAM "Include LOAM support" ON)
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_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 RealSense 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" ON)
option(WITH_OCTOMAP "Include Octomap support" ON) option(WITH_OCTOMAP "Include Octomap support" ON)
option(WITH_CPUTSDF "Include CPUTSDF support" ON) option(WITH_CPUTSDF "Include CPUTSDF support" ON)
option(WITH_OPENCHISEL "Include open_chisel support" ON) option(WITH_OPENCHISEL "Include open_chisel support" ON)
@@ -192,7 +197,7 @@ option(WITH_ALICE_VISION "Include AliceVision support" OFF)
option(WITH_FOVIS "Include FOVIS support" ON) option(WITH_FOVIS "Include FOVIS support" ON)
option(WITH_VISO2 "Include VISO2 support" ON) option(WITH_VISO2 "Include VISO2 support" ON)
option(WITH_DVO "Include DVO support" ON) option(WITH_DVO "Include DVO support" ON)
option(WITH_ORB_SLAM2 "Include ORB_SLAM2 support" ON) option(WITH_ORB_SLAM "Include ORB_SLAM2 or ORB_SLAM3 support" ON)
option(WITH_OKVIS "Include OKVIS support" ON) option(WITH_OKVIS "Include OKVIS support" ON)
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" ON) option(WITH_VINS "Include VINS-Fusion support" ON)
@@ -322,19 +327,26 @@ IF(WITH_QT)
ENDIF(QT4_FOUND OR Qt5_FOUND) ENDIF(QT4_FOUND OR Qt5_FOUND)
ENDIF(WITH_QT) ENDIF(WITH_QT)
IF(WITH_SUPERPOINT_TORCH) IF(WITH_TORCH)
FIND_PACKAGE(Torch QUIET) FIND_PACKAGE(Torch QUIET)
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)
ENDIF(WITH_SUPERPOINT_TORCH) ENDIF(WITH_TORCH)
IF(WITH_PYMATCHER) IF(WITH_PYTHON)
FIND_PACKAGE(Python3 COMPONENTS Interpreter Development) FIND_PACKAGE(Python3 COMPONENTS Interpreter Development)
IF(Python3_FOUND) IF(Python3_FOUND)
MESSAGE(STATUS "Found Python3") MESSAGE(STATUS "Found Python3")
ENDIF(Python3_FOUND) ENDIF(Python3_FOUND)
ENDIF(WITH_PYMATCHER) ENDIF(WITH_PYTHON)
IF(WITH_PDAL)
FIND_PACKAGE(PDAL QUIET)
IF(PDAL_FOUND)
MESSAGE(STATUS "Found PDAL ${PDAL_VERSION}: ${PDAL_INCLUDE_DIRS}")
ENDIF(PDAL_FOUND)
ENDIF(WITH_PDAL)
IF(WITH_FREENECT) IF(WITH_FREENECT)
FIND_PACKAGE(Freenect QUIET) FIND_PACKAGE(Freenect QUIET)
@@ -402,7 +414,14 @@ IF(WITH_G2O)
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}")
ENDIF(G2O_FOUND) ELSE()
FIND_PACKAGE(g2o QUIET)
IF(g2o_FOUND)
SET(G2O_FOUND ${g2o_FOUND})
SET(G2O_CPP11 1)
MESSAGE(STATUS "Found g2o (targets)")
ENDIF(g2o_FOUND)
ENDIF()
ENDIF(WITH_G2O) ENDIF(WITH_G2O)
IF(WITH_GTSAM) IF(WITH_GTSAM)
@@ -427,14 +446,28 @@ ENDIF(WITH_CVSBA)
IF(WITH_POINTMATCHER) IF(WITH_POINTMATCHER)
find_package(libpointmatcher QUIET) find_package(libpointmatcher QUIET)
IF(libpointmatcher_FOUND) IF(libpointmatcher_FOUND)
find_package(Boost COMPONENTS thread filesystem system program_options date_time REQUIRED)
if (Boost_MINOR_VERSION GREATER 47)
find_package(Boost COMPONENTS thread filesystem system program_options date_time chrono timer REQUIRED)
endif (Boost_MINOR_VERSION GREATER 47)
MESSAGE(STATUS "Found libpointmatcher: ${libpointmatcher_INCLUDE_DIRS}") MESSAGE(STATUS "Found libpointmatcher: ${libpointmatcher_INCLUDE_DIRS}")
ENDIF(libpointmatcher_FOUND) ENDIF(libpointmatcher_FOUND)
ENDIF(WITH_POINTMATCHER) ENDIF(WITH_POINTMATCHER)
IF(libpointmatcher_FOUND OR GTSAM_FOUND)
find_package(Boost COMPONENTS thread filesystem system program_options date_time REQUIRED)
IF(Boost_MINOR_VERSION GREATER 47)
find_package(Boost COMPONENTS thread filesystem system program_options date_time chrono timer REQUIRED)
ENDIF(Boost_MINOR_VERSION GREATER 47)
IF(WIN32)
MESSAGE(STATUS "Boost_LIBRARY_DIRS=${Boost_LIBRARY_DIRS}")
link_directories(${Boost_LIBRARY_DIRS})
ENDIF(WIN32)
ENDIF(libpointmatcher_FOUND OR GTSAM_FOUND)
IF(WITH_CCCORELIB)
find_package(CCCoreLib QUIET)
IF(CCCoreLib_FOUND)
MESSAGE(STATUS "Found CCCoreLib: ${CCCoreLib_INCLUDE_DIRS}")
ENDIF(CCCoreLib_FOUND)
ENDIF(WITH_CCCORELIB)
IF(WITH_LOAM) IF(WITH_LOAM)
find_package(loam_velodyne QUIET) find_package(loam_velodyne QUIET)
IF(loam_velodyne_FOUND) IF(loam_velodyne_FOUND)
@@ -458,6 +491,20 @@ IF(WITH_ZED)
ENDIF(ZED_FOUND) ENDIF(ZED_FOUND)
ENDIF(WITH_ZED) ENDIF(WITH_ZED)
IF(WITH_ZEDOC)
find_package(ZEDOC QUIET)
IF(ZEDOC_FOUND)
MESSAGE(STATUS "Found ZED Open Capture: ${ZEDOC_INCLUDE_DIRS}")
## look for HIDAPI
find_package(HIDAPI)
IF(HIDAPI_FOUND)
MESSAGE(STATUS "Found HIDAPI: ${HIDAPI_INCLUDE_DIRS}")
ELSE()
MESSAGE(FATAL_ERROR "HIDAPI is required to build with Zed Open Capture! Set -DWITH_ZEDOC=OFF if you don't have HIDAPI.")
ENDIF()
ENDIF(ZEDOC_FOUND)
ENDIF(WITH_ZEDOC)
IF(WITH_REALSENSE) IF(WITH_REALSENSE)
IF(WITH_REALSENSE_SLAM) IF(WITH_REALSENSE_SLAM)
FIND_PACKAGE(RealSense QUIET COMPONENTS slam) FIND_PACKAGE(RealSense QUIET COMPONENTS slam)
@@ -490,6 +537,13 @@ IF(WITH_MYNTEYE)
ENDIF(mynteye_FOUND) ENDIF(mynteye_FOUND)
ENDIF(WITH_MYNTEYE) ENDIF(WITH_MYNTEYE)
IF(WITH_DEPTHAI)
FIND_PACKAGE(depthai 2 QUIET)
IF(depthai_FOUND)
MESSAGE(STATUS "Found depthai-core (targets)")
ENDIF(depthai_FOUND)
ENDIF(WITH_DEPTHAI)
IF(WITH_OCTOMAP) IF(WITH_OCTOMAP)
FIND_PACKAGE(octomap QUIET) FIND_PACKAGE(octomap QUIET)
IF(octomap_FOUND) IF(octomap_FOUND)
@@ -588,59 +642,53 @@ IF(WITH_FASTCV)
ENDIF(FastCV_FOUND) ENDIF(FastCV_FOUND)
ENDIF(WITH_FASTCV) ENDIF(WITH_FASTCV)
IF(WITH_ORB_SLAM2 AND NOT G2O_FOUND) IF(WITH_ORB_SLAM AND NOT G2O_FOUND)
FIND_PACKAGE(ORB_SLAM2 QUIET) FIND_PACKAGE(ORB_SLAM QUIET)
IF(ORB_SLAM2_FOUND) IF(ORB_SLAM_FOUND)
MESSAGE(STATUS "Found ORB_SLAM2: ${ORB_SLAM2_INCLUDE_DIRS}") MESSAGE(STATUS "Found ORB_SLAM${ORB_SLAM_VERSION}: ${ORB_SLAM_INCLUDE_DIRS}")
FIND_PACKAGE(Pangolin QUIET) ENDIF(ORB_SLAM_FOUND)
IF(NOT Pangolin_FOUND) ENDIF(WITH_ORB_SLAM AND NOT G2O_FOUND)
SET(ORB_SLAM2_FOUND FALSE)
MESSAGE(STATUS "Found ORB_SLAM2 but not Pangolin, disabling ORB_SLAM2.")
ELSE()
MESSAGE(STATUS "Found Pangolin: ${Pangolin_INCLUDE_DIRS}")
SET(ORB_SLAM2_INCLUDE_DIRS ${ORB_SLAM2_INCLUDE_DIRS} ${Pangolin_INCLUDE_DIRS})
SET(ORB_SLAM2_LIBRARIES ${ORB_SLAM2_LIBRARIES} ${Pangolin_LIBRARIES})
ENDIF()
ENDIF(ORB_SLAM2_FOUND)
ENDIF(WITH_ORB_SLAM2 AND NOT G2O_FOUND)
IF(loam_velodyne_FOUND OR PCL_VERSION VERSION_GREATER "1.9.1" OR TORCH_FOUND) IF(NOT MSVC)
#LOAM and PCL>=1.10 require c++14 IF(loam_velodyne_FOUND OR PCL_VERSION VERSION_GREATER "1.9.1" OR TORCH_FOUND OR G2O_FOUND OR CCCoreLib_FOUND)
IF(NOT MSVC) #LOAM, PCL>=1.10, latest g2o and CCCoreLib require c++14
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14) CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14)
IF(COMPILER_SUPPORTS_CXX14) IF(COMPILER_SUPPORTS_CXX14)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
ELSE() set(CMAKE_CXX_STANDARD 14)
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++14 support. Please use a different C++ compiler if you want to use LOAM (set \"-DWITH_LOAM=OFF\" to build without LOAM).") ELSE()
ENDIF() message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++14 support. Please use a different C++ compiler if you want to use LOAM, latest PCL or g2o.")
ENDIF() ENDIF()
ELSEIF(G2O_FOUND OR ENDIF(loam_velodyne_FOUND OR PCL_VERSION VERSION_GREATER "1.9.1" OR TORCH_FOUND OR G2O_FOUND OR CCCoreLib_FOUND)
GTSAM_FOUND OR
CERES_FOUND OR IF( (NOT (${CMAKE_CXX_STANDARD} STREQUAL "14")) AND (
ZED_FOUND OR G2O_FOUND OR
ANDROID OR GTSAM_FOUND OR
RealSense_FOUND OR CERES_FOUND OR
realsense2_FOUND OR ZED_FOUND OR
ORB_SLAM2_FOUND OR ZEDOC_FOUND OR
okvis_FOUND OR ANDROID OR
open_chisel_FOUND OR RealSense_FOUND OR
msckf_vio_FOUND OR realsense2_FOUND OR
vins_FOUND OR ORB_SLAM_FOUND OR
libpointmatcher_FOUND) okvis_FOUND OR
#Newest versions require std11 open_chisel_FOUND OR
IF(NOT MSVC) msckf_vio_FOUND OR
include(CheckCXXCompilerFlag) vins_FOUND OR
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) libpointmatcher_FOUND))
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) #Newest versions require std11
IF(COMPILER_SUPPORTS_CXX11) include(CheckCXXCompilerFlag)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
ELSEIF(COMPILER_SUPPORTS_CXX0X) CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") IF(COMPILER_SUPPORTS_CXX11)
ELSE() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.") ELSEIF(COMPILER_SUPPORTS_CXX0X)
ENDIF() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
ENDIF() ELSE()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
ENDIF()
ENDIF()
ENDIF() ENDIF()
####### OSX BUNDLE CMAKE_INSTALL_PREFIX ####### ####### OSX BUNDLE CMAKE_INSTALL_PREFIX #######
@@ -724,9 +772,15 @@ ENDIF()
IF(NOT libpointmatcher_FOUND) IF(NOT libpointmatcher_FOUND)
SET(POINTMATCHER "//") SET(POINTMATCHER "//")
ENDIF(NOT libpointmatcher_FOUND) ENDIF(NOT libpointmatcher_FOUND)
IF(NOT CCCoreLib_FOUND)
SET(CCCORELIB "//")
ENDIF(NOT CCCoreLib_FOUND)
IF(NOT FastCV_FOUND) IF(NOT FastCV_FOUND)
SET(FASTCV "//") SET(FASTCV "//")
ENDIF(NOT FastCV_FOUND) ENDIF(NOT FastCV_FOUND)
IF(NOT PDAL_FOUND)
SET(PDAL "//")
ENDIF(NOT PDAL_FOUND)
IF(NOT loam_velodyne_FOUND) IF(NOT loam_velodyne_FOUND)
SET(LOAM "//") SET(LOAM "//")
ENDIF(NOT loam_velodyne_FOUND) ENDIF(NOT loam_velodyne_FOUND)
@@ -770,6 +824,11 @@ IF(NOT ZED_FOUND)
ELSE() ELSE()
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${ZED_LIBRARIES} ${CUDA_LIBRARIES}) SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${ZED_LIBRARIES} ${CUDA_LIBRARIES})
ENDIF() ENDIF()
IF(NOT ZEDOC_FOUND)
SET(ZEDOC "//")
ELSE()
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${ZEDOC_LIBRARIES})
ENDIF()
IF(NOT RealSense_FOUND) IF(NOT RealSense_FOUND)
SET(REALSENSE "//") SET(REALSENSE "//")
ELSE() ELSE()
@@ -786,6 +845,9 @@ ENDIF()
IF(NOT mynteye_FOUND) IF(NOT mynteye_FOUND)
SET(MYNTEYE "//") SET(MYNTEYE "//")
ENDIF(NOT mynteye_FOUND) ENDIF(NOT mynteye_FOUND)
IF(NOT depthai_FOUND)
SET(DEPTHAI "//")
ENDIF(NOT depthai_FOUND)
IF(NOT octomap_FOUND) IF(NOT octomap_FOUND)
SET(OCTOMAP "//") SET(OCTOMAP "//")
ELSE() ELSE()
@@ -834,19 +896,19 @@ IF(NOT vins_FOUND)
ELSE() ELSE()
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${vins_LIBRARIES}) SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${vins_LIBRARIES})
ENDIF() ENDIF()
IF(NOT ORB_SLAM2_FOUND) IF(NOT ORB_SLAM_FOUND)
SET(ORB_SLAM2 "//") SET(ORB_SLAM "//")
ELSE() ELSE()
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${ORB_SLAM2_LIBRARIES}) SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${ORB_SLAM_LIBRARIES})
ENDIF() ENDIF()
IF(NOT WITH_ORB_OCTREE) IF(NOT WITH_ORB_OCTREE)
SET(ORB_OCTREE "//") SET(ORB_OCTREE "//")
ENDIF() ENDIF()
IF(NOT TORCH_FOUND) IF(NOT TORCH_FOUND)
SET(SUPERPOINT_TORCH "//") SET(TORCH "//")
ENDIF() ENDIF()
IF(NOT Python3_FOUND) IF(NOT Python3_FOUND)
SET(PYMATCHER "//") SET(PYTHON "//")
ENDIF() ENDIF()
IF(ADD_VTK_GUI_SUPPORT_QT_TO_CONF) IF(ADD_VTK_GUI_SUPPORT_QT_TO_CONF)
SET(CONF_VTK_QT true) SET(CONF_VTK_QT true)
@@ -1064,12 +1126,20 @@ IF(OpenCV_FOUND)
ELSE() ELSE()
IF(OPENCV_XFEATURES2D_FOUND) IF(OPENCV_XFEATURES2D_FOUND)
IF(NONFREE STREQUAL "//") IF(NONFREE STREQUAL "//")
MESSAGE(STATUS " *With OpenCV ${OpenCV_VERSION} xfeatures2d = YES, nonfree = NO (License: BSD)") 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)")
ELSE()
MESSAGE(STATUS " *With OpenCV ${OpenCV_VERSION} xfeatures2d = YES, nonfree = NO (License: Apache 2)")
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 (License: Non commercial)")
ENDIF() ENDIF()
ELSE() ELSE()
MESSAGE(STATUS " *With OpenCV ${OpenCV_VERSION} xfeatures2d = NO, nonfree = NO (License: BSD)") 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)")
ELSE()
MESSAGE(STATUS " *With OpenCV ${OpenCV_VERSION} xfeatures2d = NO, nonfree = NO (License: Apache 2)")
ENDIF()
ENDIF() ENDIF()
ENDIF() ENDIF()
ENDIF(OpenCV_FOUND) ENDIF(OpenCV_FOUND)
@@ -1101,18 +1171,18 @@ ENDIF()
IF(TORCH_FOUND) IF(TORCH_FOUND)
MESSAGE(STATUS " With SupertPoint = YES (License: GPLv3) libtorch=${Torch_VERSION}") MESSAGE(STATUS " With SupertPoint = YES (License: GPLv3) libtorch=${Torch_VERSION}")
ELSEIF(NOT WITH_SUPERPOINT_TORCH) ELSEIF(NOT WITH_TORCH)
MESSAGE(STATUS " With SupertPoint = NO (WITH_SUPERPOINT_TORCH=OFF)") MESSAGE(STATUS " With SupertPoint = NO (WITH_TORCH=OFF)")
ELSE() ELSE()
MESSAGE(STATUS " With SupertPoint = NO (libtorch not found)") MESSAGE(STATUS " With SupertPoint = NO (libtorch not found)")
ENDIF() ENDIF()
IF(Python3_FOUND) IF(Python3_FOUND)
MESSAGE(STATUS " With Python3 = YES (License: PSF)") MESSAGE(STATUS " With Python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR} = YES (License: PSF)")
ELSEIF(NOT WITH_PYMATCHER) ELSEIF(NOT WITH_PYTHON)
MESSAGE(STATUS " With Python3 = NO (WITH_PYMATCHER=OFF)") MESSAGE(STATUS " With Python3 = NO (WITH_PYTHON=OFF)")
ELSE() ELSE()
MESSAGE(STATUS " With Python3 = NO (python3 not found)") MESSAGE(STATUS " With Python3 = NO (python not found)")
ENDIF() ENDIF()
IF(WITH_MADGWICK) IF(WITH_MADGWICK)
@@ -1129,6 +1199,14 @@ ELSE()
MESSAGE(STATUS " With FastCV = NO (FastCV not found)") MESSAGE(STATUS " With FastCV = NO (FastCV not found)")
ENDIF() ENDIF()
IF(PDAL_FOUND)
MESSAGE(STATUS " With PDAL = YES (License: BSD)")
ELSEIF(NOT WITH_PDAL)
MESSAGE(STATUS " With PDAL = NO (WITH_PDAL=OFF)")
ELSE()
MESSAGE(STATUS " With PDAL = NO (PDAL not found)")
ENDIF()
MESSAGE(STATUS "") MESSAGE(STATUS "")
MESSAGE(STATUS " Solvers:") MESSAGE(STATUS " Solvers:")
IF(WITH_TORO) IF(WITH_TORO)
@@ -1187,6 +1265,14 @@ ELSE()
MESSAGE(STATUS " *With libpointmatcher = NO (libpointmatcher not found)") MESSAGE(STATUS " *With libpointmatcher = NO (libpointmatcher not found)")
ENDIF() ENDIF()
IF(CCCoreLib_FOUND)
MESSAGE(STATUS " *With CCCoreLib = YES (License: GPLv2)")
ELSEIF(NOT WITH_POINTMATCHER)
MESSAGE(STATUS " *With CCCoreLib = NO (WITH_CCCORELIB=OFF)")
ELSE()
MESSAGE(STATUS " *With CCCoreLib = NO (CCCoreLib not found)")
ENDIF()
MESSAGE(STATUS "") MESSAGE(STATUS "")
MESSAGE(STATUS " Reconstruction Approaches:") MESSAGE(STATUS " Reconstruction Approaches:")
IF(octomap_FOUND) IF(octomap_FOUND)
@@ -1287,6 +1373,14 @@ ELSE()
MESSAGE(STATUS " With ZED = NO (ZED sdk and/or cuda not found)") MESSAGE(STATUS " With ZED = NO (ZED sdk and/or cuda not found)")
ENDIF() ENDIF()
IF(ZEDOC_FOUND)
MESSAGE(STATUS " With ZEDOC = YES")
ELSEIF(NOT WITH_ZEDOC)
MESSAGE(STATUS " With ZEDOC = NO (WITH_ZEDOC=OFF)")
ELSE()
MESSAGE(STATUS " With ZEDOC = NO (ZED Open Capture not found)")
ENDIF()
IF(RealSense_FOUND) IF(RealSense_FOUND)
MESSAGE(STATUS " With RealSense = YES (License: Apache-2)") MESSAGE(STATUS " With RealSense = YES (License: Apache-2)")
IF(RealSenseSlam_FOUND) IF(RealSenseSlam_FOUND)
@@ -1318,6 +1412,14 @@ ELSE()
MESSAGE(STATUS " With MyntEyeS = NO (mynteye s sdk not found)") MESSAGE(STATUS " With MyntEyeS = NO (mynteye s sdk not found)")
ENDIF() ENDIF()
IF(depthai_FOUND)
MESSAGE(STATUS " With DepthAI = YES (License: MIT)")
ELSEIF(NOT WITH_DEPTHAI)
MESSAGE(STATUS " With DepthAI = NO (WITH_DEPTHAI=OFF)")
ELSE()
MESSAGE(STATUS " With DepthAI = NO (depthai-core not found)")
ENDIF()
MESSAGE(STATUS "") MESSAGE(STATUS "")
MESSAGE(STATUS " Odometry Approaches:") MESSAGE(STATUS " Odometry Approaches:")
IF(loam_velodyne_FOUND) IF(loam_velodyne_FOUND)
@@ -1376,14 +1478,14 @@ ELSE()
MESSAGE(STATUS " With VINS-Fusion = NO (VINS-Fusion not found)") MESSAGE(STATUS " With VINS-Fusion = NO (VINS-Fusion not found)")
ENDIF() ENDIF()
IF(ORB_SLAM2_FOUND) IF(ORB_SLAM_FOUND)
MESSAGE(STATUS " With ORB_SLAM2 = YES (License: GPLv3)") MESSAGE(STATUS " With ORB_SLAM${ORB_SLAM_VERSION} = YES (License: GPLv3)")
ELSEIF(NOT WITH_ORB_SLAM2) ELSEIF(NOT WITH_ORB_SLAM)
MESSAGE(STATUS " With ORB_SLAM2 = NO (WITH_ORB_SLAM2=OFF)") MESSAGE(STATUS " With ORB_SLAM = NO (WITH_ORB_SLAM=OFF)")
ELSEIF(G2O_FOUND) ELSEIF(G2O_FOUND)
MESSAGE(STATUS " With ORB_SLAM2 = NO (WITH_G2O should be OFF as ORB_SLAM2 uses its own g2o version)") MESSAGE(STATUS " With ORB_SLAM = NO (WITH_G2O should be OFF as ORB_SLAM uses its own g2o version)")
ELSE() ELSE()
MESSAGE(STATUS " With ORB_SLAM2 = NO (ORB_SLAM2 not found, make sure environment variable ORB_SLAM2_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()
MESSAGE(STATUS "Show all options with: cmake -LA | grep WITH_") MESSAGE(STATUS "Show all options with: cmake -LA | grep WITH_")
+7 -3
View File
@@ -51,15 +51,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@K4A@#define RTABMAP_K4A @K4A@#define RTABMAP_K4A
@CVSBA@#define RTABMAP_CVSBA @CVSBA@#define RTABMAP_CVSBA
@POINTMATCHER@#define RTABMAP_POINTMATCHER @POINTMATCHER@#define RTABMAP_POINTMATCHER
@CCCORELIB@#define RTABMAP_CCCORELIB
@FASTCV@#define RTABMAP_FASTCV @FASTCV@#define RTABMAP_FASTCV
@PDAL@#define RTABMAP_PDAL
@LOAM@#define RTABMAP_LOAM @LOAM@#define RTABMAP_LOAM
@DC1394@#define RTABMAP_DC1394 @DC1394@#define RTABMAP_DC1394
@FLYCAPTURE2@#define RTABMAP_FLYCAPTURE2 @FLYCAPTURE2@#define RTABMAP_FLYCAPTURE2
@ZED@#define RTABMAP_ZED @ZED@#define RTABMAP_ZED
@ZEDOC@#define RTABMAP_ZEDOC
@REALSENSE@#define RTABMAP_REALSENSE @REALSENSE@#define RTABMAP_REALSENSE
@REALSENSESLAM@#define RTABMAP_REALSENSE_SLAM @REALSENSESLAM@#define RTABMAP_REALSENSE_SLAM
@REALSENSE2@#define RTABMAP_REALSENSE2 @REALSENSE2@#define RTABMAP_REALSENSE2
@MYNTEYE@#define RTABMAP_MYNTEYE @MYNTEYE@#define RTABMAP_MYNTEYE
@DEPTHAI@#define RTABMAP_DEPTHAI
@OCTOMAP@#define RTABMAP_OCTOMAP @OCTOMAP@#define RTABMAP_OCTOMAP
@CPUTSDF@#define RTABMAP_CPUTSDF @CPUTSDF@#define RTABMAP_CPUTSDF
@ALICE_VISION@#define RTABMAP_ALICE_VISION @ALICE_VISION@#define RTABMAP_ALICE_VISION
@@ -70,10 +74,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@OKVIS@#define RTABMAP_OKVIS @OKVIS@#define RTABMAP_OKVIS
@MSCKF_VIO@#define RTABMAP_MSCKF_VIO @MSCKF_VIO@#define RTABMAP_MSCKF_VIO
@VINS@#define RTABMAP_VINS @VINS@#define RTABMAP_VINS
@ORB_SLAM2@#define RTABMAP_ORB_SLAM2 @ORB_SLAM@#define RTABMAP_ORB_SLAM @ORB_SLAM_VERSION@
@ORB_OCTREE@#define RTABMAP_ORB_OCTREE @ORB_OCTREE@#define RTABMAP_ORB_OCTREE
@SUPERPOINT_TORCH@#define RTABMAP_SUPERPOINT_TORCH @TORCH@#define RTABMAP_TORCH
@PYMATCHER@#define RTABMAP_PYMATCHER @PYTHON@#define RTABMAP_PYTHON
@MADGWICK@#define RTABMAP_MADGWICK @MADGWICK@#define RTABMAP_MADGWICK
#include <pcl/pcl_config.h> #include <pcl/pcl_config.h>
+3 -3
View File
@@ -2901,7 +2901,7 @@ bool RTABMapApp::exportMesh(
// save in database // save in database
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGBNormal>); pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGBNormal>);
pcl::fromPCLPointCloud2(polygonMesh->cloud, *cloud); pcl::fromPCLPointCloud2(polygonMesh->cloud, *cloud);
cv::Mat cloudMat = rtabmap::compressData2(rtabmap::util3d::laserScanFromPointCloud(*cloud, rtabmap::Transform(), false)); // for database cv::Mat cloudMat = rtabmap::compressData2(rtabmap::util3d::laserScanFromPointCloud(*cloud, rtabmap::Transform(), false).data()); // for database
std::vector<std::vector<std::vector<RTABMAP_PCL_INDEX> > > polygons(1); std::vector<std::vector<std::vector<RTABMAP_PCL_INDEX> > > polygons(1);
polygons[0].resize(polygonMesh->polygons.size()); polygons[0].resize(polygonMesh->polygons.size());
for(unsigned int p=0; p<polygonMesh->polygons.size(); ++p) for(unsigned int p=0; p<polygonMesh->polygons.size(); ++p)
@@ -2918,7 +2918,7 @@ bool RTABMapApp::exportMesh(
{ {
pcl::PointCloud<pcl::PointNormal>::Ptr cloud(new pcl::PointCloud<pcl::PointNormal>); pcl::PointCloud<pcl::PointNormal>::Ptr cloud(new pcl::PointCloud<pcl::PointNormal>);
pcl::fromPCLPointCloud2(textureMesh->cloud, *cloud); pcl::fromPCLPointCloud2(textureMesh->cloud, *cloud);
cv::Mat cloudMat = rtabmap::compressData2(rtabmap::util3d::laserScanFromPointCloud(*cloud, rtabmap::Transform(), false)); // for database cv::Mat cloudMat = rtabmap::compressData2(rtabmap::util3d::laserScanFromPointCloud(*cloud, rtabmap::Transform(), false).data()); // for database
// save in database // save in database
std::vector<std::vector<std::vector<RTABMAP_PCL_INDEX> > > polygons(textureMesh->tex_polygons.size()); std::vector<std::vector<std::vector<RTABMAP_PCL_INDEX> > > polygons(textureMesh->tex_polygons.size());
@@ -3054,7 +3054,7 @@ bool RTABMapApp::exportMesh(
// save in database // save in database
{ {
cv::Mat cloudMat = rtabmap::compressData2(rtabmap::util3d::laserScanFromPointCloud(*mergedClouds)); // for database cv::Mat cloudMat = rtabmap::compressData2(rtabmap::util3d::laserScanFromPointCloud(*mergedClouds).data()); // for database
boost::mutex::scoped_lock lock(rtabmapMutex_); boost::mutex::scoped_lock lock(rtabmapMutex_);
rtabmap_->getMemory()->saveOptimizedMesh(cloudMat); rtabmap_->getMemory()->saveOptimizedMesh(cloudMat);
success = true; success = true;
+13 -11
View File
@@ -57,7 +57,7 @@ enum PointCloudShaders
// PointCloud shaders // PointCloud shaders
const std::string kPointCloudVertexShader = const std::string kPointCloudVertexShader =
"precision mediump float;\n" "precision highp float;\n"
"precision mediump int;\n" "precision mediump int;\n"
"attribute vec3 aVertex;\n" "attribute vec3 aVertex;\n"
"attribute vec3 aColor;\n" "attribute vec3 aColor;\n"
@@ -75,7 +75,7 @@ const std::string kPointCloudVertexShader =
" vColor = aColor;\n" " vColor = aColor;\n"
"}\n"; "}\n";
const std::string kPointCloudLightingVertexShader = const std::string kPointCloudLightingVertexShader =
"precision mediump float;\n" "precision highp float;\n"
"precision mediump int;\n" "precision mediump int;\n"
"attribute vec3 aVertex;\n" "attribute vec3 aVertex;\n"
"attribute vec3 aNormal;\n" "attribute vec3 aNormal;\n"
@@ -100,7 +100,7 @@ const std::string kPointCloudLightingVertexShader =
"}\n"; "}\n";
const std::string kPointCloudFragmentShader = const std::string kPointCloudFragmentShader =
"precision mediump float;\n" "precision highp float;\n"
"precision mediump int;\n" "precision mediump int;\n"
"uniform float uGainR;\n" "uniform float uGainR;\n"
"uniform float uGainG;\n" "uniform float uGainG;\n"
@@ -127,7 +127,8 @@ const std::string kPointCloudBlendingFragmentShader =
" vec4 textureColor = vec4(vColor.z, vColor.y, vColor.x, 1.0);\n" " vec4 textureColor = vec4(vColor.z, vColor.y, vColor.x, 1.0);\n"
" float alpha = 1.0;\n" " float alpha = 1.0;\n"
" vec2 coord = uScreenScale * gl_FragCoord.xy;\n;" " vec2 coord = uScreenScale * gl_FragCoord.xy;\n;"
" float depth = texture2D(uDepthTexture, coord).r;\n" " vec4 depthPacked = texture2D(uDepthTexture, coord);\n"
" float depth = dot(depthPacked, 1./vec4(1.,255.,65025.,16581375.));\n"
" float num = (2.0 * uNearZ * uFarZ);\n" " float num = (2.0 * uNearZ * uFarZ);\n"
" float diff = (uFarZ - uNearZ);\n" " float diff = (uFarZ - uNearZ);\n"
" float add = (uFarZ + uNearZ);\n" " float add = (uFarZ + uNearZ);\n"
@@ -141,7 +142,7 @@ const std::string kPointCloudBlendingFragmentShader =
"}\n"; "}\n";
const std::string kPointCloudDepthPackingVertexShader = const std::string kPointCloudDepthPackingVertexShader =
"precision mediump float;\n" "precision highp float;\n"
"precision mediump int;\n" "precision mediump int;\n"
"attribute vec3 aVertex;\n" "attribute vec3 aVertex;\n"
"uniform mat4 uMVP;\n" "uniform mat4 uMVP;\n"
@@ -154,15 +155,15 @@ const std::string kPointCloudDepthPackingFragmentShader =
"precision highp float;\n" "precision highp float;\n"
"precision mediump int;\n" "precision mediump int;\n"
"void main() {\n" "void main() {\n"
" float toFixed = 255.0/256.0;\n" " vec4 enc = vec4(1.,255.,65025.,16581375.) * gl_FragCoord.z;\n"
" vec4 enc = vec4(1.0, 255.0, 65025.0, 160581375.0) * toFixed * gl_FragCoord.z;\n"
" enc = fract(enc);\n" " enc = fract(enc);\n"
" enc -= enc.yzww * vec2(1./255., 0.).xxxy;\n"
" gl_FragColor = enc;\n" " gl_FragColor = enc;\n"
"}\n"; "}\n";
// Texture shaders // Texture shaders
const std::string kTextureMeshVertexShader = const std::string kTextureMeshVertexShader =
"precision mediump float;\n" "precision highp float;\n"
"precision mediump int;\n" "precision mediump int;\n"
"attribute vec3 aVertex;\n" "attribute vec3 aVertex;\n"
"attribute vec2 aTexCoord;\n" "attribute vec2 aTexCoord;\n"
@@ -185,7 +186,7 @@ const std::string kTextureMeshVertexShader =
" vLightWeighting = 1.0;\n" " vLightWeighting = 1.0;\n"
"}\n"; "}\n";
const std::string kTextureMeshLightingVertexShader = const std::string kTextureMeshLightingVertexShader =
"precision mediump float;\n" "precision highp float;\n"
"precision mediump int;\n" "precision mediump int;\n"
"attribute vec3 aVertex;\n" "attribute vec3 aVertex;\n"
"attribute vec3 aNormal;\n" "attribute vec3 aNormal;\n"
@@ -214,7 +215,7 @@ const std::string kTextureMeshLightingVertexShader =
" vLightWeighting=0.5;\n" " vLightWeighting=0.5;\n"
"}\n"; "}\n";
const std::string kTextureMeshFragmentShader = const std::string kTextureMeshFragmentShader =
"precision mediump float;\n" "precision highp float;\n"
"precision mediump int;\n" "precision mediump int;\n"
"uniform sampler2D uTexture;\n" "uniform sampler2D uTexture;\n"
"uniform float uGainR;\n" "uniform float uGainR;\n"
@@ -245,7 +246,8 @@ const std::string kTextureMeshBlendingFragmentShader =
" vec4 textureColor = texture2D(uTexture, vTexCoord);\n" " vec4 textureColor = texture2D(uTexture, vTexCoord);\n"
" float alpha = 1.0;\n" " float alpha = 1.0;\n"
" vec2 coord = uScreenScale * gl_FragCoord.xy;\n;" " vec2 coord = uScreenScale * gl_FragCoord.xy;\n;"
" float depth = texture2D(uDepthTexture, coord).r;\n" " vec4 depthPacked = texture2D(uDepthTexture, coord);\n"
" float depth = dot(depthPacked, 1./vec4(1.,255.,65025.,16581375.));\n"
" float num = (2.0 * uNearZ * uFarZ);\n" " float num = (2.0 * uNearZ * uFarZ);\n"
" float diff = (uFarZ - uNearZ);\n" " float diff = (uFarZ - uNearZ);\n"
" float add = (uFarZ + uNearZ);\n" " float add = (uFarZ + uNearZ);\n"
+23 -15
View File
@@ -97,6 +97,7 @@ Scene::Scene() :
g_(0.0f), g_(0.0f),
b_(0.0f), b_(0.0f),
fboId_(0), fboId_(0),
rboId_(0),
depthTexture_(0), depthTexture_(0),
screenWidth_(0), screenWidth_(0),
screenHeight_(0), screenHeight_(0),
@@ -176,6 +177,8 @@ void Scene::DeleteResources() {
{ {
glDeleteFramebuffers(1, &fboId_); glDeleteFramebuffers(1, &fboId_);
fboId_ = 0; fboId_ = 0;
glDeleteRenderbuffers(1, &rboId_);
rboId_ = 0;
glDeleteTextures(1, &depthTexture_); glDeleteTextures(1, &depthTexture_);
depthTexture_ = 0; depthTexture_ = 0;
} }
@@ -220,16 +223,23 @@ void Scene::SetupViewPort(int w, int h) {
UASSERT(gesture_camera_ != 0); UASSERT(gesture_camera_ != 0);
gesture_camera_->SetWindowSize(static_cast<float>(w), static_cast<float>(h)); gesture_camera_->SetWindowSize(static_cast<float>(w), static_cast<float>(h));
glViewport(0, 0, w, h); glViewport(0, 0, w, h);
if(screenWidth_ != w || fboId_ == 0) if(screenWidth_ != w || screenHeight_ != h || fboId_ == 0)
{ {
if(fboId_>0) if(fboId_>0)
{ {
glDeleteFramebuffers(1, &fboId_); glDeleteFramebuffers(1, &fboId_);
fboId_ = 0; fboId_ = 0;
glDeleteRenderbuffers(1, &rboId_);
rboId_ = 0;
glDeleteTextures(1, &depthTexture_); glDeleteTextures(1, &depthTexture_);
depthTexture_ = 0; depthTexture_ = 0;
} }
// regenerate fbo texture
// create a framebuffer object, you need to delete them when program exits.
glGenFramebuffers(1, &fboId_);
glBindFramebuffer(GL_FRAMEBUFFER, fboId_);
// Create depth texture // Create depth texture
glGenTextures(1, &depthTexture_); glGenTextures(1, &depthTexture_);
glBindTexture(GL_TEXTURE_2D, depthTexture_); glBindTexture(GL_TEXTURE_2D, depthTexture_);
@@ -237,16 +247,17 @@ void Scene::SetupViewPort(int w, int h) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, w, h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
// regenerate fbo texture glGenRenderbuffers(1, &rboId_);
// create a framebuffer object, you need to delete them when program exits. glBindRenderbuffer(GL_RENDERBUFFER, rboId_);
glGenFramebuffers(1, &fboId_); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, w, h);
glBindFramebuffer(GL_FRAMEBUFFER, fboId_); glBindRenderbuffer(GL_RENDERBUFFER, 0);
// Set the texture to be at the depth attachment point of the FBO // Set the texture to be at the color attachment point of the FBO (we pack depth 32 bits in color)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture_, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, depthTexture_, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId_);
GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER); GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if ( status != GL_FRAMEBUFFER_COMPLETE) if ( status != GL_FRAMEBUFFER_COMPLETE)
@@ -464,14 +475,13 @@ int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat
// set the rendering destination to FBO // set the rendering destination to FBO
glBindFramebuffer(GL_FRAMEBUFFER, fboId_); glBindFramebuffer(GL_FRAMEBUFFER, fboId_);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glClearColor(0, 0, 0, 0);
glClearColor(1, 1, 1, 1);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
if(renderBackgroundCamera) if(renderBackgroundCamera)
{ {
PointCloudDrawable drawable(occlusionMesh); PointCloudDrawable drawable(occlusionMesh);
drawable.Render(projectionMatrix, viewMatrix, true, pointSize_, false, false, 999.0f); drawable.Render(projectionMatrix, viewMatrix, true, pointSize_, false, false, 999.0f, 0, 0, 0, 0, 0, true);
} }
else else
{ {
@@ -479,13 +489,12 @@ int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat
for(std::vector<PointCloudDrawable*>::const_iterator iter=cloudsToDraw.begin(); iter!=cloudsToDraw.end(); ++iter) for(std::vector<PointCloudDrawable*>::const_iterator iter=cloudsToDraw.begin(); iter!=cloudsToDraw.end(); ++iter)
{ {
// set large distance to cam to use low res polygons for fast processing // set large distance to cam to use low res polygons for fast processing
(*iter)->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_, false, false, 999.0f); (*iter)->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_, false, false, 999.0f, 0, 0, 0, 0, 0, true);
} }
} }
// back to normal window-system-provided framebuffer // back to normal window-system-provided framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
} }
if(doubleTapOn_ && gesture_camera_->GetCameraType() != tango_gl::GestureCamera::kFirstPerson) if(doubleTapOn_ && gesture_camera_->GetCameraType() != tango_gl::GestureCamera::kFirstPerson)
@@ -501,8 +510,7 @@ int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat
GLubyte zValue[4]; GLubyte zValue[4];
glReadPixels(doubleTapPos_.x*screenWidth_, screenHeight_-doubleTapPos_.y*screenHeight_, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, zValue); glReadPixels(doubleTapPos_.x*screenWidth_, screenHeight_-doubleTapPos_.y*screenHeight_, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, zValue);
float fromFixed = 256.0f/255.0f; float zValueF = float(zValue[0]/255.0f) + float(zValue[1]/255.0f)/255.0f + float(zValue[2]/255.0f)/65025.0f + float(zValue[3]/255.0f)/160581375.0f;
float zValueF = float(zValue[0]/255.0f)*fromFixed + float(zValue[1]/255.0f)*fromFixed/255.0f + float(zValue[2]/255.0f)*fromFixed/65025.0f + float(zValue[3]/255.0f)*fromFixed/160581375.0f;
if(zValueF != 0.0f) if(zValueF != 0.0f)
{ {
+1
View File
@@ -204,6 +204,7 @@ class Scene {
float g_; float g_;
float b_; float b_;
GLuint fboId_; GLuint fboId_;
GLuint rboId_;
GLuint depthTexture_; GLuint depthTexture_;
GLsizei screenWidth_; GLsizei screenWidth_;
GLsizei screenHeight_; GLsizei screenHeight_;
-13
View File
@@ -1,19 +1,6 @@
### Qt Gui stuff ###
SET(headers_ui
./ObjDeletionHandler.h
)
#This will generate moc_* for Qt
IF(QT4_FOUND)
QT4_WRAP_CPP(moc_srcs ${headers_ui})
ELSE()
QT5_WRAP_CPP(moc_srcs ${headers_ui})
ENDIF()
SET(SRC_FILES SET(SRC_FILES
main.cpp main.cpp
${moc_srcs}
) )
SET(INCLUDE_DIRS SET(INCLUDE_DIRS
+8 -1
View File
@@ -35,7 +35,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/utilite/UObjDeletionThread.h" #include "rtabmap/utilite/UObjDeletionThread.h"
#include "rtabmap/utilite/UFile.h" #include "rtabmap/utilite/UFile.h"
#include "rtabmap/utilite/UConversion.h" #include "rtabmap/utilite/UConversion.h"
#include "ObjDeletionHandler.h"
#ifdef RTABMAP_PYTHON
#include "rtabmap/core/PythonInterface.h"
#endif
using namespace rtabmap; using namespace rtabmap;
@@ -45,6 +48,10 @@ int main(int argc, char* argv[])
ULogger::setType(ULogger::kTypeConsole); ULogger::setType(ULogger::kTypeConsole);
ULogger::setLevel(ULogger::kWarning); ULogger::setLevel(ULogger::kWarning);
#ifdef RTABMAP_PYTHON
PythonInterface python; // Make sure we initialize python in main thread
#endif
/* 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
@@ -0,0 +1,22 @@
## Multi-Session Visual SLAM for Illumination Invariant Localization in Indoor Environments
* Paper: https://arxiv.org/abs/2103.03827
* The setup: we did 6 mapping sessions at dusk to evaluate how well RTAB-Map can localize (only by vision) on maps taken at different illumination conditions. The data has been collected with [RTAB-Map Tango](https://play.google.com/store/apps/details?id=com.introlab.rtabmap&hl=en_CA&gl=US).
![Overview](https://github.com/introlab/rtabmap/raw/master/archive/2020-IlluminationInvariant/images/fig_overview.jpg)]
## Description
This folder contains scripts to re-generate results from the paper. The main idea behind this work is that using Multi-Session mapping can help to localize visually in illumination changing environments even with features that are not very robust to such conditions. We compared common hand-made visual features like SIFT, SURF, BRIEF, BRISK, FREAK, DAISY, KAZE with learned descriptor SuperPoint. The following picture show how robust are the visual features tested when localizing against single session recorded at different time. For example, the bottom-left and top-right cells are when the robot tries to localize the night on a map taken the day or vice-versa. The diagonal is localization performance when the localization session is about the same time than when the map was recorded. SuperPoint has clearly an advantage on this single-session experiment.
![All sessions](https://github.com/introlab/rtabmap/raw/master/archive/2020-IlluminationInvariant/images/fig_single_percentage.jpg)]
The following image shows when we do the same localization experiment at different hours, but against maps created by assembling maps taken at different hours. In this case, we can see that even binary features like BRIEF can work relatively well in illumination-variant environments. See the paper for more detailled results and comments. The line `1+2+3+4+5+6` refers to the assembled map shown below containing all mapping sessions linked together in same database.
![All sessions](https://github.com/introlab/rtabmap/raw/master/archive/2020-IlluminationInvariant/images/fig_merged_percentage.jpg)]
![All sessions](https://github.com/introlab/rtabmap/raw/master/archive/2020-IlluminationInvariant/images/fig_map_merged_999.jpg)]
Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

@@ -0,0 +1,135 @@
clear all
close all
pkg load signal
# rtabmap-report --loc 32 Loop/Odom_correction_norm/m Loop/Visual_inliers/ Timing/Total/ms . Keypoint/Current_frame/words
# Right-click on thr legend of the figure, copy all data to clipboard
# Paste in correction#.txt, inliers#.txt and time#.txt where # is the
# number of the descriptor used
skipFrameDir = '0';
prefix = 'Stat';
RAMaddOverhead = 1;
% Inliers_ratio = 'Loop/Visual_inliers/' ./ 'Keypoint/Current_frame/words'
% Odometry_average = 'Memory/Distance_travelled/m'(2:end) - 'Memory/Distance_travelled/m'(1:end-1)
statNames = {'Loop/Odom_correction_norm/m', 'Inliers_ratio_%', 'Timing/Total/ms', 'Memory/RAM_usage/MB', 'Memory/RAM_estimated/MB', 'Keypoint/Current_frame/words', 'Loop/Map_id/'}; % 'Odometry_average'
datasets = [ 0 1 6 7 9 12 14 11]; % 0 1 6 7 8 9 11 12
sep = [0, 1000, 3000, 5000, 7000, 9000, 12000];
sepName = {'16:51', '17:31', '17:58', '18:30', '18:59', '19:42'};
allCumResults = {};
allMaxResults = {};
for s=1:length(statNames)
avgResults = {};
maxResults = {};
totalResults = {};
absResults = {};
statName = strrep(statNames{s},'/','-');
for d=1:length(datasets)
if strcmp(statName,'Inliers_ratio_%')
data = dlmread([skipFrameDir '/' prefix num2str(datasets(d)) '-' 'Loop-Visual_inliers-' '.txt'], '\t', 1, 0, "emptyvalue", 0);
dataWords = dlmread([skipFrameDir '/' prefix num2str(datasets(d)) '-' 'Keypoint-Current_frame-words' '.txt'], '\t', 1, 0, "emptyvalue", 0);
data(:, 2:end) = data(:, 2:end) ./ dataWords(:, 2:end) * 100;
elseif strcmp(statName, 'Odometry_average')
data = dlmread([skipFrameDir '/' prefix num2str(datasets(d)) '-' 'Memory-Distance_travelled-m' '.txt'], '\t', 1, 0, "emptyvalue", 0);
else
data = dlmread([skipFrameDir '/' prefix num2str(datasets(d)) '-' statName '.txt'], '\t', 1, 0, "emptyvalue", 0);
endif
sessions = size(data,2)-1;
avgResultsTmp = zeros(sessions, length(sep)-1);
maxResultsTmp = zeros(sessions, length(sep)-1);
totalResultsTmp = zeros(sessions, length(sep)-1);
absResultsTmp = zeros(sessions, length(sep)-1);
for i = 1:sessions
for j = 1:length(sep)-1
x = data(:,1);
y = data(:,i+1);
y = y(x>=sep(j) & x<=sep(j+1), :);
x = x(x>=sep(j) & x<=sep(j+1), :);
if strcmp(statName, 'Odometry_average')
y(2:end) = y(2:end) - y(1:end-1);
y(y < 0.05) = 0;
elseif strcmp(statName, 'Loop-Map_id-')
y = y+1;
y(y>0) = 1;
end
if strcmp(statName, 'Memory-RAM_estimated-MB') && RAMaddOverhead == 1
% Valgrind estimated around 90 MB constant overhead
y = y + 90;
if datasets(d) == 7
%% 135 MB overhead for BRISK kernel
y = y + 135;
elseif datasets(d) == 11
%% 645 MB (library cuda) + 800 MB (network) for SuperPoint
y = y + 645+800;
elseif datasets(d) == 13 || datasets(d) == 14
%% 64 MB overhead for DAISY
y = y + 64;
endif
endif
nonzeros = y(y>0);
if strcmp(statName, 'Loop-Map_id-')
nonzeros = y;
end
if length(nonzeros) > 0
avgValue = sum(nonzeros)/length(nonzeros);
avgResultsTmp(i,j) = avgValue;
maxResultsTmp(i,j) = max(nonzeros);
totalResultsTmp(i,j) = length(nonzeros);
absResultsTmp(i,j) = sum(nonzeros);
endif
endfor
endfor
avgResults{1,d} = avgResultsTmp;
maxResults{1,d} = maxResultsTmp;
totalResults{1,d} = totalResultsTmp;
absResults{1,d} = absResultsTmp;
endfor
% compute cumulative results
cumResults = zeros(sessions+2, length(datasets)+1);
for d=1:length(datasets)
cumResults(1,d+1) = datasets(d);
if sum(totalResults{1,d}, 2)
cumResults(2:end-1,d+1) = sum(absResults{1,d}, 2) ./ sum(totalResults{1,d}, 2);
endif
cumResults(end,d+1) = sum(sum(absResults{1,d}(1:6,1:6).*eye(6,6))) / sum(sum(totalResults{1,d}(1:6,1:6).*eye(6,6)));
end
cumResults(2:end-1,1) = 1:sessions;
allCumResults{1,s} = statNames{s};
if strcmp(statNames{s}, 'Loop/Odom_correction_norm/m')
cumResults(2:end,2:end) = cumResults(2:end,2:end) * 1000;
allCumResults{1,s} = 'Loop/Odom_correction_norm/mm';
elseif strcmp(statNames{s}, 'Loop/Map_id/')
cumResults(2:end,2:end) = cumResults(2:end,2:end) * 100;
endif
allCumResults{2,s} = round(cumResults);
% compute max results
cumMaxResults = zeros(sessions+2, length(datasets)+1);
for d=1:length(datasets)
cumMaxResults(1,d+1) = datasets(d);
if sum(totalResults{1,d}, 2)
cumMaxResults(2:end-1,d+1) = max(maxResults{1,d}, [], 2);
endif
cumMaxResults(end,d+1) = max(max(maxResults{1,d}(1:6,1:6).*eye(6,6)));
end
cumMaxResults(2:end-1,1) = 1:sessions;
allMaxResults{1,s} = statNames{s};
allMaxResults{2,s} = cumMaxResults;
endfor % statNames
@@ -0,0 +1,235 @@
close all
clear all
pkg load signal
# rtabmap-report --loc 32 Loop/Map_id/ loc
# Right-click on thr legend of the figure, copy all data to clipboard
# Paste in data#.txt where # is the number of the descriptor used
resultsToShow = 1; % 1=single loc, 2=merged loc, 3=consecutive
skipFrameDir = '0';
datasetPrefix = 'Stat';
datasets = [0 1 6 7 9 12 14 11]; % 0 1 6 7 8 9 11 12
datasetsName = {'SURF' 'SIFT' 'ORB' 'FAST/FREAK' 'FAST/BRIEF' 'GFTT/FREAK' 'GFTT/BRIEF' 'BRISK' 'GFTT/ORB' 'KAZE' 'ORB-OCTREE' 'SuperPoint' 'SURF/FREAK' 'GFTT/DAISY' 'SURF/DAISY'};
sep = [0, 1000, 3000, 5000, 7000, 9000, 12000];
sepName = {'16:51', '17:31', '17:58', '18:30', '18:59', '19:42'};
if resultsToShow == 3
sep = [0, 1000, 3000, 5000, 7000, 9000];
sepName = {'17:27', '17:54', '18:27', '18:56', '19:35'};
datasetPrefix = 'Consecutive'
endif
percentResults = {};
totalResults = {};
locResults = {};
figure
colors = get(gca, 'ColorOrder');
tmp=colors(3,:);
colors(3,:) = colors(5,:);
colors(5,:) = tmp;
globalSeparators = [];
globalx = [];
globaly = [];
globalc = [];
for d=1:length(datasets)
data = dlmread([skipFrameDir '/' datasetPrefix num2str(datasets(d)) '-Loop-Map_id-' '.txt'], '\t', 1, 0, "emptyvalue", NaN);
curvesBeg = 2;
curvesEnd = size(data,2)-4;
if resultsToShow == 2
curvesBeg = 8;
curvesEnd = size(data,2);
elseif resultsToShow == 3
curvesEnd = size(data,2);
endif
curves = curvesEnd - curvesBeg + 1;
percentResultsTmp = zeros(curves, length(sep)-1);
totalResultsTmp = zeros(curves, length(sep)-1);
locResultsTmp = zeros(curves, length(sep)-1);
offset = 1;
for i = 1:curves
index = i + curvesBeg - 1;
separators = [];
x_all = [];
y_all = [];
m_all = [];
previousMax = 0;
for j = 1:length(sep)-1
x = data(:,1);
y = data(:,index);
y = y(x>=sep(j) & x<=sep(j+1), :);
x = x(x>=sep(j) & x<=sep(j+1), :);
minimum = x(1,1);
separators = [separators previousMax];
x = x - (minimum-previousMax);
previousMax = x(end,1);
y = y + 1;
m = y;
y(y>0) = 1;
y(isnan(y)) = 0;
percent = sum(y)/length(y);
percentResultsTmp(i,j) = percent;
locResultsTmp(i,j) = sum(y);
totalResultsTmp(i,j) = length(y);
y(y>0) = -(d-1)*curves -i - (d-1)*offset;
%x(y==0) = nan;
m(y==0) = nan;
y(y==0) = nan;
if resultsToShow == 2
if i==1 %% Merged 1, 6
m(m==1) = 1;
m(m==2) = 6;
elseif i==2 %% Merged 1,3(2 sessions),5
m(m==1) = 1;
m(m==2) = 3;
m(m==3) = 3;
m(m==4) = 5;
elseif i==3 %% Merged 2(2 sessions),4,6
m(m==1) = 2;
m(m==2) = 2;
m(m==4) = 6;
m(m==3) = 4;
elseif i>=4 %% Merged 1, 2(2 sessions), 3(2 sessions),4,5,6
m(m==1) = 1;
m(m==2) = 2;
m(m==3) = 2;
m(m==4) = 3;
m(m==5) = 3;
m(m==6) = 4;
m(m==7) = 5;
m(m==8) = 6;
endif
endif
x = upsample(x, 2);
y = upsample(y, 2);
m = upsample(m, 2);
x(2:2:end-1) = x(3:2:end);
y(2:2:end-1) = y(3:2:end);
m(2:2:end) = m(1:2:end);
x = x(1:end-1);
y = y(1:end-1);
m = m(1:end-1);
x_all = [x_all nan x'];
y_all = [y_all nan y'];
m_all = [m_all nan m'];
endfor
if resultsToShow == 2
globalx = [globalx x_all];
globaly = [globaly y_all];
globalc = [globalc m_all];
else
plot(x_all,y_all, 'linewidth', 3, 'color', colors(i,:))
hold on
endif
separators = [separators previousMax];
globalSeparators = separators;
endfor
percentResults{1,d} = percentResultsTmp;
totalResults{1,d} = totalResultsTmp;
locResults{1,d} = locResultsTmp;
endfor
if resultsToShow == 2
indColors = ones(length(globalc), 3);
for j=1:length(globalc)
if ~isnan(globalc(j))
indColors(j,:) = colors(globalc(j),:);
endif
endfor
for i=1:6
tmpx = globalx;
tmpy = globaly;
tmpx(globalc~=i) = nan;
tmpy(globalc~=i) = nan;
plot(tmpx, tmpy, 'linewidth', 3, 'color', colors(i,:));
if i==1
hold on
endif
endfor
endif
for j=1:length(globalSeparators)
x = globalSeparators(j);
plot([x,x],[(-length(datasets)*(curves+1)) ,0], 'k','linewidth', 2);
endfor
for d=1:length(datasets)
annotation ("textbox", [0, 0.96-((d-0.5)/length(datasets))*0.95, 0,0], 'string', datasetsName{datasets(d)+1})
endfor
for s=1:length(sep)-1
annotation ("textbox", [0.1 + ((separators(s+1)-separators(s))/2+separators(s))/separators(end)*0.75, 0.98, 0,0], 'string', sepName{s})
endfor
axis('tight')
set(gca, 'units', 'normalized');
Tight = get(gca, 'Position');
NewPos = [Tight(1) 0.01 0.77 0.95]; %New plot position [X Y W H]
set(gca, 'Position', NewPos);
if length(sep) == 7
legend('16:46', '17:27', '17:54', '18:27', '18:56', '19:35', "location", 'northeastoutside' )
else
legend('16:46', '17:27', '17:54', '18:27', '18:56', "location", 'northeastoutside' )
endif
box off
axis off
#disp(percentResults);
#disp(totalResults);
figure;
for d=1:length(datasets)
subplot(4,2,d)
data=percentResults{1,d}*100;
data(isnan(data)) = 0;
hAxes = gca;
imagesc( hAxes, data, [0, 100])
%title({"",datasetsName{datasets(d)+1}})
colors = [ones(100,1) [1:100]'*0.01 [1:100]'*0];
colors(1,:) = 1;
colormap( hAxes , colors)
c = colorbar;
labels = {};
for v=get(c,'ytick'), labels{end+1} = sprintf('%d%%',v); end
set(c,'yticklabel',labels);
if mod(d,2) == 1
ylabel("Map")
endif
xlabel([datasetsName{datasets(d)+1} " Localization"])
set (gca, "xaxislocation", "top");
set(gca, 'XTickLabel', sepName, 'fontsize',7)
if resultsToShow == 3
set(gca, 'YTickLabel', {'16:46', '17:27', '17:54', '18:27', '18:56'}, 'fontsize',7)
elseif resultsToShow == 2
set(gca, 'YTickLabel', {'1+6', '1+3+5', '2+4+6', '1+2+3+4+6', 'bundle', 'reduced'}, 'fontsize',7)
else
set(gca, 'YTickLabel', {'16:46', '17:27', '17:54', '18:27', '18:56', '19:35'}, 'fontsize',7)
endif
endfor
% compute cumulative localizations
cumResults = zeros(curves+2, length(datasets)+1);
for d=1:length(datasets)
cumResults(1,d+1) = datasets(d);
cumResults(2:end-1,d+1) = round(sum(locResults{1,d}, 2) ./ sum(totalResults{1,d}, 2) * 100);
if resultsToShow == 1
cumResults(end,d+1) = round(sum(sum(locResults{1,d}.*eye(curves,curves))) / sum(totalResults{1,d},2)(1,1) * 100);
endif
end
cumResults(2:end-1,1) = 1:curves;
cumResults
+19
View File
@@ -0,0 +1,19 @@
#!/bin/bash
SKIP=0
if [ $# -eq 1 ]
then
SKIP=$1
fi
DETECTOR=(0 1 6 7 9 11 12 14) #0 1 6 7 8 9 11 12 13 14
PREFIX="/home/mathieu/workspace/rtabmap_cv_latest/bin/"
REPORT_TOOL="${PREFIX}rtabmap-report"
for d in "${DETECTOR[@]}"
do
$REPORT_TOOL --export --export_prefix "Stat$d" --loc 32 Loop/Odom_correction_norm/m Loop/Visual_inliers/ Timing/Total/ms Loop/Map_id/ Keypoint/Current_frame/words Memory/RAM_usage/MB Memory/RAM_estimated/MB Memory/Distance_travelled/m "$SKIP/$d/loc"
$REPORT_TOOL --export --export_prefix "Consecutive$d" --loc 32 Loop/Map_id/ "$SKIP/$d/consecutive_loc"
done
@@ -0,0 +1,42 @@
#!/bin/bash
if [ $# -eq 0 ]
then
echo "No arguments supplied. It should be the detector number type (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)."
exit
fi
TYPE=$1
SKIP=0
if [ $# -eq 2 ]
then
SKIP=$2
fi
PREFIX="/home/mathieu/workspace/rtabmap_cv_latest/bin/"
REPROCESS_TOOL="${PREFIX}rtabmap-reprocess"
DETECT_MORE_LOOP_CLOSURE_TOOL="${PREFIX}rtabmap-detectMoreLoopClosures"
[ ! -d "$SKIP" ] && mkdir $SKIP
[ ! -d "$SKIP/$TYPE" ] && mkdir $SKIP/$TYPE
# 'map_190321-164651.db' 'map_190321-172717.db' 'map_190321-175428.db' 'map_190321-182709.db' 'map_190321-185608.db' 'map_190321-193556.db'
DATABASES=( 'map_190321-164651.db' 'map_190321-172717.db' 'map_190321-175428.db' 'map_190321-182709.db' 'map_190321-185608.db' 'map_190321-193556.db' )
PARAMS="--Kp/DetectorStrategy $TYPE --Vis/FeatureType $TYPE"
if [ $TYPE -eq 2 ] || [ $TYPE -eq 3 ] || [ $TYPE -eq 4 ] || [ $TYPE -eq 5 ] || [ $TYPE -eq 6 ] || [ $TYPE -eq 7 ] || [ $TYPE -eq 8 ] || [ $TYPE -eq 10 ] || [ $TYPE -eq 12 ]
then
# binary descriptors
PARAMS="--Vis/CorNNDR 0.8 $PARAMS"
else
# float descriptors
PARAMS="--Vis/CorNNDR 0.6 $PARAMS"
if
echo $PARAMS
for db in "${DATABASES[@]}"
do
$REPROCESS_TOOL --skip $SKIP --RGBD/MarkerDetection false --RGBD/ProximityBySpace true --RGBD/LocalRadius 1 --Mem/InitWMWithAllNodes true --Rtabmap/TimeThr 0 --Mem/UseOdomFeatures false --Optimizer/GravitySigma 0.1 --Mem/UseOdomGravity true --RGBD/OptimizeFromGraphEnd false --Mem/DepthAsMask false --RGBD/OptimizeMaxError 4 --RGBD/ProximityOdomGuess false --Vis/MaxFeatures 1000 --Kp/MaxFeatures 400 --Vis/EpipolarGeometryVar 0.1 --Vis/EstimationType 1 --Vis/MinInliers 20 --Rtabmap/MaxRetrieved 2 --Optimizer/Iterations 20 --Mem/CompressionParallelized true --Kp/Parallelized true --Kp/MaxDepth 0 --Kp/BadSignRatio 0.2 --BRIEF/Bytes 32 --Kp/ByteToFloat true --SURF/HessianThreshold 100 --SIFT/ContrastThreshold 0.02 --BRISK/Thresh 10 --SuperPoint/ModelPath superpoint.pt --Rtabmap/PublishRAMUsage true --ORB/EdgeThreshold 19 --ORB/ScaleFactor 2 --ORB/NLevels 3 --uerror $PARAMS $db $SKIP/$TYPE/$db
$DETECT_MORE_LOOP_CLOSURE_TOOL --uwarn $SKIP/$TYPE/$db
done
@@ -0,0 +1,16 @@
#!/bin/bash
SKIP=0
if [ $# -eq 1 ]
then
SKIP=$1
fi
DETECTOR=(0 1 6 7 9 11 12 14)
for d in "${DETECTOR[@]}"
do
./reprocess_maps.sh $d $SKIP
./run_merge.sh $d $SKIP
done
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
SKIP=0
if [ $# -eq 1 ]
then
SKIP=$1
fi
./reprocess_maps_all.sh $SKIP
./run_merge.sh $SKIP
./run_localization_single_all.sh $SKIP
./run_consecutive_localization_all.sh $SKIP
@@ -0,0 +1,31 @@
#!/bin/bash
if [ $# -eq 0 ]
then
echo "No arguments supplied. It should be the detector number type (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)."
exit
fi
TYPE=$1
SKIP=0
if [ $# -eq 2 ]
then
SKIP=$2
fi
PREFIX="/home/mathieu/workspace/rtabmap_cv_latest/bin/"
REPROCESS_TOOL="${PREFIX}rtabmap-reprocess"
SOURCE=('map_190321-164651.db' 'map_190321-172717.db' 'map_190321-175428.db' 'map_190321-182709.db' 'map_190321-185608.db')
TARGETS=($SKIP/$TYPE'/map_190321-172717.db;'$SKIP/$TYPE'/map_190321-175428.db;'$SKIP/$TYPE'/map_190321-193556.db' $SKIP/$TYPE'/map_190321-175428.db;'$SKIP/$TYPE'/map_190321-182709.db;' $SKIP/$TYPE'/map_190321-182709.db;'$SKIP/$TYPE'/map_190321-185608.db' $SKIP/$TYPE'/map_190321-185608.db;'$SKIP/$TYPE'/map_190321-193556.db' $SKIP/$TYPE'/map_190321-193556.db' )
[ ! -d "$SKIP/$TYPE/consecutive_loc" ] && mkdir $SKIP/$TYPE/consecutive_loc
for i in ${!SOURCE[@]}
do
db=${SOURCE[$i]}
loc_dbs=${TARGETS[$i]}
$REPROCESS_TOOL --Mem/IncrementalMemory false --RGBD/ProximityBySpace true --Mem/LocalizationDataSaved true --Mem/BinDataKept false --RGBD/SavedLocalizationIgnored true --uwarn "$SKIP/$TYPE/$db;$loc_dbs" $SKIP/$TYPE/consecutive_loc/loc_$db
done
@@ -0,0 +1,15 @@
#!/bin/bash
SKIP=0
if [ $# -eq 1 ]
then
SKIP=$1
fi
DETECTOR=(0 1 6 7 9 11 12 14)
for d in "${DETECTOR[@]}"
do
./run_consecutive_localization.sh $d $SKIP
done
@@ -0,0 +1,38 @@
#!/bin/bash
if [ $# -eq 0 ]
then
echo "No arguments supplied. It should be the detector number type (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)."
exit
fi
TYPE=$1
SKIP=0
if [ $# -eq 2 ]
then
SKIP=$2
fi
PREFIX="/home/mathieu/workspace/rtabmap_cv_latest/bin/"
REPROCESS_TOOL="${PREFIX}rtabmap-reprocess"
# loc_190321-165128.db;loc_190321-173134.db;loc_190321-175823.db;loc_190321-183051.db;loc_190321-185950.db;loc_190321-194226.db
LOCALIZATION_DATABASES="loc_190321-165128.db;loc_190321-173134.db;loc_190321-175823.db;loc_190321-183051.db;loc_190321-185950.db;loc_190321-194226.db"
[ ! -d "$SKIP/$TYPE/loc" ] && mkdir $SKIP/$TYPE/accuracy
db=merged_9999.db
$REPROCESS_TOOL --skip $SKIP --Mem/IncrementalMemory false --RGBD/ProximityBySpace true --Mem/LocalizationDataSaved true --Mem/BinDataKept false --RGBD/SavedLocalizationIgnored true --Kp/IncrementalFlann false --Vis/MinInliers 20 --Rtabmap/PublishRAMUsage true --RGBD/ProximityOdomGuess false --Reg/RepeatOnce true --Vis/BundleAdjustment 1 --uwarn "$SKIP/$TYPE/$db;$LOCALIZATION_DATABASES" $SKIP/$TYPE/accuracy/ProxOff_DoubleRegOn_BaOn_$db
$REPROCESS_TOOL --skip $SKIP --Mem/IncrementalMemory false --RGBD/ProximityBySpace true --Mem/LocalizationDataSaved true --Mem/BinDataKept false --RGBD/SavedLocalizationIgnored true --Kp/IncrementalFlann false --Vis/MinInliers 20 --Rtabmap/PublishRAMUsage true --RGBD/ProximityOdomGuess false --Reg/RepeatOnce false --Vis/BundleAdjustment 1 --uwarn "$SKIP/$TYPE/$db;$LOCALIZATION_DATABASES" $SKIP/$TYPE/accuracy/ProxOff_DoubleRegOff_BaOn_$db
$REPROCESS_TOOL --skip $SKIP --Mem/IncrementalMemory false --RGBD/ProximityBySpace true --Mem/LocalizationDataSaved true --Mem/BinDataKept false --RGBD/SavedLocalizationIgnored true --Kp/IncrementalFlann false --Vis/MinInliers 20 --Rtabmap/PublishRAMUsage true --RGBD/ProximityOdomGuess false --Reg/RepeatOnce true --Vis/BundleAdjustment 0 --uwarn "$SKIP/$TYPE/$db;$LOCALIZATION_DATABASES" $SKIP/$TYPE/accuracy/ProxOff_DoubleRegOn_BaOff_$db
$REPROCESS_TOOL --skip $SKIP --Mem/IncrementalMemory false --RGBD/ProximityBySpace true --Mem/LocalizationDataSaved true --Mem/BinDataKept false --RGBD/SavedLocalizationIgnored true --Kp/IncrementalFlann false --Vis/MinInliers 20 --Rtabmap/PublishRAMUsage true --RGBD/ProximityOdomGuess false --Reg/RepeatOnce false --Vis/BundleAdjustment 0 --uwarn "$SKIP/$TYPE/$db;$LOCALIZATION_DATABASES" $SKIP/$TYPE/accuracy/ProxOff_DoubleRegOff_BaOff_$db
$REPROCESS_TOOL --skip $SKIP --Mem/IncrementalMemory false --RGBD/ProximityBySpace true --Mem/LocalizationDataSaved true --Mem/BinDataKept false --RGBD/SavedLocalizationIgnored true --Kp/IncrementalFlann false --Vis/MinInliers 20 --Rtabmap/PublishRAMUsage true --RGBD/ProximityOdomGuess true --Reg/RepeatOnce true --Vis/BundleAdjustment 1 --uwarn "$SKIP/$TYPE/$db;$LOCALIZATION_DATABASES" $SKIP/$TYPE/accuracy/ProxOn_DoubleRegOn_BaOn_$db
$REPROCESS_TOOL --skip $SKIP --Mem/IncrementalMemory false --RGBD/ProximityBySpace true --Mem/LocalizationDataSaved true --Mem/BinDataKept false --RGBD/SavedLocalizationIgnored true --Kp/IncrementalFlann false --Vis/MinInliers 20 --Rtabmap/PublishRAMUsage true --RGBD/ProximityOdomGuess true --Reg/RepeatOnce true --Vis/BundleAdjustment 0 --uwarn "$SKIP/$TYPE/$db;$LOCALIZATION_DATABASES" $SKIP/$TYPE/accuracy/ProxOn_DoubleRegOn_BaOff_$db
@@ -0,0 +1,32 @@
#!/bin/bash
if [ $# -eq 0 ]
then
echo "No arguments supplied. It should be the detector number type (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)."
exit
fi
TYPE=$1
SKIP=0
if [ $# -eq 2 ]
then
SKIP=$2
fi
PREFIX="/home/mathieu/workspace/rtabmap_cv_latest/bin/"
REPROCESS_TOOL="${PREFIX}rtabmap-reprocess"
# 'map_190321-164651.db' 'map_190321-172717.db' 'map_190321-175428.db' 'map_190321-182709.db' 'map_190321-185608.db' 'map_190321-193556.db' 'merged_9999.db' 'merged_135.db' 'merged_246.db' 'merged_16.db' 'merged_9999_reduced.db'
DATABASES=( 'map_190321-164651.db' 'map_190321-172717.db' 'map_190321-175428.db' 'map_190321-182709.db' 'map_190321-185608.db' 'map_190321-193556.db' 'merged_9999.db' 'merged_135.db' 'merged_246.db' 'merged_16.db' )
# loc_190321-165128.db;loc_190321-173134.db;loc_190321-175823.db;loc_190321-183051.db;loc_190321-185950.db;loc_190321-194226.db
LOCALIZATION_DATABASES="loc_190321-165128.db;loc_190321-173134.db;loc_190321-175823.db;loc_190321-183051.db;loc_190321-185950.db;loc_190321-194226.db"
[ ! -d "$SKIP/$TYPE/loc" ] && mkdir $SKIP/$TYPE/loc
echo $PARAMS
for db in "${DATABASES[@]}"
do
$REPROCESS_TOOL --skip $SKIP --Mem/IncrementalMemory false --RGBD/ProximityBySpace true --Mem/LocalizationDataSaved true --Mem/BinDataKept false --RGBD/SavedLocalizationIgnored true --Kp/IncrementalFlann false --Vis/MinInliers 20 --Rtabmap/PublishRAMUsage true --RGBD/ProximityOdomGuess false --uwarn "$SKIP/$TYPE/$db;$LOCALIZATION_DATABASES" $SKIP/$TYPE/loc/loc_$db
done
@@ -0,0 +1,15 @@
#!/bin/bash
SKIP=0
if [ $# -eq 1 ]
then
SKIP=$1
fi
DETECTOR=(0 1 6 7 9 11 12 14)
for d in "${DETECTOR[@]}"
do
./run_localization_single.sh $d $SKIP
done
+38
View File
@@ -0,0 +1,38 @@
#!/bin/bash
if [ $# -eq 0 ]
then
echo "No arguments supplied. It should be the detector number type (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)."
exit
fi
TYPE=$1
SKIP=0
if [ $# -eq 2 ]
then
SKIP=$2
fi
PREFIX="/home/mathieu/workspace/rtabmap_cv_latest/bin/"
REPROCESS_TOOL="${PREFIX}rtabmap-reprocess"
DETECT_MORE_LOOP_CLOSURE_TOOL="${PREFIX}rtabmap-detectMoreLoopClosures"
DATABASES="$SKIP/$TYPE/map_190321-164651.db;$SKIP/$TYPE/map_190321-172717.db;$SKIP/$TYPE/map_190321-175428.db;$SKIP/$TYPE/map_190321-182709.db;$SKIP/$TYPE/map_190321-185608.db;$SKIP/$TYPE/map_190321-193556.db"
$REPROCESS_TOOL --uwarn --RGBD/OptimizeMaxError 0 "$DATABASES" $SKIP/$TYPE/merged_9999.db
$DETECT_MORE_LOOP_CLOSURE_TOOL $SKIP/$TYPE/merged_9999.db
#$REPROCESS_TOOL --uwarn --RGBD/OptimizeMaxError 0 --Mem/ReduceGraph true --Vis/MinInliers 60 "$DATABASES" $SKIP/$TYPE/merged_9999_reduced.db
#$DETECT_MORE_LOOP_CLOSURE_TOOL $SKIP/$TYPE/merged_9999_reduced.db
$REPROCESS_TOOL --uwarn --RGBD/OptimizeMaxError 0 "$SKIP/$TYPE/map_190321-164651.db;$SKIP/$TYPE/map_190321-193556.db" $SKIP/$TYPE/merged_16.db
$DETECT_MORE_LOOP_CLOSURE_TOOL $SKIP/$TYPE/merged_16.db
$REPROCESS_TOOL --uwarn --RGBD/OptimizeMaxError 0 "$SKIP/$TYPE/map_190321-164651.db;$SKIP/$TYPE/map_190321-175428.db;$SKIP/$TYPE/map_190321-185608.db" $SKIP/$TYPE/merged_135.db
$DETECT_MORE_LOOP_CLOSURE_TOOL $SKIP/$TYPE/merged_135.db
$REPROCESS_TOOL --uwarn --RGBD/OptimizeMaxError 0 "$SKIP/$TYPE/map_190321-172717.db;$SKIP/$TYPE/map_190321-182709.db;$SKIP/$TYPE/map_190321-193556.db" $SKIP/$TYPE/merged_246.db
$DETECT_MORE_LOOP_CLOSURE_TOOL $SKIP/$TYPE/merged_246.db
+19
View File
@@ -0,0 +1,19 @@
#!/bin/bash
SKIP=0
if [ $# -eq 1 ]
then
SKIP=$1
fi
DETECTOR=(0 1 6 7 8 9 11 12 14)
PREFIX="/home/mathieu/workspace/rtabmap_cv_latest/bin/"
REPORT_TOOL="${PREFIX}rtabmap-report"
for d in "${DETECTOR[@]}"
do
valgrind --tool=massif --time-unit=ms --detailed-freq=1 --max-snapshots=100 ${PREFIX}rtabmap-reprocess --Mem/IncrementalMemory false --Kp/IncrementalFlann false "${SKIP}/${d}/merged_9999.db;map_190321-164651.db" output.db
rm output.db
done
+234
View File
@@ -0,0 +1,234 @@
#.rst:
# FindHIDAPI
# ----------
#
# Try to find HIDAPI library, from http://www.signal11.us/oss/hidapi/
#
# Cache Variables: (probably not for direct use in your scripts)
# HIDAPI_INCLUDE_DIR
# HIDAPI_LIBRARY
#
# Non-cache variables you might use in your CMakeLists.txt:
# HIDAPI_FOUND
# HIDAPI_INCLUDE_DIRS
# HIDAPI_LIBRARIES
#
# COMPONENTS
# ^^^^^^^^^^
#
# This module respects several COMPONENTS specifying the backend you prefer:
# ``any`` (the default), ``libusb``, and ``hidraw``.
# The availablility of the latter two depends on your platform.
#
#
# IMPORTED Targets
# ^^^^^^^^^^^^^^^^
# This module defines :prop_tgt:`IMPORTED` target ``HIDAPI::hidapi`` (in all cases or
# if no components specified), ``HIDAPI::hidapi-libusb`` (if you requested the libusb component),
# and ``HIDAPI::hidapi-hidraw`` (if you requested the hidraw component),
#
# Result Variables
# ^^^^^^^^^^^^^^^^
#
# ``HIDAPI_FOUND``
# True if HIDAPI or the requested components (if any) were found.
#
# We recommend using the imported targets instead of the following.
#
# ``HIDAPI_INCLUDE_DIRS``
# ``HIDAPI_LIBRARIES``
#
# Original Author:
# 2009-2010, 2019 Ryan Pavlik <ryan.pavlik@collabora.com> <abiryan@ryand.net>
# http://academic.cleardefinition.com
#
# Copyright Iowa State University 2009-2010.
# Copyright Collabora, Ltd. 2019.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
cmake_policy(SET CMP0045 NEW)
cmake_policy(SET CMP0053 NEW)
cmake_policy(SET CMP0054 NEW)
set(HIDAPI_ROOT_DIR
"${HIDAPI_ROOT_DIR}"
CACHE PATH "Root to search for HIDAPI")
# Clean up components
if("${HIDAPI_FIND_COMPONENTS}")
if(WIN32 OR APPLE)
# This makes no sense on Windows or Mac, which have native APIs
list(REMOVE HIDAPI_FIND_COMPONENTS libusb)
endif()
if(NOT ${CMAKE_SYSTEM} MATCHES "Linux")
# hidraw is only on linux
list(REMOVE HIDAPI_FIND_COMPONENTS hidraw)
endif()
endif()
if(NOT "${HIDAPI_FIND_COMPONENTS}")
# Default to any
set(HIDAPI_FIND_COMPONENTS any)
endif()
# Ask pkg-config for hints
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
set(_old_prefix_path "${CMAKE_PREFIX_PATH}")
# So pkg-config uses HIDAPI_ROOT_DIR too.
if(HIDAPI_ROOT_DIR)
list(APPEND CMAKE_PREFIX_PATH ${HIDAPI_ROOT_DIR})
endif()
pkg_check_modules(PC_HIDAPI_LIBUSB QUIET hidapi-libusb)
pkg_check_modules(PC_HIDAPI_HIDRAW QUIET hidapi-hidraw)
# Restore
set(CMAKE_PREFIX_PATH "${_old_prefix_path}")
endif()
# Actually search
find_library(
HIDAPI_UNDECORATED_LIBRARY
NAMES hidapi
PATHS "${HIDAPI_ROOT_DIR}"
PATH_SUFFIXES lib)
find_library(
HIDAPI_LIBUSB_LIBRARY
NAMES hidapi hidapi-libusb
PATHS "${HIDAPI_ROOT_DIR}"
PATH_SUFFIXES lib
HINTS ${PC_HIDAPI_LIBUSB_LIBRARY_DIRS})
if(CMAKE_SYSTEM MATCHES "Linux")
find_library(
HIDAPI_HIDRAW_LIBRARY
NAMES hidapi-hidraw
HINTS ${PC_HIDAPI_HIDRAW_LIBRARY_DIRS})
endif()
find_path(
HIDAPI_INCLUDE_DIR
NAMES hidapi.h
PATHS "${HIDAPI_ROOT_DIR}"
PATH_SUFFIXES hidapi include include/hidapi
HINTS ${PC_HIDAPI_HIDRAW_INCLUDE_DIRS} ${PC_HIDAPI_LIBUSB_INCLUDE_DIRS})
find_package(Threads QUIET)
###
# Compute the "I don't care which backend" library
###
set(HIDAPI_LIBRARY)
# First, try to use a preferred backend if supplied
if("${HIDAPI_FIND_COMPONENTS}" MATCHES "libusb"
AND HIDAPI_LIBUSB_LIBRARY
AND NOT HIDAPI_LIBRARY)
set(HIDAPI_LIBRARY ${HIDAPI_LIBUSB_LIBRARY})
endif()
if("${HIDAPI_FIND_COMPONENTS}" MATCHES "hidraw"
AND HIDAPI_HIDRAW_LIBRARY
AND NOT HIDAPI_LIBRARY)
set(HIDAPI_LIBRARY ${HIDAPI_HIDRAW_LIBRARY})
endif()
# Then, if we don't have a preferred one, settle for anything.
if(NOT HIDAPI_LIBRARY)
if(HIDAPI_LIBUSB_LIBRARY)
set(HIDAPI_LIBRARY ${HIDAPI_LIBUSB_LIBRARY})
elseif(HIDAPI_HIDRAW_LIBRARY)
set(HIDAPI_LIBRARY ${HIDAPI_HIDRAW_LIBRARY})
elseif(HIDAPI_UNDECORATED_LIBRARY)
set(HIDAPI_LIBRARY ${HIDAPI_UNDECORATED_LIBRARY})
endif()
endif()
###
# Determine if the various requested components are found.
###
set(_hidapi_component_required_vars)
foreach(_comp IN LISTS HIDAPI_FIND_COMPONENTS)
if("${_comp}" STREQUAL "any")
list(APPEND _hidapi_component_required_vars HIDAPI_INCLUDE_DIR
HIDAPI_LIBRARY)
if(HIDAPI_INCLUDE_DIR AND EXISTS "${HIDAPI_LIBRARY}")
set(HIDAPI_any_FOUND TRUE)
mark_as_advanced(HIDAPI_INCLUDE_DIR)
else()
set(HIDAPI_any_FOUND FALSE)
endif()
elseif("${_comp}" STREQUAL "libusb")
list(APPEND _hidapi_component_required_vars HIDAPI_INCLUDE_DIR
HIDAPI_LIBUSB_LIBRARY)
if(HIDAPI_INCLUDE_DIR AND EXISTS "${HIDAPI_LIBUSB_LIBRARY}")
set(HIDAPI_libusb_FOUND TRUE)
mark_as_advanced(HIDAPI_INCLUDE_DIR HIDAPI_LIBUSB_LIBRARY)
else()
set(HIDAPI_libusb_FOUND FALSE)
endif()
elseif("${_comp}" STREQUAL "hidraw")
list(APPEND _hidapi_component_required_vars HIDAPI_INCLUDE_DIR
HIDAPI_HIDRAW_LIBRARY)
if(HIDAPI_INCLUDE_DIR AND EXISTS "${HIDAPI_HIDRAW_LIBRARY}")
set(HIDAPI_hidraw_FOUND TRUE)
mark_as_advanced(HIDAPI_INCLUDE_DIR HIDAPI_HIDRAW_LIBRARY)
else()
set(HIDAPI_hidraw_FOUND FALSE)
endif()
else()
message(WARNING "${_comp} is not a recognized HIDAPI component")
set(HIDAPI_${_comp}_FOUND FALSE)
endif()
endforeach()
unset(_comp)
###
# FPHSA call
###
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
HIDAPI REQUIRED_VARS ${_hidapi_component_required_vars} THREADS_FOUND
HANDLE_COMPONENTS)
if(HIDAPI_FOUND)
set(HIDAPI_LIBRARIES "${HIDAPI_LIBRARY}")
set(HIDAPI_INCLUDE_DIRS "${HIDAPI_INCLUDE_DIR}")
if(NOT TARGET HIDAPI::hidapi)
add_library(HIDAPI::hidapi UNKNOWN IMPORTED)
set_target_properties(
HIDAPI::hidapi
PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION ${HIDAPI_LIBRARY})
set_property(
TARGET HIDAPI::hidapi PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES
Threads::Threads)
endif()
endif()
if(HIDAPI_libusb_FOUND AND NOT TARGET HIDAPI::hidapi-libusb)
add_library(HIDAPI::hidapi-libusb UNKNOWN IMPORTED)
set_target_properties(
HIDAPI::hidapi-libusb
PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" IMPORTED_LOCATION
${HIDAPI_LIBUSB_LIBRARY})
set_property(TARGET HIDAPI::hidapi-libusb
PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES Threads::Threads)
endif()
if(HIDAPI_hidraw_FOUND AND NOT TARGET HIDAPI::hidapi-hidraw)
add_library(HIDAPI::hidapi-hidraw UNKNOWN IMPORTED)
set_target_properties(
HIDAPI::hidapi-hidraw
PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" IMPORTED_LOCATION
${HIDAPI_HIDRAW_LIBRARY})
set_property(TARGET HIDAPI::hidapi-hidraw
PROPERTY IMPORTED_LINK_INTERFACE_LIBRARIES Threads::Threads)
endif()
+53
View File
@@ -0,0 +1,53 @@
# - Find ORB_SLAM2 OR ORB_SLAM3
#
# It sets the following variables:
# ORB_SLAM_FOUND - Set to false, or undefined, if ORB_SLAM isn't found.
# ORB_SLAM_INCLUDE_DIRS - The ORB_SLAM include directory.
# ORB_SLAM_LIBRARIES - The ORB_SLAM library to link against.
# ORB_SLAM_VERSION - The ORB_SLAM major version.
#
# Set ORB_SLAM_ROOT_DIR environment variable as the path to ORB_SLAM2 or ORB_SLAM3 root folder.
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_SLAM3_LIBRARY NAMES ORB_SLAM3 PATHS $ENV{ORB_SLAM_ROOT_DIR}/lib)
find_path(g2o_INCLUDE_DIR NAMES g2o/core/sparse_optimizer.h PATHS $ENV{ORB_SLAM_ROOT_DIR}/Thirdparty/g2o NO_DEFAULT_PATH)
find_library(g2o_LIBRARY NAMES g2o PATHS $ENV{ORB_SLAM_ROOT_DIR}/Thirdparty/g2o/lib NO_DEFAULT_PATH)
find_library(DBoW2_LIBRARY NAMES DBoW2 PATHS $ENV{ORB_SLAM_ROOT_DIR}/Thirdparty/DBoW2/lib NO_DEFAULT_PATH)
IF(ORB_SLAM2_LIBRARY)
SET(ORB_SLAM_VERSION 2)
SET(ORB_SLAM_LIBRARY ${ORB_SLAM2_LIBRARY})
ELSEIF(ORB_SLAM3_LIBRARY)
SET(ORB_SLAM_VERSION 3)
SET(ORB_SLAM_LIBRARY ${ORB_SLAM3_LIBRARY})
ENDIF()
IF (ORB_SLAM_INCLUDE_DIR AND ORB_SLAM_LIBRARY AND DBoW2_LIBRARY AND g2o_INCLUDE_DIR AND g2o_LIBRARY)
SET(ORB_SLAM_FOUND TRUE)
SET(ORB_SLAM_INCLUDE_DIRS ${ORB_SLAM_INCLUDE_DIR} ${ORB_SLAM_INCLUDE_DIR}/CameraModels ${g2o_INCLUDE_DIR} $ENV{ORB_SLAM_ROOT_DIR})
SET(ORB_SLAM_LIBRARIES ${g2o_LIBRARY} ${ORB_SLAM_LIBRARY} ${DBoW2_LIBRARY})
ENDIF (ORB_SLAM_INCLUDE_DIR AND ORB_SLAM_LIBRARY AND DBoW2_LIBRARY AND g2o_INCLUDE_DIR AND g2o_LIBRARY)
FIND_PACKAGE(Pangolin QUIET)
IF(NOT Pangolin_FOUND)
SET(ORB_SLAM_FOUND FALSE)
MESSAGE(STATUS "Found ORB_SLAM but not Pangolin, disabling ORB_SLAM.")
ELSE()
MESSAGE(STATUS "Found Pangolin: ${Pangolin_INCLUDE_DIRS}")
SET(ORB_SLAM_INCLUDE_DIRS ${ORB_SLAM_INCLUDE_DIRS} ${Pangolin_INCLUDE_DIRS})
SET(ORB_SLAM_LIBRARIES ${ORB_SLAM_LIBRARIES} ${Pangolin_LIBRARIES})
ENDIF()
IF (ORB_SLAM_FOUND)
# show which ORB_SLAM was found only if not quiet
IF (NOT ORB_SLAM_FIND_QUIETLY)
MESSAGE(STATUS "Found ORB_SLAM${ORB_SLAM_VERSION}: ${ORB_SLAM_LIBRARIES}")
ENDIF (NOT ORB_SLAM_FIND_QUIETLY)
ELSE (ORB_SLAM_FOUND)
# fatal error if ORB_SLAM is required but not found
IF (ORB_SLAM_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find ORB_SLAM")
ENDIF (ORB_SLAM_FIND_REQUIRED)
ENDIF (ORB_SLAM_FOUND)
-33
View File
@@ -1,33 +0,0 @@
# - Find ORB_SLAM2
#
# It sets the following variables:
# ORB_SLAM2_FOUND - Set to false, or undefined, if ORB_SLAM2 isn't found.
# ORB_SLAM2_INCLUDE_DIRS - The ORB_SLAM2 include directory.
# ORB_SLAM2_LIBRARIES - The ORB_SLAM2 library to link against.
#
# Set ORB_SLAM2_ROOT_DIR environment variable as the path to ORB_SLAM2 root folder.
find_path(ORB_SLAM2_INCLUDE_DIR NAMES System.h PATHS $ENV{ORB_SLAM2_ROOT_DIR}/include)
find_library(ORB_SLAM2_LIBRARY NAMES ORB_SLAM2 PATHS $ENV{ORB_SLAM2_ROOT_DIR}/lib)
find_path(g2o_INCLUDE_DIR NAMES g2o/core/sparse_optimizer.h PATHS $ENV{ORB_SLAM2_ROOT_DIR}/Thirdparty/g2o NO_DEFAULT_PATH)
find_library(g2o_LIBRARY NAMES g2o PATHS $ENV{ORB_SLAM2_ROOT_DIR}/Thirdparty/g2o/lib NO_DEFAULT_PATH)
find_library(DBoW2_LIBRARY NAMES DBoW2 PATHS $ENV{ORB_SLAM2_ROOT_DIR}/Thirdparty/DBoW2/lib NO_DEFAULT_PATH)
IF (ORB_SLAM2_INCLUDE_DIR AND ORB_SLAM2_LIBRARY AND DBoW2_LIBRARY AND g2o_INCLUDE_DIR AND g2o_LIBRARY)
SET(ORB_SLAM2_FOUND TRUE)
SET(ORB_SLAM2_INCLUDE_DIRS ${ORB_SLAM2_INCLUDE_DIR} ${g2o_INCLUDE_DIR} $ENV{ORB_SLAM2_ROOT_DIR})
SET(ORB_SLAM2_LIBRARIES ${g2o_LIBRARY} ${ORB_SLAM2_LIBRARY} ${DBoW2_LIBRARY})
ENDIF (ORB_SLAM2_INCLUDE_DIR AND ORB_SLAM2_LIBRARY AND DBoW2_LIBRARY AND g2o_INCLUDE_DIR AND g2o_LIBRARY)
IF (ORB_SLAM2_FOUND)
# show which ORB_SLAM2 was found only if not quiet
IF (NOT ORB_SLAM2_FIND_QUIETLY)
MESSAGE(STATUS "Found ORB_SLAM2: ${ORB_SLAM2_LIBRARIES}")
ENDIF (NOT ORB_SLAM2_FIND_QUIETLY)
ELSE (ORB_SLAM2_FOUND)
# fatal error if ORB_SLAM2 is required but not found
IF (ORB_SLAM2_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find ORB_SLAM2")
ENDIF (ORB_SLAM2_FIND_REQUIRED)
ENDIF (ORB_SLAM2_FOUND)
+28
View File
@@ -0,0 +1,28 @@
# - Find ZED Open Capture
# This module finds zed open capture library
#
# It sets the following variables:
# ZEDOC_FOUND - Set to false, or undefined, if ZEDOC isn't found.
# ZEDOC_INCLUDE_DIRS - The ZEDOC include directory.
# ZEDOC_LIBRARIES - The ZEDOC library to link against.
find_library(ZEDOC_LIBRARY NAMES zed_open_capture PATHS $ENV{ZEDOC_ROOT_DIR}/lib)
find_path(ZEDOC_INCLUDE_DIR NAMES zed-open-capture/videocapture.hpp PATHS $ENV{ZEDOC_ROOT_DIR}/include)
IF (ZEDOC_INCLUDE_DIR AND ZEDOC_LIBRARY)
SET(ZEDOC_FOUND TRUE)
SET(ZEDOC_INCLUDE_DIRS ${ZEDOC_INCLUDE_DIR})
SET(ZEDOC_LIBRARIES ${ZEDOC_LIBRARY})
ENDIF (ZEDOC_INCLUDE_DIR AND ZEDOC_LIBRARY)
IF (ZEDOC_FOUND)
# show which ZEDOC was found only if not quiet
IF (NOT _FIND_QUIETLY)
MESSAGE(STATUS "Found ZEDOC: ${ZEDOC_LIBRARIES}")
ENDIF (NOT ZEDOC_FIND_QUIETLY)
ELSE (ZEDOC_FOUND)
# fatal error if ZEDOC is required but not found
IF (ZEDOC_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find ZEDOC (Zed Open Capture)")
ENDIF (ZEDOC_FIND_REQUIRED)
ENDIF (ZEDOC_FOUND)
@@ -32,5 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/core/camera/CameraStereoImages.h> #include <rtabmap/core/camera/CameraStereoImages.h>
#include <rtabmap/core/camera/CameraStereoVideo.h> #include <rtabmap/core/camera/CameraStereoVideo.h>
#include <rtabmap/core/camera/CameraStereoZed.h> #include <rtabmap/core/camera/CameraStereoZed.h>
#include <rtabmap/core/camera/CameraStereoZedOC.h>
#include <rtabmap/core/camera/CameraStereoTara.h> #include <rtabmap/core/camera/CameraStereoTara.h>
#include <rtabmap/core/camera/CameraMyntEye.h> #include <rtabmap/core/camera/CameraMyntEye.h>
#include <rtabmap/core/camera/CameraDepthAI.h>
+2 -1
View File
@@ -69,7 +69,7 @@ public:
void setDistortionModel(const std::string & path); void setDistortionModel(const std::string & path);
void enableBilateralFiltering(float sigmaS, float sigmaR); void enableBilateralFiltering(float sigmaS, float sigmaR);
void disableBilateralFiltering() {_bilateralFiltering = false;} void disableBilateralFiltering() {_bilateralFiltering = false;}
void enableIMUFiltering(int filteringStrategy=1, const ParametersMap & parameters = ParametersMap()); void enableIMUFiltering(int filteringStrategy=1, const ParametersMap & parameters = ParametersMap(), bool baseFrameConversion = false);
void disableIMUFiltering(); void disableIMUFiltering();
RTABMAP_DEPRECATED(void setScanParameters( RTABMAP_DEPRECATED(void setScanParameters(
@@ -125,6 +125,7 @@ private:
float _bilateralSigmaS; float _bilateralSigmaS;
float _bilateralSigmaR; float _bilateralSigmaR;
IMUFilter * _imuFilter; IMUFilter * _imuFilter;
bool _imuBaseFrameConversion;
}; };
} // namespace rtabmap } // namespace rtabmap
+2 -1
View File
@@ -120,7 +120,8 @@ public:
kFeatureSuperPointTorch=11, //new 0.19.7 kFeatureSuperPointTorch=11, //new 0.19.7
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
static std::string typeName(Type type) static std::string typeName(Type type)
{ {
+3
View File
@@ -327,6 +327,9 @@ std::list<std::map<int, Transform> > RTABMAP_EXP getPaths(
std::map<int, Transform> poses, std::map<int, Transform> poses,
const std::multimap<int, Link> & links); const std::multimap<int, Link> & links);
void RTABMAP_EXP computeMinMax(const std::map<int, Transform> & poses,
cv::Vec3f & min,
cv::Vec3f & max);
} /* namespace graph */ } /* namespace graph */
+5 -1
View File
@@ -9,7 +9,8 @@
#define IMU_H_ #define IMU_H_
#include <opencv2/core/core.hpp> #include <opencv2/core/core.hpp>
#include <rtabmap/utilite/ULogger.h> #include <rtabmap/utilite/UEvent.h>
#include <rtabmap/core/Transform.h>
namespace rtabmap { namespace rtabmap {
@@ -60,6 +61,9 @@ public:
const Transform & localTransform() const {return localTransform_;} const Transform & localTransform() const {return localTransform_;}
// apply local transform rotation to data, and set Identity rotation for local transform
void convertToBaseFrame();
bool empty() const bool empty() const
{ {
return localTransform_.isNull(); return localTransform_.isNull();
+35
View File
@@ -71,11 +71,35 @@ public:
public: public:
LaserScan(); LaserScan();
LaserScan(const LaserScan & data,
int maxPoints,
float maxRange,
const Transform & localTransform = Transform::getIdentity());
RTABMAP_DEPRECATED(LaserScan(const LaserScan & data,
int maxPoints,
float maxRange,
Format format,
const Transform & localTransform = Transform::getIdentity()), "Use version without \"format\" argument.");
LaserScan(const cv::Mat & data, LaserScan(const cv::Mat & data,
int maxPoints, int maxPoints,
float maxRange, float maxRange,
Format format, Format format,
const Transform & localTransform = Transform::getIdentity()); const Transform & localTransform = Transform::getIdentity());
RTABMAP_DEPRECATED(LaserScan(const LaserScan & data,
Format format,
float minRange,
float maxRange,
float angleMin,
float angleMax,
float angleIncrement,
const Transform & localTransform = Transform::getIdentity()), "Use version without \"format\" argument.");
LaserScan(const LaserScan & data,
float minRange,
float maxRange,
float angleMin,
float angleMax,
float angleIncrement,
const Transform & localTransform = Transform::getIdentity());
LaserScan(const cv::Mat & data, LaserScan(const cv::Mat & data,
Format format, Format format,
float minRange, float minRange,
@@ -114,6 +138,17 @@ public:
void clear() {data_ = cv::Mat();} void clear() {data_ = cv::Mat();}
private:
void init(const cv::Mat & data,
Format format,
float minRange,
float maxRange,
float angleMin,
float angleMax,
float angleIncrement,
int maxPoints,
const Transform & localTransform = Transform::getIdentity());
private: private:
cv::Mat data_; cv::Mat data_;
Format format_; Format format_;
+2 -2
View File
@@ -49,7 +49,7 @@ public:
kTypeFovis = 2, kTypeFovis = 2,
kTypeViso2 = 3, kTypeViso2 = 3,
kTypeDVO = 4, kTypeDVO = 4,
kTypeORBSLAM2 = 5, kTypeORBSLAM = 5,
kTypeOkvis = 6, kTypeOkvis = 6,
kTypeLOAM = 7, kTypeLOAM = 7,
kTypeMSCKF = 8, kTypeMSCKF = 8,
@@ -67,7 +67,7 @@ public:
virtual void reset(const Transform & initialPose = Transform::getIdentity()); virtual void reset(const Transform & initialPose = Transform::getIdentity());
virtual Odometry::Type getType() = 0; virtual Odometry::Type getType() = 0;
virtual bool canProcessRawImages() const {return false;} virtual bool canProcessRawImages() const {return false;}
virtual bool canProcessIMU() const {return false;} virtual bool canProcessAsyncIMU() const {return false;}
//getters //getters
const Transform & getPose() const {return _pose;} const Transform & getPose() const {return _pose;}
+3 -1
View File
@@ -84,6 +84,7 @@ public:
output.transformFiltered = transformFiltered; output.transformFiltered = transformFiltered;
output.transformGroundTruth = transformGroundTruth; output.transformGroundTruth = transformGroundTruth;
output.guessVelocity = guessVelocity; output.guessVelocity = guessVelocity;
output.guess = guess;
output.distanceTravelled = distanceTravelled; output.distanceTravelled = distanceTravelled;
output.memoryUsage = memoryUsage; output.memoryUsage = memoryUsage;
output.gravityRollError = gravityRollError; output.gravityRollError = gravityRollError;
@@ -111,7 +112,8 @@ public:
Transform transform; Transform transform;
Transform transformFiltered; Transform transformFiltered;
Transform transformGroundTruth; Transform transformGroundTruth;
Transform guessVelocity; Transform guessVelocity; // deprecated, will be removed. Use guess and interval instead.
Transform guess;
float distanceTravelled; float distanceTravelled;
int memoryUsage; //MB int memoryUsage; //MB
double gravityRollError; double gravityRollError;
+47
View File
@@ -0,0 +1,47 @@
/*
Copyright (c) 2010-2021, 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 CORELIB_INCLUDE_RTABMAP_CORE_PDALWRITER_H_
#define CORELIB_INCLUDE_RTABMAP_CORE_PDALWRITER_H_
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
namespace rtabmap {
std::string getPDALSupportedWriters();
int savePDALFile(const std::string & filePath, const pcl::PointCloud<pcl::PointXYZ> & cloud, const std::vector<int> & cameraIds = std::vector<int>(), bool binary = false);
int savePDALFile(const std::string & filePath, const pcl::PointCloud<pcl::PointXYZRGB> & cloud, const std::vector<int> & cameraIds = std::vector<int>(), bool binary = false);
int savePDALFile(const std::string & filePath, const pcl::PointCloud<pcl::PointXYZRGBNormal> & cloud, const std::vector<int> & cameraIds = std::vector<int>(), bool binary = false);
int savePDALFile(const std::string & filePath, const pcl::PointCloud<pcl::PointXYZI> & cloud, const std::vector<int> & cameraIds = std::vector<int>(), bool binary = false);
int savePDALFile(const std::string & filePath, const pcl::PointCloud<pcl::PointXYZINormal> & cloud, const std::vector<int> & cameraIds = std::vector<int>(), bool binary = false);
}
#endif /* CORELIB_INCLUDE_RTABMAP_CORE_PDALWRITER_H_ */
+47 -33
View File
@@ -244,9 +244,9 @@ class RTABMAP_EXP Parameters
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"); 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");
#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"); 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");
#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.");
@@ -296,7 +296,7 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(FAST, CV, int, 0, "Enable FastCV implementation if non-zero (and RTAB-Map is built with FastCV support). Values should be 9 and 10."); RTABMAP_PARAM(FAST, CV, int, 0, "Enable FastCV implementation if non-zero (and RTAB-Map is built with FastCV support). Values should be 9 and 10.");
RTABMAP_PARAM(GFTT, QualityLevel, double, 0.001, ""); RTABMAP_PARAM(GFTT, QualityLevel, double, 0.001, "");
RTABMAP_PARAM(GFTT, MinDistance, double, 3, ""); RTABMAP_PARAM(GFTT, MinDistance, double, 7, "");
RTABMAP_PARAM(GFTT, BlockSize, int, 3, ""); RTABMAP_PARAM(GFTT, BlockSize, int, 3, "");
RTABMAP_PARAM(GFTT, UseHarrisDetector, bool, false, ""); RTABMAP_PARAM(GFTT, UseHarrisDetector, bool, false, "");
RTABMAP_PARAM(GFTT, K, double, 0.04, ""); RTABMAP_PARAM(GFTT, K, double, 0.04, "");
@@ -332,6 +332,9 @@ class RTABMAP_EXP 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(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.");
// BayesFilter // BayesFilter
RTABMAP_PARAM(Bayes, VirtualPlacePriorThr, float, 0.9, "Virtual place prior"); RTABMAP_PARAM(Bayes, VirtualPlacePriorThr, float, 0.9, "Virtual place prior");
RTABMAP_PARAM_STR(Bayes, PredictionLC, "0.1 0.36 0.30 0.16 0.062 0.0151 0.00255 0.000324 2.5e-05 1.3e-06 4.8e-08 1.2e-09 1.9e-11 2.2e-13 1.7e-15 8.5e-18 2.9e-20 6.9e-23", "Prediction of loop closures (Gaussian-like, here with sigma=1.6) - Format: {VirtualPlaceProb, LoopClosureProb, NeighborLvl1, NeighborLvl2, ...}."); RTABMAP_PARAM_STR(Bayes, PredictionLC, "0.1 0.36 0.30 0.16 0.062 0.0151 0.00255 0.000324 2.5e-05 1.3e-06 4.8e-08 1.2e-09 1.9e-11 2.2e-13 1.7e-15 8.5e-18 2.9e-20 6.9e-23", "Prediction of loop closures (Gaussian-like, here with sigma=1.6) - Format: {VirtualPlaceProb, LoopClosureProb, NeighborLvl1, NeighborLvl2, ...}.");
@@ -344,7 +347,7 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(VhEp, RansacParam2, float, 0.99, "Fundamental matrix (see cvFindFundamentalMat()): Performance of RANSAC."); RTABMAP_PARAM(VhEp, RansacParam2, float, 0.99, "Fundamental matrix (see cvFindFundamentalMat()): Performance of RANSAC.");
// RGB-D SLAM // RGB-D SLAM
RTABMAP_PARAM(RGBD, Enabled, bool, true, ""); 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, "Minimum linear displacement (m) to update the map. Rehearsal is done prior to this, so weights are still updated.");
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, "Minimum angular displacement (rad) to update the map. Rehearsal is done prior to this, so weights are still updated.");
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).");
@@ -353,7 +356,7 @@ class RTABMAP_EXP Parameters
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. Not compatible with \"%s\" if enabled.", kOptimizerRobust().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, SavedLocalizationIgnored, bool, false, "Ignore last saved localization pose from previous session. If true, RTAB-Map won't assume it is restarting from the same place than where it shut down previously."); 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, GoalReachedRadius, float, 0.5, "Goal reached radius (m)."); RTABMAP_PARAM(RGBD, GoalReachedRadius, float, 0.5, "Goal reached radius (m).");
RTABMAP_PARAM(RGBD, PlanStuckIterations, int, 0, "Mark the current goal node on the path as unreachable if it is not updated after X iterations (0=disabled). If all upcoming nodes on the path are unreachabled, the plan fails."); RTABMAP_PARAM(RGBD, PlanStuckIterations, int, 0, "Mark the current goal node on the path as unreachable if it is not updated after X iterations (0=disabled). If all upcoming nodes on the path are unreachabled, the plan fails.");
RTABMAP_PARAM(RGBD, PlanLinearVelocity, float, 0, "Linear velocity (m/sec) used to compute path weights."); RTABMAP_PARAM(RGBD, PlanLinearVelocity, float, 0, "Linear velocity (m/sec) used to compute path weights.");
@@ -362,8 +365,9 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(RGBD, MaxLocalRetrieved, unsigned int, 2, "Maximum local locations retrieved (0=disabled) near the current pose in the local map or on the current planned path (those on the planned path have priority)."); RTABMAP_PARAM(RGBD, MaxLocalRetrieved, unsigned int, 2, "Maximum local locations retrieved (0=disabled) near the current pose in the local map or on the current planned path (those on the planned path have priority).");
RTABMAP_PARAM(RGBD, LocalRadius, float, 10, "Local radius (m) for nodes selection in the local map. This parameter is used in some approaches about the local map management."); RTABMAP_PARAM(RGBD, LocalRadius, float, 10, "Local radius (m) for nodes selection in the local map. This parameter is used in some approaches about the local map management.");
RTABMAP_PARAM(RGBD, LocalImmunizationRatio, float, 0.25, "Ratio of working memory for which local nodes are immunized from transfer."); RTABMAP_PARAM(RGBD, LocalImmunizationRatio, float, 0.25, "Ratio of working memory for which local nodes are immunized from transfer.");
RTABMAP_PARAM(RGBD, ScanMatchingIdsSavedInLinks, bool, true, "Save scan matching IDs in link's user data."); RTABMAP_PARAM(RGBD, ScanMatchingIdsSavedInLinks, bool, true, "Save scan matching IDs from one-to-many proximity detection in link's user data.");
RTABMAP_PARAM(RGBD, NeighborLinkRefining, bool, false, uFormat("When a new node is added to the graph, the transformation of its neighbor link to the previous node is refined using registration approach selected (%s).", kRegStrategy().c_str())); RTABMAP_PARAM(RGBD, NeighborLinkRefining, bool, false, uFormat("When a new node is added to the graph, the transformation of its neighbor link to the previous node is refined using registration approach selected (%s).", kRegStrategy().c_str()));
RTABMAP_PARAM(RGBD, LoopClosureIdentityGuess, bool, false, uFormat("Use Identity matrix as guess when computing loop closure transform, otherwise no guess is used, thus assuming that registration strategy selected (%s) can deal with transformation estimation without guess.", kRegStrategy().c_str()));
RTABMAP_PARAM(RGBD, LoopClosureReextractFeatures, bool, false, "Extract features even if there are some already in the nodes."); RTABMAP_PARAM(RGBD, LoopClosureReextractFeatures, bool, false, "Extract features even if there are some already in the nodes.");
RTABMAP_PARAM(RGBD, LocalBundleOnLoopClosure, bool, false, "Do local bundle adjustment with neighborhood of the loop closure."); RTABMAP_PARAM(RGBD, LocalBundleOnLoopClosure, bool, false, "Do local bundle adjustment with neighborhood of the loop closure.");
RTABMAP_PARAM(RGBD, CreateOccupancyGrid, bool, false, "Create local occupancy grid maps. See \"Grid\" group for parameters."); RTABMAP_PARAM(RGBD, CreateOccupancyGrid, bool, false, "Create local occupancy grid maps. See \"Grid\" group for parameters.");
@@ -375,12 +379,12 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(RGBD, ProximityByTime, bool, false, "Detection over all locations in STM."); RTABMAP_PARAM(RGBD, ProximityByTime, bool, false, "Detection over all locations in STM.");
RTABMAP_PARAM(RGBD, ProximityBySpace, bool, true, "Detection over locations (in Working Memory) near in space."); RTABMAP_PARAM(RGBD, ProximityBySpace, bool, true, "Detection over locations (in Working Memory) near in space.");
RTABMAP_PARAM(RGBD, ProximityMaxGraphDepth, int, 50, "Maximum depth from the current/last loop closure location and the local loop closure hypotheses. Set 0 to ignore."); RTABMAP_PARAM(RGBD, ProximityMaxGraphDepth, int, 50, "Maximum depth from the current/last loop closure location and the local loop closure hypotheses. Set 0 to ignore.");
RTABMAP_PARAM(RGBD, ProximityMaxPaths, int, 3, "Maximum paths compared (from the most recent) for proximity detection by space. 0 means no limit."); RTABMAP_PARAM(RGBD, ProximityMaxPaths, int, 3, "Maximum paths compared (from the most recent) for proximity detection. 0 means no limit.");
RTABMAP_PARAM(RGBD, ProximityPathFilteringRadius, float, 1, "Path filtering radius to reduce the number of nodes to compare in a path. A path should also be inside that radius to be considered for proximity detection."); RTABMAP_PARAM(RGBD, ProximityPathFilteringRadius, float, 1, "Path filtering radius to reduce the number of nodes to compare in a path in one-to-many proximity detection. The nearest node in a path should be inside that radius to be considered for one-to-one proximity detection.");
RTABMAP_PARAM(RGBD, ProximityPathMaxNeighbors, int, 0, "Maximum neighbor nodes compared on each path. Set to 0 to disable merging the laser scans."); RTABMAP_PARAM(RGBD, ProximityPathMaxNeighbors, int, 0, "Maximum neighbor nodes compared on each path for one-to-many proximity detection. Set to 0 to disable one-to-many proximity detection (by merging the laser scans).");
RTABMAP_PARAM(RGBD, ProximityPathRawPosesUsed, bool, true, "When comparing to a local path, merge the scan using the odometry poses (with neighbor link optimizations) instead of the ones in the optimized local graph."); RTABMAP_PARAM(RGBD, ProximityPathRawPosesUsed, bool, true, "When comparing to a local path for one-to-many proximity detection, merge the scans using the odometry poses (with neighbor link optimizations) instead of the ones in the optimized local graph.");
RTABMAP_PARAM(RGBD, ProximityAngle, float, 45, "Maximum angle (degrees) for visual proximity detection."); RTABMAP_PARAM(RGBD, ProximityAngle, float, 45, "Maximum angle (degrees) for one-to-one proximity detection.");
RTABMAP_PARAM(RGBD, ProximityOdomGuess, bool, false, "Use odometry as motion guess for visual proximity detection."); RTABMAP_PARAM(RGBD, ProximityOdomGuess, bool, false, "Use odometry as motion guess for one-to-one proximity detection.");
// Graph optimization // Graph optimization
#ifdef RTABMAP_GTSAM #ifdef RTABMAP_GTSAM
@@ -408,9 +412,13 @@ class RTABMAP_EXP Parameters
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, 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, 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)
RTABMAP_PARAM(Optimizer, GravitySigma, float, 0.3, uFormat("Gravity sigma value (>=0, typically between 0.1 and 0.3). Optimization is done while preserving gravity orientation of the poses. This should be used only with visual/lidar inertial odometry approaches, for which we assume that all odometry poses are aligned with gravity. Set to 0 to disable gravity constraints. Currently supported only with g2o and GTSAM optimization strategies (see %s).", kOptimizerStrategy().c_str()));
#else
RTABMAP_PARAM(Optimizer, GravitySigma, float, 0.0, uFormat("Gravity sigma value (>=0, typically between 0.1 and 0.3). Optimization is done while preserving gravity orientation of the poses. This should be used only with visual/lidar inertial odometry approaches, for which we assume that all odometry poses are aligned with gravity. Set to 0 to disable gravity constraints. Currently supported only with g2o and GTSAM optimization strategies (see %s).", kOptimizerStrategy().c_str())); RTABMAP_PARAM(Optimizer, GravitySigma, float, 0.0, uFormat("Gravity sigma value (>=0, typically between 0.1 and 0.3). Optimization is done while preserving gravity orientation of the poses. This should be used only with visual/lidar inertial odometry approaches, for which we assume that all odometry poses are aligned with gravity. Set to 0 to disable gravity constraints. Currently supported only with g2o and GTSAM optimization strategies (see %s).", kOptimizerStrategy().c_str()));
#endif
#ifdef RTABMAP_ORB_SLAM2 #ifdef RTABMAP_ORB_SLAM
RTABMAP_PARAM(g2o, Solver, int, 3, "0=csparse 1=pcg 2=cholmod 3=Eigen"); RTABMAP_PARAM(g2o, Solver, int, 3, "0=csparse 1=pcg 2=cholmod 3=Eigen");
#else #else
RTABMAP_PARAM(g2o, Solver, int, 0, "0=csparse 1=pcg 2=cholmod 3=Eigen"); RTABMAP_PARAM(g2o, Solver, int, 0, "0=csparse 1=pcg 2=cholmod 3=Eigen");
@@ -452,7 +460,7 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(OdomF2M, ScanSubtractAngle, float, 45, uFormat("[Geometry] Max angle (degrees) used to filter points of a new added scan to local map (when \"%s\">0). 0 means any angle.", kOdomF2MScanSubtractRadius().c_str()).c_str()); RTABMAP_PARAM(OdomF2M, ScanSubtractAngle, float, 45, uFormat("[Geometry] Max angle (degrees) used to filter points of a new added scan to local map (when \"%s\">0). 0 means any angle.", kOdomF2MScanSubtractRadius().c_str()).c_str());
RTABMAP_PARAM(OdomF2M, ScanRange, float, 0, "[Geometry] Distance Range used to filter points of local map (when > 0). 0 means local map is updated using time and not range."); RTABMAP_PARAM(OdomF2M, ScanRange, float, 0, "[Geometry] Distance Range used to filter points of local map (when > 0). 0 means local map is updated using time and not range.");
RTABMAP_PARAM(OdomF2M, ValidDepthRatio, float, 0.75, "If a new frame has points without valid depth, they are added to local feature map only if points with valid depth on total points is over this ratio. Setting to 1 means no points without valid depth are added to local feature map."); RTABMAP_PARAM(OdomF2M, ValidDepthRatio, float, 0.75, "If a new frame has points without valid depth, they are added to local feature map only if points with valid depth on total points is over this ratio. Setting to 1 means no points without valid depth are added to local feature map.");
#if defined(RTABMAP_G2O) || defined(RTABMAP_ORB_SLAM2) #if defined(RTABMAP_G2O) || defined(RTABMAP_ORB_SLAM)
RTABMAP_PARAM(OdomF2M, BundleAdjustment, int, 1, "Local bundle adjustment: 0=disabled, 1=g2o, 2=cvsba, 3=Ceres."); RTABMAP_PARAM(OdomF2M, BundleAdjustment, int, 1, "Local bundle adjustment: 0=disabled, 1=g2o, 2=cvsba, 3=Ceres.");
#else #else
RTABMAP_PARAM(OdomF2M, BundleAdjustment, int, 0, "Local bundle adjustment: 0=disabled, 1=g2o, 2=cvsba, 3=Ceres."); RTABMAP_PARAM(OdomF2M, BundleAdjustment, int, 0, "Local bundle adjustment: 0=disabled, 1=g2o, 2=cvsba, 3=Ceres.");
@@ -513,12 +521,12 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(OdomViso2, BucketHeight, double, 50, "Height of bucket."); RTABMAP_PARAM(OdomViso2, BucketHeight, double, 50, "Height of bucket.");
// Odometry ORB_SLAM2 // Odometry ORB_SLAM2
RTABMAP_PARAM_STR(OdomORBSLAM2, VocPath, "", "Path to ORB vocabulary (*.txt)."); RTABMAP_PARAM_STR(OdomORBSLAM, VocPath, "", "Path to ORB vocabulary (*.txt).");
RTABMAP_PARAM(OdomORBSLAM2, 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(OdomORBSLAM2, ThDepth, double, 40.0, "Close/Far threshold. Baseline times."); RTABMAP_PARAM(OdomORBSLAM, ThDepth, double, 40.0, "Close/Far threshold. Baseline times.");
RTABMAP_PARAM(OdomORBSLAM2, Fps, float, 0.0, "Camera FPS."); RTABMAP_PARAM(OdomORBSLAM, Fps, float, 0.0, "Camera FPS.");
RTABMAP_PARAM(OdomORBSLAM2, MaxFeatures, int, 1000, "Maximum ORB features extracted per frame."); RTABMAP_PARAM(OdomORBSLAM, MaxFeatures, int, 1000, "Maximum ORB features extracted per frame.");
RTABMAP_PARAM(OdomORBSLAM2, MapSize, int, 3000, "Maximum size of the feature map (0 means infinite)."); RTABMAP_PARAM(OdomORBSLAM, MapSize, int, 3000, "Maximum size of the feature map (0 means infinite).");
// Odometry OKVIS // Odometry OKVIS
RTABMAP_PARAM_STR(OdomOKVIS, ConfigPath, "", "Path of OKVIS config file."); RTABMAP_PARAM_STR(OdomOKVIS, ConfigPath, "", "Path of OKVIS config file.");
@@ -574,7 +582,7 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(Vis, RefineIterations, int, 5, uFormat("[%s = 0] Number of iterations used to refine the transformation found by RANSAC. 0 means that the transformation is not refined.", kVisEstimationType().c_str())); RTABMAP_PARAM(Vis, RefineIterations, int, 5, uFormat("[%s = 0] Number of iterations used to refine the transformation found by RANSAC. 0 means that the transformation is not refined.", kVisEstimationType().c_str()));
RTABMAP_PARAM(Vis, PnPReprojError, float, 2, uFormat("[%s = 1] PnP reprojection error.", kVisEstimationType().c_str())); RTABMAP_PARAM(Vis, PnPReprojError, float, 2, uFormat("[%s = 1] PnP reprojection error.", kVisEstimationType().c_str()));
RTABMAP_PARAM(Vis, PnPFlags, int, 0, uFormat("[%s = 1] PnP flags: 0=Iterative, 1=EPNP, 2=P3P", kVisEstimationType().c_str())); RTABMAP_PARAM(Vis, PnPFlags, int, 0, uFormat("[%s = 1] PnP flags: 0=Iterative, 1=EPNP, 2=P3P", kVisEstimationType().c_str()));
#if defined(RTABMAP_G2O) || defined(RTABMAP_ORB_SLAM2) #if defined(RTABMAP_G2O) || defined(RTABMAP_ORB_SLAM)
RTABMAP_PARAM(Vis, PnPRefineIterations, int, 0, uFormat("[%s = 1] Refine iterations. Set to 0 if \"%s\" is also used.", kVisEstimationType().c_str(), kVisBundleAdjustment().c_str())); RTABMAP_PARAM(Vis, PnPRefineIterations, int, 0, uFormat("[%s = 1] Refine iterations. Set to 0 if \"%s\" is also used.", kVisEstimationType().c_str(), kVisBundleAdjustment().c_str()));
#else #else
RTABMAP_PARAM(Vis, PnPRefineIterations, int, 1, uFormat("[%s = 1] Refine iterations. Set to 0 if \"%s\" is also used.", kVisEstimationType().c_str(), kVisBundleAdjustment().c_str())); RTABMAP_PARAM(Vis, PnPRefineIterations, int, 1, uFormat("[%s = 1] Refine iterations. Set to 0 if \"%s\" is also used.", kVisEstimationType().c_str(), kVisBundleAdjustment().c_str()));
@@ -588,9 +596,9 @@ class RTABMAP_EXP 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"); 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");
#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"); 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");
#endif #endif
RTABMAP_PARAM(Vis, MaxFeatures, int, 1000, "0 no limits."); RTABMAP_PARAM(Vis, MaxFeatures, int, 1000, "0 no limits.");
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).");
@@ -605,20 +613,20 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(Vis, CorType, int, 0, "Correspondences computation approach: 0=Features Matching, 1=Optical Flow"); RTABMAP_PARAM(Vis, CorType, int, 0, "Correspondences computation approach: 0=Features Matching, 1=Optical Flow");
RTABMAP_PARAM(Vis, CorNNType, int, 1, uFormat("[%s=0] kNNFlannNaive=0, kNNFlannKdTree=1, kNNFlannLSH=2, kNNBruteForce=3, kNNBruteForceGPU=4, BruteForceCrossCheck=5, SuperGlue=6, GMS=7. Used for features matching approach.", kVisCorType().c_str())); RTABMAP_PARAM(Vis, CorNNType, int, 1, uFormat("[%s=0] kNNFlannNaive=0, kNNFlannKdTree=1, kNNFlannLSH=2, kNNBruteForce=3, kNNBruteForceGPU=4, BruteForceCrossCheck=5, SuperGlue=6, GMS=7. Used for features matching approach.", kVisCorType().c_str()));
RTABMAP_PARAM(Vis, CorNNDR, float, 0.8, uFormat("[%s=0] NNDR: nearest neighbor distance ratio. Used for knn features matching approach.", kVisCorType().c_str())); RTABMAP_PARAM(Vis, CorNNDR, float, 0.8, uFormat("[%s=0] NNDR: nearest neighbor distance ratio. Used for knn features matching approach.", kVisCorType().c_str()));
RTABMAP_PARAM(Vis, CorGuessWinSize, int, 20, uFormat("[%s=0] Matching window size (pixels) around projected points when a guess transform is provided to find correspondences. 0 means disabled.", kVisCorType().c_str())); RTABMAP_PARAM(Vis, CorGuessWinSize, int, 40, uFormat("[%s=0] Matching window size (pixels) around projected points when a guess transform is provided to find correspondences. 0 means disabled.", kVisCorType().c_str()));
RTABMAP_PARAM(Vis, CorGuessMatchToProjection, bool, false, uFormat("[%s=0] Match frame's corners to source's projected points (when guess transform is provided) instead of projected points to frame's corners.", kVisCorType().c_str())); RTABMAP_PARAM(Vis, CorGuessMatchToProjection, bool, false, uFormat("[%s=0] Match frame's corners to source's projected points (when guess transform is provided) instead of projected points to frame's corners.", kVisCorType().c_str()));
RTABMAP_PARAM(Vis, CorFlowWinSize, int, 16, uFormat("[%s=1] See cv::calcOpticalFlowPyrLK(). Used for optical flow approach.", kVisCorType().c_str())); RTABMAP_PARAM(Vis, CorFlowWinSize, int, 16, 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, 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()));
#if defined(RTABMAP_G2O) || defined(RTABMAP_ORB_SLAM2) #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.");
#endif #endif
// Features matching approaches // Features matching approaches
RTABMAP_PARAM_STR(PyMatcher, Path, "", "Path to python script file (see available ones in rtabmap/corelib/src/pymatcher/*). See the header to see where the script should be copied."); RTABMAP_PARAM_STR(PyMatcher, 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(PyMatcher, Iterations, int, 20, "Sinkhorn iterations. Used by SuperGlue."); RTABMAP_PARAM(PyMatcher, Iterations, int, 20, "Sinkhorn iterations. Used by SuperGlue.");
RTABMAP_PARAM(PyMatcher, Threshold, float, 0.2, "Used by SuperGlue."); RTABMAP_PARAM(PyMatcher, Threshold, float, 0.2, "Used by SuperGlue.");
RTABMAP_PARAM(PyMatcher, Cuda, bool, true, "Used by SuperGlue."); RTABMAP_PARAM(PyMatcher, Cuda, bool, true, "Used by SuperGlue.");
@@ -629,9 +637,14 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(GMS, ThresholdFactor, double, 6.0, "The higher, the less matches."); RTABMAP_PARAM(GMS, ThresholdFactor, double, 6.0, "The higher, the less matches.");
// ICP registration parameters // ICP registration parameters
#ifdef RTABMAP_POINTMATCHER
RTABMAP_PARAM(Icp, Strategy, int, 1, "ICP implementation: 0=Point Cloud Library, 1=libpointmatcher, 2=CCCoreLib (CloudCompare).");
#else
RTABMAP_PARAM(Icp, Strategy, int, 0, "ICP implementation: 0=Point Cloud Library, 1=libpointmatcher, 2=CCCoreLib (CloudCompare).");
#endif
RTABMAP_PARAM(Icp, MaxTranslation, float, 0.2, "Maximum ICP translation correction accepted (m)."); RTABMAP_PARAM(Icp, MaxTranslation, float, 0.2, "Maximum ICP translation correction accepted (m).");
RTABMAP_PARAM(Icp, MaxRotation, float, 0.78, "Maximum ICP rotation correction accepted (rad)."); RTABMAP_PARAM(Icp, MaxRotation, float, 0.78, "Maximum ICP rotation correction accepted (rad).");
RTABMAP_PARAM(Icp, VoxelSize, float, 0.0, "Uniform sampling voxel size (0=disabled)."); RTABMAP_PARAM(Icp, VoxelSize, float, 0.05, "Uniform sampling voxel size (0=disabled).");
RTABMAP_PARAM(Icp, DownsamplingStep, int, 1, "Downsampling step size (1=no sampling). This is done before uniform sampling."); RTABMAP_PARAM(Icp, DownsamplingStep, int, 1, "Downsampling step size (1=no sampling). This is done before uniform sampling.");
RTABMAP_PARAM(Icp, RangeMin, float, 0, "Minimum range filtering (0=disabled)."); RTABMAP_PARAM(Icp, RangeMin, float, 0, "Minimum range filtering (0=disabled).");
RTABMAP_PARAM(Icp, RangeMax, float, 0, "Maximum range filtering (0=disabled)."); RTABMAP_PARAM(Icp, RangeMax, float, 0, "Maximum range filtering (0=disabled).");
@@ -643,6 +656,7 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(Icp, Iterations, int, 30, "Max iterations."); RTABMAP_PARAM(Icp, Iterations, int, 30, "Max iterations.");
RTABMAP_PARAM(Icp, Epsilon, float, 0, "Set the transformation epsilon (maximum allowable difference between two consecutive transformations) in order for an optimization to be considered as having converged to the final solution."); RTABMAP_PARAM(Icp, Epsilon, float, 0, "Set the transformation epsilon (maximum allowable difference between two consecutive transformations) in order for an optimization to be considered as having converged to the final solution.");
RTABMAP_PARAM(Icp, CorrespondenceRatio, float, 0.1, "Ratio of matching correspondences to accept the transform."); RTABMAP_PARAM(Icp, CorrespondenceRatio, float, 0.1, "Ratio of matching correspondences to accept the transform.");
RTABMAP_PARAM(Icp, Force4DoF, bool, false, uFormat("Limit ICP to x, y, z and yaw DoF. Available if %s > 0.", kIcpStrategy().c_str()));
#ifdef RTABMAP_POINTMATCHER #ifdef RTABMAP_POINTMATCHER
RTABMAP_PARAM(Icp, PointToPlane, bool, true, "Use point to plane ICP."); RTABMAP_PARAM(Icp, PointToPlane, bool, true, "Use point to plane ICP.");
#else #else
@@ -653,18 +667,17 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(Icp, PointToPlaneGroundNormalsUp, float, 0.0, "Invert normals on ground if they are pointing down (useful for ring-like 3D LiDARs). 0 means disabled, 1 means only normals perfectly aligned with -z axis. This is only done with 3D scans."); RTABMAP_PARAM(Icp, PointToPlaneGroundNormalsUp, float, 0.0, "Invert normals on ground if they are pointing down (useful for ring-like 3D LiDARs). 0 means disabled, 1 means only normals perfectly aligned with -z axis. This is only done with 3D scans.");
RTABMAP_PARAM(Icp, PointToPlaneMinComplexity, float, 0.02, uFormat("Minimum structural complexity (0.0=low, 1.0=high) of the scan to do PointToPlane registration, otherwise PointToPoint registration is done instead and strategy from %s is used. This check is done only when %s=true.", kIcpPointToPlaneLowComplexityStrategy().c_str(), kIcpPointToPlane().c_str())); RTABMAP_PARAM(Icp, PointToPlaneMinComplexity, float, 0.02, uFormat("Minimum structural complexity (0.0=low, 1.0=high) of the scan to do PointToPlane registration, otherwise PointToPoint registration is done instead and strategy from %s is used. This check is done only when %s=true.", kIcpPointToPlaneLowComplexityStrategy().c_str(), kIcpPointToPlane().c_str()));
RTABMAP_PARAM(Icp, PointToPlaneLowComplexityStrategy, int, 1, uFormat("If structural complexity is below %s: set to 0 to so that the transform is automatically rejected, set to 1 to limit ICP correction in axes with most constraints (e.g., for a corridor-like environment, the resulting transform will be limited in y and yaw, x will taken from the guess), set to 2 to accept \"as is\" the transform computed by PointToPoint.", kIcpPointToPlaneMinComplexity().c_str())); RTABMAP_PARAM(Icp, PointToPlaneLowComplexityStrategy, int, 1, uFormat("If structural complexity is below %s: set to 0 to so that the transform is automatically rejected, set to 1 to limit ICP correction in axes with most constraints (e.g., for a corridor-like environment, the resulting transform will be limited in y and yaw, x will taken from the guess), set to 2 to accept \"as is\" the transform computed by PointToPoint.", kIcpPointToPlaneMinComplexity().c_str()));
RTABMAP_PARAM(Icp, OutlierRatio, float, 0.85, uFormat("Outlier ratio used with %s>0. For libpointmatcher, this parameter set TrimmedDistOutlierFilter/ratio for convenience when configuration file is not set. For CCCoreLib, this parameter set the \"finalOverlapRatio\". The value should be between 0 and 1.", kIcpStrategy().c_str()));
// libpointmatcher // libpointmatcher
#ifdef RTABMAP_POINTMATCHER
RTABMAP_PARAM(Icp, PM, bool, true, "Use libpointmatcher for ICP registration instead of PCL's implementation.");
#else
RTABMAP_PARAM(Icp, PM, bool, false, "Use libpointmatcher for ICP registration instead of PCL's implementation.");
#endif
RTABMAP_PARAM_STR(Icp, PMConfig, "", uFormat("Configuration file (*.yaml) used by libpointmatcher. Note that data filters set for libpointmatcher are done after filtering done by rtabmap (i.e., %s, %s), so make sure to disable those in rtabmap if you want to use only those from libpointmatcher. Parameters %s, %s and %s are also ignored if configuration file is set.", kIcpVoxelSize().c_str(), kIcpDownsamplingStep().c_str(), kIcpIterations().c_str(), kIcpEpsilon().c_str(), kIcpMaxCorrespondenceDistance().c_str()).c_str()); RTABMAP_PARAM_STR(Icp, PMConfig, "", uFormat("Configuration file (*.yaml) used by libpointmatcher. Note that data filters set for libpointmatcher are done after filtering done by rtabmap (i.e., %s, %s), so make sure to disable those in rtabmap if you want to use only those from libpointmatcher. Parameters %s, %s and %s are also ignored if configuration file is set.", kIcpVoxelSize().c_str(), kIcpDownsamplingStep().c_str(), kIcpIterations().c_str(), kIcpEpsilon().c_str(), kIcpMaxCorrespondenceDistance().c_str()).c_str());
RTABMAP_PARAM(Icp, PMMatcherKnn, int, 1, "KDTreeMatcher/knn: number of nearest neighbors to consider it the reference. For convenience when configuration file is not set."); RTABMAP_PARAM(Icp, PMMatcherKnn, int, 1, "KDTreeMatcher/knn: number of nearest neighbors to consider it the reference. For convenience when configuration file is not set.");
RTABMAP_PARAM(Icp, PMMatcherEpsilon, float, 0.0, "KDTreeMatcher/epsilon: approximation to use for the nearest-neighbor search. For convenience when configuration file is not set."); RTABMAP_PARAM(Icp, PMMatcherEpsilon, float, 0.0, "KDTreeMatcher/epsilon: approximation to use for the nearest-neighbor search. For convenience when configuration file is not set.");
RTABMAP_PARAM(Icp, PMMatcherIntensity, bool, false, uFormat("KDTreeMatcher: among nearest neighbors, keep only the one with the most similar intensity. This only work with %s>1.", kIcpPMMatcherKnn().c_str())); RTABMAP_PARAM(Icp, PMMatcherIntensity, bool, false, uFormat("KDTreeMatcher: among nearest neighbors, keep only the one with the most similar intensity. This only work with %s>1.", kIcpPMMatcherKnn().c_str()));
RTABMAP_PARAM(Icp, PMOutlierRatio, float, 0.95, "TrimmedDistOutlierFilter/ratio: For convenience when configuration file is not set. For kinect-like point cloud, use 0.65.");
RTABMAP_PARAM(Icp, CCSamplingLimit, unsigned int, 50000, "Maximum number of points per cloud (they are randomly resampled below this limit otherwise).");
RTABMAP_PARAM(Icp, CCFilterOutFarthestPoints, bool, false, "If true, the algorithm will automatically ignore farthest points from the reference, for better convergence.");
RTABMAP_PARAM(Icp, CCMaxFinalRMS, float, 0.2, "Maximum final RMS error.");
// Stereo disparity // Stereo disparity
RTABMAP_PARAM(Stereo, WinWidth, int, 15, "Window width."); RTABMAP_PARAM(Stereo, WinWidth, int, 15, "Window width.");
@@ -745,6 +758,7 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(GridGlobal, MinSize, float, 0.0, "Minimum map size (m)."); RTABMAP_PARAM(GridGlobal, MinSize, float, 0.0, "Minimum map size (m).");
RTABMAP_PARAM(GridGlobal, Eroded, bool, false, "Erode obstacle cells."); RTABMAP_PARAM(GridGlobal, Eroded, bool, false, "Erode obstacle cells.");
RTABMAP_PARAM(GridGlobal, MaxNodes, int, 0, "Maximum nodes assembled in the map starting from the last node (0=unlimited)."); RTABMAP_PARAM(GridGlobal, MaxNodes, int, 0, "Maximum nodes assembled in the map starting from the last node (0=unlimited).");
RTABMAP_PARAM(GridGlobal, AltitudeDelta, float, 0, "Assemble only nodes that have the same altitude of +-delta meters of the current pose (0=disabled). This is used to generate 2D occupancy grid based on the current altitude (e.g., multi-floor building).");
RTABMAP_PARAM(GridGlobal, OccupancyThr, float, 0.5, "Occupancy threshold (value between 0 and 1)."); RTABMAP_PARAM(GridGlobal, OccupancyThr, float, 0.5, "Occupancy threshold (value between 0 and 1).");
RTABMAP_PARAM(GridGlobal, ProbHit, float, 0.7, "Probability of a hit (value between 0.5 and 1)."); RTABMAP_PARAM(GridGlobal, ProbHit, float, 0.7, "Probability of a hit (value between 0.5 and 1).");
RTABMAP_PARAM(GridGlobal, ProbMiss, float, 0.4, "Probability of a miss (value between 0 and 0.5)."); RTABMAP_PARAM(GridGlobal, ProbMiss, float, 0.4, "Probability of a miss (value between 0 and 0.5).");
@@ -0,0 +1,41 @@
/*
* PythonInterface.h
*
* Created on: Jan. 14, 2021
* Author: mathieu
*/
#ifndef CORELIB_SRC_PYTHON_PYTHONINTERFACE_H_
#define CORELIB_SRC_PYTHON_PYTHONINTERFACE_H_
#include <string>
#include <rtabmap/utilite/UMutex.h>
#include <Python.h>
namespace rtabmap {
class PythonInterface
{
public:
PythonInterface();
virtual ~PythonInterface();
protected:
std::string getTraceback(); // should be called between lock() and unlock()
void lock();
void unlock();
private:
static UMutex mutex_;
static int refCount_;
protected:
static PyThreadState * mainThreadState_;
static unsigned long mainThreadID_;
PyThreadState * threadState_;
};
}
#endif /* CORELIB_SRC_PYTHON_PYTHONINTERFACE_H_ */
@@ -56,6 +56,7 @@ protected:
virtual float getMinGeometryCorrespondencesRatioImpl() const {return _correspondenceRatio;} virtual float getMinGeometryCorrespondencesRatioImpl() const {return _correspondenceRatio;}
private: private:
int _strategy;
float _maxTranslation; float _maxTranslation;
float _maxRotation; float _maxRotation;
float _voxelSize; float _voxelSize;
@@ -66,19 +67,24 @@ private:
int _maxIterations; int _maxIterations;
float _epsilon; float _epsilon;
float _correspondenceRatio; float _correspondenceRatio;
bool _force4DoF;
bool _pointToPlane; bool _pointToPlane;
int _pointToPlaneK; int _pointToPlaneK;
float _pointToPlaneRadius; float _pointToPlaneRadius;
float _pointToPlaneGroundNormalsUp; float _pointToPlaneGroundNormalsUp;
float _pointToPlaneMinComplexity; float _pointToPlaneMinComplexity;
int _pointToPlaneLowComplexityStrategy; int _pointToPlaneLowComplexityStrategy;
bool _libpointmatcher;
std::string _libpointmatcherConfig; std::string _libpointmatcherConfig;
int _libpointmatcherKnn; int _libpointmatcherKnn;
float _libpointmatcherEpsilon; float _libpointmatcherEpsilon;
bool _libpointmatcherIntensity; bool _libpointmatcherIntensity;
float _libpointmatcherOutlierRatio; float _outlierRatio;
unsigned int _ccSamplingLimit;
bool _ccFilterOutFarthestPoints;
double _ccMaxFinalRMS;
void * _libpointmatcherICP; void * _libpointmatcherICP;
void * _libpointmatcherICPFilters;
}; };
} }
@@ -37,7 +37,7 @@ namespace rtabmap {
class Feature2D; class Feature2D;
#ifdef RTABMAP_PYMATCHER #ifdef RTABMAP_PYTHON
class PyMatcher; class PyMatcher;
#endif #endif
@@ -105,7 +105,7 @@ private:
Feature2D * _detectorFrom; Feature2D * _detectorFrom;
Feature2D * _detectorTo; Feature2D * _detectorTo;
#ifdef RTABMAP_PYMATCHER #ifdef RTABMAP_PYTHON
PyMatcher * _pyMatcher; PyMatcher * _pyMatcher;
#endif #endif
}; };
+5 -3
View File
@@ -199,12 +199,13 @@ public:
std::map<int, Transform> getNodesInRadius(const Transform & pose, float radius); // If radius=0, RGBD/LocalRadius is used. Can return landmarks. std::map<int, Transform> getNodesInRadius(const Transform & pose, float radius); // If radius=0, RGBD/LocalRadius is used. Can return landmarks.
std::map<int, Transform> getNodesInRadius(int nodeId, float radius); // If nodeId==0, return poses around latest node. If radius=0, RGBD/LocalRadius is used. Can return landmarks and use landmark id (negative) as request. std::map<int, Transform> getNodesInRadius(int nodeId, float radius); // If nodeId==0, return poses around latest node. If radius=0, RGBD/LocalRadius is used. Can return landmarks and use landmark id (negative) as request.
int detectMoreLoopClosures( int detectMoreLoopClosures(
float clusterRadius = 0.5f, float clusterRadiusMax = 0.5f,
float clusterAngle = M_PI/6.0f, float clusterAngle = M_PI/6.0f,
int iterations = 1, int iterations = 1,
bool intraSession = true, bool intraSession = true,
bool interSession = true, bool interSession = true,
const ProgressState * state = 0); const ProgressState * state = 0,
float clusterRadiusMin = 0.0f);
int refineLinks(); int refineLinks();
bool addLink(const Link & link); bool addLink(const Link & link);
cv::Mat getInformation(const cv::Mat & covariance) const; cv::Mat getInformation(const cv::Mat & covariance) const;
@@ -281,6 +282,7 @@ private:
bool _proximityByTime; bool _proximityByTime;
bool _proximityBySpace; bool _proximityBySpace;
bool _scanMatchingIdsSavedInLinks; bool _scanMatchingIdsSavedInLinks;
bool _loopClosureIdentityGuess;
float _localRadius; float _localRadius;
float _localImmunizationRatio; float _localImmunizationRatio;
int _proximityMaxGraphDepth; int _proximityMaxGraphDepth;
@@ -300,7 +302,7 @@ private:
int _pathStuckIterations; int _pathStuckIterations;
float _pathLinearVelocity; float _pathLinearVelocity;
float _pathAngularVelocity; float _pathAngularVelocity;
bool _savedLocalizationIgnored; bool _restartAtOrigin;
bool _loopCovLimited; bool _loopCovLimited;
bool _loopGPS; bool _loopGPS;
int _maxOdomCacheSize; int _maxOdomCacheSize;
@@ -140,6 +140,8 @@ private:
cv::Mat F_; cv::Mat F_;
}; };
RTABMAP_EXP std::ostream& operator<<(std::ostream& os, const StereoCameraModel& model);
} // rtabmap } // rtabmap
#endif /* STEREOCAMERAMODEL_H_ */ #endif /* STEREOCAMERAMODEL_H_ */
@@ -0,0 +1,83 @@
/*
Copyright (c) 2010-2021, 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/RtabmapExp.h" // DLL export/import defines
#include "rtabmap/core/StereoCameraModel.h"
#include "rtabmap/core/Camera.h"
#include "rtabmap/core/Version.h"
#ifdef RTABMAP_DEPTHAI
#ifndef DEPTHAI_OPENCV_SUPPORT
#define DEPTHAI_OPENCV_SUPPORT
#endif
#include <depthai/depthai.hpp>
#endif
namespace rtabmap
{
class RTABMAP_EXP CameraDepthAI :
public Camera
{
public:
static bool available();
public:
CameraDepthAI(
const std::string & deviceSerial = "",
int resolution = 1, // 0=720p, 1=800p, 2=400p
float imageRate=0.0f,
const Transform & localTransform = CameraModel::opticalRotation());
virtual ~CameraDepthAI();
void setOutputDepth(bool enabled, int confidence = 200);
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
virtual bool isCalibrated() const;
virtual std::string getSerial() const;
protected:
virtual SensorData captureImage(CameraInfo * info = 0);
private:
#ifdef RTABMAP_DEPTHAI
StereoCameraModel stereoModel_;
std::string deviceSerial_;
bool outputDepth_;
int depthConfidence_;
int resolution_;
std::shared_ptr<dai::Device> device_;
std::shared_ptr<dai::DataOutputQueue> leftQueue_;
std::shared_ptr<dai::DataOutputQueue> rightOrDepthQueue_;
#endif
};
} // namespace rtabmap
@@ -36,6 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <pcl/pcl_config.h> #include <pcl/pcl_config.h>
#ifdef RTABMAP_REALSENSE2 #ifdef RTABMAP_REALSENSE2
#include <librealsense2/rs.hpp>
#include <librealsense2/hpp/rs_frame.hpp> #include <librealsense2/hpp/rs_frame.hpp>
#endif #endif
@@ -75,6 +76,7 @@ public:
void setEmitterEnabled(bool enabled); void setEmitterEnabled(bool enabled);
void setIRFormat(bool enabled, bool useDepthInsteadOfRightImage); void setIRFormat(bool enabled, bool useDepthInsteadOfRightImage);
void setResolution(int width, int height, int fps = 30); void setResolution(int width, int height, int fps = 30);
void setDepthResolution(int width, int height, int fps = 30);
void setGlobalTimeSync(bool enabled); void setGlobalTimeSync(bool enabled);
void publishInterIMU(bool enabled); void publishInterIMU(bool enabled);
void setDualMode(bool enabled, const Transform & extrinsics); void setDualMode(bool enabled, const Transform & extrinsics);
@@ -85,6 +87,7 @@ public:
#ifdef RTABMAP_REALSENSE2 #ifdef RTABMAP_REALSENSE2
private: private:
void close();
void imu_callback(rs2::frame frame); void imu_callback(rs2::frame frame);
void pose_callback(rs2::frame frame); void pose_callback(rs2::frame frame);
void frame_callback(rs2::frame frame); void frame_callback(rs2::frame frame);
@@ -102,14 +105,14 @@ protected:
private: private:
#ifdef RTABMAP_REALSENSE2 #ifdef RTABMAP_REALSENSE2
rs2::context * ctx_; rs2::context ctx_;
std::vector<rs2::device *> dev_; std::vector<rs2::device> dev_;
std::string deviceId_; std::string deviceId_;
rs2::syncer * syncer_; rs2::syncer syncer_;
float depth_scale_meters_; float depth_scale_meters_;
rs2_intrinsics * depthIntrinsics_; rs2_intrinsics depthIntrinsics_;
rs2_intrinsics * rgbIntrinsics_; rs2_intrinsics rgbIntrinsics_;
rs2_extrinsics * depthToRGBExtrinsics_; rs2_extrinsics depthToRGBExtrinsics_;
cv::Mat depthBuffer_; cv::Mat depthBuffer_;
cv::Mat rgbBuffer_; cv::Mat rgbBuffer_;
CameraModel model_; CameraModel model_;
@@ -132,13 +135,15 @@ private:
int cameraWidth_; int cameraWidth_;
int cameraHeight_; int cameraHeight_;
int cameraFps_; int cameraFps_;
int cameraDepthWidth_;
int cameraDepthHeight_;
int cameraDepthFps_;
bool globalTimeSync_; bool globalTimeSync_;
bool publishInterIMU_; bool publishInterIMU_;
bool dualMode_; bool dualMode_;
Transform dualExtrinsics_; Transform dualExtrinsics_;
std::string jsonConfig_; std::string jsonConfig_;
bool closing_; bool closing_;
bool isL500_;
static Transform realsense2PoseRotation_; static Transform realsense2PoseRotation_;
static Transform realsense2PoseRotationInv_; static Transform realsense2PoseRotationInv_;
@@ -70,6 +70,8 @@ public:
virtual bool isCalibrated() const; virtual bool isCalibrated() const;
virtual std::string getSerial() const; virtual std::string getSerial() const;
void setResolution(int width, int height) {_width=width, _height=height;}
protected: protected:
virtual SensorData captureImage(CameraInfo * info = 0); virtual SensorData captureImage(CameraInfo * info = 0);
@@ -84,6 +86,8 @@ private:
CameraVideo::Source src_; CameraVideo::Source src_;
int usbDevice_; int usbDevice_;
int usbDevice2_; int usbDevice2_;
int _width;
int _height;
}; };
} // namespace rtabmap } // namespace rtabmap
@@ -25,42 +25,59 @@ 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 OBJDELETIONHANDLER_H_ #pragma once
#define OBJDELETIONHANDLER_H_
#include "rtabmap/utilite/UEventsHandler.h" #include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
#include "rtabmap/utilite/UEvent.h"
#include <QtCore/QObject>
class ObjDeletionHandler : public QObject, public UEventsHandler #include "rtabmap/core/StereoCameraModel.h"
#include "rtabmap/core/Camera.h"
#include "rtabmap/core/Version.h"
namespace sl_oc {
namespace video {
class VideoCapture;
}
namespace sensors {
class SensorCapture;
}
}
namespace rtabmap
{ {
Q_OBJECT class ZedOCThread;
class RTABMAP_EXP CameraStereoZedOC :
public Camera
{
public:
static bool available();
public: public:
ObjDeletionHandler(int watchedId, QObject * receiver = 0, const char * member = 0) : _watchedId(watchedId) CameraStereoZedOC(
{ int deviceId,
if(receiver && member) int resolution = 3, // 0=HD2K, 1=HD1080, 2=HD720, 3=VGA
{ float imageRate=0.0f,
connect(this, SIGNAL(objDeletionEventReceived(int)), receiver, member); const Transform & localTransform = CameraModel::opticalRotation());
} virtual ~CameraStereoZedOC();
}
virtual ~ObjDeletionHandler() {}
Q_SIGNALS: virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
void objDeletionEventReceived(int); virtual bool isCalibrated() const;
virtual std::string getSerial() const;
protected: protected:
virtual bool handleEvent(UEvent * event) virtual SensorData captureImage(CameraInfo * info = 0);
{
if(event->getClassName().compare("UObjDeletedEvent") == 0 &&
event->getCode() == _watchedId)
{
Q_EMIT objDeletionEventReceived(_watchedId);
}
return false;
}
private: private:
int _watchedId; #ifdef RTABMAP_ZEDOC
sl_oc::video::VideoCapture * zed_;
sl_oc::sensors::SensorCapture * sensors_;
ZedOCThread * imuThread_;
StereoCameraModel stereoModel_;
int usbDevice_;
int resolution_;
uint64_t lastStamp_;
#endif
}; };
#endif /* OBJDELETIONHANDLER_H_ */
} // namespace rtabmap
@@ -50,7 +50,6 @@ public:
virtual void reset(const Transform & initialPose = Transform::getIdentity()); virtual void reset(const Transform & initialPose = Transform::getIdentity());
const Signature & getMap() const {return *map_;} const Signature & getMap() const {return *map_;}
const Signature & getLastFrame() const {return *lastFrame_;} const Signature & getLastFrame() const {return *lastFrame_;}
virtual bool canProcessIMU() const;
virtual Odometry::Type getType() {return Odometry::kTypeF2M;} virtual Odometry::Type getType() {return Odometry::kTypeF2M;}
@@ -79,7 +78,6 @@ private:
Signature * lastFrame_; Signature * lastFrame_;
int lastFrameOldestNewId_; int lastFrameOldestNewId_;
std::vector<std::pair<pcl::PointCloud<pcl::PointXYZINormal>::Ptr, pcl::IndicesPtr> > scansBuffer_; std::vector<std::pair<pcl::PointCloud<pcl::PointXYZINormal>::Ptr, pcl::IndicesPtr> > scansBuffer_;
bool initGravity_;
std::map<int, std::map<int, FeatureBA> > bundleWordReferences_; //<WordId, <FrameId, pt2D+depth>> std::map<int, std::map<int, FeatureBA> > bundleWordReferences_; //<WordId, <FrameId, pt2D+depth>>
std::map<int, Transform> bundlePoses_; std::map<int, Transform> bundlePoses_;
@@ -44,7 +44,7 @@ public:
virtual void reset(const Transform & initialPose = Transform::getIdentity()); virtual void reset(const Transform & initialPose = Transform::getIdentity());
virtual Odometry::Type getType() {return Odometry::kTypeMSCKF;} virtual Odometry::Type getType() {return Odometry::kTypeMSCKF;}
virtual bool canProcessRawImages() const {return true;} virtual bool canProcessRawImages() const {return true;}
virtual bool canProcessIMU() const {return true;} virtual bool canProcessAsyncIMU() const {return true;}
private: private:
virtual Transform computeTransform(SensorData & image, const Transform & guess = Transform(), OdometryInfo * info = 0); virtual Transform computeTransform(SensorData & image, const Transform & guess = Transform(), OdometryInfo * info = 0);
@@ -25,41 +25,48 @@ 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 ODOMETRYORBSLAM2_H_ #ifndef ODOMETRYORBSLAM_H_
#define ODOMETRYORBSLAM2_H_ #define ODOMETRYORBSLAM_H_
#include <rtabmap/core/Odometry.h> #include <rtabmap/core/Odometry.h>
#if RTABMAP_ORB_SLAM == 3
namespace ORB_SLAM3 {
#else
namespace ORB_SLAM2 { namespace ORB_SLAM2 {
#endif
class System; class System;
} }
class ORBSLAM2System; class ORBSLAMSystem;
namespace rtabmap { namespace rtabmap {
class RTABMAP_EXP OdometryORBSLAM2 : public Odometry class RTABMAP_EXP OdometryORBSLAM : public Odometry
{ {
public: public:
OdometryORBSLAM2(const rtabmap::ParametersMap & parameters = rtabmap::ParametersMap()); OdometryORBSLAM(const rtabmap::ParametersMap & parameters = rtabmap::ParametersMap());
virtual ~OdometryORBSLAM2(); virtual ~OdometryORBSLAM();
virtual void reset(const Transform & initialPose = Transform::getIdentity()); virtual void reset(const Transform & initialPose = Transform::getIdentity());
virtual Odometry::Type getType() {return Odometry::kTypeORBSLAM2;} virtual Odometry::Type getType() {return Odometry::kTypeORBSLAM;}
virtual bool canProcessAsyncIMU() const;
private: private:
virtual Transform computeTransform(SensorData & image, const Transform & guess = Transform(), OdometryInfo * info = 0); virtual Transform computeTransform(SensorData & image, const Transform & guess = Transform(), OdometryInfo * info = 0);
private: private:
#ifdef RTABMAP_ORB_SLAM2 #ifdef RTABMAP_ORB_SLAM
ORBSLAM2System * orbslam2_; ORBSLAMSystem * orbslam_;
bool firstFrame_; bool firstFrame_;
Transform originLocalTransform_; Transform originLocalTransform_;
Transform previousPose_; Transform previousPose_;
bool useIMU_;
Transform imuLocalTransform_;
#endif #endif
}; };
} }
#endif /* ODOMETRYORBSLAM2_H_ */ #endif /* ODOMETRYORBSLAM_H_ */
@@ -46,7 +46,7 @@ public:
virtual void reset(const Transform & initialPose = Transform::getIdentity()); virtual void reset(const Transform & initialPose = Transform::getIdentity());
virtual Odometry::Type getType() {return Odometry::kTypeOkvis;} virtual Odometry::Type getType() {return Odometry::kTypeOkvis;}
virtual bool canProcessRawImages() const {return true;} virtual bool canProcessRawImages() const {return true;}
virtual bool canProcessIMU() const {return true;} virtual bool canProcessAsyncIMU() const {return true;}
private: private:
virtual Transform computeTransform(SensorData & image, const Transform & guess = Transform(), OdometryInfo * info = 0); virtual Transform computeTransform(SensorData & image, const Transform & guess = Transform(), OdometryInfo * info = 0);
@@ -43,7 +43,7 @@ public:
virtual void reset(const Transform & initialPose = Transform::getIdentity()); virtual void reset(const Transform & initialPose = Transform::getIdentity());
virtual Odometry::Type getType() {return Odometry::kTypeVINS;} virtual Odometry::Type getType() {return Odometry::kTypeVINS;}
virtual bool canProcessRawImages() const {return true;} virtual bool canProcessRawImages() const {return true;}
virtual bool canProcessIMU() const {return true;} virtual bool canProcessAsyncIMU() const {return true;}
private: private:
virtual Transform computeTransform(SensorData & image, const Transform & guess = Transform(), OdometryInfo * info = 0); virtual Transform computeTransform(SensorData & image, const Transform & guess = Transform(), OdometryInfo * info = 0);
+49 -20
View File
@@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/core/SensorData.h> #include <rtabmap/core/SensorData.h>
#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 <map> #include <map>
#include <list> #include <list>
@@ -198,35 +199,36 @@ pcl::PointCloud<pcl::PointXYZ> RTABMAP_EXP laserScanFromDepthImages(
LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PCLPointCloud2 & cloud, bool filterNaNs = true, bool is2D = false, const Transform & transform = Transform()); LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PCLPointCloud2 & cloud, bool filterNaNs = true, bool is2D = false, const Transform & transform = Transform());
// return CV_32FC3 (x,y,z) // return CV_32FC3 (x,y,z)
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const Transform & transform = Transform(), bool filterNaNs = true);
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const pcl::IndicesPtr & indices, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const pcl::IndicesPtr & indices, const Transform & transform = Transform(), bool filterNaNs = true);
// return CV_32FC6 (x,y,z,normal_x,normal_y,normal_z) // return CV_32FC6 (x,y,z,normal_x,normal_y,normal_z)
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointNormal> & cloud, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointNormal> & cloud, const Transform & transform = Transform(), bool filterNaNs = true);
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointNormal> & cloud, const pcl::IndicesPtr & indices, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointNormal> & cloud, const pcl::IndicesPtr & indices, const Transform & transform = Transform(), bool filterNaNs = true);
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const pcl::PointCloud<pcl::Normal> & normals, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const pcl::PointCloud<pcl::Normal> & normals, const Transform & transform = Transform(), bool filterNaNs = true);
// return CV_32FC4 (x,y,z,rgb) // return CV_32FC4 (x,y,z,rgb)
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGB> & cloud, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGB> & cloud, const Transform & transform = Transform(), bool filterNaNs = true);
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGB> & cloud, const pcl::IndicesPtr & indices, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGB> & cloud, const pcl::IndicesPtr & indices, const Transform & transform = Transform(), bool filterNaNs = true);
// return CV_32FC4 (x,y,z,I) // return CV_32FC4 (x,y,z,I)
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZI> & cloud, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZI> & cloud, const Transform & transform = Transform(), bool filterNaNs = true);
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZI> & cloud, const pcl::IndicesPtr & indices, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZI> & 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)
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGB> & cloud, const pcl::PointCloud<pcl::Normal> & normals, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGB> & cloud, const pcl::PointCloud<pcl::Normal> & normals, const Transform & transform = Transform(), bool filterNaNs = true);
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGBNormal> & cloud, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGBNormal> & cloud, const Transform & transform = Transform(), bool filterNaNs = true);
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGBNormal> & cloud, const pcl::IndicesPtr & indices, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGBNormal> & cloud, const pcl::IndicesPtr & indices, const Transform & transform = Transform(), bool filterNaNs = true);
// return CV_32FC7 (x,y,z,I,normal_x,normal_y,normal_z) // return CV_32FC7 (x,y,z,I,normal_x,normal_y,normal_z)
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZI> & cloud, const pcl::PointCloud<pcl::Normal> & normals, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZI> & cloud, const pcl::PointCloud<pcl::Normal> & normals, const Transform & transform = Transform(), bool filterNaNs = true);
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZINormal> & cloud, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZINormal> & cloud, const Transform & transform = Transform(), bool filterNaNs = true);
LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZINormal> & cloud, const pcl::IndicesPtr & indices, const Transform & transform = Transform(), bool filterNaNs = true);
// return CV_32FC2 (x,y) // return CV_32FC2 (x,y)
cv::Mat RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const Transform & transform = Transform(), bool filterNaNs = true);
// return CV_32FC3 (x,y,I) // return CV_32FC3 (x,y,I)
cv::Mat RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointXYZI> & cloud, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointXYZI> & cloud, const Transform & transform = Transform(), bool filterNaNs = true);
// return CV_32FC5 (x,y,normal_x, normal_y, normal_z) // return CV_32FC5 (x,y,normal_x, normal_y, normal_z)
cv::Mat RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointNormal> & cloud, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointNormal> & cloud, const Transform & transform = Transform(), bool filterNaNs = true);
cv::Mat RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const pcl::PointCloud<pcl::Normal> & normals, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const pcl::PointCloud<pcl::Normal> & normals, const Transform & transform = Transform(), bool filterNaNs = true);
// return CV_32FC6 (x,y,I,normal_x, normal_y, normal_z) // return CV_32FC6 (x,y,I,normal_x, normal_y, normal_z)
cv::Mat RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointXYZINormal> & cloud, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointXYZINormal> & cloud, const Transform & transform = Transform(), bool filterNaNs = true);
cv::Mat RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointXYZI> & cloud, const pcl::PointCloud<pcl::Normal> & normals, const Transform & transform = Transform(), bool filterNaNs = true); LaserScan RTABMAP_EXP laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointXYZI> & cloud, const pcl::PointCloud<pcl::Normal> & normals, const Transform & transform = Transform(), bool filterNaNs = true);
pcl::PCLPointCloud2::Ptr RTABMAP_EXP laserScanToPointCloud2(const LaserScan & laserScan, const Transform & transform = Transform()); pcl::PCLPointCloud2::Ptr RTABMAP_EXP laserScanToPointCloud2(const LaserScan & laserScan, const Transform & transform = Transform());
// For 2d laserScan, z is set to null. // For 2d laserScan, z is set to null.
@@ -299,6 +301,33 @@ void RTABMAP_EXP fillProjectedCloudHoles(
bool verticalDirection, bool verticalDirection,
bool fillToBorder); bool fillToBorder);
/**
* For each point, return pixel of the best camera (NodeID->CameraIndex)
* looking at it based on the policy and parameters
*/
std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > RTABMAP_EXP projectCloudToCameras (
const pcl::PointCloud<pcl::PointXYZRGBNormal> & cloud,
const std::map<int, Transform> & cameraPoses,
const std::map<int, std::vector<CameraModel> > & cameraModels,
float maxDistance = 0.0f,
float maxAngle = 0.0f,
const std::vector<float> & roiRatios = std::vector<float>(),
bool distanceToCamPolicy = false,
const ProgressState * state = 0);
/**
* For each point, return pixel of the best camera (NodeID->CameraIndex)
* looking at it based on the policy and parameters
*/
std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > RTABMAP_EXP projectCloudToCameras (
const pcl::PointCloud<pcl::PointXYZINormal> & cloud,
const std::map<int, Transform> & cameraPoses,
const std::map<int, std::vector<CameraModel> > & cameraModels,
float maxDistance = 0.0f,
float maxAngle = 0.0f,
const std::vector<float> & roiRatios = std::vector<float>(),
bool distanceToCamPolicy = false,
const ProgressState * state = 0);
bool RTABMAP_EXP isFinite(const cv::Point3f & pt); bool RTABMAP_EXP isFinite(const cv::Point3f & pt);
pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP concatenateClouds( pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP concatenateClouds(
@@ -279,6 +279,20 @@ pcl::IndicesPtr RTABMAP_EXP cropBox(
const Eigen::Vector4f & max, const Eigen::Vector4f & max,
const Transform & transform = Transform::getIdentity(), const Transform & transform = Transform::getIdentity(),
bool negative = false); bool negative = false);
pcl::IndicesPtr RTABMAP_EXP cropBox(
const pcl::PointCloud<pcl::PointXYZI>::Ptr & cloud,
const pcl::IndicesPtr & indices,
const Eigen::Vector4f & min,
const Eigen::Vector4f & max,
const Transform & transform = Transform::getIdentity(),
bool negative = false);
pcl::IndicesPtr RTABMAP_EXP cropBox(
const pcl::PointCloud<pcl::PointXYZINormal>::Ptr & cloud,
const pcl::IndicesPtr & indices,
const Eigen::Vector4f & min,
const Eigen::Vector4f & max,
const Transform & transform = Transform::getIdentity(),
bool negative = false);
pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP cropBox( pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP cropBox(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
const Eigen::Vector4f & min, const Eigen::Vector4f & min,
@@ -297,6 +311,12 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP cropBox(
const Eigen::Vector4f & max, const Eigen::Vector4f & max,
const Transform & transform = Transform::getIdentity(), const Transform & transform = Transform::getIdentity(),
bool negative = false); bool negative = false);
pcl::PointCloud<pcl::PointXYZI>::Ptr RTABMAP_EXP cropBox(
const pcl::PointCloud<pcl::PointXYZI>::Ptr & cloud,
const Eigen::Vector4f & min,
const Eigen::Vector4f & max,
const Transform & transform = Transform::getIdentity(),
bool negative = false);
pcl::PointCloud<pcl::PointXYZINormal>::Ptr RTABMAP_EXP cropBox( pcl::PointCloud<pcl::PointXYZINormal>::Ptr RTABMAP_EXP cropBox(
const pcl::PointCloud<pcl::PointXYZINormal>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZINormal>::Ptr & cloud,
const Eigen::Vector4f & min, const Eigen::Vector4f & min,
@@ -346,6 +366,8 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP removeNaNFromPointCloud(
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud); const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud);
pcl::PointCloud<pcl::PointXYZI>::Ptr RTABMAP_EXP removeNaNFromPointCloud( pcl::PointCloud<pcl::PointXYZI>::Ptr RTABMAP_EXP removeNaNFromPointCloud(
const pcl::PointCloud<pcl::PointXYZI>::Ptr & cloud); const pcl::PointCloud<pcl::PointXYZI>::Ptr & cloud);
pcl::PCLPointCloud2::Ptr RTABMAP_EXP removeNaNFromPointCloud(
const pcl::PCLPointCloud2::Ptr & cloud);
pcl::PointCloud<pcl::PointNormal>::Ptr RTABMAP_EXP removeNaNNormalsFromPointCloud( pcl::PointCloud<pcl::PointNormal>::Ptr RTABMAP_EXP removeNaNNormalsFromPointCloud(
@@ -408,6 +430,16 @@ pcl::IndicesPtr RTABMAP_EXP radiusFiltering(
const pcl::IndicesPtr & indices, const pcl::IndicesPtr & indices,
float radiusSearch, float radiusSearch,
int minNeighborsInRadius); int minNeighborsInRadius);
pcl::IndicesPtr RTABMAP_EXP radiusFiltering(
const pcl::PointCloud<pcl::PointXYZI>::Ptr & cloud,
const pcl::IndicesPtr & indices,
float radiusSearch,
int minNeighborsInRadius);
pcl::IndicesPtr RTABMAP_EXP radiusFiltering(
const pcl::PointCloud<pcl::PointXYZINormal>::Ptr & cloud,
const pcl::IndicesPtr & indices,
float radiusSearch,
int minNeighborsInRadius);
/** /**
* For convenience. * For convenience.
@@ -590,6 +622,13 @@ pcl::IndicesPtr RTABMAP_EXP normalFiltering(
const Eigen::Vector4f & normal, const Eigen::Vector4f & normal,
int normalKSearch, int normalKSearch,
const Eigen::Vector4f & viewpoint); const Eigen::Vector4f & viewpoint);
pcl::IndicesPtr RTABMAP_EXP normalFiltering(
const pcl::PointCloud<pcl::PointXYZI>::Ptr & cloud,
const pcl::IndicesPtr & indices,
float angleMax,
const Eigen::Vector4f & normal,
int normalKSearch,
const Eigen::Vector4f & viewpoint);
pcl::IndicesPtr RTABMAP_EXP normalFiltering( pcl::IndicesPtr RTABMAP_EXP normalFiltering(
const pcl::PointCloud<pcl::PointNormal>::Ptr & cloud, const pcl::PointCloud<pcl::PointNormal>::Ptr & cloud,
const pcl::IndicesPtr & indices, const pcl::IndicesPtr & indices,
@@ -604,6 +643,13 @@ pcl::IndicesPtr RTABMAP_EXP normalFiltering(
const Eigen::Vector4f & normal, const Eigen::Vector4f & normal,
int normalKSearch, int normalKSearch,
const Eigen::Vector4f & viewpoint); const Eigen::Vector4f & viewpoint);
pcl::IndicesPtr RTABMAP_EXP normalFiltering(
const pcl::PointCloud<pcl::PointXYZINormal>::Ptr & cloud,
const pcl::IndicesPtr & indices,
float angleMax,
const Eigen::Vector4f & normal,
int normalKSearch,
const Eigen::Vector4f & viewpoint);
/** /**
* For convenience. * For convenience.
@@ -661,6 +707,20 @@ std::vector<pcl::IndicesPtr> RTABMAP_EXP extractClusters(
int minClusterSize, int minClusterSize,
int maxClusterSize = std::numeric_limits<int>::max(), int maxClusterSize = std::numeric_limits<int>::max(),
int * biggestClusterIndex = 0); int * biggestClusterIndex = 0);
std::vector<pcl::IndicesPtr> RTABMAP_EXP extractClusters(
const pcl::PointCloud<pcl::PointXYZI>::Ptr & cloud,
const pcl::IndicesPtr & indices,
float clusterTolerance,
int minClusterSize,
int maxClusterSize = std::numeric_limits<int>::max(),
int * biggestClusterIndex = 0);
std::vector<pcl::IndicesPtr> RTABMAP_EXP extractClusters(
const pcl::PointCloud<pcl::PointXYZINormal>::Ptr & cloud,
const pcl::IndicesPtr & indices,
float clusterTolerance,
int minClusterSize,
int maxClusterSize = std::numeric_limits<int>::max(),
int * biggestClusterIndex = 0);
pcl::IndicesPtr RTABMAP_EXP extractIndices( pcl::IndicesPtr RTABMAP_EXP extractIndices(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
@@ -678,6 +738,14 @@ pcl::IndicesPtr RTABMAP_EXP extractIndices(
const pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr & cloud,
const pcl::IndicesPtr & indices, const pcl::IndicesPtr & indices,
bool negative); bool negative);
pcl::IndicesPtr RTABMAP_EXP extractIndices(
const pcl::PointCloud<pcl::PointXYZI>::Ptr & cloud,
const pcl::IndicesPtr & indices,
bool negative);
pcl::IndicesPtr RTABMAP_EXP extractIndices(
const pcl::PointCloud<pcl::PointXYZINormal>::Ptr & cloud,
const pcl::IndicesPtr & indices,
bool negative);
pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP extractIndices( pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP extractIndices(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
@@ -700,6 +768,16 @@ pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr RTABMAP_EXP extractIndices(
const pcl::IndicesPtr & indices, const pcl::IndicesPtr & indices,
bool negative, bool negative,
bool keepOrganized); bool keepOrganized);
pcl::PointCloud<pcl::PointXYZI>::Ptr RTABMAP_EXP extractIndices(
const pcl::PointCloud<pcl::PointXYZI>::Ptr & cloud,
const pcl::IndicesPtr & indices,
bool negative,
bool keepOrganized);
pcl::PointCloud<pcl::PointXYZINormal>::Ptr RTABMAP_EXP extractIndices(
const pcl::PointCloud<pcl::PointXYZINormal>::Ptr & cloud,
const pcl::IndicesPtr & indices,
bool negative,
bool keepOrganized);
pcl::IndicesPtr extractPlane( pcl::IndicesPtr extractPlane(
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud, const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
@@ -99,6 +99,21 @@ RTABMAP_DEPRECATED(cv::Mat RTABMAP_EXP create2DMap(const std::map<int, Transform
float minMapSize = 0.0f, float minMapSize = 0.0f,
float scanMaxRange = 0.0f), "Use interface with cv::Mat scans."); float scanMaxRange = 0.0f), "Use interface with cv::Mat scans.");
/**
* Create 2d Occupancy grid (CV_8S)
* -1 = unknown
* 0 = empty space
* 100 = obstacle
* @param poses
* @param scans, should be CV_32FC2 type!
* @param viewpoints
* @param cellSize m
* @param unknownSpaceFilled if false no fill, otherwise a virtual laser sweeps the unknown space from each pose (stopping on detected obstacle)
* @param xMin
* @param yMin
* @param minMapSize minimum map size in meters
* @param scanMaxRange laser scan maximum range, would be set if unknownSpaceFilled=true
*/
cv::Mat RTABMAP_EXP create2DMap(const std::map<int, Transform> & poses, cv::Mat RTABMAP_EXP create2DMap(const std::map<int, Transform> & poses,
const std::map<int, std::pair<cv::Mat, cv::Mat> > & scans, // <id, <hit, no hit> >, in /base_link frame const std::map<int, std::pair<cv::Mat, cv::Mat> > & scans, // <id, <hit, no hit> >, in /base_link frame
const std::map<int, cv::Point3f > & viewpoints, // /base_link -> /base_scan const std::map<int, cv::Point3f > & viewpoints, // /base_link -> /base_scan
+80 -13
View File
@@ -33,9 +33,11 @@ SET(SRC_FILES
camera/CameraStereoImages.cpp camera/CameraStereoImages.cpp
camera/CameraStereoVideo.cpp camera/CameraStereoVideo.cpp
camera/CameraStereoZed.cpp camera/CameraStereoZed.cpp
camera/CameraStereoZedOC.cpp
camera/CameraStereoTara.cpp camera/CameraStereoTara.cpp
camera/CameraVideo.cpp camera/CameraVideo.cpp
camera/CameraMyntEye.cpp camera/CameraMyntEye.cpp
camera/CameraDepthAI.cpp
EpipolarGeometry.cpp EpipolarGeometry.cpp
VisualWord.cpp VisualWord.cpp
@@ -85,11 +87,12 @@ SET(SRC_FILES
odometry/OdometryViso2.cpp odometry/OdometryViso2.cpp
odometry/OdometryDVO.cpp odometry/OdometryDVO.cpp
odometry/OdometryOkvis.cpp odometry/OdometryOkvis.cpp
odometry/OdometryORBSLAM2.cpp odometry/OdometryORBSLAM.cpp
odometry/OdometryLOAM.cpp odometry/OdometryLOAM.cpp
odometry/OdometryMSCKF.cpp odometry/OdometryMSCKF.cpp
odometry/OdometryVINS.cpp odometry/OdometryVINS.cpp
IMU.cpp
IMUThread.cpp IMUThread.cpp
IMUFilter.cpp IMUFilter.cpp
imufilter/ComplementaryFilter.cpp imufilter/ComplementaryFilter.cpp
@@ -195,11 +198,13 @@ IF(Python3_FOUND)
) )
SET(SRC_FILES SET(SRC_FILES
${SRC_FILES} ${SRC_FILES}
pymatcher/PyMatcher.cpp python/PythonInterface.cpp
python/PyMatcher.cpp
python/PyDetector.cpp
) )
SET(INCLUDE_DIRS SET(INCLUDE_DIRS
${TORCH_INCLUDE_DIRS} ${TORCH_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}/pymatcher ${CMAKE_CURRENT_SOURCE_DIR}/python
${INCLUDE_DIRS} ${INCLUDE_DIRS}
) )
ENDIF(Python3_FOUND) ENDIF(Python3_FOUND)
@@ -335,6 +340,14 @@ IF(mynteye_FOUND)
) )
ENDIF(mynteye_FOUND) ENDIF(mynteye_FOUND)
IF(depthai_FOUND)
SET(LIBRARIES
${LIBRARIES}
depthai::depthai-core
depthai::depthai-opencv
)
ENDIF(depthai_FOUND)
IF(WITH_TORO) IF(WITH_TORO)
SET(SRC_FILES SET(SRC_FILES
${SRC_FILES} ${SRC_FILES}
@@ -348,14 +361,29 @@ IF(WITH_TORO)
ENDIF(WITH_TORO) ENDIF(WITH_TORO)
IF(G2O_FOUND) IF(G2O_FOUND)
SET(INCLUDE_DIRS IF(g2o_FOUND)
SET(LIBRARIES
${LIBRARIES}
g2o::core
g2o::solver_cholmod
g2o::solver_eigen
g2o::solver_pcg
g2o::solver_csparse
g2o::csparse_extension
g2o::types_slam2d
g2o::types_slam3d
g2o::types_sba
)
ELSE()
SET(INCLUDE_DIRS
${INCLUDE_DIRS} ${INCLUDE_DIRS}
${G2O_INCLUDE_DIRS} ${G2O_INCLUDE_DIRS}
) )
SET(LIBRARIES SET(LIBRARIES
${LIBRARIES} ${LIBRARIES}
${G2O_LIBRARIES} ${G2O_LIBRARIES}
) )
ENDIF()
SET(SRC_FILES SET(SRC_FILES
${SRC_FILES} ${SRC_FILES}
optimizer/g2o/edge_se3_xyzprior.cpp optimizer/g2o/edge_se3_xyzprior.cpp
@@ -405,6 +433,13 @@ IF(libpointmatcher_FOUND)
) )
ENDIF(libpointmatcher_FOUND) ENDIF(libpointmatcher_FOUND)
IF(CCCoreLib_FOUND)
SET(LIBRARIES
${LIBRARIES}
CCCoreLib::CCCoreLib
)
ENDIF(CCCoreLib_FOUND)
IF(FastCV_FOUND) IF(FastCV_FOUND)
SET(INCLUDE_DIRS SET(INCLUDE_DIRS
${INCLUDE_DIRS} ${INCLUDE_DIRS}
@@ -416,6 +451,25 @@ IF(FastCV_FOUND)
) )
ENDIF(FastCV_FOUND) ENDIF(FastCV_FOUND)
IF(PDAL_FOUND)
SET(INCLUDE_DIRS
${INCLUDE_DIRS}
${PDAL_INCLUDE_DIRS}
)
SET(LIBRARIES
${LIBRARIES}
${PDAL_LIBRARIES}
)
SET(SRC_FILES
${SRC_FILES}
PDALWriter.cpp
)
IF(PDAL_VERSION VERSION_LESS "1.7")
add_definitions("-DRTABMAP_PDAL_16")
ENDIF(PDAL_VERSION VERSION_LESS "1.7")
ENDIF(PDAL_FOUND)
IF(loam_velodyne_FOUND) IF(loam_velodyne_FOUND)
SET(INCLUDE_DIRS SET(INCLUDE_DIRS
${INCLUDE_DIRS} ${INCLUDE_DIRS}
@@ -448,6 +502,19 @@ IF(ZED_FOUND)
ENDIF(CUDA_FOUND) ENDIF(CUDA_FOUND)
ENDIF(ZED_FOUND) ENDIF(ZED_FOUND)
IF(ZEDOC_FOUND)
SET(INCLUDE_DIRS
${INCLUDE_DIRS}
${ZEDOC_INCLUDE_DIRS}
${HIDAPI_INCLUDE_DIRS}
)
SET(LIBRARIES
${LIBRARIES}
${ZEDOC_LIBRARIES}
${HIDAPI_LIBRARIES}
)
ENDIF(ZEDOC_FOUND)
IF(octomap_FOUND) IF(octomap_FOUND)
SET(INCLUDE_DIRS SET(INCLUDE_DIRS
${INCLUDE_DIRS} ${INCLUDE_DIRS}
@@ -542,16 +609,16 @@ IF(vins_FOUND)
) )
ENDIF(vins_FOUND) ENDIF(vins_FOUND)
IF(ORB_SLAM2_FOUND) IF(ORB_SLAM_FOUND)
SET(INCLUDE_DIRS SET(INCLUDE_DIRS
${ORB_SLAM2_INCLUDE_DIRS} #before so that g2o includes are taken from ORB_SLAM2 directory before the official g2o one ${ORB_SLAM_INCLUDE_DIRS} #before so that g2o includes are taken from ORB_SLAM directory before the official g2o one
${INCLUDE_DIRS} ${INCLUDE_DIRS}
) )
SET(LIBRARIES SET(LIBRARIES
${ORB_SLAM2_LIBRARIES} ${ORB_SLAM_LIBRARIES}
${LIBRARIES} ${LIBRARIES}
) )
ENDIF(ORB_SLAM2_FOUND) ENDIF(ORB_SLAM_FOUND)
IF(GTSAM_FOUND) IF(GTSAM_FOUND)
# Make sure GTSAM is built with system Eigen, not the included one in its package # Make sure GTSAM is built with system Eigen, not the included one in its package
@@ -608,8 +675,8 @@ foreach(arg ${RESOURCES})
set(RESOURCES_HEADERS "${RESOURCES_HEADERS}" "${CMAKE_CURRENT_BINARY_DIR}/${output}.h") set(RESOURCES_HEADERS "${RESOURCES_HEADERS}" "${CMAKE_CURRENT_BINARY_DIR}/${output}.h")
endforeach(arg ${RESOURCES}) endforeach(arg ${RESOURCES})
MESSAGE(STATUS "RESOURCES = ${RESOURCES}") #MESSAGE(STATUS "RESOURCES = ${RESOURCES}")
MESSAGE(STATUS "RESOURCES_HEADERS = ${RESOURCES_HEADERS}") #MESSAGE(STATUS "RESOURCES_HEADERS = ${RESOURCES_HEADERS}")
IF(ANDROID) IF(ANDROID)
+3 -4
View File
@@ -37,8 +37,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace rtabmap { namespace rtabmap {
CameraModel::CameraModel() : CameraModel::CameraModel()
localTransform_(0,0,1,0, -1,0,0,0, 0,-1,0,0)
{ {
} }
@@ -234,7 +233,7 @@ bool CameraModel::load(const std::string & filePath)
n = fs["camera_name"]; n = fs["camera_name"];
if(n.type() != cv::FileNode::NONE) if(n.type() != cv::FileNode::NONE)
{ {
name_ = (int)n; name_ = (std::string)n;
} }
else else
{ {
@@ -767,7 +766,7 @@ bool CameraModel::inFrame(int u, int v) const
std::ostream& operator<<(std::ostream& os, const CameraModel& model) std::ostream& operator<<(std::ostream& os, const CameraModel& model)
{ {
os << "Name: " << model.name() << std::endl os << "Name: " << model.name().c_str() << std::endl
<< "Size: " << model.imageWidth() << "x" << model.imageHeight() << std::endl << "Size: " << model.imageWidth() << "x" << model.imageHeight() << std::endl
<< "K= " << model.K_raw() << std::endl << "K= " << model.K_raw() << std::endl
<< "D= " << model.D_raw() << std::endl << "D= " << model.D_raw() << std::endl
+26 -16
View File
@@ -67,7 +67,8 @@ CameraThread::CameraThread(Camera * camera, const ParametersMap & parameters) :
_bilateralFiltering(false), _bilateralFiltering(false),
_bilateralSigmaS(10), _bilateralSigmaS(10),
_bilateralSigmaR(0.1), _bilateralSigmaR(0.1),
_imuFilter(0) _imuFilter(0),
_imuBaseFrameConversion(false)
{ {
UASSERT(_camera != 0); UASSERT(_camera != 0);
} }
@@ -117,10 +118,11 @@ void CameraThread::enableBilateralFiltering(float sigmaS, float sigmaR)
_bilateralSigmaR = sigmaR; _bilateralSigmaR = sigmaR;
} }
void CameraThread::enableIMUFiltering(int filteringStrategy, const ParametersMap & parameters) void CameraThread::enableIMUFiltering(int filteringStrategy, const ParametersMap & parameters, bool baseFrameConversion)
{ {
delete _imuFilter; delete _imuFilter;
_imuFilter = IMUFilter::create((IMUFilter::Type)filteringStrategy, parameters); _imuFilter = IMUFilter::create((IMUFilter::Type)filteringStrategy, parameters);
_imuBaseFrameConversion = baseFrameConversion;
} }
void CameraThread::disableIMUFiltering() void CameraThread::disableIMUFiltering()
@@ -174,7 +176,7 @@ void CameraThread::mainLoop()
CameraInfo info; CameraInfo info;
SensorData data = _camera->takeImage(&info); SensorData data = _camera->takeImage(&info);
if(!data.imageRaw().empty() || (dynamic_cast<DBReader*>(_camera) != 0 && data.id()>0)) // intermediate nodes could not have image set if(!data.imageRaw().empty() || !data.laserScanRaw().empty() || (dynamic_cast<DBReader*>(_camera) != 0 && data.id()>0)) // intermediate nodes could not have image set
{ {
postUpdate(&data, &info); postUpdate(&data, &info);
@@ -406,9 +408,8 @@ void CameraThread::postUpdate(SensorData * dataPtr, CameraInfo * info) const
_scanRangeMin, _scanRangeMin,
validIndices.get()); validIndices.get());
float maxPoints = (data.depthRaw().rows/_scanDownsampleStep)*(data.depthRaw().cols/_scanDownsampleStep); float maxPoints = (data.depthRaw().rows/_scanDownsampleStep)*(data.depthRaw().cols/_scanDownsampleStep);
cv::Mat scan; LaserScan scan;
const Transform & baseToScan = data.cameraModels()[0].localTransform(); const Transform & baseToScan = data.cameraModels()[0].localTransform();
LaserScan::Format format = LaserScan::kXYZRGB;
if(validIndices->size()) if(validIndices->size())
{ {
if(_scanVoxelSize>0.0f) if(_scanVoxelSize>0.0f)
@@ -433,7 +434,6 @@ void CameraThread::postUpdate(SensorData * dataPtr, CameraInfo * info) const
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloudNormals(new pcl::PointCloud<pcl::PointXYZRGBNormal>); pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloudNormals(new pcl::PointCloud<pcl::PointXYZRGBNormal>);
pcl::concatenateFields(*cloud, *normals, *cloudNormals); pcl::concatenateFields(*cloud, *normals, *cloudNormals);
scan = util3d::laserScanFromPointCloud(*cloudNormals, baseToScan.inverse()); scan = util3d::laserScanFromPointCloud(*cloudNormals, baseToScan.inverse());
format = LaserScan::kXYZRGBNormal;
} }
else else
{ {
@@ -441,7 +441,7 @@ void CameraThread::postUpdate(SensorData * dataPtr, CameraInfo * info) const
} }
} }
} }
data.setLaserScan(LaserScan(scan, (int)maxPoints, _scanRangeMax, format, baseToScan)); data.setLaserScan(LaserScan(scan, (int)maxPoints, _scanRangeMax, baseToScan));
if(info) info->timeScanFromDepth = timer.ticks(); if(info) info->timeScanFromDepth = timer.ticks();
} }
else else
@@ -472,21 +472,31 @@ void CameraThread::postUpdate(SensorData * dataPtr, CameraInfo * info) const
} }
else else
{ {
// Transform IMU data in base_link to correctly initialize yaw
IMU imu = data.imu();
if(_imuBaseFrameConversion)
{
UASSERT(!data.imu().localTransform().isNull());
imu.convertToBaseFrame();
}
_imuFilter->update( _imuFilter->update(
data.imu().angularVelocity()[0], imu.angularVelocity()[0],
data.imu().angularVelocity()[1], imu.angularVelocity()[1],
data.imu().angularVelocity()[2], imu.angularVelocity()[2],
data.imu().linearAcceleration()[0], imu.linearAcceleration()[0],
data.imu().linearAcceleration()[1], imu.linearAcceleration()[1],
data.imu().linearAcceleration()[2], imu.linearAcceleration()[2],
data.stamp()); data.stamp());
double qx,qy,qz,qw; double qx,qy,qz,qw;
_imuFilter->getOrientation(qx,qy,qz,qw); _imuFilter->getOrientation(qx,qy,qz,qw);
data.setIMU(IMU( data.setIMU(IMU(
cv::Vec4d(qx,qy,qz,qw), cv::Mat::eye(3,3,CV_64FC1), cv::Vec4d(qx,qy,qz,qw), cv::Mat::eye(3,3,CV_64FC1),
data.imu().angularVelocity(), data.imu().angularVelocityCovariance(), imu.angularVelocity(), imu.angularVelocityCovariance(),
data.imu().linearAcceleration(), data.imu().linearAccelerationCovariance(), imu.linearAcceleration(), imu.linearAccelerationCovariance(),
data.imu().localTransform())); imu.localTransform()));
UDEBUG("%f %f %f %f (gyro=%f %f %f, acc=%f %f %f, %fs)", UDEBUG("%f %f %f %f (gyro=%f %f %f, acc=%f %f %f, %fs)",
data.imu().orientation()[0], data.imu().orientation()[0],
data.imu().orientation()[1], data.imu().orientation()[1],
+12
View File
@@ -200,6 +200,18 @@ bool DBReader::init(
{ {
_calibrated = true; _calibrated = true;
} }
else
{
Signature * s = _dbDriver->loadSignature(*_ids.begin());
_dbDriver->loadNodeData(s);
if( s->sensorData().imageCompressed().empty() &&
s->getWords().empty() &&
!s->sensorData().laserScanCompressed().empty())
{
_calibrated = true; // only scans
}
delete s;
}
} }
} }
else else
+24 -11
View File
@@ -44,10 +44,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "opencv/ORBextractor.h" #include "opencv/ORBextractor.h"
#endif #endif
#ifdef RTABMAP_SUPERPOINT_TORCH #ifdef RTABMAP_TORCH
#include "superpoint_torch/SuperPoint.h" #include "superpoint_torch/SuperPoint.h"
#endif #endif
#ifdef RTABMAP_PYTHON
#include "python/PyDetector.h"
#endif
#if CV_MAJOR_VERSION < 3 #if CV_MAJOR_VERSION < 3
#include "opencv/Orb.h" #include "opencv/Orb.h"
#ifdef HAVE_OPENCV_GPU #ifdef HAVE_OPENCV_GPU
@@ -298,7 +302,11 @@ void Feature2D::limitKeypoints(std::vector<cv::KeyPoint> & keypoints, std::vecto
int removed = (int)hessianMap.size()-maxKeypoints; int removed = (int)hessianMap.size()-maxKeypoints;
std::multimap<float, int>::reverse_iterator iter = hessianMap.rbegin(); std::multimap<float, int>::reverse_iterator iter = hessianMap.rbegin();
std::vector<cv::KeyPoint> kptsTmp(maxKeypoints); std::vector<cv::KeyPoint> kptsTmp(maxKeypoints);
std::vector<cv::Point3f> kpts3DTmp(maxKeypoints); std::vector<cv::Point3f> kpts3DTmp;
if(!keypoints3D.empty())
{
kpts3DTmp.resize(maxKeypoints);
}
cv::Mat descriptorsTmp; cv::Mat descriptorsTmp;
if(descriptors.rows) if(descriptors.rows)
{ {
@@ -580,7 +588,7 @@ Feature2D * Feature2D::create(Feature2D::Type type, const ParametersMap & parame
} }
#endif #endif
#ifndef RTABMAP_SUPERPOINT_TORCH #ifndef RTABMAP_TORCH
if(type == Feature2D::kFeatureSuperPointTorch) if(type == Feature2D::kFeatureSuperPointTorch)
{ {
UWARN("SupertPoint Torch feature cannot be used as RTAB-Map is not built with the option enabled. GFTT/ORB is used instead."); UWARN("SupertPoint Torch feature cannot be used as RTAB-Map is not built with the option enabled. GFTT/ORB is used instead.");
@@ -624,7 +632,7 @@ Feature2D * Feature2D::create(Feature2D::Type type, const ParametersMap & parame
case Feature2D::kFeatureOrbOctree: case Feature2D::kFeatureOrbOctree:
feature2D = new ORBOctree(parameters); feature2D = new ORBOctree(parameters);
break; break;
#ifdef RTABMAP_SUPERPOINT_TORCH #ifdef RTABMAP_TORCH
case Feature2D::kFeatureSuperPointTorch: case Feature2D::kFeatureSuperPointTorch:
feature2D = new SuperPointTorch(parameters); feature2D = new SuperPointTorch(parameters);
break; break;
@@ -638,6 +646,11 @@ Feature2D * Feature2D::create(Feature2D::Type type, const ParametersMap & parame
case Feature2D::kFeatureSurfDaisy: case Feature2D::kFeatureSurfDaisy:
feature2D = new SURF_DAISY(parameters); feature2D = new SURF_DAISY(parameters);
break; break;
#ifdef RTABMAP_PYTHON
case Feature2D::kFeaturePyDetector:
feature2D = new PyDetector(parameters);
break;
#endif
#ifdef RTABMAP_NONFREE #ifdef RTABMAP_NONFREE
default: default:
feature2D = new SURF(parameters); feature2D = new SURF(parameters);
@@ -2047,7 +2060,7 @@ void SuperPointTorch::parseParameters(const ParametersMap & parameters)
Feature2D::parseParameters(parameters); Feature2D::parseParameters(parameters);
std::string previousPath = path_; std::string previousPath = path_;
#ifdef RTABMAP_SUPERPOINT_TORCH #ifdef RTABMAP_TORCH
bool previousCuda = cuda_; bool previousCuda = cuda_;
#endif #endif
Parameters::parse(parameters, Parameters::kSuperPointModelPath(), path_); Parameters::parse(parameters, Parameters::kSuperPointModelPath(), path_);
@@ -2056,7 +2069,7 @@ void SuperPointTorch::parseParameters(const ParametersMap & parameters)
Parameters::parse(parameters, Parameters::kSuperPointNMSRadius(), minDistance_); Parameters::parse(parameters, Parameters::kSuperPointNMSRadius(), minDistance_);
Parameters::parse(parameters, Parameters::kSuperPointCuda(), cuda_); Parameters::parse(parameters, Parameters::kSuperPointCuda(), cuda_);
#ifdef RTABMAP_SUPERPOINT_TORCH #ifdef RTABMAP_TORCH
if(superPoint_.get() == 0 || path_.compare(previousPath) != 0 || previousCuda != cuda_) if(superPoint_.get() == 0 || path_.compare(previousPath) != 0 || previousCuda != cuda_)
{ {
superPoint_ = cv::Ptr<SPDetector>(new SPDetector(path_, threshold_, nms_, minDistance_, cuda_)); superPoint_ = cv::Ptr<SPDetector>(new SPDetector(path_, threshold_, nms_, minDistance_, cuda_));
@@ -2068,29 +2081,29 @@ void SuperPointTorch::parseParameters(const ParametersMap & parameters)
superPoint_->setMinDistance(minDistance_); superPoint_->setMinDistance(minDistance_);
} }
#else #else
UWARN("RTAB-Map is not built with SuperPoint 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!");
#endif #endif
} }
std::vector<cv::KeyPoint> SuperPointTorch::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask) std::vector<cv::KeyPoint> SuperPointTorch::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask)
{ {
#ifdef RTABMAP_SUPERPOINT_TORCH #ifdef RTABMAP_TORCH
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U); UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
UASSERT_MSG(roi.x==0 && roi.y ==0, "Not supporting ROI"); UASSERT_MSG(roi.x==0 && roi.y ==0, "Not supporting ROI");
return superPoint_->detect(image, mask); return superPoint_->detect(image, mask);
#else #else
UWARN("RTAB-Map is not built with SuperPoint 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 std::vector<cv::KeyPoint>(); return std::vector<cv::KeyPoint>();
#endif #endif
} }
cv::Mat SuperPointTorch::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const cv::Mat SuperPointTorch::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const
{ {
#ifdef RTABMAP_SUPERPOINT_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); return superPoint_->compute(keypoints);
#else #else
UWARN("RTAB-Map is not built with SuperPoint 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();
#endif #endif
} }
+33
View File
@@ -125,6 +125,12 @@ bool exportPoses(
// Format: stamp x y z qx qy qz qw // Format: stamp x y z qx qy qz qw
Eigen::Quaternionf q = pose.getQuaternionf(); Eigen::Quaternionf q = pose.getQuaternionf();
if(iter == poses.begin())
{
// header
fprintf(fout, "# timestamp x y z qx qy qz qw\n");
}
UASSERT(uContains(stamps, iter->first)); UASSERT(uContains(stamps, iter->first));
fprintf(fout, "%f %f %f %f %f %f %f %f\n", fprintf(fout, "%f %f %f %f %f %f %f %f\n",
stamps.at(iter->first), stamps.at(iter->first),
@@ -2328,6 +2334,33 @@ std::list<std::map<int, Transform> > getPaths(
return paths; return paths;
} }
void computeMinMax(const std::map<int, Transform> & poses,
cv::Vec3f & min,
cv::Vec3f & max)
{
if(!poses.empty())
{
min[0] = max[0] = poses.begin()->second.x();
min[1] = max[1] = poses.begin()->second.y();
min[2] = max[2] = poses.begin()->second.z();
for(std::map<int, Transform>::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
{
if(min[0] > iter->second.x())
min[0] = iter->second.x();
if(max[0] < iter->second.x())
max[0] = iter->second.x();
if(min[1] > iter->second.y())
min[1] = iter->second.y();
if(max[1] < iter->second.y())
max[1] = iter->second.y();
if(min[2] > iter->second.z())
min[2] = iter->second.z();
if(max[2] < iter->second.z())
max[2] = iter->second.z();
}
}
}
} /* namespace graph */ } /* namespace graph */
} /* namespace rtabmap */ } /* namespace rtabmap */
+74
View File
@@ -0,0 +1,74 @@
/*
Copyright (c) 2010-2021, 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.
*/
#include <rtabmap/core/IMU.h>
namespace rtabmap {
void IMU::convertToBaseFrame()
{
if(!localTransform_.isNull() && !localTransform_.rotation().isIdentity())
{
cv::Mat rotationMatrix, rotationMatrixT;
localTransform_.rotationMatrix().convertTo(rotationMatrix, CV_64FC1);
cv::transpose(rotationMatrix, rotationMatrixT);
cv::Mat_<double> v = rotationMatrix * cv::Mat(linearAcceleration_);
linearAcceleration_ = cv::Vec3d(v(0,0), v(0,1), v(0,2));
if(!linearAccelerationCovariance_.empty())
{
linearAccelerationCovariance_ = rotationMatrix * linearAccelerationCovariance_ * rotationMatrixT;
}
v = rotationMatrix * cv::Mat(angularVelocity_);
angularVelocity_ = cv::Vec3d(v(0,0), v(0,1), v(0,2));
if(!angularVelocityCovariance_.empty())
{
angularVelocityCovariance_ = rotationMatrix * angularVelocityCovariance_ * rotationMatrixT;
}
if(!(orientation_[0] == 0.0 && orientation_[1] == 0.0 && orientation_[2] == 0.0))
{
// orientation includes roll and pitch but not yaw in local transform
Eigen::Quaterniond qTheta =
Eigen::AngleAxisd(0, Eigen::Vector3d::UnitX()) *
Eigen::AngleAxisd(0, Eigen::Vector3d::UnitY()) *
Eigen::AngleAxisd(localTransform_.theta(), Eigen::Vector3d::UnitZ());
Eigen::Quaterniond q = qTheta * Eigen::Quaterniond(orientation_[3], orientation_[0], orientation_[1], orientation_[2]) * localTransform_.getQuaterniond().inverse();
orientation_ = cv::Vec4d(q.x(),q.y(),q.z(),q.w());
if(!orientationCovariance_.empty())
{
orientationCovariance_ = rotationMatrix * orientationCovariance_ * rotationMatrixT;
}
}
localTransform_ = Transform(localTransform_.x(), localTransform_.y(), localTransform_.z(), 0,0,0);
}
}
} //namespace rtabmap
+102 -44
View File
@@ -209,42 +209,60 @@ LaserScan::LaserScan() :
{ {
} }
LaserScan::LaserScan(
const LaserScan & scan,
int maxPoints,
float maxRange,
const Transform & localTransform)
{
UASSERT(scan.empty() || scan.format() != kUnknown);
init(scan.data(), scan.format(), 0, maxRange, 0, 0, 0, maxPoints, localTransform);
}
LaserScan::LaserScan(
const LaserScan & scan,
int maxPoints,
float maxRange,
Format format,
const Transform & localTransform)
{
init(scan.data(), format, 0, maxRange, 0, 0, 0, maxPoints, localTransform);
}
LaserScan::LaserScan( LaserScan::LaserScan(
const cv::Mat & data, const cv::Mat & data,
int maxPoints, int maxPoints,
float maxRange, float maxRange,
Format format, Format format,
const Transform & localTransform) : const Transform & localTransform)
data_(data),
format_(format),
maxPoints_(maxPoints),
rangeMin_(0),
rangeMax_(maxRange),
angleMin_(0),
angleMax_(0),
angleIncrement_(0),
localTransform_(localTransform)
{ {
UASSERT(data.empty() || data.rows == 1); init(data, format, 0, maxRange, 0, 0, 0, maxPoints, localTransform);
UASSERT(data.empty() || data.type() == CV_8UC1 || data.type() == CV_32FC2 || data.type() == CV_32FC3 || data.type() == CV_32FC(4) || data.type() == CV_32FC(5) || data.type() == CV_32FC(6) || data.type() == CV_32FC(7)); }
UASSERT(!localTransform.isNull());
if(!data.empty() && !isCompressed()) LaserScan::LaserScan(
{ const LaserScan & scan,
if(format == kUnknown) float minRange,
{ float maxRange,
*this = backwardCompatibility(data_, maxPoints_, rangeMax_, localTransform_); float angleMin,
} float angleMax,
else // verify that format corresponds to expected number of channels float angleIncrement,
{ const Transform & localTransform)
UASSERT_MSG(data.channels() != 2 || (data.channels() == 2 && format == kXY), uFormat("format=%s", LaserScan::formatName(format).c_str()).c_str()); {
UASSERT_MSG(data.channels() != 3 || (data.channels() == 3 && (format == kXYZ || format == kXYI)), uFormat("format=%s", LaserScan::formatName(format).c_str()).c_str()); UASSERT(scan.empty() || scan.format() != kUnknown);
UASSERT_MSG(data.channels() != 4 || (data.channels() == 4 && (format == kXYZI || format == kXYZRGB)), uFormat("format=%s", LaserScan::formatName(format).c_str()).c_str()); init(scan.data(), scan.format(), minRange, maxRange, angleMin, angleMax, angleIncrement, 0, localTransform);
UASSERT_MSG(data.channels() != 5 || (data.channels() == 5 && (format == kXYNormal)), uFormat("format=%s", LaserScan::formatName(format).c_str()).c_str()); }
UASSERT_MSG(data.channels() != 6 || (data.channels() == 6 && (format == kXYINormal || format == kXYZNormal)), uFormat("format=%s", LaserScan::formatName(format).c_str()).c_str());
UASSERT_MSG(data.channels() != 7 || (data.channels() == 7 && (format == kXYZRGBNormal || format == kXYZINormal)), uFormat("format=%s", LaserScan::formatName(format).c_str()).c_str()); LaserScan::LaserScan(
} const LaserScan & scan,
} Format format,
float minRange,
float maxRange,
float angleMin,
float angleMax,
float angleIncrement,
const Transform & localTransform)
{
init(scan.data(), format, minRange, maxRange, angleMin, angleMax, angleIncrement, 0, localTransform);
} }
LaserScan::LaserScan( LaserScan::LaserScan(
@@ -255,37 +273,77 @@ LaserScan::LaserScan(
float angleMin, float angleMin,
float angleMax, float angleMax,
float angleIncrement, float angleIncrement,
const Transform & localTransform) : const Transform & localTransform)
data_(data),
format_(format),
rangeMin_(minRange),
rangeMax_(maxRange),
angleMin_(angleMin),
angleMax_(angleMax),
angleIncrement_(angleIncrement),
localTransform_(localTransform)
{ {
UASSERT(maxRange>minRange); init(data, format, minRange, maxRange, angleMin, angleMax, angleIncrement, 0, localTransform);
UASSERT(angleMax>angleMin); }
UASSERT(angleIncrement != 0.0f);
maxPoints_ = std::ceil((angleMax - angleMin) / angleIncrement)+1;
void LaserScan::init(
const cv::Mat & data,
Format format,
float rangeMin,
float rangeMax,
float angleMin,
float angleMax,
float angleIncrement,
int maxPoints,
const Transform & localTransform)
{
UASSERT(data.empty() || data.rows == 1); UASSERT(data.empty() || data.rows == 1);
UASSERT(data.empty() || data.type() == CV_8UC1 || data.type() == CV_32FC2 || data.type() == CV_32FC3 || data.type() == CV_32FC(4) || data.type() == CV_32FC(5) || data.type() == CV_32FC(6) || data.type() == CV_32FC(7)); UASSERT(data.empty() || data.type() == CV_8UC1 || data.type() == CV_32FC2 || data.type() == CV_32FC3 || data.type() == CV_32FC(4) || data.type() == CV_32FC(5) || data.type() == CV_32FC(6) || data.type() == CV_32FC(7));
UASSERT(!localTransform.isNull()); UASSERT(!localTransform.isNull());
bool is2D = false;
if(angleIncrement != 0.0f)
{
// 2D scan
is2D = true;
UASSERT(rangeMax>rangeMin);
UASSERT((angleIncrement>0 && angleMax>angleMin) || (angleIncrement<0 && angleMax<angleMin));
maxPoints_ = std::ceil((angleMax - angleMin) / angleIncrement)+1;
}
else
{
// 3D scan
UASSERT(rangeMax>=rangeMin);
maxPoints_ = maxPoints;
}
data_ = data;
format_ = format;
rangeMin_ = rangeMin;
rangeMax_ = rangeMax;
angleMin_ = angleMin;
angleMax_ = angleMax;
angleIncrement_ = angleIncrement;
localTransform_ = localTransform;
if(!data.empty() && !isCompressed()) if(!data.empty() && !isCompressed())
{ {
if(data_.cols > maxPoints_) if(is2D && data_.cols > maxPoints_)
{ {
UWARN("The number of points (%d) in the scan is over the maximum " UWARN("The number of points (%d) in the scan is over the maximum "
"points (%d) defined by angle settings (min=%f max=%f inc=%f). " "points (%d) defined by angle settings (min=%f max=%f inc=%f). "
"The scan info may be wrong!", "The scan info may be wrong!",
data_.cols, maxPoints_, angleMin_, angleMax_, angleIncrement_); data_.cols, maxPoints_, angleMin_, angleMax_, angleIncrement_);
} }
else if(!is2D && maxPoints_>0 && data_.cols > maxPoints_)
{
UDEBUG("The number of points (%d) in the scan is over the maximum "
"points (%d) defined by max points setting.",
data_.cols, maxPoints_);
}
if(format == kUnknown) if(format == kUnknown)
{ {
*this = backwardCompatibility(data_, rangeMin_, rangeMax_, angleMin_, angleMax_, angleIncrement_, localTransform_); if(angleIncrement_ != 0)
{
*this = backwardCompatibility(data_, rangeMin_, rangeMax_, angleMin_, angleMax_, angleIncrement_, localTransform_);
}
else
{
*this = backwardCompatibility(data_, maxPoints_, rangeMax_, localTransform_);
}
} }
else // verify that format corresponds to expected number of channels else // verify that format corresponds to expected number of channels
{ {
+38 -11
View File
@@ -2059,7 +2059,29 @@ std::map<int, Transform> Memory::loadOptimizedPoses(Transform * lastlocalization
{ {
if(_dbDriver) if(_dbDriver)
{ {
return _dbDriver->loadOptimizedPoses(lastlocalizationPose); bool ok = true;
std::map<int, Transform> poses = _dbDriver->loadOptimizedPoses(lastlocalizationPose);
// Make sure optimized poses match the working directory! Otherwise return nothing.
for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end() && ok; ++iter)
{
if(_workingMem.find(iter->first)==_workingMem.end())
{
ok = false;
}
}
if(!ok)
{
UWARN("Optimized poses (%d) and working memory "
"size (%d) don't match. Returning empty optimized "
"poses to force re-update. If you want to use the "
"saved optimized poses, set %s to true",
(int)poses.size(),
(int)_workingMem.size(),
Parameters::kMemInitWMWithAllNodes().c_str());
return std::map<int, Transform>();
}
return poses;
} }
return std::map<int, Transform>(); return std::map<int, Transform>();
} }
@@ -3053,7 +3075,7 @@ Transform Memory::computeIcpTransformMulti(
Transform t; Transform t;
if(!fromScan.isEmpty() && !toScan.isEmpty()) if(!fromScan.isEmpty() && !toScan.isEmpty())
{ {
Transform guess = poses.at(fromId).inverse() * poses.at(toId); Transform guess = poses.at(toId).inverse() * poses.at(fromId);
float guessNorm = guess.getNorm(); float guessNorm = guess.getNorm();
if(fromScan.rangeMax() > 0.0f && toScan.rangeMax() > 0.0f && if(fromScan.rangeMax() > 0.0f && toScan.rangeMax() > 0.0f &&
guessNorm > fromScan.rangeMax() + toScan.rangeMax()) guessNorm > fromScan.rangeMax() + toScan.rangeMax())
@@ -3144,7 +3166,7 @@ Transform Memory::computeIcpTransformMulti(
} }
} }
cv::Mat assembledScan; LaserScan assembledScan;
if(assembledToNormalClouds->size()) if(assembledToNormalClouds->size())
{ {
assembledScan = fromScan.is2d()?util3d::laserScan2dFromPointCloud(*assembledToNormalClouds):util3d::laserScanFromPointCloud(*assembledToNormalClouds); assembledScan = fromScan.is2d()?util3d::laserScan2dFromPointCloud(*assembledToNormalClouds):util3d::laserScanFromPointCloud(*assembledToNormalClouds);
@@ -3183,17 +3205,20 @@ Transform Memory::computeIcpTransformMulti(
assembledScan = util3d::laserScanFromPointCloud(*assembledToRGBClouds); assembledScan = util3d::laserScanFromPointCloud(*assembledToRGBClouds);
} }
} }
UDEBUG("assembledScan=%d points", assembledScan.cols); UDEBUG("assembledScan=%d points", assembledScan.size());
// scans are in base frame but for 2d scans, set the height so that correspondences matching works // scans are in base frame but for 2d scans, set the height so that correspondences matching works
assembledData.setLaserScan( assembledData.setLaserScan(
LaserScan(assembledScan, LaserScan(assembledScan,
fromScan.maxPoints()?fromScan.maxPoints():maxPoints, maxPoints,
fromScan.rangeMax(), fromScan.rangeMax(),
toScan.format(),
fromScan.is2d()?Transform(0,0,fromScan.localTransform().z(),0,0,0):Transform::getIdentity())); fromScan.is2d()?Transform(0,0,fromScan.localTransform().z(),0,0,0):Transform::getIdentity()));
t = _registrationIcpMulti->computeTransformation(fromS->sensorData(), assembledData, guess, info); t = _registrationIcpMulti->computeTransformation(assembledData, fromS->sensorData(), guess, info);
if(!t.isNull())
{
t = t.inverse();
}
} }
return t; return t;
@@ -3532,11 +3557,11 @@ unsigned long Memory::getMemoryUsed() const
} }
memoryUsage += _landmarksIndex.size() * (sizeof(int)+sizeof(std::set<int>) + sizeof(std::map<int, std::set<int> >::iterator)) + sizeof(std::map<int, std::set<int> >); memoryUsage += _landmarksIndex.size() * (sizeof(int)+sizeof(std::set<int>) + sizeof(std::map<int, std::set<int> >::iterator)) + sizeof(std::map<int, std::set<int> >);
memoryUsage += _landmarksInvertedIndex.size() * (sizeof(int)+sizeof(std::set<int>) + sizeof(std::map<int, std::set<int> >::iterator)) + sizeof(std::map<int, std::set<int> >); memoryUsage += _landmarksInvertedIndex.size() * (sizeof(int)+sizeof(std::set<int>) + sizeof(std::map<int, std::set<int> >::iterator)) + sizeof(std::map<int, std::set<int> >);
for(std::map<int, std::set<int>>::const_iterator iter=_landmarksIndex.begin(); iter!=_landmarksIndex.end(); ++iter) for(std::map<int, std::set<int> >::const_iterator iter=_landmarksIndex.begin(); iter!=_landmarksIndex.end(); ++iter)
{ {
memoryUsage+=iter->second.size()*(sizeof(int)+sizeof(std::set<int>::iterator)) + sizeof(std::set<int>); memoryUsage+=iter->second.size()*(sizeof(int)+sizeof(std::set<int>::iterator)) + sizeof(std::set<int>);
} }
for(std::map<int, std::set<int>>::const_iterator iter=_landmarksInvertedIndex.begin(); iter!=_landmarksInvertedIndex.end(); ++iter) for(std::map<int, std::set<int> >::const_iterator iter=_landmarksInvertedIndex.begin(); iter!=_landmarksInvertedIndex.end(); ++iter)
{ {
memoryUsage+=iter->second.size()*(sizeof(int)+sizeof(std::set<int>::iterator)) + sizeof(std::set<int>); memoryUsage+=iter->second.size()*(sizeof(int)+sizeof(std::set<int>::iterator)) + sizeof(std::set<int>);
} }
@@ -4131,7 +4156,7 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
float t; float t;
std::vector<cv::KeyPoint> keypoints; std::vector<cv::KeyPoint> keypoints;
cv::Mat descriptors; cv::Mat descriptors;
bool isIntermediateNode = data.id() < 0 || (data.imageRaw().empty() && data.keypoints().empty()); bool isIntermediateNode = data.id() < 0 || (data.imageRaw().empty() && data.keypoints().empty() && data.laserScanRaw().empty());
int id = data.id(); int id = data.id();
if(_generateIds) if(_generateIds)
{ {
@@ -4205,6 +4230,7 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
"full calibration. If images are already rectified, set %s parameter back to true.", "full calibration. If images are already rectified, set %s parameter back to true.",
(int)i, (int)i,
Parameters::kRtabmapImagesAlreadyRectified().c_str()); Parameters::kRtabmapImagesAlreadyRectified().c_str());
std::cout << data.cameraModels()[i] << std::endl;
return 0; return 0;
} }
} }
@@ -5246,7 +5272,8 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
// Occupancy grid map stuff // Occupancy grid map stuff
if(_createOccupancyGrid && !isIntermediateNode) if(_createOccupancyGrid && !isIntermediateNode)
{ {
if(!data.depthOrRightRaw().empty()) if( (_occupancy->isGridFromDepth() && !data.depthOrRightRaw().empty()) ||
(!_occupancy->isGridFromDepth() && !data.laserScanRaw().empty()))
{ {
cv::Mat ground, obstacles, empty; cv::Mat ground, obstacles, empty;
float cellSize = 0.0f; float cellSize = 0.0f;
+23 -17
View File
@@ -286,8 +286,8 @@ void OccupancyGrid::createLocalMap(
cv::Mat & emptyCells, cv::Mat & emptyCells,
cv::Point3f & viewPoint) const cv::Point3f & viewPoint) const
{ {
UDEBUG("scan format=%d, occupancyFromDepth_=%d normalsSegmentation_=%d grid3D_=%d", UDEBUG("scan format=%s, occupancyFromDepth_=%d normalsSegmentation_=%d grid3D_=%d",
node.sensorData().laserScanRaw().isEmpty()?0:node.sensorData().laserScanRaw().format(), occupancyFromDepth_?1:0, normalsSegmentation_?1:0, grid3D_?1:0); node.sensorData().laserScanRaw().isEmpty()?"NA":node.sensorData().laserScanRaw().formatName().c_str(), occupancyFromDepth_?1:0, normalsSegmentation_?1:0, grid3D_?1:0);
if((node.sensorData().laserScanRaw().is2d()) && !occupancyFromDepth_) if((node.sensorData().laserScanRaw().is2d()) && !occupancyFromDepth_)
{ {
@@ -407,7 +407,7 @@ void OccupancyGrid::createLocalMap(
const Transform & t = node.sensorData().stereoCameraModel().localTransform(); const Transform & t = node.sensorData().stereoCameraModel().localTransform();
viewPoint = cv::Point3f(t.x(), t.y(), t.z()); viewPoint = cv::Point3f(t.x(), t.y(), t.z());
} }
createLocalMap(LaserScan(util3d::laserScanFromPointCloud(*cloud, indices), 0, 0.0f, LaserScan::kXYZRGB), node.getPose(), groundCells, obstacleCells, emptyCells, viewPoint); createLocalMap(LaserScan(util3d::laserScanFromPointCloud(*cloud, indices), 0, 0.0f), node.getPose(), groundCells, obstacleCells, emptyCells, viewPoint);
} }
} }
} }
@@ -445,8 +445,8 @@ void OccupancyGrid::createLocalMap(
UDEBUG("groundIndices=%d, obstaclesIndices=%d", (int)groundIndices->size(), (int)obstaclesIndices->size()); UDEBUG("groundIndices=%d, obstaclesIndices=%d", (int)groundIndices->size(), (int)obstaclesIndices->size());
if(grid3D_) if(grid3D_)
{ {
groundCloud = util3d::laserScanFromPointCloud(*cloudSegmented, groundIndices); groundCloud = util3d::laserScanFromPointCloud(*cloudSegmented, groundIndices).data();
obstaclesCloud = util3d::laserScanFromPointCloud(*cloudSegmented, obstaclesIndices); obstaclesCloud = util3d::laserScanFromPointCloud(*cloudSegmented, obstaclesIndices).data();
} }
else else
{ {
@@ -460,8 +460,8 @@ void OccupancyGrid::createLocalMap(
UDEBUG("groundIndices=%d, obstaclesIndices=%d", (int)groundIndices->size(), (int)obstaclesIndices->size()); UDEBUG("groundIndices=%d, obstaclesIndices=%d", (int)groundIndices->size(), (int)obstaclesIndices->size());
if(grid3D_) if(grid3D_)
{ {
groundCloud = util3d::laserScanFromPointCloud(*cloudSegmented, groundIndices); groundCloud = util3d::laserScanFromPointCloud(*cloudSegmented, groundIndices).data();
obstaclesCloud = util3d::laserScanFromPointCloud(*cloudSegmented, obstaclesIndices); obstaclesCloud = util3d::laserScanFromPointCloud(*cloudSegmented, obstaclesIndices).data();
} }
else else
{ {
@@ -475,8 +475,8 @@ void OccupancyGrid::createLocalMap(
UDEBUG("groundIndices=%d, obstaclesIndices=%d", (int)groundIndices->size(), (int)obstaclesIndices->size()); UDEBUG("groundIndices=%d, obstaclesIndices=%d", (int)groundIndices->size(), (int)obstaclesIndices->size());
if(grid3D_) if(grid3D_)
{ {
groundCloud = util3d::laserScanFromPointCloud(*cloudSegmented, groundIndices); groundCloud = util3d::laserScanFromPointCloud(*cloudSegmented, groundIndices).data();
obstaclesCloud = util3d::laserScanFromPointCloud(*cloudSegmented, obstaclesIndices); obstaclesCloud = util3d::laserScanFromPointCloud(*cloudSegmented, obstaclesIndices).data();
} }
else else
{ {
@@ -490,8 +490,8 @@ void OccupancyGrid::createLocalMap(
UDEBUG("groundIndices=%d, obstaclesIndices=%d", (int)groundIndices->size(), (int)obstaclesIndices->size()); UDEBUG("groundIndices=%d, obstaclesIndices=%d", (int)groundIndices->size(), (int)obstaclesIndices->size());
if(grid3D_) if(grid3D_)
{ {
groundCloud = util3d::laserScanFromPointCloud(*cloudSegmented, groundIndices); groundCloud = util3d::laserScanFromPointCloud(*cloudSegmented, groundIndices).data();
obstaclesCloud = util3d::laserScanFromPointCloud(*cloudSegmented, obstaclesIndices); obstaclesCloud = util3d::laserScanFromPointCloud(*cloudSegmented, obstaclesIndices).data();
} }
else else
{ {
@@ -543,17 +543,17 @@ void OccupancyGrid::createLocalMap(
UDEBUG("ground=%d obstacles=%d empty=%d", (int)groundIndices->size(), (int)obstaclesIndices->size(), (int)emptyIndices->size()); UDEBUG("ground=%d obstacles=%d empty=%d", (int)groundIndices->size(), (int)obstaclesIndices->size(), (int)emptyIndices->size());
if(scan.hasRGB()) if(scan.hasRGB())
{ {
groundCells = util3d::laserScanFromPointCloud(*cloudWithRayTracing, groundIndices, tinv); groundCells = util3d::laserScanFromPointCloud(*cloudWithRayTracing, groundIndices, tinv).data();
obstacleCells = util3d::laserScanFromPointCloud(*cloudWithRayTracing, obstaclesIndices, tinv); obstacleCells = util3d::laserScanFromPointCloud(*cloudWithRayTracing, obstaclesIndices, tinv).data();
emptyCells = util3d::laserScanFromPointCloud(*cloudWithRayTracing, emptyIndices, tinv); emptyCells = util3d::laserScanFromPointCloud(*cloudWithRayTracing, emptyIndices, tinv).data();
} }
else else
{ {
pcl::PointCloud<pcl::PointXYZ>::Ptr cloudWithRayTracing2(new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr cloudWithRayTracing2(new pcl::PointCloud<pcl::PointXYZ>);
pcl::copyPointCloud(*cloudWithRayTracing, *cloudWithRayTracing2); pcl::copyPointCloud(*cloudWithRayTracing, *cloudWithRayTracing2);
groundCells = util3d::laserScanFromPointCloud(*cloudWithRayTracing2, groundIndices, tinv); groundCells = util3d::laserScanFromPointCloud(*cloudWithRayTracing2, groundIndices, tinv).data();
obstacleCells = util3d::laserScanFromPointCloud(*cloudWithRayTracing2, obstaclesIndices, tinv); obstacleCells = util3d::laserScanFromPointCloud(*cloudWithRayTracing2, obstaclesIndices, tinv).data();
emptyCells = util3d::laserScanFromPointCloud(*cloudWithRayTracing2, emptyIndices, tinv); emptyCells = util3d::laserScanFromPointCloud(*cloudWithRayTracing2, emptyIndices, tinv).data();
} }
} }
} }
@@ -669,6 +669,10 @@ cv::Mat OccupancyGrid::getProbMap(float & xMin, float & yMin) const
} }
} }
} }
else
{
UWARN("Map info is empty, cannot generate probabilistic occupancy grid");
}
return map; return map;
} }
@@ -1244,6 +1248,7 @@ bool OccupancyGrid::update(const std::map<int, Transform> & posesIn)
ptBegin.y = 0; ptBegin.y = 0;
if(ptEnd.y >= map.rows) if(ptEnd.y >= map.rows)
ptEnd.y = map.rows-1; ptEnd.y = map.rows-1;
for(int i=ptBegin.x; i<ptEnd.x; ++i) for(int i=ptBegin.x; i<ptEnd.x; ++i)
{ {
for(int j=ptBegin.y; j<ptEnd.y; ++j) for(int j=ptBegin.y; j<ptEnd.y; ++j)
@@ -1282,6 +1287,7 @@ bool OccupancyGrid::update(const std::map<int, Transform> & posesIn)
info[0] = (float)kter->first; info[0] = (float)kter->first;
info[1] = float(i) * cellSize_ + xMin; info[1] = float(i) * cellSize_ + xMin;
info[2] = float(j) * cellSize_ + yMin; info[2] = float(j) * cellSize_ + yMin;
info[3] = probClampingMin_;
cter->second.first+=1; cter->second.first+=1;
} }
value = -2; // free space (footprint) value = -2; // free space (footprint)
+48 -20
View File
@@ -32,7 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/core/odometry/OdometryViso2.h" #include "rtabmap/core/odometry/OdometryViso2.h"
#include "rtabmap/core/odometry/OdometryDVO.h" #include "rtabmap/core/odometry/OdometryDVO.h"
#include "rtabmap/core/odometry/OdometryOkvis.h" #include "rtabmap/core/odometry/OdometryOkvis.h"
#include "rtabmap/core/odometry/OdometryORBSLAM2.h" #include "rtabmap/core/odometry/OdometryORBSLAM.h"
#include "rtabmap/core/odometry/OdometryLOAM.h" #include "rtabmap/core/odometry/OdometryLOAM.h"
#include "rtabmap/core/odometry/OdometryMSCKF.h" #include "rtabmap/core/odometry/OdometryMSCKF.h"
#include "rtabmap/core/odometry/OdometryVINS.h" #include "rtabmap/core/odometry/OdometryVINS.h"
@@ -80,8 +80,8 @@ Odometry * Odometry::create(Odometry::Type & type, const ParametersMap & paramet
case Odometry::kTypeDVO: case Odometry::kTypeDVO:
odometry = new OdometryDVO(parameters); odometry = new OdometryDVO(parameters);
break; break;
case Odometry::kTypeORBSLAM2: case Odometry::kTypeORBSLAM:
odometry = new OdometryORBSLAM2(parameters); odometry = new OdometryORBSLAM(parameters);
break; break;
case Odometry::kTypeOkvis: case Odometry::kTypeOkvis:
odometry = new OdometryOkvis(parameters); odometry = new OdometryOkvis(parameters);
@@ -284,6 +284,39 @@ Transform Odometry::process(SensorData & data, const Transform & guessIn, Odomet
{ {
UASSERT_MSG(data.id() >= 0, uFormat("Input data should have ID greater or equal than 0 (id=%d)!", data.id()).c_str()); UASSERT_MSG(data.id() >= 0, uFormat("Input data should have ID greater or equal than 0 (id=%d)!", data.id()).c_str());
// cache imu data
if(!data.imu().empty() && !this->canProcessAsyncIMU())
{
if(!(data.imu().orientation()[0] == 0.0 && data.imu().orientation()[1] == 0.0 && data.imu().orientation()[2] == 0.0))
{
Transform orientation(0,0,0, data.imu().orientation()[0], data.imu().orientation()[1], data.imu().orientation()[2], data.imu().orientation()[3]);
// orientation includes roll and pitch but not yaw in local transform
Transform imuT = Transform(data.imu().localTransform().x(),data.imu().localTransform().y(),data.imu().localTransform().z(), 0,0,data.imu().localTransform().theta()) *
orientation*
data.imu().localTransform().rotation().inverse();
IMU imu2 = data.imu();
imu2.convertToBaseFrame();
if( this->getPose().r11() == 1.0f && this->getPose().r22() == 1.0f && this->getPose().r33() == 1.0f &&
this->framesProcessed() == 0)
{
Eigen::Quaterniond imuQuat = imuT.getQuaterniond();
Transform previous = this->getPose();
Transform newFramePose = Transform(previous.x(), previous.y(), previous.z(), imuQuat.x(), imuQuat.y(), imuQuat.z(), imuQuat.w());
UWARN("Updated initial pose from %s to %s with IMU orientation", previous.prettyPrint().c_str(), newFramePose.prettyPrint().c_str());
this->reset(newFramePose);
}
imus_.insert(std::make_pair(data.stamp(), imuT));
if(imus_.size() > 1000)
{
imus_.erase(imus_.begin());
}
}
}
if(!_imagesAlreadyRectified && !this->canProcessRawImages() && !data.imageRaw().empty()) if(!_imagesAlreadyRectified && !this->canProcessRawImages() && !data.imageRaw().empty())
{ {
if(data.stereoCameraModel().isValidForRectification()) if(data.stereoCameraModel().isValidForRectification())
@@ -386,21 +419,6 @@ Transform Odometry::process(SensorData & data, const Transform & guessIn, Odomet
} }
} }
// cache imu data
if(!data.imu().empty())
{
if(!(data.imu().orientation()[0] == 0.0 && data.imu().orientation()[1] == 0.0 && data.imu().orientation()[2] == 0.0))
{
Transform orientation(0,0,0, data.imu().orientation()[0], data.imu().orientation()[1], data.imu().orientation()[2], data.imu().orientation()[3]);
// orientation includes roll and pitch but not yaw in local transform
imus_.insert(std::make_pair(data.stamp(), Transform(0,0,data.imu().localTransform().theta()) * orientation*data.imu().localTransform().inverse()));
if(imus_.size() > 1000)
{
imus_.erase(imus_.begin());
}
}
}
// KITTI datasets start with stamp=0 // KITTI datasets start with stamp=0
double dt = previousStamp_>0.0f || (previousStamp_==0.0f && framesProcessed()==1)?data.stamp() - previousStamp_:0.0; double dt = previousStamp_>0.0f || (previousStamp_==0.0f && framesProcessed()==1)?data.stamp() - previousStamp_:0.0;
Transform guess = dt>0.0 && guessFromMotion_ && !velocityGuess_.isNull()?Transform::getIdentity():Transform(); Transform guess = dt>0.0 && guessFromMotion_ && !velocityGuess_.isNull()?Transform::getIdentity():Transform();
@@ -447,7 +465,7 @@ Transform Odometry::process(SensorData & data, const Transform & guessIn, Odomet
{ {
guess = guessIn; guess = guessIn;
} }
else if(!data.imu().empty() && !imus_.empty()) else if(!imus_.empty())
{ {
// replace orientation guess with IMU (if available) // replace orientation guess with IMU (if available)
imuCurrentTransform = Transform::getTransform(imus_, data.stamp()); imuCurrentTransform = Transform::getTransform(imus_, data.stamp());
@@ -458,6 +476,14 @@ Transform Odometry::process(SensorData & data, const Transform & guessIn, Odomet
orientation.r11(), orientation.r12(), orientation.r13(), guess.x(), orientation.r11(), orientation.r12(), orientation.r13(), guess.x(),
orientation.r21(), orientation.r22(), orientation.r23(), guess.y(), orientation.r21(), orientation.r22(), orientation.r23(), guess.y(),
orientation.r31(), orientation.r32(), orientation.r33(), guess.z()); orientation.r31(), orientation.r32(), orientation.r33(), guess.z());
if(_force3DoF)
{
guess = guess.to3DoF();
}
}
else if(!imuLastTransform_.isNull())
{
UWARN("Could not find imu transform at %f", data.stamp());
} }
} }
@@ -503,6 +529,7 @@ Transform Odometry::process(SensorData & data, const Transform & guessIn, Odomet
kpts[i].octave += log2value; kpts[i].octave += log2value;
} }
data.setFeatures(kpts, decimatedData.keypoints3D(), decimatedData.descriptors()); data.setFeatures(kpts, decimatedData.keypoints3D(), decimatedData.descriptors());
data.setLaserScan(decimatedData.laserScanRaw());
if(info) if(info)
{ {
@@ -523,7 +550,7 @@ Transform Odometry::process(SensorData & data, const Transform & guessIn, Odomet
} }
} }
} }
else else if(!data.imageRaw().empty() || !data.laserScanRaw().isEmpty() || (this->canProcessAsyncIMU() && !data.imu().empty()))
{ {
t = this->computeTransform(data, guess, info); t = this->computeTransform(data, guess, info);
} }
@@ -540,6 +567,7 @@ Transform Odometry::process(SensorData & data, const Transform & guessIn, Odomet
info->stamp = data.stamp(); info->stamp = data.stamp();
info->interval = dt; info->interval = dt;
info->transform = t; info->transform = t;
info->guess = guess;
if(_publishRAMUsage) if(_publishRAMUsage)
{ {
info->memoryUsage = UProcessInfo::getMemoryUsage()/(1024*1024); info->memoryUsage = UProcessInfo::getMemoryUsage()/(1024*1024);
+4 -3
View File
@@ -119,7 +119,7 @@ void OdometryThread::mainLoop()
OdometryInfo info; OdometryInfo info;
UDEBUG("Processing data..."); UDEBUG("Processing data...");
Transform pose = _odometry->process(data, &info); Transform pose = _odometry->process(data, &info);
if(!data.imageRaw().empty() || (pose.isNull() && data.imu().empty())) if(!data.imageRaw().empty() || !data.laserScanRaw().empty() || (pose.isNull() && data.imu().empty()))
{ {
UDEBUG("Odom pose = %s", pose.prettyPrint().c_str()); UDEBUG("Odom pose = %s", pose.prettyPrint().c_str());
// a null pose notify that odometry could not be computed // a null pose notify that odometry could not be computed
@@ -134,9 +134,10 @@ void OdometryThread::addData(const SensorData & data)
{ {
if(dynamic_cast<OdometryMono*>(_odometry) == 0) if(dynamic_cast<OdometryMono*>(_odometry) == 0)
{ {
if(data.imageRaw().empty() || data.depthOrRightRaw().empty() || (data.cameraModels().size()==0 && !data.stereoCameraModel().isValidForProjection())) if((data.imageRaw().empty() || data.depthOrRightRaw().empty() || (data.cameraModels().size()==0 && !data.stereoCameraModel().isValidForProjection())) &&
data.laserScanRaw().empty())
{ {
ULOGGER_ERROR("Missing some information (images empty or missing calibration)!?"); ULOGGER_ERROR("Missing some information (images/scans empty or missing calibration)!?");
return; return;
} }
} }
+454
View File
@@ -0,0 +1,454 @@
/*
Copyright (c) 2010-2021, 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.
*/
#include <rtabmap/core/PDALWriter.h>
#include <rtabmap/utilite/UFile.h>
#include <rtabmap/utilite/ULogger.h>
#include <rtabmap/utilite/UStl.h>
#include <rtabmap/utilite/UConversion.h>
#include <pdal/io/BufferReader.hpp>
#include <pdal/StageFactory.hpp>
#include <pdal/PluginManager.hpp>
#ifdef RTABMAP_PDAL_16
#include <pdal/pdal_defines.h>
#else
#include <pdal/pdal_features.hpp>
#endif
namespace rtabmap {
std::string getPDALSupportedWriters()
{
std::string output;
// Force plugin loading.
#if PDAL_VERSION_MAJOR>1 || (PDAL_VERSION_MAJOR == 1 && PDAL_VERSION_MINOR > 7) || (PDAL_VERSION_MAJOR == 1 && PDAL_VERSION_MINOR == 7 && PDAL_VERSION_MINOR>=1)
pdal::StageFactory f;
pdal::PluginManager<pdal::Stage>::loadAll();
pdal::StringList stages = pdal::PluginManager<pdal::Stage>::names();
#else
pdal::StageFactory f(false);
pdal::StringList stages = pdal::PluginManager::names(PF_PluginType_Writer);
#endif
for(pdal::StringList::iterator iter=stages.begin(); iter!=stages.end(); ++iter)
{
if(!uStrContains(*iter, "writers"))
{
continue;
}
if(iter->compare("writers.null") == 0)
{
continue;
}
if(iter!=stages.begin())
{
output += " ";
}
output += UFile::getExtension(*iter);
}
return output;
}
int savePDALFile(const std::string & filePath,
const pcl::PointCloud<pcl::PointXYZ> & cloud,
const std::vector<int> & cameraIds,
bool binary)
{
UASSERT_MSG(cameraIds.empty() || cameraIds.size() == cloud.size(),
uFormat("cameraIds=%d cloud=%d", (int)cameraIds.size(), (int)cloud.size()).c_str());
pdal::PointTable table;
if(!cameraIds.empty())
{
table.layout()->registerDims({
pdal::Dimension::Id::X,
pdal::Dimension::Id::Y,
pdal::Dimension::Id::Z,
pdal::Dimension::Id::PointSourceId});
}
else
{
table.layout()->registerDims({
pdal::Dimension::Id::X,
pdal::Dimension::Id::Y,
pdal::Dimension::Id::Z});
}
pdal::BufferReader bufferReader;
pdal::PointViewPtr view(new pdal::PointView(table));
for(size_t i=0; i<cloud.size(); ++i)
{
view->setField(pdal::Dimension::Id::X, i, cloud.at(i).x);
view->setField(pdal::Dimension::Id::Y, i, cloud.at(i).y);
view->setField(pdal::Dimension::Id::Z, i, cloud.at(i).z);
if(!cameraIds.empty())
{
view->setField(pdal::Dimension::Id::PointSourceId, i, cameraIds.at(i));
}
}
bufferReader.addView(view);
pdal::StageFactory factory;
std::string ext = UFile::getExtension(filePath);
pdal::Stage *writer = factory.createStage("writers." + ext);
if(writer)
{
pdal::Options writerOps;
writerOps.add("filename", filePath);
if(ext.compare("ply")==0) writerOps.add("storage_mode", binary?"little endian":"ascii"); // PLY
if(ext.compare("pcd")==0) writerOps.add("compression", binary?"binary":"ascii"); // PCD
writer->setOptions(writerOps);
writer->setInput(bufferReader);
writer->prepare(table);
writer->execute(table);
}
else
{
UERROR("PDAL: cannot find writer for extension \"%s\". Available extensions: \"%s\"",
UFile::getExtension(filePath).c_str(),
getPDALSupportedWriters().c_str());
return 1;
}
return 0; //success
}
int savePDALFile(const std::string & filePath,
const pcl::PointCloud<pcl::PointXYZRGB> & cloud,
const std::vector<int> & cameraIds,
bool binary)
{
UASSERT_MSG(cameraIds.empty() || cameraIds.size() == cloud.size(),
uFormat("cameraIds=%d cloud=%d", (int)cameraIds.size(), (int)cloud.size()).c_str());
pdal::PointTable table;
if(!cameraIds.empty())
{
table.layout()->registerDims({
pdal::Dimension::Id::X,
pdal::Dimension::Id::Y,
pdal::Dimension::Id::Z,
pdal::Dimension::Id::Red,
pdal::Dimension::Id::Green,
pdal::Dimension::Id::Blue,
pdal::Dimension::Id::PointSourceId});
}
else
{
table.layout()->registerDims({
pdal::Dimension::Id::X,
pdal::Dimension::Id::Y,
pdal::Dimension::Id::Z,
pdal::Dimension::Id::Red,
pdal::Dimension::Id::Green,
pdal::Dimension::Id::Blue});
}
pdal::BufferReader bufferReader;
pdal::PointViewPtr view(new pdal::PointView(table));
for(size_t i=0; i<cloud.size(); ++i)
{
view->setField(pdal::Dimension::Id::X, i, cloud.at(i).x);
view->setField(pdal::Dimension::Id::Y, i, cloud.at(i).y);
view->setField(pdal::Dimension::Id::Z, i, cloud.at(i).z);
view->setField(pdal::Dimension::Id::Red, i, cloud.at(i).r);
view->setField(pdal::Dimension::Id::Green, i, cloud.at(i).g);
view->setField(pdal::Dimension::Id::Blue, i, cloud.at(i).b);
if(!cameraIds.empty())
{
view->setField(pdal::Dimension::Id::PointSourceId, i, cameraIds.at(i));
}
}
bufferReader.addView(view);
pdal::StageFactory factory;
std::string ext = UFile::getExtension(filePath);
pdal::Stage *writer = factory.createStage("writers." + ext);
if(writer)
{
pdal::Options writerOps;
writerOps.add("filename", filePath);
if(ext.compare("ply")==0) writerOps.add("storage_mode", binary?"little endian":"ascii"); // PLY
if(ext.compare("pcd")==0) writerOps.add("compression", binary?"binary":"ascii"); // PCD
writer->setOptions(writerOps);
writer->setInput(bufferReader);
writer->prepare(table);
writer->execute(table);
}
else
{
UERROR("PDAL: cannot find writer for extension \"%s\". Available extensions: \"%s\"",
UFile::getExtension(filePath).c_str(),
getPDALSupportedWriters().c_str());
return 1;
}
return 0; //success
}
int savePDALFile(const std::string & filePath,
const pcl::PointCloud<pcl::PointXYZRGBNormal> & cloud,
const std::vector<int> & cameraIds,
bool binary)
{
UASSERT_MSG(cameraIds.empty() || cameraIds.size() == cloud.size(),
uFormat("cameraIds=%d cloud=%d", (int)cameraIds.size(), (int)cloud.size()).c_str());
pdal::PointTable table;
if(!cameraIds.empty())
{
table.layout()->registerDims({
pdal::Dimension::Id::X,
pdal::Dimension::Id::Y,
pdal::Dimension::Id::Z,
pdal::Dimension::Id::Red,
pdal::Dimension::Id::Green,
pdal::Dimension::Id::Blue,
pdal::Dimension::Id::NormalX,
pdal::Dimension::Id::NormalY,
pdal::Dimension::Id::NormalZ,
pdal::Dimension::Id::PointSourceId});
}
else
{
table.layout()->registerDims({
pdal::Dimension::Id::X,
pdal::Dimension::Id::Y,
pdal::Dimension::Id::Z,
pdal::Dimension::Id::Red,
pdal::Dimension::Id::Green,
pdal::Dimension::Id::Blue,
pdal::Dimension::Id::NormalX,
pdal::Dimension::Id::NormalY,
pdal::Dimension::Id::NormalZ});
}
pdal::BufferReader bufferReader;
pdal::PointViewPtr view(new pdal::PointView(table));
for(size_t i=0; i<cloud.size(); ++i)
{
view->setField(pdal::Dimension::Id::X, i, cloud.at(i).x);
view->setField(pdal::Dimension::Id::Y, i, cloud.at(i).y);
view->setField(pdal::Dimension::Id::Z, i, cloud.at(i).z);
view->setField(pdal::Dimension::Id::Red, i, cloud.at(i).r);
view->setField(pdal::Dimension::Id::Green, i, cloud.at(i).g);
view->setField(pdal::Dimension::Id::Blue, i, cloud.at(i).b);
view->setField(pdal::Dimension::Id::NormalX, i, cloud.at(i).normal_x);
view->setField(pdal::Dimension::Id::NormalY, i, cloud.at(i).normal_y);
view->setField(pdal::Dimension::Id::NormalZ, i, cloud.at(i).normal_z);
if(!cameraIds.empty())
{
view->setField(pdal::Dimension::Id::PointSourceId, i, cameraIds.at(i));
}
}
bufferReader.addView(view);
pdal::StageFactory factory;
std::string ext = UFile::getExtension(filePath);
pdal::Stage *writer = factory.createStage("writers." + ext);
if(writer)
{
pdal::Options writerOps;
writerOps.add("filename", filePath);
if(ext.compare("ply")==0) writerOps.add("storage_mode", binary?"little endian":"ascii"); // PLY
if(ext.compare("pcd")==0) writerOps.add("compression", binary?"binary":"ascii"); // PCD
writer->setOptions(writerOps);
writer->setInput(bufferReader);
writer->prepare(table);
writer->execute(table);
}
else
{
UERROR("PDAL: cannot find writer for extension \"%s\". Available extensions: \"%s\"",
UFile::getExtension(filePath).c_str(),
getPDALSupportedWriters().c_str());
return 1;
}
return 0; //success
}
int savePDALFile(const std::string & filePath,
const pcl::PointCloud<pcl::PointXYZI> & cloud,
const std::vector<int> & cameraIds,
bool binary)
{
UASSERT_MSG(cameraIds.empty() || cameraIds.size() == cloud.size(),
uFormat("cameraIds=%d cloud=%d", (int)cameraIds.size(), (int)cloud.size()).c_str());
pdal::PointTable table;
if(!cameraIds.empty())
{
table.layout()->registerDims({
pdal::Dimension::Id::X,
pdal::Dimension::Id::Y,
pdal::Dimension::Id::Z,
pdal::Dimension::Id::Intensity,
pdal::Dimension::Id::PointSourceId});
}
else
{
table.layout()->registerDims({
pdal::Dimension::Id::X,
pdal::Dimension::Id::Y,
pdal::Dimension::Id::Z,
pdal::Dimension::Id::Intensity});
}
pdal::BufferReader bufferReader;
pdal::PointViewPtr view(new pdal::PointView(table));
for(size_t i=0; i<cloud.size(); ++i)
{
view->setField(pdal::Dimension::Id::X, i, cloud.at(i).x);
view->setField(pdal::Dimension::Id::Y, i, cloud.at(i).y);
view->setField(pdal::Dimension::Id::Z, i, cloud.at(i).z);
view->setField(pdal::Dimension::Id::Intensity, i, (unsigned short)cloud.at(i).intensity);
if(!cameraIds.empty())
{
view->setField(pdal::Dimension::Id::PointSourceId, i, cameraIds.at(i));
}
}
bufferReader.addView(view);
pdal::StageFactory factory;
std::string ext = UFile::getExtension(filePath);
pdal::Stage *writer = factory.createStage("writers." + ext);
if(writer)
{
pdal::Options writerOps;
writerOps.add("filename", filePath);
if(ext.compare("ply")==0) writerOps.add("storage_mode", binary?"little endian":"ascii"); // PLY
if(ext.compare("pcd")==0) writerOps.add("compression", binary?"binary":"ascii"); // PCD
writer->setOptions(writerOps);
writer->setInput(bufferReader);
writer->prepare(table);
writer->execute(table);
}
else
{
UERROR("PDAL: cannot find writer for extension \"%s\". Available extensions: \"%s\"",
UFile::getExtension(filePath).c_str(),
getPDALSupportedWriters().c_str());
return 1;
}
return 0; //success
}
int savePDALFile(const std::string & filePath,
const pcl::PointCloud<pcl::PointXYZINormal> & cloud,
const std::vector<int> & cameraIds,
bool binary)
{
UASSERT_MSG(cameraIds.empty() || cameraIds.size() == cloud.size(),
uFormat("cameraIds=%d cloud=%d", (int)cameraIds.size(), (int)cloud.size()).c_str());
pdal::PointTable table;
if(!cameraIds.empty())
{
table.layout()->registerDims({
pdal::Dimension::Id::X,
pdal::Dimension::Id::Y,
pdal::Dimension::Id::Z,
pdal::Dimension::Id::Intensity,
pdal::Dimension::Id::NormalX,
pdal::Dimension::Id::NormalY,
pdal::Dimension::Id::NormalZ,
pdal::Dimension::Id::PointSourceId});
}
else
{
table.layout()->registerDims({
pdal::Dimension::Id::X,
pdal::Dimension::Id::Y,
pdal::Dimension::Id::Z,
pdal::Dimension::Id::Intensity,
pdal::Dimension::Id::NormalX,
pdal::Dimension::Id::NormalY,
pdal::Dimension::Id::NormalZ});
}
pdal::BufferReader bufferReader;
pdal::PointViewPtr view(new pdal::PointView(table));
for(size_t i=0; i<cloud.size(); ++i)
{
view->setField(pdal::Dimension::Id::X, i, cloud.at(i).x);
view->setField(pdal::Dimension::Id::Y, i, cloud.at(i).y);
view->setField(pdal::Dimension::Id::Z, i, cloud.at(i).z);
view->setField(pdal::Dimension::Id::Intensity, i, (unsigned short)cloud.at(i).intensity);
view->setField(pdal::Dimension::Id::NormalX, i, cloud.at(i).normal_x);
view->setField(pdal::Dimension::Id::NormalY, i, cloud.at(i).normal_y);
view->setField(pdal::Dimension::Id::NormalZ, i, cloud.at(i).normal_z);
if(!cameraIds.empty())
{
view->setField(pdal::Dimension::Id::PointSourceId, i, cameraIds.at(i));
}
}
bufferReader.addView(view);
pdal::StageFactory factory;
std::string ext = UFile::getExtension(filePath);
pdal::Stage *writer = factory.createStage("writers." + ext);
if(writer)
{
pdal::Options writerOps;
writerOps.add("filename", filePath);
if(ext.compare("ply")==0) writerOps.add("storage_mode", binary?"little endian":"ascii"); // PLY
if(ext.compare("pcd")==0) writerOps.add("compression", binary?"binary":"ascii"); // PCD
writer->setOptions(writerOps);
writer->setInput(bufferReader);
writer->prepare(table);
writer->execute(table);
}
else
{
UERROR("PDAL: cannot find writer for extension \"%s\". Available extensions: \"%s\"",
UFile::getExtension(filePath).c_str(),
getPDALSupportedWriters().c_str());
return 1;
}
return 0; //success
}
}
+45 -5
View File
@@ -167,7 +167,8 @@ bool Parameters::isFeatureParameter(const std::string & parameter)
group.compare("GFTT") == 0 || group.compare("GFTT") == 0 ||
group.compare("BRISK") == 0 || group.compare("BRISK") == 0 ||
group.compare("KAZE") == 0 || group.compare("KAZE") == 0 ||
group.compare("SuperPoint") == 0; group.compare("SuperPoint") == 0 ||
group.compare("PyDetector") == 0;
} }
rtabmap::ParametersMap Parameters::getDefaultOdometryParameters(bool stereo, bool vis, bool icp) rtabmap::ParametersMap Parameters::getDefaultOdometryParameters(bool stereo, bool vis, bool icp)
@@ -186,7 +187,8 @@ rtabmap::ParametersMap Parameters::getDefaultOdometryParameters(bool stereo, boo
group.compare("g2o") == 0 || group.compare("g2o") == 0 ||
group.compare("GTSAM") == 0 || group.compare("GTSAM") == 0 ||
(vis && (group.compare("Vis") == 0 || group.compare("PyMatcher") == 0 || group.compare("GMS") == 0)) || (vis && (group.compare("Vis") == 0 || group.compare("PyMatcher") == 0 || group.compare("GMS") == 0)) ||
iter->first.compare(kRtabmapPublishRAMUsage())==0) iter->first.compare(kRtabmapPublishRAMUsage())==0 ||
iter->first.compare(kRtabmapImagesAlreadyRectified())==0)
{ {
odomParameters.insert(*iter); odomParameters.insert(*iter);
} }
@@ -232,6 +234,20 @@ const std::map<std::string, std::pair<bool, std::string> > & Parameters::getRemo
{ {
// removed parameters // removed parameters
// 0.20.9
removedParameters_.insert(std::make_pair("OdomORBSLAM2/VocPath", std::make_pair(true, Parameters::kOdomORBSLAMVocPath())));
removedParameters_.insert(std::make_pair("OdomORBSLAM2/Bf", std::make_pair(true, Parameters::kOdomORBSLAMBf())));
removedParameters_.insert(std::make_pair("OdomORBSLAM2/ThDepth", std::make_pair(true, Parameters::kOdomORBSLAMThDepth())));
removedParameters_.insert(std::make_pair("OdomORBSLAM2/Fps", std::make_pair(true, Parameters::kOdomORBSLAMFps())));
removedParameters_.insert(std::make_pair("OdomORBSLAM2/MaxFeatures", std::make_pair(true, Parameters::kOdomORBSLAMMaxFeatures())));
removedParameters_.insert(std::make_pair("OdomORBSLAM2/MapSize", std::make_pair(true, Parameters::kOdomORBSLAMMapSize())));
removedParameters_.insert(std::make_pair("RGBD/SavedLocalizationIgnored", std::make_pair(true, Parameters::kRGBDStartAtOrigin())));
removedParameters_.insert(std::make_pair("Icp/PMForce4DoF", std::make_pair(true, Parameters::kIcpForce4DoF())));
removedParameters_.insert(std::make_pair("Icp/PM", std::make_pair(true, Parameters::kIcpStrategy()))); // convert "true" to "1"
removedParameters_.insert(std::make_pair("Icp/PMOutlierRatio", std::make_pair(true, Parameters::kIcpOutlierRatio())));
// 0.20. // 0.20.
removedParameters_.insert(std::make_pair("SuperGlue/Path", std::make_pair(true, Parameters::kPyMatcherPath()))); removedParameters_.insert(std::make_pair("SuperGlue/Path", std::make_pair(true, Parameters::kPyMatcherPath())));
removedParameters_.insert(std::make_pair("SuperGlue/Iterations", std::make_pair(true, Parameters::kPyMatcherIterations()))); removedParameters_.insert(std::make_pair("SuperGlue/Iterations", std::make_pair(true, Parameters::kPyMatcherIterations())));
@@ -624,13 +640,13 @@ ParametersMap Parameters::parseArguments(int argc, char * argv[], bool onlyParam
std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl; std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl;
#endif #endif
str = "With SuperPoint Torch:"; str = "With SuperPoint Torch:";
#ifdef RTABMAP_SUPERPOINT_TORCH #ifdef RTABMAP_TORCH
std::cout << str << std::setw(spacing - str.size()) << "true" << std::endl; std::cout << str << std::setw(spacing - str.size()) << "true" << std::endl;
#else #else
std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl; std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl;
#endif #endif
str = "With Python3:"; str = "With Python3:";
#ifdef RTABMAP_PYMATCHER #ifdef RTABMAP_PYTHON
std::cout << str << std::setw(spacing - str.size()) << "true" << std::endl; std::cout << str << std::setw(spacing - str.size()) << "true" << std::endl;
#else #else
std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl; std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl;
@@ -730,6 +746,12 @@ ParametersMap Parameters::parseArguments(int argc, char * argv[], bool onlyParam
std::cout << str << std::setw(spacing - str.size()) << "true" << std::endl; std::cout << str << std::setw(spacing - str.size()) << "true" << std::endl;
#else #else
std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl; std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl;
#endif
str = "With ZED Open Capture:";
#ifdef RTABMAP_ZEDOC
std::cout << str << std::setw(spacing - str.size()) << "true" << std::endl;
#else
std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl;
#endif #endif
str = "With RealSense:"; str = "With RealSense:";
#ifdef RTABMAP_REALSENSE #ifdef RTABMAP_REALSENSE
@@ -754,12 +776,24 @@ ParametersMap Parameters::parseArguments(int argc, char * argv[], bool onlyParam
std::cout << str << std::setw(spacing - str.size()) << "true" << std::endl; std::cout << str << std::setw(spacing - str.size()) << "true" << std::endl;
#else #else
std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl; std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl;
#endif
str = "With DepthAI:";
#ifdef RTABMAP_DEPTHAI
std::cout << str << std::setw(spacing - str.size()) << "true" << std::endl;
#else
std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl;
#endif #endif
str = "With libpointmatcher:"; str = "With libpointmatcher:";
#ifdef RTABMAP_POINTMATCHER #ifdef RTABMAP_POINTMATCHER
std::cout << str << std::setw(spacing - str.size()) << "true" << std::endl; std::cout << str << std::setw(spacing - str.size()) << "true" << std::endl;
#else #else
std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl; std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl;
#endif
str = "With CCCoreLib:";
#ifdef RTABMAP_CCCORELIB
std::cout << str << std::setw(spacing - str.size()) << "true" << std::endl;
#else
std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl;
#endif #endif
str = "With octomap:"; str = "With octomap:";
#ifdef RTABMAP_OCTOMAP #ifdef RTABMAP_OCTOMAP
@@ -809,8 +843,14 @@ ParametersMap Parameters::parseArguments(int argc, char * argv[], bool onlyParam
#else #else
std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl; std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl;
#endif #endif
#if RTABMAP_ORB_SLAM == 3
str = "With ORB_SLAM3:";
#elif RTABMAP_ORB_SLAM == 2
str = "With ORB_SLAM2:"; str = "With ORB_SLAM2:";
#ifdef RTABMAP_ORB_SLAM2 #else
str = "With ORB_SLAM:";
#endif
#ifdef RTABMAP_ORB_SLAM
std::cout << str << std::setw(spacing - str.size()) << "true" << std::endl; std::cout << str << std::setw(spacing - str.size()) << "true" << std::endl;
#else #else
std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl; std::cout << str << std::setw(spacing - str.size()) << "false" << std::endl;
File diff suppressed because it is too large Load Diff
+7 -7
View File
@@ -51,8 +51,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtflann/flann.hpp> #include <rtflann/flann.hpp>
#ifdef RTABMAP_PYMATCHER #ifdef RTABMAP_PYTHON
#include <pymatcher/PyMatcher.h> #include "python/PyMatcher.h"
#endif #endif
namespace rtabmap { namespace rtabmap {
@@ -87,7 +87,7 @@ RegistrationVis::RegistrationVis(const ParametersMap & parameters, Registration
_maxInliersMeanDistance(Parameters::defaultVisMeanInliersDistance()), _maxInliersMeanDistance(Parameters::defaultVisMeanInliersDistance()),
_detectorFrom(0), _detectorFrom(0),
_detectorTo(0) _detectorTo(0)
#ifdef RTABMAP_PYMATCHER #ifdef RTABMAP_PYTHON
, ,
_pyMatcher(0) _pyMatcher(0)
#endif #endif
@@ -153,7 +153,7 @@ void RegistrationVis::parseParameters(const ParametersMap & parameters)
if(_nnType == 6) if(_nnType == 6)
{ {
// verify that we have Python3 support // verify that we have Python3 support
#ifndef RTABMAP_PYMATCHER #ifndef RTABMAP_PYTHON
UWARN("%s is set to 6 but RTAB-Map is not built with Python3 support, using default %d.", UWARN("%s is set to 6 but RTAB-Map is not built with Python3 support, using default %d.",
Parameters::kVisCorNNType().c_str(), Parameters::defaultVisCorNNType()); Parameters::kVisCorNNType().c_str(), Parameters::defaultVisCorNNType());
_nnType = Parameters::defaultVisCorNNType(); _nnType = Parameters::defaultVisCorNNType();
@@ -268,7 +268,7 @@ RegistrationVis::~RegistrationVis()
{ {
delete _detectorFrom; delete _detectorFrom;
delete _detectorTo; delete _detectorTo;
#ifdef RTABMAP_PYMATCHER #ifdef RTABMAP_PYTHON
delete _pyMatcher; delete _pyMatcher;
#endif #endif
} }
@@ -1152,7 +1152,7 @@ Transform RegistrationVis::computeTransformationImpl(
// match between all descriptors // match between all descriptors
std::list<int> fromWordIds; std::list<int> fromWordIds;
std::list<int> toWordIds; std::list<int> toWordIds;
#ifdef RTABMAP_PYMATCHER #ifdef RTABMAP_PYTHON
if(_nnType == 5 || (_nnType == 6 && _pyMatcher) || _nnType==7) if(_nnType == 5 || (_nnType == 6 && _pyMatcher) || _nnType==7)
#else #else
if(_nnType == 5 || _nnType == 7) // bruteforce cross check or GMS if(_nnType == 5 || _nnType == 7) // bruteforce cross check or GMS
@@ -1173,7 +1173,7 @@ Transform RegistrationVis::computeTransformationImpl(
{ {
std::vector<int> toWordIdsV(descriptorsTo.rows, 0); std::vector<int> toWordIdsV(descriptorsTo.rows, 0);
std::vector<cv::DMatch> matches; std::vector<cv::DMatch> matches;
#ifdef RTABMAP_PYMATCHER #ifdef RTABMAP_PYTHON
if(_nnType == 6 && _pyMatcher && if(_nnType == 6 && _pyMatcher &&
descriptorsTo.cols == descriptorsFrom.cols && descriptorsTo.cols == descriptorsFrom.cols &&
descriptorsTo.rows == (int)kptsTo.size() && descriptorsTo.rows == (int)kptsTo.size() &&

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