Compare commits

..

236 Commits

Author SHA1 Message Date
matlabbe
8d23f19f6c bump ros package version 2022-10-01 18:30:51 -07:00
matlabbe
9afbcf2d06 detectMoreLoopClosures tool: regenerate global occupancy grid for convenience if there was one before 2022-09-30 15:48:09 -07:00
matlabbe
30bf5895ca Fixed #909 2022-09-30 14:17:23 -07:00
matlabbe
e0a2adcb45 Updated latest jfr2018 docker 2022-09-27 16:37:25 -07:00
matlabbe
87faea7a85 Fixed ceres linker issue with floam dependency (if WITH_CERES is OFF) 2022-09-27 23:35:13 +00:00
matlabbe
74c6e9cfec Fixed compilation error about stereoCameraModel() not found (#905) with OpenVINS odometry 2022-09-27 13:48:57 -07:00
matlabbe
675dad5f76 Fixed compilation error about stereoCameraModel() not found (#905) with odometry approaches: Fovis, MSCKF, Okvis, VINS, Viso2. 2022-09-27 18:56:05 +00:00
matlabbe
55546132a0 Fixed build on 16.04 2022-09-27 17:22:52 +00:00
matlabbe
fa31affea0 Pnp multicam refactoring (#902)
* gui: fixed wrongly showing landmark rejected when it was not (because a loop closure was rejected at the same time)

* Added Vis/PnPMaxVariance and RGBD/InvertedReg parameters. Implemented inlier distribution computation for multicam.

* On loc/small displacement: don't remove from odom cache if loop is rejected (maybe first loc)

* Loc: don't prune odom cache on small movement if delayed loc is enabled

* loc/small movement: cleanup bidirectional links

* Cov/PnP: fixed objPt transform to estimate depth

Co-authored-by: mathieu86 <mathieu@robust.ai>
2022-09-24 12:29:42 -07:00
matlabbe
95a76cb696 gui: fixed wrongly showing landmark rejected when it was not (because a loop closure was rejected at the same time) 2022-09-22 15:16:08 -07:00
matlabbe
737675c6f1 fixed dereference end iterator assert (#900) 2022-09-19 07:34:48 -07:00
matlabbe
4d6bc78e3d implement multi camera marker detection #898 (#899)
* Added multicamera marker detection support

* Fixed marker detection on camera index> 0

Co-authored-by: mathieu86 <mathieu@robust.ai>
2022-09-14 17:13:59 -07:00
matlabbe
adfb250d4e 2022-IlluminationInvariant: set RGBD/OptimizeMaxError to 0 to make it easier to reproduce results of the paper 2022-09-13 19:58:55 -07:00
matlabbe
a14b39b953 fixed android docker file not found on CI 2022-09-13 00:45:39 -07:00
matlabbe
3dd0965a15 Updated archive/2022-IlluminationInvariant/README.md 2022-09-13 00:29:44 -07:00
matlabbe
e059ead7f5 Merge branch 'master' of https://github.com/introlab/rtabmap 2022-09-12 23:22:59 -07:00
matlabbe
749cd096ff Fixed map::at() seg fault when localizing on a database with multiple disjoint sessions 2022-09-13 06:19:23 +00:00
matlabbe
37b920396c Added docker image for frontiers2022 (updated README in archive/2022-IlluminationInvariant) 2022-09-11 13:03:32 -07:00
matlabbe
0dc5fbdd70 fixed #873 2022-09-06 16:19:20 -07:00
matlabbe
f1c987a0ce Fixed android build (res tool not found) 2022-09-04 14:29:59 -04:00
matlabbe
69b0caed6f Update README.md 2022-09-04 13:39:40 -04:00
Windel Bouwman
8826f136a9 Use imported target for res_tool during cross compilation. (#865) 2022-09-04 13:18:14 -04:00
matlabbe
8cd4a6feff OdomF2M: fixed lidar-only broken from commit 9797918d52 2022-07-28 11:48:55 -04:00
matlabbe
33e54430a1 bump version 0.20.20 (api changes on CameraModel) 2022-07-28 10:51:13 -04:00
matlabbe
9797918d52 fixed https://github.com/introlab/rtabmap_ros/issues/790 2022-07-27 10:15:21 -04:00
matlabbe
aa3b71dbf6 docker: added missing wget dependency for arm64 (opengv dpendency) 2022-07-20 22:39:41 -04:00
matlabbe
34ed9d79c7 export: added --texture_blur filtering option 2022-07-20 22:08:45 -04:00
matlabbe
5943a8b065 Added stereo multi-camera support (#884)
* Integrated OpenGV

* Fixed build without opengv

* Cmake: moved OpenGV dependency status under solvers group

* Added multi-stereocamera models support

* Fixed OpenGV 0 sample error when one of the camera doesn't have features. Fixed g2o BA id offset with multi-camera.

* Fixed multicam 3d points generated from stereo correspondences

* db: Fixed multi stereo models not loaded correctly

* gui: fixed stereo rectification option, RegVis: fixed projection error with old databases (image size not set in calibration)

* OdomF2M: Fixed map.at error when bundle adjustment is not used

* depthai: added imu firmware update option for convenience

* Fixed various refactor errors

* Moved "large number stereo correspondences rejected" warning outside computeCorrespondences function for multicam

* Added error log if ba correspondences are computed with empty signatures

* fixed compilation errors with latest opencv

Co-authored-by: mathieu86 <mathieu@robust.ai>
2022-07-20 15:20:14 -04:00
matlabbe
71a28bb570 Update README.md 2022-06-29 22:23:56 -04:00
matlabbe
89f56642b7 Update README.md 2022-06-26 21:30:14 -07:00
matlabbe
fb6770d70f Update README.md 2022-06-26 20:59:20 -07:00
matlabbe
a10eb062e5 Update README.md 2022-06-26 20:58:15 -07:00
matlabbe
4d502c9e0d Create README.md 2022-06-26 20:54:34 -07:00
matlabbe
83c1adfd1e Updated illumination invariant paper documentation 2022-06-26 20:46:08 -07:00
mathieu86
bc42bc3520 Added Kp/ByteToFloat parameter to odom parameters 2022-06-09 10:51:08 -07:00
matlabbe
8f8256c1dd would fix: #618 #790 #795 (#871) 2022-05-30 07:24:04 -04:00
matlabbe
744c737da1 Update README.md 2022-05-28 17:22:50 -04:00
matlabbe
4cfd3ba496 Updated cmake workflow name 2022-05-28 17:20:49 -04:00
matlabbe
2da333895c workflow: added minimal build for Ubuntu 22.04 2022-05-28 17:14:55 -04:00
matlabbe
601e4015fb fixed android docker script path 2022-05-28 16:15:51 -04:00
matlabbe
47c94a4474 workflows docker: use current context instead of cloning the repo inside dockerfile 2022-05-28 16:11:52 -04:00
matlabbe
cf64b20e1f Fixed error: ‘drawAxis’ is not a member of ‘cv::aruco’ (opencv 4.5.5) 2022-05-10 22:47:15 -04:00
matlabbe
5d200a0799 Fixed _markerPriorsLinearVariance not intitialized 2022-05-05 11:08:44 -04:00
matlabbe
dab7aa6e58 export: added min_range option 2022-05-03 23:12:09 -04:00
matlabbe
b646c5e1db Marker priors (#859)
* Added MarkerPriors parameter

* Fixed Marker/Priors format to use '|' instead ';'. Fixed landmark priors not used.

* Marker: added priors variance parameters

* g2o: refactored backward compatibility includes

* fixed build with old g2o
2022-04-28 09:18:30 -04:00
matlabbe
190071678f Statistics: Added Memory/New_landmark. Rtabmap: don't remove node on small movements when a new landmark has been just detected. DbViewer: fixed missing statistics when ignored nodes are not saved in database. 2022-04-25 12:19:22 -04:00
matlabbe
dc58266eda ORBSLAM2: fixed build 2022-04-10 19:42:15 -04:00
matlabbe
e92dfd50e1 GUI: set default working dir if it is empty in the loaded config 2022-04-10 15:59:38 -04:00
matlabbe
1857111d7d Reprocess: added option to stream only one camera (in case of multi-camera database) 2022-04-06 14:07:23 -04:00
matlabbe
3e630e0250 UPlot: fixed number of digits after the decimal points to 6 when exporting data to text 2022-04-04 11:42:36 -04:00
matlabbe
d35193721b report tool: option --loc can be used without a number. 2022-04-01 13:53:32 -04:00
matlabbe
e46af2c3cd DbViewer: Added GroundTruth pose in node info labels 2022-03-31 12:00:52 -04:00
matlabbe
6cefc6d00a DBViewer: added camera frustums in Constraints View 2022-03-25 11:24:34 -04:00
matlabbe
ff739a98a5 Removed opencv's optflow module from required dependency (https://github.com/introlab/rtabmap/issues/427#issuecomment-1058767133) 2022-03-07 00:12:56 -05:00
matlabbe
4321c3040a CameraDepthAI: fixed imu transform and depth mode with latest depthai-core version 2022-03-06 22:25:01 -05:00
matlabbe
1e82fd3110 ImageView: added option to set maximum range for depth colormap 2022-03-03 18:01:04 -05:00
matlabbe
b9c7182a08 Update package.xml 2022-03-03 14:06:15 -05:00
matlabbe
656da152b3 multiband: fixed error when intermediate nodes without data are in memory 2022-03-01 18:42:43 -05:00
matlabbe
f140e99881 DBViewer: fixed kml export disabled for poses when there are gps values. Fixed commas used instead of dots for float in kml export on french machine. 2022-02-27 15:20:02 -05:00
matlabbe
53e0099dd8 ios: tmp database is now public, so it can be copied from file explorer / Finder in case recovery fails. 2022-02-27 14:32:19 -05:00
matlabbe
51f779628f Recovery: original database is erased/replaced only after successful recovery (in case there is an seg fault during recovery). 2022-02-27 13:50:40 -05:00
matlabbe
e7ee025127 Export: fixed texturing assert when there are intermediate nodes 2022-02-25 02:08:08 -05:00
matlabbe
e6a5fe9c26 Don't do neighbor refining if fast movement has been detected 2022-02-20 18:09:39 -05:00
matlabbe
e297320dd5 Removed backward compatibility with RGBD/OptimizeMaxError to be able to use ratio lower than 1. 2022-02-20 13:44:53 -05:00
matlabbe
4d895785a6 GraphViewer: added Ensure Frame Visible menu option. MainWindow: fixed loop signature failed to load image warning when camera is not used. 2022-02-19 16:16:29 -05:00
matlabbe
c2c68c0caf Updated exported poses in TUM format to avoid confusion with header when importing in CloudCompare 2022-02-18 12:17:47 -05:00
matlabbe
9bd758a62c SuperPoint: return at minimum 2 features or 0 (fixed crash when only one feature). Python: added main python instance from Rtabmap object (to get python instancied once for ROS). MultiSessionWidget: Fixed layout warning. Memory::computeTransform() avoid re-instanciating RegistrationVis when Reg/Strategy=1 for guess transform (to fix PyMatcher re-initialized every time). CMake: added video module to opencv required components. 2022-02-15 01:28:38 -05:00
matlabbe
578c19cc38 Export CLI: for --poses_camera option with intermediate nodes in db, re-use previous camera models of last valid node with data. 2022-02-13 14:45:08 -05:00
matlabbe
4776de7931 rtabmap: updated proximity paths check order when likehood is not available (use closest node). MainWindow: don't pause when error happens in monitoring mode / ROS. DbViewer: show local transform of scan. 2022-02-12 16:46:10 -05:00
matlabbe
191e165a28 GUI: Added Multi-Session Localization view. CameraModel: set localTransform to optical rotation in default constructor (fixed matrix invertion errors with code ignoring setting local transform), save/read local transform in/from camera calibration yaml file (so that local transform is also exported when extracting rgb/depth images). Rtabmap: in localization mode, ignore landmarks farther than RGBD/LocalRadius if no global loop closures are already in odometry cache. 2022-02-12 13:35:23 -05:00
matlabbe
f584f42ea4 rtabmap/dbreader: save odometry covariance in pose prior link when in localization mode and saving localization data. 2022-02-06 20:17:46 -05:00
matlabbe
b44b212218 Bump 0.20.19. OdomF2M: scale x0.1 covariance when local bundle adjustment is done. Rtabmap: fixed GT localization error when RGBD/MaxOdomCacheSize is used. 2022-02-06 17:41:53 -05:00
matlabbe
9ad6b626e4 Updated how covariance is computed for 2d-3d estimation without query's depth image available (instead of computed from reprojection error) 2022-02-05 16:41:43 -05:00
matlabbe
32ad92e2d2 GraphView: added optional overlay to better see odometry cache constraints. rtabmap: keep global loop closure id in statistics when proximity is detected on same node. 2022-02-03 21:58:36 -05:00
matlabbe
6f8f6d4d8e android: reverted export zip cleanup (keep zip files in export subdir for easy usb transfer) 2022-02-02 17:05:49 -05:00
matlabbe
c99203bbed CMake: added explicit opencv modules to avoid VTK6-VTK7 issues on Focal (vtk6 dependency coming with opencv_viz 4.2 module and vtk7 coming from PCL) 2022-02-01 13:40:02 -05:00
matlabbe
20d873c29e android: fixed backward compatibility target folder for android <30. Open: files are sorted by last modified date. 2022-01-30 15:47:08 -05:00
matlabbe
4d8c1d8b90 bump 0.20.18 2022-01-28 17:12:24 -05:00
matlabbe
315350dbfc CCCorelib: updated wrong output check. Updated RGBD/MaxOdomCacheSize approach to work properly with Rtabmap/CreateIntermediateNodes=true. 2022-01-28 14:48:32 -05:00
matlabbe
02140f92db fixed build 2022-01-27 22:55:59 -05:00
matlabbe
402afc07ed ExportDialog: added ground normals up option, added camera projection mask and decimation options. Export CLI: added --ground_normals_up and --cam_projection_mask options, changed --bin option by --ascii option (now binary by default). DBViewer: warn when scan from depth option is enabled but there is no depth. 2022-01-27 17:57:56 -05:00
matlabbe
a8e5bbf415 export: added --texture_roi_ratios option 2022-01-26 20:12:04 -05:00
matlabbe
5b3a7d5674 Localization: fixed always rejected localization when proximity and global loop closures are both detected at the same time at two different locations (clearing proximity detections from odometry cache if global loop closures are good). 2022-01-26 15:39:09 -05:00
matlabbe
d56692640e DBViewer: fixed grid cell size in 3D View. Memory/Grid, using Icp/PointToPlaneGroundNormalsUp parameter when normals are computed. Grid: fixed 2D noHit ray tracing. 2022-01-25 18:10:43 -05:00
Ben
2dc7b59b05 allow negative min disparity in StereoBM dialog (#817) 2022-01-24 17:02:47 -05:00
Ben
bbe10bca39 fix missing curl install in focal dockerfile (#816)
* add missing curl install to focal dockerfile

* add missing apt-get update
2022-01-24 16:44:39 -05:00
matlabbe
e2dc3ac67e OctoMap: fixed empty occupancy not correctly updated when ray tracing is done on more than one local map 2022-01-23 16:29:11 -05:00
matlabbe
83d1e27b81 Refactored graph::getPosesInRadius -> graph::findNearestPoses. Labels can be removed: added Remove label option in MainWindow. In localization mode, label set with id=0 is set to nearest node of current pose. 2022-01-20 18:56:38 -05:00
matlabbe
3c215b9b4d android: fixed driver preference for arcore 2022-01-20 10:57:39 -05:00
matlabbe
bdaed2f362 Tango: fixed google tango driver not selected automatically on first use 2022-01-19 20:24:23 -05:00
matlabbe
e048d8ae72 Fixed compilation error without octomap 2022-01-19 19:53:49 -05:00
matlabbe
5b868d665f Grid/Sensor=2: fixed viewpoint offset bug of the camera. 2022-01-19 19:27:32 -05:00
matlabbe
a56373f66d GUI/ExportClouds: fixed color of scans having RGB instead of intensity. 2022-01-19 16:59:43 -05:00
matlabbe
5ec73bee8d ios: improved significantly rendering performance 2022-01-19 02:11:38 -05:00
matlabbe
b1dd44526d ios: fixed background camera not shown in landscape mode (iPhone) 2022-01-17 22:06:35 -05:00
matlabbe
de62bbb9b7 Grid: don't filter max range before doing ray tracing (to ray trace empty space). 2022-01-17 14:22:11 -05:00
matlabbe
7a5c50cb0e Fixed compilation warnings 2022-01-16 15:27:52 -05:00
matlabbe
9622fe8393 Parameters: set default Icp/PointToPlaneRadius to 0 to avoid 'Both radius and K defined' error when using 3d lidar. 2022-01-16 12:56:18 -05:00
matlabbe
5f55f63443 report: ignoring landmarks after optimization to avoid errors when exporting poses 2022-01-15 22:02:45 -05:00
matlabbe
aa0e6ef692 GUI:Export Poses: fixed poses!=stamps issue when there are landmarks (landmarks now only exported with g2o format) 2022-01-15 21:49:40 -05:00
matlabbe
03a106ea36 Fixed build without g2o 2022-01-15 13:00:12 -05:00
matlabbe
29a2b64a0c RGBD/NeighborLinkRefining: do one proximity detection by time if intermediate nodes are added. Optimized radiusFiltering(). Updated default parameters of proportionalRadiusFiltering(). 2022-01-14 18:47:57 -05:00
matlabbe
51f6b32f47 Fixed windows build (https://ci.appveyor.com/project/matlabbe/rtabmap/builds/42207812) 2022-01-14 14:33:32 -05:00
matlabbe
9e0173f4cb Export: added random sample filter, added proportional radius filter, refactored when normals are computed (now after the clouds are assembled and voxelized), moved ceiling and floor filtering inside assembling loop. 2022-01-14 13:36:01 -05:00
matlabbe
12c2dd707c Localization with Reg/Force3DoF=true, fixed how graph optimization errors are computed (use only x,y,yaw). 2022-01-12 16:59:03 -05:00
matlabbe
fcec98105d Added RGBD/ProximityMergedScanCovFactor parameter. Localization: fixed output height when Reg/Force3DoF=true but input poses are 6DoF. Transform: added is3DoF() and is4DoF() functions. GTSAM: when Reg/Force3DoF=true, copy input roll,pitch,z values for output poses. RegIcp: fixed working memory dir '~' conversion. RGBD/ProximityGlobalScanMap: fixed map::at error when some nodes don't have scans. 2022-01-12 16:14:42 -05:00
matlabbe
a4ec95963e Fixed a debug information 2022-01-11 15:59:53 -05:00
matlabbe
49353b134c LaserScan: fixed destination format when source is empty with operator+ 2022-01-11 15:32:30 -05:00
Tim Clephas
f69085304e List dependencies only once (#812) 2022-01-11 10:40:48 -05:00
Marvin Stüde
3f797e02e3 Adds Boost serialization package for libpointmatcher case (#810) 2022-01-07 13:11:12 -05:00
matlabbe
ab50ba0b6c Fixed android30 2022-01-05 21:39:27 -05:00
matlabbe
528b640a18 workflows: added android30 docker image 2022-01-04 20:54:53 -05:00
matlabbe
4d8a7b4659 CameraTango: fixed opencv4 errors 2022-01-04 20:49:03 +00:00
matlabbe
ba6575fcb9 Added android30 build 2022-01-04 14:55:32 -05:00
matlabbe
1173f06bc8 android: fixed opencv4 deprecated errors 2022-01-04 19:46:20 +00:00
matlabbe
a08fce2068 ios: added requestReview() 2022-01-03 20:57:41 -05:00
matlabbe
d8324a11d5 android: fixed sharing file exiting bug, fixed camera not correctly set back to device default on reset settings. 2022-01-03 17:51:23 -05:00
matlabbe
a6c9b3babe 💄 changed some cmake warnings in info 2022-01-03 16:33:21 -05:00
matlabbe
145430cafd Fixed noetic build (g2o error) 2022-01-03 16:05:11 -05:00
matlabbe
5194f40794 Fixed g2o build error with melodic/noetic versions 2022-01-03 15:37:06 -05:00
matlabbe
129bbf8f98 ios: added placeholder R in Library view for db not having preview (like recovered database) 2022-01-03 13:44:29 -05:00
matlabbe
a9d4a16ba4 bump ios version 0.20.17 2022-01-02 23:40:46 -05:00
matlabbe
b2f13c2772 android: fixed g2o seg fault (CACHE_SE3_OFFSET not registered) 2022-01-02 23:30:55 -05:00
matlabbe
f3ace6c86a Added recovery feature to android 2022-01-02 18:09:57 -05:00
matlabbe
3147b4ab56 ios: added recovery feature 2022-01-02 17:08:44 -05:00
matlabbe
fcde52c6bf ios: set First-P. View by default 2021-12-30 15:37:46 -05:00
matlabbe
5b31a4725d Update README.md 2021-12-29 19:05:35 -05:00
matlabbe
e4955ee386 GUI: fixed mynteye raw images support error 2021-12-29 16:12:02 -05:00
matlabbe
e5b4973ddc GUI: Added Orbbec Astra icon 2021-12-29 15:53:40 -05:00
matlabbe
f3095a2e0a Calibration dialog: fixed right panel width size. Win32: packaging missing cudnn dlls (when torch is used) 2021-12-29 15:13:13 -05:00
matlabbe
044145926f ios: incremented build number 2021-12-28 18:35:55 -05:00
matlabbe
a3823594a4 Converted an assert to an error. 2021-12-26 14:53:22 -05:00
matlabbe
3071da42f3 Optimizer: don't fix roll/pitch on root node if gravity constraints are fed 2021-12-25 16:57:03 -05:00
matlabbe
93ee8f9b30 Working dir path: convert ~ to Home for convenience. Localization: don't show "cannot optimize" warning when RGBD/MaxOdomCacheSize=0 2021-12-24 18:24:44 -05:00
matlabbe
7ca881453e RGBD/StartAtOrigin: set first node of the graph, not Identity 2021-12-20 17:01:08 -05:00
matlabbe
8662eb0dd7 Statistics: added OdomCache data for debugging 2021-12-18 18:53:59 -05:00
matlabbe
33130890fd Localization: Improved resulting pose in case there are gravity constraints. iOS: clear odom trace when not visible, fixed opt mesh not correctly aligned with graph on loading when switching RGBD/OptimizeFromGraphEnd. 2021-12-18 15:37:49 -05:00
matlabbe
bca8b30832 Localization 2d Slam: automatically rotate landmark links to have z-axis up for correct 3DoF optimization. When RGBD/MaxOdomCacheSize is used, wait for at least 2 temporal localizations before adjusting the pose (to avoid big jumps when only one constraint is used). 2021-12-17 11:00:37 -05:00
matlabbe
6eb81cbb72 Added RGBD/MaxOdomCacheSize option to iOS App. 2021-12-12 20:40:28 -05:00
matlabbe
0e62050824 rtabmap: fixed graph re-optimized with only virtual links in localization mode (which can make gtsam crash because of under constrained covariance) 2021-12-12 13:07:02 -05:00
matlabbe
cf5e90238b Statistics: added LoopOdom_correction stats for landmark detections. 2021-12-10 21:58:11 -05:00
matlabbe
8cf12c6135 Improved localization mode accuracy (decreasing jumps on consecutive loop closures or landmark detections). Updated usage of parameter RGBD/MaxOdomCacheSize (default 0->10) 2021-12-10 17:48:36 -05:00
matlabbe
4ab0090ecd Support feature-only rectification when using external extracted features. 2021-12-06 09:26:10 -05:00
matlabbe
580e35afb1 Fixed missing 3D keypoints when RGBD/LoopClosureReextractFeatures=true and Reg/Strategy=1 (https://github.com/introlab/rtabmap_ros/issues/668). DBViewer: fixed wrong poses optimization with GTSAM when showing scans of loop closures by proximity by space (multiscan) while there are GPS priors. 2021-12-05 17:38:53 -05:00
matlabbe
12906f4490 DBViewer: export poses: added explicit otion for ground truth if available 2021-12-03 13:43:53 -05:00
matlabbe
baae713471 Fixed unknown lines for octomap 2D grid projection. (https://github.com/introlab/rtabmap_ros/issues/684) 2021-11-30 20:34:51 -05:00
matlabbe
67710ef94c Export: optimized camera projection RAM usage. Added --texture_angle and --cam_projection_decimation options. 2021-11-21 17:10:57 -05:00
matlabbe
090ae0c444 DbViewer: added option to show disparity instead of right image in main views for stereo data 2021-11-20 16:36:54 -05:00
matlabbe
6684bafe34 fixed typo 2021-11-16 18:22:45 -05:00
matlabbe
5fcbe2ed70 iOS: fixed install script (#785 #741) 2021-11-16 18:11:40 -05:00
matlabbe
459c7b2bd7 Export: added --min_cluster option. 2021-11-16 11:58:55 -05:00
matlabbe
9ae2c46546 CMake: fixed build without Python and Ceres if WITH_PYTHON and WITH_CERES are OFF (even if found by third party libraries, related to #783). 2021-11-15 18:00:17 -05:00
matlabbe
7af2a27e89 Improved log error when ROI is set with SuperPoint (https://github.com/introlab/rtabmap_ros/issues/676) 2021-11-14 20:26:42 -05:00
matlabbe
dbecaac809 Moved bin dir inside build directory (#784)
* Moved bin directory inside build directory (to make easier different builds with same source directory)

* Switched include order to avoid problems with remaining Version.h still in source directory taen before the one in binary dir. Fixed android build (updated res tool search path).

* workflow-cmake: fixed path to bin directory
2021-11-14 19:29:37 -05:00
matlabbe
6c07a670ee Added OdometryOpen3D 2021-11-13 19:45:57 -05:00
matlabbe
4ba805b5b3 Report: fixed landmarks not used during optimization. Reprocess: added --nolandmark option to ignore landmarks in input database. 2021-11-12 12:47:54 -05:00
matlabbe
b002e85e0f Update ProgressDialog.h
Typo param name should be in seconds, not milliseconds.
2021-11-09 17:36:34 -05:00
matlabbe
ec2aa5c952 OpenNI2: depth shift can be negative. MainWindow: postProcessing() refactoring (split with and without dialog). 2021-11-09 10:16:12 -05:00
matlabbe
06150c697f Fixed #750 2021-11-08 14:20:21 -05:00
matlabbe
38bcb0060c CMake: set default to OFF for some optional dependencies that require specific versions or patches before integrating with rtabmap, otherwise there could be seg faults on runtime even if compilation worked. 2021-11-08 13:47:27 -05:00
matlabbe
ddd5eb5a41 CameraRealSense2: Odom extrinsics against another sensor can be calibrated with having to calibrate stereo first. DBViewer: fixed local grid wrongly using global grid parameters. 2021-11-05 18:05:50 -04:00
matlabbe
20bc281db7 DbViewer: don't show landmark links for ignored ndoes (w=-9), auto-zoom grid map if there are a lot of unknowns. Updated Docker nvidia files to include default Documents/RTAB-Map directory. 2021-11-04 13:00:08 -04:00
matlabbe
7c5acd8970 Parameters: Changed Grid/FromDepth to Grid/Sensor to add a new choice to use both scan and depth for local grids. Increased version to 0.20.15. 2021-10-29 20:05:12 -04:00
matlabbe
1886f99cbf Merge branch 'RobotnikAutomation-master' 2021-10-29 13:58:14 -04:00
matlabbe
2ad334df90 Added filter_floor and adjusted default values. 2021-10-29 13:58:00 -04:00
matlabbe
0ab5a8f43e Merge branch 'master' of https://github.com/RobotnikAutomation/rtabmap into RobotnikAutomation-master 2021-10-29 13:57:16 -04:00
matlabbe
8682026396 Rtabmap: when optimizing graph, removed guess for rootid to avoid global rotation drift over time. CameraStereoImages: set BayerMode also to right image. GraphView: fixed 0 width for line inside NodeItem. Reprocess: added -loc_null and -gt options. 2021-10-23 11:17:42 -04:00
Ines
6cb741667d Add ceiling filter to rtabmap-export 2021-10-22 12:36:53 +02:00
matlabbe
56c5622d20 docker: added "make -j12" for rtabmap build 2021-10-16 18:14:24 -04:00
matlabbe
e245782c6c worflows: added back arm64 2021-10-15 14:58:56 -04:00
matlabbe
9895e4c162 workflow: test images without arm64 2021-10-15 09:29:34 -04:00
matlabbe
f67087075a Updated docker images (removed amd64 script) 2021-10-14 21:49:50 -04:00
matlabbe
d0242b14cf DetectMoreLoopClosures CLI: show overridden parameters 2021-10-11 13:52:55 -04:00
matlabbe
d16e24a1a3 Fixed compiler warning 2021-10-07 10:19:32 -04:00
matlabbe
ab5fd5018b DbViewer: added update all landmark covariances menu action, also enabled edit constraint on landmark links. Covariance can be set to 9999. 2021-10-06 11:34:40 -04:00
matlabbe
44810a14e0 Show if built with PDAL on --version option 2021-10-01 11:49:45 -04:00
matlabbe
697fe5ebb3 Workflows: updated docker multi-arch (removed armv7) 2021-09-30 18:00:17 -04:00
matlabbe
54c0ee4244 Workflows: added multi-arch docker images 2021-09-30 15:37:05 -04:00
matlabbe
d284cd11cf Updated package.xml version to 0.20.14 2021-09-30 10:14:24 -04:00
matlabbe
467ea42981 OdometryFLOAM: fixed published local scan map local transform 2021-09-30 10:05:56 -04:00
matlabbe
77d947d4fb Fixed FLOAM not working when local transform is not Identity. DBViewer: warn user when scan from dpeth is checked and there are no depth images in db. 2021-09-30 09:53:50 -04:00
matlabbe
533d78d570 Fixed OdometryOpenVINS build errors with latest OpenVINS code. 2021-09-28 17:12:08 -04:00
matlabbe
aee034c5ed Update CMakeLists.txt
Setting WITH_FLOAM to OFF by default because floam binaries (this [version](https://github.com/flynneva/floam)) in ros is not compatible.
2021-09-27 20:20:11 -04:00
matlabbe
0092e15cd7 Update docker.yml 2021-09-27 20:04:12 -04:00
matlabbe
23d9e0e4bb Docker: updated bionic/focal's geogram patch 2021-09-27 19:48:18 -04:00
matlabbe
8c56b5b1ce CMake: added WITH_OPENMP option (to be able to disable it). CameraOpenNI2: Added depth decimation parameter. CLAMS: can apply distortion model to smaller images. 2021-09-24 17:31:16 -04:00
matlabbe
bccc5b13af FLOAM: added some debug logs 2021-09-24 11:32:25 -04:00
matlabbe
5f65618d40 Added OdomLOAM/Resolution parameter 2021-09-22 10:48:59 -04:00
matlabbe
cff0d15460 Fixed "wrong scan number" error when OdomLOAM/Sensor is 0 (VLP16) 2021-09-22 10:06:34 -04:00
matlabbe
b6671f4d8c workflow/docker: added CACHE_DATE to android builds to avoid caching rtabmap build 2021-09-20 16:02:37 -04:00
matlabbe
9db66600b3 workflow: added android23 docker image 2021-09-20 15:46:14 -04:00
matlabbe
67cd4b69c1 workflow: updated docker tags / cache var 2021-09-20 13:34:30 -04:00
matlabbe
cffb7981b6 docker: fixed bionic build with latest alicevision (cmake>=3.11 required) 2021-09-20 12:32:51 -04:00
matlabbe
71ffd922ed workflow: fixed typo 2021-09-20 11:37:58 -04:00
matlabbe
870467393b workflow: add docker buildcache 2021-09-20 11:33:19 -04:00
matlabbe
79f203a2c4 docker workflow: fixed build matrix 2021-09-20 11:16:12 -04:00
matlabbe
baa5b638ae Added "docker" workflow 2021-09-20 11:11:21 -04:00
matlabbe
8f12463f71 Docker: upgraded alicevision version 2.4.0 in bionic/focal images 2021-09-19 20:42:56 -04:00
matlabbe
14b56813d3 Updated for AliceVision >=2.4.0 compatibility. Export: added --multiband_contrib option. 2021-09-19 20:20:45 -04:00
matlabbe
44b057b0d7 DbViewer: fixed icp from depth option not used when refining or adding loop closures automaticaly 2021-09-13 15:59:19 -04:00
matlabbe
a901f20d06 0.20.14: added globalBundleAdjustment CLI, added Rtabmap/Memory::cleanupLocalGrids function, init with optimizedPoses from db even in mapping mode, reprocess: added -db option to save optimized 2d grid in database. 2021-09-11 11:35:43 -04:00
matlabbe
3ba02d2ef6 Added OdometryFLOAM (Odom/Strategy=11) 2021-09-09 17:38:54 -04:00
matlabbe
263e0170f1 export: refactored ba (to support stereo data) 2021-09-09 14:22:02 -04:00
matlabbe
e017a0fcf4 DbViewer: fixed initial rootid with older databases, fixed RGBD/OptimizeFromGraphEnd not correctly used. 2021-09-08 18:13:20 -04:00
matlabbe
103db3181b Update README.md 2021-09-08 17:13:13 -04:00
matlabbe
bc253df24a Update README.md 2021-09-08 17:11:34 -04:00
matlabbe
544ea9dff2 Update cmake.yml 2021-09-08 13:31:00 -04:00
matlabbe
09c2c4bbcb Removed travis config, now use Github actions (see .github/workflows/cmake.yml) fixed #768 2021-09-08 12:09:59 -04:00
matlabbe
c209cf1c9b Update cmake.yml
Added info after build
2021-09-08 12:06:14 -04:00
matlabbe
202d59b408 Update cmake.yml
Added ros setup.bash before cmake
2021-09-08 11:59:04 -04:00
matlabbe
9671daf9c3 Update cmake.yml 2021-09-08 11:53:13 -04:00
matlabbe
b5518ff618 Update cmake.yml 2021-09-08 11:46:29 -04:00
matlabbe
2111b6497b Update cmake.yml
use setup-ros action
2021-09-08 11:37:03 -04:00
matlabbe
b51b2525a5 Added Github actions for melodic/focal 2021-09-08 11:24:11 -04:00
matlabbe
45d51808e3 💄 2021-09-08 09:38:16 -04:00
matlabbe
bc39b19517 projectCloudToCamerasImpl: fixed bug using wrong camera models 2021-09-08 09:34:21 -04:00
matlabbe
7baedf4c72 texturing: remove assert when poses and models are not the same size (just ignore poses without models, intermediate nodes issue) 2021-09-07 16:26:56 -04:00
matlabbe
20361400e1 export: output intensity channel with RGB when --cam_projection and --scan options are set (PDAL required) 2021-09-07 15:57:23 -04:00
matlabbe
c43118cde8 Fixed F2F-Optical flow not creating keyframes bug 2021-09-03 15:33:22 -04:00
matlabbe
371a3ef851 fixed CleanupLocalGrids install target 2021-09-01 10:23:45 -04:00
matlabbe
daefc5ff54 Added rtabmap-cleanupLocalGrids CLI 2021-08-28 22:19:59 -04:00
matlabbe
b932da6dcf DbViewer: Adjusted GraphView's root id based on latest valid node on initialization 2021-08-28 20:23:44 -04:00
matlabbe
f88ce1618b OdometryORBSLAM3: fixed re-initilisation of camera parameters when restarting camera with different config. 2021-08-26 15:34:48 -04:00
matlabbe
c5e4d67f80 export: don't assert if gain is zero (means disabled) 2021-08-16 20:27:31 -04:00
matlabbe
ed68fe777b Added more options for multiband texturing 2021-08-16 13:14:02 -04:00
matlabbe
6fb553a5e7 Update README.md 2021-08-13 14:46:56 -04:00
matlabbe
db00e04cc1 rtabmap-info: updated to show parameters not in the database. 2021-08-12 10:55:08 -04:00
matlabbe
eeecb21793 export tool: added --camera_projection_keep_all option 2021-08-03 13:46:39 -04:00
matlabbe
a5685c3e31 Fixed build without DepthAI dep 2021-07-28 17:05:16 -04:00
matlabbe
138d4aa1be If RGBD/LoopClosureReextractFeatures=true, don't save raw features (3d point, descriptor) to Feature table. 2021-07-28 14:32:32 -04:00
matlabbe
79d2b3fade Merge branch 'master' of https://github.com/introlab/rtabmap 2021-07-28 14:19:49 -04:00
matlabbe
32bf0f9d61 Fixed CameraDepthAI with latest depthai version (using now camera eeprom calibration and added imu support) 2021-07-28 14:19:30 -04:00
matlabbe
22a771e29c trigger travis.com 2021-07-20 14:09:40 -04:00
matlabbe
17d8a92614 Update README.md 2021-07-20 12:58:42 -04:00
matlabbe
a91cd0c659 Update README.md 2021-07-20 12:58:16 -04:00
matlabbe
ae92ec40d7 Fixed build with LOAM dependency 2021-07-14 13:22:47 -04:00
373 changed files with 15865 additions and 6496 deletions

1
.dockerignore Normal file
View File

@@ -0,0 +1 @@
build/*

67
.github/workflows/cmake-ros.yml vendored Normal file
View File

@@ -0,0 +1,67 @@
name: CMake-ROS
on:
push:
branches:
- '**'
pull_request:
branches:
- '**'
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
jobs:
build:
# The CMake configure and build commands are platform agnostic and should work equally
# well on Windows or Mac. You can convert this to a matrix build if you need
# cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
name: Build on ros ${{ matrix.ros_distro }} and ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-20.04, ubuntu-18.04]
include:
- os: ubuntu-20.04
ros_distro: 'noetic'
- os: ubuntu-18.04
ros_distro: 'melodic'
steps:
- uses: ros-tooling/setup-ros@v0.2
with:
required-ros-distributions: ${{ matrix.ros_distro }}
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get -y install ros-${{ matrix.ros_distro }}-rtabmap-ros
sudo apt-get -y remove ros-${{ matrix.ros_distro }}-rtabmap
- uses: actions/checkout@v2
- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: |
source /opt/ros/${{ matrix.ros_distro }}/setup.bash
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build
# Build your program with the given configuration
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Info
working-directory: ${{github.workspace}}/build/bin
run: |
source /opt/ros/${{ matrix.ros_distro }}/setup.bash
./rtabmap-console --version
# - name: Test
# working-directory: ${{github.workspace}}/build
# # Execute tests defined by the CMake configuration.
# # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
# run: ctest -C ${{env.BUILD_TYPE}}

48
.github/workflows/cmake.yml vendored Normal file
View File

@@ -0,0 +1,48 @@
name: CMake
on:
push:
branches:
- '**'
pull_request:
branches:
- '**'
env:
BUILD_TYPE: Release
jobs:
build:
name: ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-22.04, ubuntu-20.04, ubuntu-18.04]
steps:
- name: Install dependencies
run: |
DEBIAN_FRONTEND=noninteractive
sudo apt-get update
sudo apt-get -y install libopencv-dev libpcl-dev git cmake software-properties-common
- uses: actions/checkout@v2
- name: Configure CMake
run: |
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
- name: Info
working-directory: ${{github.workspace}}/build/bin
run: |
./rtabmap-console --version
# - name: Test
# working-directory: ${{github.workspace}}/build
# # Execute tests defined by the CMake configuration.
# # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
# run: ctest -C ${{env.BUILD_TYPE}}

105
.github/workflows/docker.yml vendored Normal file
View File

@@ -0,0 +1,105 @@
name: docker
on:
push:
branches:
- 'master'
jobs:
docker:
runs-on: ubuntu-latest
strategy:
matrix:
docker_tag: [xenial, bionic, focal, android23, android24, android26, android30]
include:
- docker_tag: xenial
docker_tags: |
introlab3it/rtabmap:xenial
introlab3it/rtabmap:16.04
docker_platforms: |
linux/amd64
docker_path: 'xenial'
- docker_tag: bionic
docker_tags: |
introlab3it/rtabmap:bionic
introlab3it/rtabmap:18.04
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'bionic'
- docker_tag: focal
docker_tags: |
introlab3it/rtabmap:focal
introlab3it/rtabmap:20.04
introlab3it/rtabmap:latest
docker_platforms: |
linux/amd64
linux/arm64
docker_path: 'focal'
- docker_tag: android23
docker_tags: |
introlab3it/rtabmap:android23
introlab3it/rtabmap:tango
docker_args: |
API_VERSION=23
docker_platforms: |
linux/amd64
docker_path: 'bionic/android/rtabmap_apiXX'
- docker_tag: android24
docker_tags: |
introlab3it/rtabmap:android24
docker_args: |
API_VERSION=24
docker_platforms: |
linux/amd64
docker_path: 'bionic/android/rtabmap_apiXX'
- docker_tag: android26
docker_tags: |
introlab3it/rtabmap:android26
docker_args: |
API_VERSION=26
docker_platforms: |
linux/amd64
docker_path: 'bionic/android/rtabmap_apiXX'
- docker_tag: android30
docker_tags: |
introlab3it/rtabmap:android30
docker_args: |
API_VERSION=30
docker_platforms: |
linux/amd64
docker_path: 'bionic/android/rtabmap_apiXX'
steps:
-
name: Checkout
uses: actions/checkout@v2
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
with:
platforms: all
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
-
name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v2
with:
context: .
push: true
platforms: ${{ matrix.docker_platforms }}
file: ./docker/${{ matrix.docker_path }}/Dockerfile
build-args: |
${{ matrix.docker_args }}
tags: ${{ matrix.docker_tags }}
cache-from: type=registry,ref=introlab3it/rtabmap:${{ matrix.docker_tag }}
cache-to: type=inline

View File

@@ -1,80 +0,0 @@
language: cpp
jobs:
include:
# - name: osx
# compiler: clang
# os: osx
# install:
# - brew install sqlite
# - brew install pcl
# - brew install opencv@3
# - name: linux-trusty
# compiler: gcc
# os: linux
# dist: trusty
# install:
# - 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 -
# - sudo apt-get update
# - sudo apt-get update && sudo apt-get install dpkg
# - sudo apt-get -y install ros-indigo-rtabmap-ros
# - sudo apt-get -y remove ros-indigo-rtabmap
#
# before_script:
# - source /opt/ros/indigo/setup.bash
- name: linux-xenial
compiler: gcc
os: linux
dist: xenial
install:
- 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 -
- sudo apt-get update
- sudo apt-get update && sudo apt-get install dpkg
- sudo apt-get -y install ros-kinetic-rtabmap-ros
- sudo apt-get -y remove ros-kinetic-rtabmap
before_script:
- source /opt/ros/kinetic/setup.bash
- name: linux-bionic
compiler: gcc
os: linux
dist: bionic
install:
- 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 -
- sudo apt-get update
- sudo apt-get update && sudo apt-get install dpkg
- sudo apt-get -y install ros-melodic-rtabmap-ros
- sudo apt-get -y remove ros-melodic-rtabmap
before_script:
- source /opt/ros/melodic/setup.bash
- name: linux-focal
compiler: gcc
os: linux
dist: focal
install:
- 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 -
- sudo apt-get update
- sudo apt-get update && sudo apt-get install dpkg
- sudo apt-get -y install ros-noetic-rtabmap-ros
- sudo apt-get -y remove ros-noetic-rtabmap
before_script:
- source /opt/ros/noetic/setup.bash
script:
- mkdir -p build && cd build
- cmake ..
- make
notifications:
email:
- matlabbe@gmail.com

View File

@@ -20,7 +20,7 @@ SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
#######################
SET(RTABMAP_MAJOR_VERSION 0)
SET(RTABMAP_MINOR_VERSION 20)
SET(RTABMAP_PATCH_VERSION 13)
SET(RTABMAP_PATCH_VERSION 21)
SET(RTABMAP_VERSION
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})
@@ -123,9 +123,9 @@ OPTION( BUILD_SHARED_LIBS "Set to OFF to build static libraries" ON )
####### OUTPUT DIR #######
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
# Avoid Visual Studio bin/Release and bin/Debug sub directories
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
@@ -181,12 +181,14 @@ option(WITH_DC1394 "Include dc1394 support" ON)
option(WITH_G2O "Include g2o support" ON)
option(WITH_GTSAM "Include GTSAM support" ON)
option(WITH_TORO "Include TORO support" ON)
option(WITH_CERES "Include Ceres support" ON)
option(WITH_CERES "Include Ceres support" OFF)
option(WITH_VERTIGO "Include Vertigo support" ON)
option(WITH_CVSBA "Include cvsba support" ON)
option(WITH_CVSBA "Include cvsba support" OFF)
option(WITH_POINTMATCHER "Include libpointmatcher support" ON)
option(WITH_CCCORELIB "Include CCCoreLib support" ON)
option(WITH_LOAM "Include LOAM support" ON)
option(WITH_CCCORELIB "Include CCCoreLib support" OFF)
option(WITH_OPEN3D "Include Open3D support" OFF)
option(WITH_LOAM "Include LOAM support" OFF)
option(WITH_FLOAM "Include FLOAM support" OFF)
option(WITH_FLYCAPTURE2 "Include FlyCapture2/Triclops support" ON)
option(WITH_ZED "Include ZED sdk support" ON)
option(WITH_ZEDOC "Include ZED Open Capture support" ON)
@@ -194,21 +196,23 @@ option(WITH_REALSENSE "Include RealSense support" ON)
option(WITH_REALSENSE_SLAM "Include RealSenseSlam support" ON)
option(WITH_REALSENSE2 "Include RealSense support" ON)
option(WITH_MYNTEYE "Include mynteye-s support" ON)
option(WITH_DEPTHAI "Include depthai-core support" ON)
option(WITH_DEPTHAI "Include depthai-core support" OFF)
option(WITH_OCTOMAP "Include Octomap support" ON)
option(WITH_CPUTSDF "Include CPUTSDF support" ON)
option(WITH_OPENCHISEL "Include open_chisel support" ON)
option(WITH_CPUTSDF "Include CPUTSDF support" OFF)
option(WITH_OPENCHISEL "Include open_chisel support" OFF)
option(WITH_ALICE_VISION "Include AliceVision support" OFF)
option(WITH_FOVIS "Include FOVIS support" ON)
option(WITH_VISO2 "Include VISO2 support" ON)
option(WITH_DVO "Include DVO support" ON)
option(WITH_ORB_SLAM "Include ORB_SLAM2 or ORB_SLAM3 support" ON)
option(WITH_OKVIS "Include OKVIS support" ON)
option(WITH_FOVIS "Include FOVIS support" OFF)
option(WITH_VISO2 "Include VISO2 support" OFF)
option(WITH_DVO "Include DVO support" OFF)
option(WITH_ORB_SLAM "Include ORB_SLAM2 or ORB_SLAM3 support" OFF)
option(WITH_OKVIS "Include OKVIS support" OFF)
option(WITH_MSCKF_VIO "Include MSCKF_VIO support" OFF)
option(WITH_VINS "Include VINS-Fusion support" ON)
option(WITH_OPENVINS "Include OpenVINS support" ON)
option(WITH_VINS "Include VINS-Fusion support" OFF)
option(WITH_OPENVINS "Include OpenVINS support" OFF)
option(WITH_MADGWICK "Include Madgwick IMU filtering support" ON)
option(WITH_FASTCV "Include FastCV support" ON)
option(WITH_OPENMP "Include OpenMP support" ON)
option(WITH_OPENGV "Include OpenGV support" OFF)
IF(MOBILE_BUILD)
option(PCL_OMP "With PCL OMP implementations" OFF)
ELSE()
@@ -218,7 +222,7 @@ ENDIF()
set(RTABMAP_QT_VERSION AUTO CACHE STRING "Force a specific Qt version.")
set_property(CACHE RTABMAP_QT_VERSION PROPERTY STRINGS AUTO 4 5)
FIND_PACKAGE(OpenCV REQUIRED QUIET)
FIND_PACKAGE(OpenCV REQUIRED QUIET COMPONENTS core calib3d imgproc highgui stitching photo video OPTIONAL_COMPONENTS aruco xfeatures2d nonfree gpu cudafeatures2d)
IF(WITH_QT)
FIND_PACKAGE(PCL 1.7 REQUIRED QUIET COMPONENTS common io kdtree search surface filters registration sample_consensus segmentation visualization)
@@ -253,7 +257,7 @@ endif()
# OpenMP ("-fopenmp" should be added for flann included in PCL)
# the gcc-4.2.1 coming with MacOS X is not compatible with the OpenMP pragmas we use, so disabling OpenMP for it
if((NOT APPLE) OR (NOT CMAKE_COMPILER_IS_GNUCXX) OR (GCC_VERSION VERSION_GREATER 4.2.1) OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
if(((NOT APPLE) OR (NOT CMAKE_COMPILER_IS_GNUCXX) OR (GCC_VERSION VERSION_GREATER 4.2.1) OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")) AND WITH_OPENMP)
find_package(OpenMP COMPONENTS C CXX)
endif()
if(OPENMP_FOUND)
@@ -262,9 +266,10 @@ if(OPENMP_FOUND)
set(CMAKE_INSTALL_OPENMP_LIBRARIES TRUE)
message (STATUS "Found OpenMP: ${OpenMP_CXX_LIBRARIES}")
if(PCL_OMP)
message (STATUS "Add PCL_OMP to definitions")
add_definitions(-DPCL_OMP)
endif(PCL_OMP)
else(OPENMP_FOUND)
elseif(WITH_OPENMP)
message (STATUS "Not found OpenMP")
endif()
@@ -345,6 +350,13 @@ IF(WITH_QT)
ENDIF(QT4_FOUND OR Qt5_FOUND)
ENDIF(WITH_QT)
IF(NOT VTK_FOUND)
# Newest PCL versions won't set -DDISABLE_VTK
IF(NOT "${PCL_DEFINITIONS}" MATCHES "-DDISABLE_VTK")
SET(PCL_DEFINITIONS "${PCL_DEFINITIONS};-DDISABLE_VTK")
ENDIF()
ENDIF(NOT VTK_FOUND)
IF(WITH_TORCH)
FIND_PACKAGE(Torch QUIET)
IF(TORCH_FOUND)
@@ -353,7 +365,7 @@ IF(WITH_TORCH)
ENDIF(WITH_TORCH)
IF(WITH_PYTHON)
FIND_PACKAGE(Python3 COMPONENTS Interpreter Development)
FIND_PACKAGE(Python3 COMPONENTS Interpreter Development NumPy)
IF(Python3_FOUND)
MESSAGE(STATUS "Found Python3")
ENDIF(Python3_FOUND)
@@ -433,7 +445,20 @@ IF(WITH_G2O)
IF(g2o_FOUND)
MESSAGE(STATUS "Found g2o (targets)")
SET(G2O_FOUND ${g2o_FOUND})
get_target_property(G2O_INCLUDES g2o::core INTERFACE_INCLUDE_DIRECTORIES)
MESSAGE(STATUS "g2o include dir: ${G2O_INCLUDES}")
FIND_FILE(G2O_FACTORY_FILE g2o/core/factory.h
PATHS ${G2O_INCLUDES}
NO_DEFAULT_PATH)
FILE(READ ${G2O_FACTORY_FILE} TMPTXT)
STRING(FIND "${TMPTXT}" "shared_ptr" matchres)
IF(${matchres} EQUAL -1)
MESSAGE(STATUS "Old g2o factory version detected without shared ptr (factory file: ${G2O_FACTORY_FILE}).")
SET(G2O_CPP11 2)
ELSE()
MESSAGE(STATUS "Latest g2o factory version detected with shared ptr (factory file: ${G2O_FACTORY_FILE}).")
SET(G2O_CPP11 1)
ENDIF()
ELSE()
FIND_PACKAGE(G2O QUIET)
IF(G2O_FOUND)
@@ -471,7 +496,7 @@ 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)
find_package(Boost COMPONENTS thread filesystem system program_options date_time chrono timer serialization REQUIRED)
ENDIF(Boost_MINOR_VERSION GREATER 47)
IF(WIN32)
MESSAGE(STATUS "Boost_LIBRARY_DIRS=${Boost_LIBRARY_DIRS}")
@@ -486,6 +511,19 @@ IF(WITH_CCCORELIB)
ENDIF(CCCoreLib_FOUND)
ENDIF(WITH_CCCORELIB)
IF(WITH_OPEN3D)
IF(${CMAKE_VERSION} VERSION_LESS "3.19.0")
MESSAGE(WARNING "Open3D requires CMake version >=3.19 (current is ${CMAKE_VERSION})")
ELSE()
# Build Open3D like this to avoid linker errors in rtabmap:
# cmake -DBUILD_SHARED_LIBS=ON -DGLIBCXX_USE_CXX11_ABI=ON -DCMAKE_BUILD_TYPE=Release ..
find_package(Open3D QUIET)
IF(Open3D_FOUND)
MESSAGE(STATUS "Found Open3D: ${Open3DINCLUDE_DIRS}")
ENDIF(Open3D_FOUND)
ENDIF()
ENDIF(WITH_OPEN3D)
IF(WITH_LOAM)
find_package(loam_velodyne QUIET)
IF(loam_velodyne_FOUND)
@@ -493,6 +531,14 @@ IF(WITH_LOAM)
ENDIF(loam_velodyne_FOUND)
ENDIF(WITH_LOAM)
IF(WITH_FLOAM)
find_package(floam QUIET)
IF(floam_FOUND)
MESSAGE(STATUS "Found floam: ${floam_INCLUDE_DIRS}")
FIND_PACKAGE(Ceres QUIET REQUIRED)
ENDIF(floam_FOUND)
ENDIF(WITH_FLOAM)
SET(ZED_FOUND FALSE)
IF(WITH_ZED)
find_package(ZED 2 QUIET)
@@ -594,6 +640,7 @@ IF(WITH_ALICE_VISION)
ENDIF(${AliceVision_VERSION} VERSION_LESS_EQUAL "2.2")
SET(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};/usr/local/lib/cmake/modules")
find_package(Geogram REQUIRED QUIET)
find_package(assimp QUIET)
add_definitions("-DRTABMAP_ALICE_VISION_MAJOR=${AliceVision_VERSION_MAJOR}")
add_definitions("-DRTABMAP_ALICE_VISION_MINOR=${AliceVision_VERSION_MINOR}")
add_definitions("-DRTABMAP_ALICE_VISION_PATCH=${AliceVision_VERSION_PATCH}")
@@ -635,9 +682,14 @@ IF(WITH_OKVIS)
ENDIF(WITH_OKVIS)
# If built with okvis, we found already ceres above
IF(NOT okvis_FOUND AND WITH_CERES)
IF(WITH_CERES)
IF(NOT okvis_FOUND AND NOT floam_FOUND)
FIND_PACKAGE(Ceres QUIET)
ENDIF(NOT okvis_FOUND AND WITH_CERES)
MESSAGE(STATUS "Found ceres ${Ceres_VERSION}: ${CERES_INCLUDE_DIRS}")
ENDIF(NOT okvis_FOUND AND NOT floam_FOUND)
ELSEIF(Ceres_FOUND)
MESSAGE(WARNING "WITH_CERES is OFF, but it still included by dependencies Okvis or FLOAM")
ENDIF()
IF(WITH_MSCKF_VIO)
FIND_PACKAGE(msckf_vio QUIET)
@@ -670,6 +722,13 @@ IF(WITH_FASTCV)
ENDIF(FastCV_FOUND)
ENDIF(WITH_FASTCV)
IF(WITH_OPENGV)
FIND_PACKAGE(opengv QUIET)
IF(opengv_FOUND)
MESSAGE(STATUS "Found OpenGV: ${opengv_INCLUDE_DIRS}")
ENDIF(opengv_FOUND)
ENDIF(WITH_OPENGV)
IF(WITH_ORB_SLAM AND NOT G2O_FOUND)
FIND_PACKAGE(ORB_SLAM QUIET)
IF(ORB_SLAM_FOUND)
@@ -678,8 +737,8 @@ IF(WITH_ORB_SLAM AND NOT G2O_FOUND)
ENDIF(WITH_ORB_SLAM AND NOT G2O_FOUND)
IF(NOT MSVC)
IF(loam_velodyne_FOUND OR PCL_VERSION VERSION_GREATER "1.9.1" OR TORCH_FOUND OR G2O_FOUND OR CCCoreLib_FOUND)
#LOAM, PCL>=1.10, latest g2o and CCCoreLib require c++14
IF((NOT WITH_MSCKF_VIO OR NOT msckf_vio_FOUND) AND (loam_velodyne_FOUND OR floam_FOUND OR PCL_VERSION VERSION_GREATER "1.9.1" OR TORCH_FOUND OR G2O_FOUND OR CCCoreLib_FOUND OR Open3D_FOUND))
#LOAM, PCL>=1.10, latest g2o and CCCoreLib require c++14, but MSCKF_VIO requires c++11
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14)
IF(COMPILER_SUPPORTS_CXX14)
@@ -688,7 +747,7 @@ IF(NOT MSVC)
ELSE()
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(loam_velodyne_FOUND OR PCL_VERSION VERSION_GREATER "1.9.1" OR TORCH_FOUND OR G2O_FOUND OR CCCoreLib_FOUND)
ENDIF()
IF( (NOT (${CMAKE_CXX_STANDARD} STREQUAL "14")) AND (
G2O_FOUND OR
@@ -773,6 +832,7 @@ ENDIF()
IF(NOT G2O_FOUND)
SET(G2O "//")
SET(G2O_CPP_CONF "//")
ELSE()
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${G2O_LIBRARIES})
IF(NOT G2O_CPP11)
@@ -804,15 +864,24 @@ ENDIF(NOT libpointmatcher_FOUND)
IF(NOT CCCoreLib_FOUND)
SET(CCCORELIB "//")
ENDIF(NOT CCCoreLib_FOUND)
IF(NOT Open3D_FOUND)
SET(OPEN3D "//")
ENDIF(NOT Open3D_FOUND)
IF(NOT FastCV_FOUND)
SET(FASTCV "//")
ENDIF(NOT FastCV_FOUND)
IF(NOT opengv_FOUND)
SET(OPENGV "//")
ENDIF(NOT opengv_FOUND)
IF(NOT PDAL_FOUND)
SET(PDAL "//")
ENDIF(NOT PDAL_FOUND)
IF(NOT loam_velodyne_FOUND)
SET(LOAM "//")
ENDIF(NOT loam_velodyne_FOUND)
IF(NOT floam_FOUND)
SET(FLOAM "//")
ENDIF(NOT floam_FOUND)
IF(NOT Freenect_FOUND)
SET(FREENECT "//")
ELSE()
@@ -875,8 +944,12 @@ IF(NOT mynteye_FOUND)
SET(MYNTEYE "//")
ENDIF(NOT mynteye_FOUND)
IF(NOT depthai_FOUND)
SET(CONF_DEPTH_AI OFF)
SET(DEPTHAI "//")
ENDIF(NOT depthai_FOUND)
ELSE()
SET(CONF_DEPTH_AI ON)
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} depthai::core depthai::opencv)
ENDIF()
IF(NOT octomap_FOUND)
SET(OCTOMAP "//")
ELSE()
@@ -941,7 +1014,7 @@ ENDIF()
IF(NOT TORCH_FOUND)
SET(TORCH "//")
ENDIF()
IF(NOT Python3_FOUND)
IF(NOT WITH_PYTHON OR NOT Python3_FOUND)
SET(PYTHON "//")
ENDIF()
IF(ADD_VTK_GUI_SUPPORT_QT_TO_CONF)
@@ -957,7 +1030,7 @@ IF(NOT WITH_MADGWICK)
SET(MADGWICK "//")
ENDIF()
CONFIGURE_FILE(Version.h.in ${PROJECT_SOURCE_DIR}/corelib/include/${PROJECT_PREFIX}/core/Version.h)
CONFIGURE_FILE(Version.h.in ${CMAKE_CURRENT_BINARY_DIR}/corelib/include/${PROJECT_PREFIX}/core/Version.h)
ADD_SUBDIRECTORY( utilite )
ADD_SUBDIRECTORY( corelib )
@@ -1001,7 +1074,8 @@ file(RELATIVE_PATH REL_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}/${INSTALL_CMAKE_DIR}
file(RELATIVE_PATH REL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/${INSTALL_CMAKE_DIR}" "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
# ... for the build tree
set(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/corelib/include"
set(CONF_INCLUDE_DIRS "${PROJECT_BINARY_DIR}/corelib/include"
"${PROJECT_SOURCE_DIR}/corelib/include"
"${PROJECT_SOURCE_DIR}/guilib/include"
"${PROJECT_SOURCE_DIR}/utilite/include")
set(CONF_LIB_DIR "${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
@@ -1212,7 +1286,7 @@ ELSE()
MESSAGE(STATUS " With SupertPoint = NO (libtorch not found)")
ENDIF()
IF(Python3_FOUND)
IF(WITH_PYTHON AND Python3_FOUND)
MESSAGE(STATUS " With Python${Python3_VERSION_MAJOR}.${Python3_VERSION_MINOR} = YES (License: PSF)")
ELSEIF(NOT WITH_PYTHON)
MESSAGE(STATUS " With Python3 = NO (WITH_PYTHON=OFF)")
@@ -1267,7 +1341,11 @@ MESSAGE(STATUS " *With GTSAM = NO (GTSAM not found)")
ENDIF()
IF(CERES_FOUND)
MESSAGE(STATUS " *With Ceres = YES (License: BSD)")
IF(WITH_CERES)
MESSAGE(STATUS " *With Ceres ${Ceres_VERSION} = YES (License: BSD)")
ELSE()
MESSAGE(STATUS " *With Ceres ${Ceres_VERSION} = YES (License: BSD, WITH_CERES=OFF but it is enabled by okvis or floam dependencies)")
ENDIF()
ELSEIF(NOT WITH_CERES)
MESSAGE(STATUS " *With Ceres = NO (WITH_CERES=OFF)")
ELSE()
@@ -1302,12 +1380,30 @@ ENDIF()
IF(CCCoreLib_FOUND)
MESSAGE(STATUS " With CCCoreLib = YES (License: GPLv2)")
ELSEIF(NOT WITH_POINTMATCHER)
ELSEIF(NOT WITH_CCCORELIB)
MESSAGE(STATUS " With CCCoreLib = NO (WITH_CCCORELIB=OFF)")
ELSE()
MESSAGE(STATUS " With CCCoreLib = NO (CCCoreLib not found)")
ENDIF()
IF(Open3D_FOUND)
MESSAGE(STATUS " With Open3D = YES (License: MIT)")
ELSEIF(NOT WITH_OPEN3D)
MESSAGE(STATUS " With Open3D = NO (WITH_OPEN3D=OFF)")
ELSEIF(${CMAKE_VERSION} VERSION_LESS "3.19.0")
MESSAGE(STATUS " With Open3D = NO (Open3D requires CMake>=3.19)")
ELSE()
MESSAGE(STATUS " With Open3D = NO (Open3D not found)")
ENDIF()
IF(opengv_FOUND)
MESSAGE(STATUS " With OpenGV = YES (License: BSD)")
ELSEIF(NOT WITH_OPENGV)
MESSAGE(STATUS " With OpenGV = NO (WITH_OPENGV=OFF)")
ELSE()
MESSAGE(STATUS " With OpenGV = NO (OpenGV not found)")
ENDIF()
MESSAGE(STATUS "")
MESSAGE(STATUS " Reconstruction Approaches:")
IF(octomap_FOUND)
@@ -1465,6 +1561,14 @@ ELSE()
MESSAGE(STATUS " With loam_velodyne = NO (loam_velodyne not found)")
ENDIF()
IF(floam_FOUND)
MESSAGE(STATUS " With floam = YES (License: BSD)")
ELSEIF(NOT WITH_FLOAM)
MESSAGE(STATUS " With floam = NO (WITH_FLOAM=OFF)")
ELSE()
MESSAGE(STATUS " With floam = NO (floam not found)")
ENDIF()
IF(libfovis_FOUND)
MESSAGE(STATUS " With libfovis = YES (License: GPLv2)")
ELSEIF(NOT WITH_FOVIS)
@@ -1534,12 +1638,12 @@ ENDIF()
MESSAGE(STATUS "Show all options with: cmake -LA | grep WITH_")
MESSAGE(STATUS "--------------------------------------------")
IF(NOT GTSAM_FOUND AND NOT G2O_FOUND AND NOT WITH_TORO AND NOT CERES_FOUND)
IF(NOT GTSAM_FOUND AND NOT G2O_FOUND AND NOT WITH_TORO AND NOT WITH_CERES AND NOT CERES_FOUND)
MESSAGE(SEND_ERROR "No graph optimizer found! You should have at least one of these options:
g2o (https://github.com/RainerKuemmerle/g2o)
GTSAM (https://collab.cc.gatech.edu/borg/gtsam)
Ceres (http://ceres-solver.org)
set -DWITH_TORO=ON")
ENDIF(NOT GTSAM_FOUND AND NOT G2O_FOUND AND NOT WITH_TORO AND NOT CERES_FOUND)
ENDIF(NOT GTSAM_FOUND AND NOT G2O_FOUND AND NOT WITH_TORO AND NOT WITH_CERES AND NOT CERES_FOUND)
# vim: set et ft=cmake fenc=utf-8 ff=unix sts=0 sw=2 ts=2 :

View File

@@ -1,13 +1,15 @@
rtabmap ![Analytics](https://ga-beacon-279122.nn.r.appspot.com/UA-56986679-3/github-main?pixel)
rtabmap
=======
[![RTAB-Map Logo](https://raw.githubusercontent.com/introlab/rtabmap/master/guilib/src/images/RTAB-Map100.png)](http://introlab.github.io/rtabmap)
[![Release][release-image]][releases]
[![License][license-image]][license]
Linux: [![Build Status](https://travis-ci.org/introlab/rtabmap.svg?branch=master)](https://travis-ci.org/introlab/rtabmap) Windows: [![Build status](https://ci.appveyor.com/api/projects/status/hr73xspix9oqa26h/branch/master?svg=true)](https://ci.appveyor.com/project/matlabbe/rtabmap/branch/master)
[release-image]: https://img.shields.io/badge/release-0.20.7-green.svg?style=flat
* Linux: [![Build Status](https://github.com/introlab/rtabmap/actions/workflows/cmake.yml/badge.svg)](https://github.com/introlab/rtabmap/actions/workflows/cmake.yml) [![Build Status](https://github.com/introlab/rtabmap/actions/workflows/cmake-ros.yml/badge.svg)](https://github.com/introlab/rtabmap/actions/workflows/cmake-ros.yml) [![docker](https://github.com/introlab/rtabmap/actions/workflows/docker.yml/badge.svg)](https://github.com/introlab/rtabmap/actions/workflows/docker.yml)
* Windows: [![Build status](https://ci.appveyor.com/api/projects/status/hr73xspix9oqa26h/branch/master?svg=true)](https://ci.appveyor.com/project/matlabbe/rtabmap/branch/master)
[release-image]: https://img.shields.io/badge/release-0.20.16-green.svg?style=flat
[releases]: https://github.com/introlab/rtabmap/releases
[license-image]: https://img.shields.io/badge/license-BSD-green.svg?style=flat
@@ -15,7 +17,8 @@ Linux: [![Build Status](https://travis-ci.org/introlab/rtabmap.svg?branch=master
RTAB-Map library and standalone application.
For more information, visit the [RTAB-Map's home page](http://introlab.github.io/rtabmap) or the [RTAB-Map's wiki](https://github.com/introlab/rtabmap/wiki).
* For more information (e.g., papers, major updates), visit [RTAB-Map's home page](http://introlab.github.io/rtabmap).
* For installation instructions and examples, visit [RTAB-Map's wiki](https://github.com/introlab/rtabmap/wiki).
To use RTAB-Map under ROS, visit the [rtabmap](http://wiki.ros.org/rtabmap) page on the ROS wiki.

View File

@@ -81,6 +81,9 @@ endif()
if(@CONF_VTK_QT@ AND ${WITH_GUI})
find_package(VTK COMPONENTS vtkGUISupportQt NO_MODULE) # to define vtkGUISupportQt target
endif(@CONF_VTK_QT@ AND ${WITH_GUI})
if(@CONF_DEPTH_AI@)
FIND_PACKAGE(depthai 2 QUIET REQUIRED)
endif(@CONF_DEPTH_AI@)
SET(RTABMap_LIBRARIES ${RTABMap_LIBRARIES} "@CONF_DEPENDENCIES@")
#backward compatibilities

View File

@@ -40,7 +40,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@NONFREE@#define RTABMAP_NONFREE
@TORO@#define RTABMAP_TORO
@G2O@#define RTABMAP_G2O
@G2O_CPP_CONF@#define RTABMAP_G2O_CPP11
@G2O_CPP_CONF@#define RTABMAP_G2O_CPP11 @G2O_CPP11@
@GTSAM@#define RTABMAP_GTSAM
@CERES@#define RTABMAP_CERES
@VERTIGO@#define RTABMAP_VERTIGO
@@ -52,9 +52,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@CVSBA@#define RTABMAP_CVSBA
@POINTMATCHER@#define RTABMAP_POINTMATCHER
@CCCORELIB@#define RTABMAP_CCCORELIB
@OPEN3D@#define RTABMAP_OPEN3D
@FASTCV@#define RTABMAP_FASTCV
@OPENGV@#define RTABMAP_OPENGV
@PDAL@#define RTABMAP_PDAL
@LOAM@#define RTABMAP_LOAM
@FLOAM@#define RTABMAP_FLOAM
@DC1394@#define RTABMAP_DC1394
@FLYCAPTURE2@#define RTABMAP_FLYCAPTURE2
@ZED@#define RTABMAP_ZED

View File

@@ -18,6 +18,11 @@
<!-- This is the platform API where depth16 support in android was introduced. -->
<uses-sdk android:minSdkVersion="@ANDROID_NATIVE_API_LEVEL@" />
<queries>
<package android:name="com.google.ar.core" />
<package android:name="com.huawei.ar.engine" />
</queries>
<!-- This .apk has no Java code itself, so set hasCode to false. -->
<application
android:label="@string/app_name"
@@ -43,6 +48,15 @@
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<action android:name="android.intent.action.SEND_MULTIPLE" />
<action android:name="android.intent.action.OPEN_DOCUMENT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/octet-stream" />
<data android:pathPattern=".*\.db" />
</intent-filter>
</activity>
<activity android:name="SettingsActivity" android:label="@string/settings" android:screenOrientation="fullSensor"/>

View File

@@ -3,6 +3,7 @@ SET(INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/tango-gl/include
${CMAKE_CURRENT_SOURCE_DIR}/third-party/include
${PROJECT_BINARY_DIR}/corelib/include
${PROJECT_SOURCE_DIR}/corelib/include
${PROJECT_SOURCE_DIR}/utilite/include
${OpenCV_INCLUDE_DIRS}

View File

@@ -520,11 +520,11 @@ SensorData CameraARCore::captureImage(CameraInfo * info)
cv::Mat yuv(height+height/2, width, CV_8UC1);
memcpy(yuv.data, plane_data, data_length);
memcpy(yuv.data+data_length, plane_uv_data, height/2*width);
cv::cvtColor(yuv, rgb, CV_YUV2BGR_NV21);
cv::cvtColor(yuv, rgb, cv::COLOR_YUV2BGR_NV21);
}
else
{
cv::cvtColor(cv::Mat(height+height/2, width, CV_8UC1, (void*)plane_data), rgb, CV_YUV2BGR_NV21);
cv::cvtColor(cv::Mat(height+height/2, width, CV_8UC1, (void*)plane_data), rgb, cv::COLOR_YUV2BGR_NV21);
}
std::vector<cv::KeyPoint> kpts;

View File

@@ -244,7 +244,7 @@ SensorData CameraAREngine::captureImage(CameraInfo * info)
cv::Mat outputRGB;
if(imageData != nullptr && len>0)
{
cv::cvtColor(cv::Mat(height+height/2, width, CV_8UC1, (void*)imageData), outputRGB, CV_YUV2BGR_NV21);
cv::cvtColor(cv::Mat(height+height/2, width, CV_8UC1, (void*)imageData), outputRGB, cv::COLOR_YUV2BGR_NV21);
}
//Depth

View File

@@ -171,7 +171,7 @@ void CameraMobile::setData(const SensorData & data, const Transform & pose, cons
if(textureId_ != 0 && texCoord != 0)
{
cv::Mat rgbImage;
cv::cvtColor(data.imageRaw(), rgbImage, CV_BGR2RGBA);
cv::cvtColor(data.imageRaw(), rgbImage, cv::COLOR_BGR2RGBA);
glBindTexture(GL_TEXTURE_2D, textureId_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

View File

@@ -478,15 +478,15 @@ void CameraTango::cloudReceived(const cv::Mat & cloud, double timestamp)
LOGD("tangoColorType=%d", tangoColorType);
if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_RGBA_8888)
{
cv::cvtColor(tangoImage, rgb, CV_RGBA2BGR);
cv::cvtColor(tangoImage, rgb, cv::COLOR_RGBA2BGR);
}
else if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_YV12)
{
cv::cvtColor(tangoImage, rgb, CV_YUV2BGR_YV12);
cv::cvtColor(tangoImage, rgb, cv::COLOR_YUV2BGR_YV12);
}
else if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_YCrCb_420_SP)
{
cv::cvtColor(tangoImage, rgb, CV_YUV2BGR_NV21);
cv::cvtColor(tangoImage, rgb, cv::COLOR_YUV2BGR_NV21);
}
else if(tangoColorType == 35)
{

View File

@@ -64,6 +64,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/core/Memory.h>
#include <rtabmap/core/GainCompensator.h>
#include <rtabmap/core/DBDriver.h>
#include <rtabmap/core/Recovery.h>
#include <pcl/common/common.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/io/ply_io.h>
@@ -82,6 +83,43 @@ static JavaVM *jvm;
static jobject RTABMapActivity = 0;
#endif
#ifdef __ANDROID__
#ifndef DISABLE_LOG
//ref: https://codelab.wordpress.com/2014/11/03/how-to-use-standard-output-streams-for-logging-in-android-apps/
static int pfd[2];
static pthread_t thr;
static void *thread_func(void*)
{
ssize_t rdsz;
char buf[128];
while((rdsz = read(pfd[0], buf, sizeof buf - 1)) > 0) {
if(buf[rdsz - 1] == '\n') --rdsz;
buf[rdsz] = 0; /* add null-terminator */
__android_log_write(ANDROID_LOG_DEBUG, LOG_TAG, buf);
}
return 0;
}
int start_logger()
{
/* make stdout line-buffered and stderr unbuffered */
setvbuf(stdout, 0, _IOLBF, 0);
setvbuf(stderr, 0, _IONBF, 0);
/* create the pipe and redirect stdout and stderr */
pipe(pfd);
dup2(pfd[1], 1);
dup2(pfd[1], 2);
/* spawn the logging thread */
if(pthread_create(&thr, 0, thread_func, 0) == -1)
return -1;
pthread_detach(thr);
return 0;
}
#endif
#endif
rtabmap::ParametersMap RTABMapApp::getRtabmapParameters()
{
rtabmap::ParametersMap parameters;
@@ -243,6 +281,12 @@ RTABMapApp::RTABMapApp() :
this->registerToEventsManager();
LOGI("RTABMapApp::RTABMapApp() end");
#ifdef __ANDROID__
#ifndef DISABLE_LOG
start_logger();
#endif
#endif
}
#ifndef __ANDROID__ // __APPLE__
@@ -305,9 +349,9 @@ void RTABMapApp::setScreenRotation(int displayRotation, int cameraRotation)
}
}
int RTABMapApp::openDatabase(const std::string & databasePath, bool databaseInMemory, bool optimize, const std::string & databaseSource)
int RTABMapApp::openDatabase(const std::string & databasePath, bool databaseInMemory, bool optimize, bool clearDatabase)
{
LOGW("Opening database %s (inMemory=%d, optimize=%d)", databasePath.c_str(), databaseInMemory?1:0, optimize?1:0);
LOGW("Opening database %s (inMemory=%d, optimize=%d, clearDatabase=%d)", databasePath.c_str(), databaseInMemory?1:0, optimize?1:0, clearDatabase?1:0);
this->unregisterFromEventsManager(); // to ignore published init events when closing rtabmap
status_.first = rtabmap::RtabmapEventInit::kInitializing;
rtabmapMutex_.lock();
@@ -360,11 +404,11 @@ int RTABMapApp::openDatabase(const std::string & databasePath, bool databaseInMe
std::vector<std::vector<Eigen::Vector2f> > texCoords;
#endif
cv::Mat textures;
if(!databaseSource.empty())
if(!databasePath.empty() && UFile::exists(databasePath) && !clearDatabase)
{
UEventsManager::post(new rtabmap::RtabmapEventInit(rtabmap::RtabmapEventInit::kInfo, "Loading optimized cloud/mesh..."));
rtabmap::DBDriver * driver = rtabmap::DBDriver::create();
if(driver->openConnection(databaseSource))
if(driver->openConnection(databasePath))
{
cloudMat = driver->loadOptimizedMesh(&polygons, &texCoords, &textures);
if(!cloudMat.empty())
@@ -416,12 +460,10 @@ int RTABMapApp::openDatabase(const std::string & databasePath, bool databaseInMe
}
UEventsManager::post(new rtabmap::RtabmapEventInit(rtabmap::RtabmapEventInit::kInfo, "Loading database..."));
if(clearDatabase)
{
LOGI("Erasing database \"%s\"...", databasePath.c_str());
UFile::erase(databasePath);
if(!databaseSource.empty())
{
LOGI("Copying database source \"%s\" to \"%s\"...", databaseSource.c_str(), databasePath.c_str());
UFile::copy(databaseSource, databasePath);
}
//Rtabmap
@@ -448,7 +490,7 @@ int RTABMapApp::openDatabase(const std::string & databasePath, bool databaseInMe
poses,
links,
true,
true,
false, // Make sure poses are the same than optimized mesh (in case we switched RGBD/OptimizedFromGraphEnd)
&signatures,
true,
true,
@@ -593,7 +635,7 @@ int RTABMapApp::openDatabase(const std::string & databasePath, bool databaseInMe
if(renderingTextureDecimation_>1)
{
cv::Size reducedSize(data.imageRaw().cols/renderingTextureDecimation_, data.imageRaw().rows/renderingTextureDecimation_);
cv::resize(data.imageRaw(), inserted.first->second.texture, reducedSize, 0, 0, CV_INTER_LINEAR);
cv::resize(data.imageRaw(), inserted.first->second.texture, reducedSize, 0, 0, cv::INTER_LINEAR);
}
else
{
@@ -1199,7 +1241,12 @@ int RTABMapApp::Render()
std::list<rtabmap::RtabmapEvent*> rtabmapEvents;
try
{
UTimer fpsTime;
if(camera_ == 0)
{
// We are not doing continous drawing, just measure single draw
fpsTime_.restart();
}
#ifdef DEBUG_RENDERING_PERFORMANCE
UTimer time;
#endif
@@ -1399,7 +1446,14 @@ int RTABMapApp::Render()
}
else if(rtabmapThread_ && rtabmapThread_->isRunning() && landmark!=0)
{
if(rejected)
{
main_scene_.setBackgroundColor(0.5, 0.325f, 0); // dark orange
}
else
{
main_scene_.setBackgroundColor(1, 0.65f, 0); // orange
}
}
else if(rtabmapThread_ && rtabmapThread_->isRunning() && rejected>0)
{
@@ -1439,12 +1493,12 @@ int RTABMapApp::Render()
main_scene_.setMeshRendering(main_scene_.hasMesh(g_optMeshId), main_scene_.hasTexture(g_optMeshId));
fpsTime.restart();
main_scene_.setFrustumVisible(camera_!=0);
lastDrawnCloudsCount_ = main_scene_.Render(uvsTransformed, arViewMatrix, arProjectionMatrix);
if(renderingTime_ < fpsTime.elapsed())
double fpsTime = fpsTime_.ticks();
if(renderingTime_ < fpsTime)
{
renderingTime_ = fpsTime.elapsed();
renderingTime_ = fpsTime;
}
// revert state
@@ -1571,7 +1625,7 @@ int RTABMapApp::Render()
{
cv::Size reducedSize(textureRaw.cols/renderingTextureDecimation_, textureRaw.rows/renderingTextureDecimation_);
LOGD("resize image from %dx%d to %dx%d", textureRaw.cols, textureRaw.rows, reducedSize.width, reducedSize.height);
cv::resize(textureRaw, iter->second.texture, reducedSize, 0, 0, CV_INTER_LINEAR);
cv::resize(textureRaw, iter->second.texture, reducedSize, 0, 0, cv::INTER_LINEAR);
}
else
{
@@ -1856,7 +1910,7 @@ int RTABMapApp::Render()
if(renderingTextureDecimation_ > 1)
{
cv::Size reducedSize(data.imageRaw().cols/renderingTextureDecimation_, data.imageRaw().rows/renderingTextureDecimation_);
cv::resize(data.imageRaw(), inserted.first->second.texture, reducedSize, 0, 0, CV_INTER_LINEAR);
cv::resize(data.imageRaw(), inserted.first->second.texture, reducedSize, 0, 0, cv::INTER_LINEAR);
#ifdef DEBUG_RENDERING_PERFORMANCE
LOGW("resize image from %dx%d to %dx%d (%fs)", data.imageRaw().cols, data.imageRaw().rows, reducedSize.width, reducedSize.height, time.ticks());
#endif
@@ -2046,12 +2100,12 @@ int RTABMapApp::Render()
notifyDataLoaded = true;
}
fpsTime.restart();
main_scene_.setFrustumVisible(camera_!=0);
lastDrawnCloudsCount_ = main_scene_.Render(uvsTransformed, arViewMatrix, arProjectionMatrix, occlusionMesh, true);
if(renderingTime_ < fpsTime.elapsed())
double fpsTime = fpsTime_.ticks();
if(renderingTime_ < fpsTime)
{
renderingTime_ = fpsTime.elapsed();
renderingTime_ = fpsTime;
}
if(rtabmapEvents.size())
@@ -2089,7 +2143,7 @@ int RTABMapApp::Render()
cv::Mat image(h, w, CV_8UC4);
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, image.data);
cv::flip(image, image, 0);
cv::cvtColor(image, image, CV_RGBA2BGRA);
cv::cvtColor(image, image, cv::COLOR_RGBA2BGRA);
cv::Mat roi;
if(w>h)
{
@@ -2108,16 +2162,6 @@ int RTABMapApp::Render()
screenshotReady_.release();
}
if((openingDatabase_ && !visualizingMesh_) || exporting_ || postProcessing_)
{
// throttle rendering max 5Hz if we are doing some processing
double renderTime = fpsTime.elapsed();
if(0.2 - renderTime > 0.0)
{
uSleep((0.2 - renderTime)*1000);
}
}
if((rtabmapThread_==0 || !rtabmapThread_->isRunning()) && lastPostRenderEventTime_ > 0.0)
{
double interval = UTimer::now() - lastPostRenderEventTime_;
@@ -2550,6 +2594,26 @@ void RTABMapApp::save(const std::string & databasePath)
}
}
bool RTABMapApp::recover(const std::string & from, const std::string & to)
{
std::string errorMsg;
if(!databaseRecovery(from, false, &errorMsg, &progressionStatus_))
{
LOGE("Recovery Error: %s", errorMsg.c_str());
return false;
}
else
{
LOGI("Renaming %s to %s", from.c_str(), to.c_str());
if(UFile::rename(from, to) != 0)
{
LOGE("Failed renaming %s to %s", from.c_str(), to.c_str());
return false;
}
return true;
}
}
void RTABMapApp::cancelProcessing()
{
UWARN("Processing canceled!");
@@ -3704,14 +3768,14 @@ void RTABMapApp::postOdometryEvent(
cv::Mat yuv(rgbHeight+rgbHeight/2, rgbWidth, CV_8UC1);
memcpy(yuv.data, yPlane, yPlaneLen);
memcpy(yuv.data+yPlaneLen, vPlane, rgbHeight/2*rgbWidth);
cv::cvtColor(yuv, outputRGB, CV_YUV2BGR_NV21);
cv::cvtColor(yuv, outputRGB, cv::COLOR_YUV2BGR_NV21);
}
else
{
#ifdef __ANDROID__
cv::cvtColor(cv::Mat(rgbHeight+rgbHeight/2, rgbWidth, CV_8UC1, (void*)yPlane), outputRGB, CV_YUV2BGR_NV21);
cv::cvtColor(cv::Mat(rgbHeight+rgbHeight/2, rgbWidth, CV_8UC1, (void*)yPlane), outputRGB, cv::COLOR_YUV2BGR_NV21);
#else // __APPLE__
cv::cvtColor(cv::Mat(rgbHeight+rgbHeight/2, rgbWidth, CV_8UC1, (void*)yPlane), outputRGB, CV_YUV2RGB_NV21);
cv::cvtColor(cv::Mat(rgbHeight+rgbHeight/2, rgbWidth, CV_8UC1, (void*)yPlane), outputRGB, cv::COLOR_YUV2RGB_NV21);
#endif
}

View File

@@ -75,7 +75,7 @@ class RTABMapApp : public UEventsHandler {
void setScreenRotation(int displayRotation, int cameraRotation);
int openDatabase(const std::string & databasePath, bool databaseInMemory, bool optimize, const std::string & databaseSource=std::string());
int openDatabase(const std::string & databasePath, bool databaseInMemory, bool optimize, bool clearDatabase);
bool isBuiltWith(int cameraDriver) const;
#ifdef __ANDROID__
@@ -153,6 +153,7 @@ class RTABMapApp : public UEventsHandler {
void addEnvSensor(int type, float value);
void save(const std::string & databasePath);
bool recover(const std::string & from, const std::string & to);
void cancelProcessing();
bool exportMesh(
float cloudVoxelSize,
@@ -266,6 +267,8 @@ class RTABMapApp : public UEventsHandler {
// movement and point cloud.
Scene main_scene_;
UTimer fpsTime_;
std::list<rtabmap::RtabmapEvent*> rtabmapEvents_;
std::list<rtabmap::OdometryEvent> odomEvents_;
std::list<rtabmap::Transform> poseEvents_;

View File

@@ -89,13 +89,13 @@ Java_com_introlab_rtabmap_RTABMapLib_setScreenRotation(
JNIEXPORT int JNICALL
Java_com_introlab_rtabmap_RTABMapLib_openDatabase(
JNIEnv* env, jclass, jlong native_application, jstring databasePath, bool databaseInMemory, bool optimize)
JNIEnv* env, jclass, jlong native_application, jstring databasePath, bool databaseInMemory, bool optimize, bool clearDatabase)
{
std::string databasePathC;
GetJStringContent(env,databasePath,databasePathC);
if(native_application)
{
return native(native_application)->openDatabase(databasePathC, databaseInMemory, optimize);
return native(native_application)->openDatabase(databasePathC, databaseInMemory, optimize, clearDatabase);
}
else
{
@@ -104,17 +104,17 @@ Java_com_introlab_rtabmap_RTABMapLib_openDatabase(
}
}
JNIEXPORT int JNICALL
Java_com_introlab_rtabmap_RTABMapLib_openDatabase2(
JNIEnv* env, jclass, jlong native_application, jstring databaseSource, jstring databasePath, bool databaseInMemory, bool optimize)
JNIEXPORT bool JNICALL
Java_com_introlab_rtabmap_RTABMapLib_recover(
JNIEnv* env, jclass, jlong native_application, jstring from, jstring to)
{
if(native_application)
{
std::string databasePathC;
GetJStringContent(env,databasePath,databasePathC);
std::string databaseSourceC;
GetJStringContent(env,databaseSource,databaseSourceC);
return native(native_application)->openDatabase(databasePathC, databaseInMemory, optimize, databaseSourceC);
std::string toC;
GetJStringContent(env,to,toC);
std::string fromC;
GetJStringContent(env,from,fromC);
return native(native_application)->recover(fromC, toC);
}
else
{

View File

@@ -309,8 +309,8 @@ PointCloudDrawable::PointCloudDrawable(
float gainR,
float gainG,
float gainB) :
vertex_buffers_(0),
textures_(0),
vertex_buffer_(0),
texture_(0),
nPoints_(0),
pose_(rtabmap::Transform::getIdentity()),
poseGl_(1.0f),
@@ -320,14 +320,16 @@ PointCloudDrawable::PointCloudDrawable(
gainG_(gainG),
gainB_(gainB)
{
index_buffers_.resize(6, 0);
index_buffers_count_.resize(6, 0);
updateCloud(cloud, indices);
}
PointCloudDrawable::PointCloudDrawable(
const rtabmap::Mesh & mesh,
bool createWireframe) :
vertex_buffers_(0),
textures_(0),
vertex_buffer_(0),
texture_(0),
nPoints_(0),
pose_(rtabmap::Transform::getIdentity()),
poseGl_(1.0f),
@@ -337,64 +339,83 @@ PointCloudDrawable::PointCloudDrawable(
gainG_(1.0f),
gainB_(1.0f)
{
index_buffers_.resize(6, 0);
index_buffers_count_.resize(6, 0);
updateMesh(mesh, createWireframe);
}
PointCloudDrawable::~PointCloudDrawable()
{
LOGI("Freeing cloud buffer %d", vertex_buffers_);
if (vertex_buffers_)
LOGI("Freeing cloud buffer %d", vertex_buffer_);
if (vertex_buffer_)
{
glDeleteBuffers(1, &vertex_buffers_);
glDeleteBuffers(1, &vertex_buffer_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
vertex_buffers_ = 0;
vertex_buffer_ = 0;
}
if (textures_)
if (texture_)
{
glDeleteTextures(1, &textures_);
glDeleteTextures(1, &texture_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
textures_ = 0;
texture_ = 0;
}
for(size_t i=0; i<index_buffers_.size(); ++i)
{
if(index_buffers_[i])
{
glDeleteBuffers(1, &index_buffers_[i]);
index_buffers_[i] = 0;
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
}
}
}
void PointCloudDrawable::updatePolygons(const std::vector<pcl::Vertices> & polygons, const std::vector<pcl::Vertices> & polygonsLowRes, bool createWireframe)
{
for(int i=0; i<4; ++i)
{
if(index_buffers_[i])
{
glDeleteBuffers(1, &index_buffers_[i]);
index_buffers_[i] = 0;
tango_gl::util::CheckGlError("PointCloudDrawable::updatePolygons() clearing polygon buffers");
}
}
//LOGD("Update polygons");
polygons_.clear();
polygonLines_.clear();
polygonsLowRes_.clear();
polygonLinesLowRes_.clear();
if(polygons.size() && organizedToDenseIndices_.size())
{
unsigned int polygonSize = polygons[0].vertices.size();
size_t polygonSize = polygons[0].vertices.size();
UASSERT(polygonSize == 3);
polygons_.resize(polygons.size() * polygonSize);
std::vector<std::vector<GLuint> > indexes(4);
indexes[0].resize(polygons.size() * polygonSize);
if(createWireframe)
polygonLines_.resize(polygons_.size()*2);
indexes[2].resize(indexes[0].size()*2);
int oi = 0;
int li = 0;
for(unsigned int i=0; i<polygons.size(); ++i)
for(size_t i=0; i<polygons.size(); ++i)
{
UASSERT(polygons[i].vertices.size() == polygonSize);
for(unsigned int j=0; j<polygonSize; ++j)
{
polygons_[oi++] = organizedToDenseIndices_.at(polygons[i].vertices[j]);
indexes[0][oi++] = organizedToDenseIndices_.at(polygons[i].vertices[j]);
if(createWireframe)
{
polygonLines_[li++] = organizedToDenseIndices_.at(polygons[i].vertices[j]);
polygonLines_[li++] = organizedToDenseIndices_.at(polygons[i].vertices[(j+1) % polygonSize]);
indexes[2][li++] = organizedToDenseIndices_.at(polygons[i].vertices[j]);
indexes[2][li++] = organizedToDenseIndices_.at(polygons[i].vertices[(j+1) % polygonSize]);
}
}
}
if(polygonsLowRes.size())
{
unsigned int polygonSize = polygonsLowRes[0].vertices.size();
size_t polygonSize = polygonsLowRes[0].vertices.size();
UASSERT(polygonSize == 3);
polygonsLowRes_.resize(polygonsLowRes.size() * polygonSize);
indexes[1].resize(polygonsLowRes.size() * polygonSize);
if(createWireframe)
polygonLinesLowRes_.resize(polygonsLowRes_.size()*2);
indexes[3].resize(indexes[1].size()*2);
int oi = 0;
int li = 0;
for(unsigned int i=0; i<polygonsLowRes.size(); ++i)
@@ -402,15 +423,44 @@ void PointCloudDrawable::updatePolygons(const std::vector<pcl::Vertices> & polyg
UASSERT(polygonsLowRes[i].vertices.size() == polygonSize);
for(unsigned int j=0; j<polygonSize; ++j)
{
polygonsLowRes_[oi++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[j]);
indexes[1][oi++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[j]);
if(createWireframe)
{
polygonLinesLowRes_[li++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[j]);
polygonLinesLowRes_[li++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[(j+1)%polygonSize]);
indexes[3][li++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[j]);
indexes[3][li++] = organizedToDenseIndices_.at(polygonsLowRes[i].vertices[(j+1)%polygonSize]);
}
}
}
}
// Generate index buffers
for(size_t i=0; i<indexes.size(); ++i)
{
if(!indexes[i].empty())
{
glGenBuffers(1, &index_buffers_[i]);
if(!index_buffers_[i])
{
LOGE("OpenGL: could not generate index buffer %ld\n", i);
return;
}
LOGD("Adding polygon index %ld size=%ld", i, indexes[i].size());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[i]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * indexes[i].size(), indexes[i].data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
index_buffers_count_[i] = (int)indexes[i].size();
GLint error = glGetError();
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate indexes (0x%x)\n", error);
index_buffers_[i] = 0;
return;
}
}
}
}
}
@@ -418,43 +468,51 @@ void PointCloudDrawable::updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Pt
{
UASSERT(cloud.get() && !cloud->empty());
nPoints_ = 0;
polygons_.clear();
polygonsLowRes_.clear();
verticesLowRes_.clear();
verticesLowLowRes_.clear();
aabbMinModel_ = aabbMinWorld_ = pcl::PointXYZ(1000,1000,1000);
aabbMaxModel_ = aabbMaxWorld_ = pcl::PointXYZ(-1000,-1000,-1000);
if (vertex_buffers_)
if (vertex_buffer_)
{
glDeleteBuffers(1, &vertex_buffers_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
vertex_buffers_ = 0;
glDeleteBuffers(1, &vertex_buffer_);
tango_gl::util::CheckGlError("PointCloudDrawable::updateCloud() clear vertex buffer");
vertex_buffer_ = 0;
}
if (textures_)
if (texture_)
{
glDeleteTextures(1, &textures_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
textures_ = 0;
glDeleteTextures(1, &texture_);
tango_gl::util::CheckGlError("PointCloudDrawable::updateCloud() clear texture buffer");
texture_ = 0;
}
glGenBuffers(1, &vertex_buffers_);
if(!vertex_buffers_)
for(size_t i=0; i<index_buffers_.size(); ++i)
{
if(index_buffers_[i])
{
glDeleteBuffers(1, &index_buffers_[i]);
index_buffers_[i] = 0;
tango_gl::util::CheckGlError("PointCloudDrawable::updateCloud() clear index buffer");
}
}
glGenBuffers(1, &vertex_buffer_);
if(!vertex_buffer_)
{
LOGE("OpenGL: could not generate vertex buffers\n");
return;
}
LOGI("Creating cloud buffer %d", vertex_buffers_);
LOGI("Creating cloud buffer %d", vertex_buffer_);
std::vector<float> vertices;
int totalPoints = 0;
size_t totalPoints = 0;
std::vector<GLuint> verticesLowRes;
std::vector<GLuint> verticesLowLowRes;
if(indices.get() && indices->size())
{
totalPoints = indices->size();
vertices.resize(indices->size()*4);
verticesLowRes_.resize(cloud->isOrganized()?totalPoints:0);
verticesLowLowRes_.resize(cloud->isOrganized()?totalPoints:0);
verticesLowRes.resize(cloud->isOrganized()?totalPoints:0);
verticesLowLowRes.resize(cloud->isOrganized()?totalPoints:0);
int oi_low = 0;
int oi_lowlow = 0;
for(unsigned int i=0; i<indices->size(); ++i)
@@ -471,23 +529,23 @@ void PointCloudDrawable::updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Pt
{
if(indices->at(i)%LOW_DEC == 0 && (indices->at(i)/cloud->width) % LOW_DEC == 0)
{
verticesLowRes_[oi_low++] = i;
verticesLowRes[oi_low++] = i;
}
if(indices->at(i)%LOWLOW_DEC == 0 && (indices->at(i)/cloud->width) % LOWLOW_DEC == 0)
{
verticesLowLowRes_[oi_lowlow++] = i;
verticesLowLowRes[oi_lowlow++] = i;
}
}
}
verticesLowRes_.resize(oi_low);
verticesLowLowRes_.resize(oi_lowlow);
verticesLowRes.resize(oi_low);
verticesLowLowRes.resize(oi_lowlow);
}
else
{
totalPoints = cloud->size();
vertices.resize(cloud->size()*4);
verticesLowRes_.resize(cloud->isOrganized()?totalPoints:0);
verticesLowLowRes_.resize(cloud->isOrganized()?totalPoints:0);
verticesLowRes.resize(cloud->isOrganized()?totalPoints:0);
verticesLowLowRes.resize(cloud->isOrganized()?totalPoints:0);
int oi_low = 0;
int oi_lowlow = 0;
for(unsigned int i=0; i<cloud->size(); ++i)
@@ -504,19 +562,19 @@ void PointCloudDrawable::updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Pt
{
if(i%LOW_DEC == 0 && (i/cloud->width) % LOW_DEC == 0)
{
verticesLowRes_[oi_low++] = i;
verticesLowRes[oi_low++] = i;
}
if(i%LOWLOW_DEC == 0 && (i/cloud->width) % LOWLOW_DEC == 0)
{
verticesLowLowRes_[oi_lowlow++] = i;
verticesLowLowRes[oi_lowlow++] = i;
}
}
}
verticesLowRes_.resize(oi_low);
verticesLowLowRes_.resize(oi_lowlow);
verticesLowRes.resize(oi_low);
verticesLowLowRes.resize(oi_lowlow);
}
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (int)vertices.size(), (const void *)vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -524,11 +582,40 @@ void PointCloudDrawable::updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Pt
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate point cloud (0x%x)\n", error);
vertex_buffers_ = 0;
vertex_buffer_ = 0;
return;
}
nPoints_ = totalPoints;
// vertex index buffers
for(size_t i=4; i<5; ++i)
{
if((i==4 && !verticesLowRes.empty()) ||
(i==5 && !verticesLowLowRes.empty()))
{
glGenBuffers(1, &index_buffers_[i]);
if(!index_buffers_[i])
{
LOGE("OpenGL: could not generate index buffer %ld\n", i);
return;
}
index_buffers_count_[i] = i==4?(int)verticesLowRes.size():(int)verticesLowLowRes.size();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[i]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * index_buffers_count_[i], i==4?verticesLowRes.data():verticesLowLowRes.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
GLint error = glGetError();
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate indexes (0x%x)\n", error);
index_buffers_[i] = 0;
return;
}
}
}
nPoints_ = (int)totalPoints;
}
void PointCloudDrawable::updateMesh(const rtabmap::Mesh & mesh, bool createWireframe)
@@ -538,11 +625,21 @@ void PointCloudDrawable::updateMesh(const rtabmap::Mesh & mesh, bool createWiref
aabbMinModel_ = aabbMinWorld_ = pcl::PointXYZ(1000,1000,1000);
aabbMaxModel_ = aabbMaxWorld_ = pcl::PointXYZ(-1000,-1000,-1000);
if (vertex_buffers_)
if (vertex_buffer_)
{
glDeleteBuffers(1, &vertex_buffers_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
vertex_buffers_ = 0;
glDeleteBuffers(1, &vertex_buffer_);
tango_gl::util::CheckGlError("PointCloudDrawable::updateMesh() clear vertex buffer");
vertex_buffer_ = 0;
}
for(size_t i=0; i<index_buffers_.size(); ++i)
{
if(index_buffers_[i])
{
glDeleteBuffers(1, &index_buffers_[i]);
index_buffers_[i] = 0;
tango_gl::util::CheckGlError("PointCloudDrawable::updateMesh() clear index buffer");
}
}
gainR_ = mesh.gains[0];
@@ -552,17 +649,17 @@ void PointCloudDrawable::updateMesh(const rtabmap::Mesh & mesh, bool createWiref
bool textureUpdate = false;
if(!mesh.texture.empty() && mesh.texture.type() == CV_8UC3)
{
if (textures_)
if (texture_)
{
glDeleteTextures(1, &textures_);
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
textures_ = 0;
glDeleteTextures(1, &texture_);
tango_gl::util::CheckGlError("PointCloudDrawable::updateMesh() clear texture buffer");
texture_ = 0;
}
textureUpdate = true;
}
glGenBuffers(1, &vertex_buffers_);
if(!vertex_buffers_)
glGenBuffers(1, &vertex_buffer_);
if(!vertex_buffer_)
{
LOGE("OpenGL: could not generate vertex buffers\n");
return;
@@ -570,10 +667,10 @@ void PointCloudDrawable::updateMesh(const rtabmap::Mesh & mesh, bool createWiref
if(textureUpdate)
{
glGenTextures(1, &textures_);
if(!textures_)
glGenTextures(1, &texture_);
if(!texture_)
{
vertex_buffers_ = 0;
vertex_buffer_ = 0;
LOGE("OpenGL: could not generate texture buffers\n");
return;
}
@@ -591,11 +688,13 @@ void PointCloudDrawable::updateMesh(const rtabmap::Mesh & mesh, bool createWiref
polygonsLowRes = mesh.polygonsLowRes; // only in organized we keep the low res
organizedToDenseIndices_ = std::vector<unsigned int>(mesh.cloud->width*mesh.cloud->height, -1);
totalPoints = (int)mesh.indices->size();
verticesLowRes_.resize(totalPoints);
verticesLowLowRes_.resize(totalPoints);
std::vector<GLuint> verticesLowRes;
std::vector<GLuint> verticesLowLowRes;
verticesLowRes.resize(totalPoints);
verticesLowLowRes.resize(totalPoints);
int oi_low = 0;
int oi_lowlow = 0;
if(textures_ && polygons.size())
if(texture_ && polygons.size())
{
int items = hasNormals_?9:6;
vertices = std::vector<float>(mesh.indices->size()*items);
@@ -628,11 +727,11 @@ void PointCloudDrawable::updateMesh(const rtabmap::Mesh & mesh, bool createWiref
if(mesh.indices->at(i)%LOW_DEC == 0 && (mesh.indices->at(i)/mesh.cloud->width) % LOW_DEC == 0)
{
verticesLowRes_[oi_low++] = i;
verticesLowRes[oi_low++] = i;
}
if(mesh.indices->at(i)%LOWLOW_DEC == 0 && (mesh.indices->at(i)/mesh.cloud->width) % LOWLOW_DEC == 0)
{
verticesLowLowRes_[oi_lowlow++] = i;
verticesLowLowRes[oi_lowlow++] = i;
}
}
}
@@ -663,20 +762,48 @@ void PointCloudDrawable::updateMesh(const rtabmap::Mesh & mesh, bool createWiref
if(mesh.indices->at(i)%LOW_DEC == 0 && (mesh.indices->at(i)/mesh.cloud->width) % LOW_DEC == 0)
{
verticesLowRes_[oi_low++] = i;
verticesLowRes[oi_low++] = i;
}
if(mesh.indices->at(i)%LOWLOW_DEC == 0 && (mesh.indices->at(i)/mesh.cloud->width) % LOWLOW_DEC == 0)
{
verticesLowLowRes_[oi_lowlow++] = i;
verticesLowLowRes[oi_lowlow++] = i;
}
}
}
verticesLowRes.resize(oi_low);
verticesLowLowRes.resize(oi_lowlow);
// vertex index buffers
for(size_t i=4; i<5; ++i)
{
if((i==4 && !verticesLowRes.empty()) ||
(i==5 && !verticesLowLowRes.empty()))
{
glGenBuffers(1, &index_buffers_[i]);
if(!index_buffers_[i])
{
LOGE("OpenGL: could not generate index buffer %ld\n", i);
return;
}
index_buffers_count_[i] = i==4?(int)verticesLowRes.size():(int)verticesLowLowRes.size();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[i]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * index_buffers_count_[i], i==4?verticesLowRes.data():verticesLowLowRes.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
GLint error = glGetError();
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate indexes (0x%x)\n", error);
index_buffers_[i] = 0;
return;
}
}
}
verticesLowRes_.resize(oi_low);
verticesLowLowRes_.resize(oi_lowlow);
}
else // assume dense mesh with texCoords set to polygons
{
if(textures_ && polygons.size())
if(texture_ && polygons.size())
{
//LOGD("Dense mesh with texture (%d texCoords %d points %d polygons %dx%d)",
// (int)mesh.texCoords.size(), (int)mesh.cloud->size(), (int)mesh.polygons.size(), texture.cols, texture.rows);
@@ -743,7 +870,7 @@ void PointCloudDrawable::updateMesh(const rtabmap::Mesh & mesh, bool createWiref
}
else
{
totalPoints = mesh.cloud->size();
totalPoints = (int)mesh.cloud->size();
//LOGD("Dense mesh");
int items = hasNormals_?7:4;
organizedToDenseIndices_ = std::vector<unsigned int>(totalPoints, -1);
@@ -771,7 +898,7 @@ void PointCloudDrawable::updateMesh(const rtabmap::Mesh & mesh, bool createWiref
}
}
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (int)vertices.size(), (const void *)vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -779,11 +906,11 @@ void PointCloudDrawable::updateMesh(const rtabmap::Mesh & mesh, bool createWiref
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate point cloud (0x%x)\n", error);
vertex_buffers_ = 0;
vertex_buffer_ = 0;
return;
}
if(textures_ && textureUpdate)
if(texture_ && textureUpdate)
{
//GLint maxTextureSize = 0;
//glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
@@ -793,13 +920,13 @@ void PointCloudDrawable::updateMesh(const rtabmap::Mesh & mesh, bool createWiref
//LOGW("maxTextureUnits=%d", maxTextureUnits);
// gen texture from image
glBindTexture(GL_TEXTURE_2D, textures_);
glBindTexture(GL_TEXTURE_2D, texture_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
cv::Mat rgbImage;
cv::cvtColor(mesh.texture, rgbImage, CV_BGR2RGBA);
cv::cvtColor(mesh.texture, rgbImage, cv::COLOR_BGR2RGBA);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
//glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
@@ -811,20 +938,17 @@ void PointCloudDrawable::updateMesh(const rtabmap::Mesh & mesh, bool createWiref
if(error != GL_NO_ERROR)
{
LOGE("OpenGL: Could not allocate texture (0x%x)\n", error);
textures_ = 0;
texture_ = 0;
glDeleteBuffers(1, &vertex_buffers_);
vertex_buffers_ = 0;
glDeleteBuffers(1, &vertex_buffer_);
vertex_buffer_ = 0;
return;
}
}
nPoints_ = totalPoints;
if(polygons_.size() != polygons.size())
{
updatePolygons(polygons, polygonsLowRes, createWireframe);
}
if(!pose_.isNull())
{
@@ -886,14 +1010,14 @@ void PointCloudDrawable::Render(
bool packDepthToColorChannel,
bool wireFrame) const
{
if(vertex_buffers_ && nPoints_ && visible_ && !shaderPrograms_.empty())
if(vertex_buffer_ && nPoints_ && visible_ && !shaderPrograms_.empty())
{
if(packDepthToColorChannel || !hasNormals_)
{
lighting = false;
}
if(packDepthToColorChannel || !(meshRendering && textureRendering && textures_))
if(packDepthToColorChannel || !(meshRendering && textureRendering && texture_))
{
textureRendering = false;
}
@@ -996,7 +1120,7 @@ void PointCloudDrawable::Render(
// Texture activate unit 0
glActiveTexture(GL_TEXTURE0);
// Bind the texture to this unit.
glBindTexture(GL_TEXTURE_2D, textures_);
glBindTexture(GL_TEXTURE_2D, texture_);
// Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
GLuint texture_handle = glGetUniformLocation(program, "uTexture");
glUniform1i(texture_handle, 0);
@@ -1012,8 +1136,8 @@ void PointCloudDrawable::Render(
}
tango_gl::util::CheckGlError("Pointcloud::Render() common");
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_);
if(textures_)
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
if(texture_)
{
glVertexAttribPointer(attribute_vertex, 3, GL_FLOAT, GL_FALSE, (hasNormals_?9:6)*sizeof(GLfloat), 0);
if(textureRendering)
@@ -1044,53 +1168,49 @@ void PointCloudDrawable::Render(
tango_gl::util::CheckGlError("Pointcloud::Render() set attribute pointer");
UTimer drawTime;
if(textureRendering)
if((textureRendering || meshRendering) && index_buffers_[0])
{
if(distanceToCameraSqr<16.0f || polygonsLowRes_.empty())
float dist = meshRendering?50.0f:16.0f;
if(distanceToCameraSqr<dist || index_buffers_[1]==0)
{
wireFrame = wireFrame && polygonLines_.size();
wireFrame = wireFrame && index_buffers_[2];
if(wireFrame)
glDrawElements(GL_LINES, polygonLines_.size(), GL_UNSIGNED_INT, polygonLines_.data());
else
glDrawElements(GL_TRIANGLES, polygons_.size(), GL_UNSIGNED_INT, polygons_.data());
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[2]);
glDrawElements(GL_LINES, index_buffers_count_[2], GL_UNSIGNED_INT, 0);
}
else
{
wireFrame = wireFrame && polygonLinesLowRes_.size();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[0]);
glDrawElements(GL_TRIANGLES, index_buffers_count_[0], GL_UNSIGNED_INT, 0);
}
}
else
{
wireFrame = wireFrame && index_buffers_[3];
if(wireFrame)
glDrawElements(GL_LINES, polygonLinesLowRes_.size(), GL_UNSIGNED_INT, polygonLinesLowRes_.data());
else
glDrawElements(GL_TRIANGLES, polygonsLowRes_.size(), GL_UNSIGNED_INT, polygonsLowRes_.data());
}
}
else if(meshRendering && polygons_.size())
{
if(distanceToCameraSqr<50.0f || polygonsLowRes_.empty())
{
wireFrame = wireFrame && polygonLines_.size();
if(wireFrame)
glDrawElements(GL_LINES, polygonLines_.size(), GL_UNSIGNED_INT, polygonLines_.data());
else
glDrawElements(GL_TRIANGLES, polygons_.size(), GL_UNSIGNED_INT, polygons_.data());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[3]);
glDrawElements(GL_LINES, index_buffers_count_[3], GL_UNSIGNED_INT, 0);
}
else
{
wireFrame = wireFrame && polygonLinesLowRes_.size();
if(wireFrame)
glDrawElements(GL_LINES, polygonLinesLowRes_.size(), GL_UNSIGNED_INT, polygonLinesLowRes_.data());
else
glDrawElements(GL_TRIANGLES, polygonsLowRes_.size(), GL_UNSIGNED_INT, polygonsLowRes_.data());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[1]);
glDrawElements(GL_TRIANGLES, index_buffers_count_[1], GL_UNSIGNED_INT, 0);
}
}
else if(!verticesLowRes_.empty())
}
else if(index_buffers_[4])
{
if(distanceToCameraSqr>600.0f)
if(distanceToCameraSqr>600.0f && index_buffers_[5])
{
glDrawElements(GL_POINTS, verticesLowLowRes_.size(), GL_UNSIGNED_INT, verticesLowLowRes_.data());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[5]);
glDrawElements(GL_POINTS, index_buffers_count_[5], GL_UNSIGNED_INT, 0);
}
else if(distanceToCameraSqr>150.0f)
{
glDrawElements(GL_POINTS, verticesLowRes_.size(), GL_UNSIGNED_INT, verticesLowRes_.data());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffers_[4]);
glDrawElements(GL_POINTS, index_buffers_count_[4], GL_UNSIGNED_INT, 0);
}
else
{
@@ -1106,6 +1226,7 @@ void PointCloudDrawable::Render(
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glUseProgram(0);
tango_gl::util::CheckGlError("Pointcloud::Render() cleaning");

View File

@@ -70,8 +70,8 @@ private:
rtabmap::Transform getPose() const {return pose_;}
const glm::mat4 & getPoseGl() const {return poseGl_;}
bool isVisible() const {return visible_;}
bool hasMesh() const {return polygons_.size()!=0;}
bool hasTexture() const {return textures_ != 0;}
bool hasMesh() const {return index_buffers_[0] != 0;}
bool hasTexture() const {return texture_ != 0;}
float getMinHeight() const {return minHeight_;}
const pcl::PointXYZ & aabbMinModel() const {return aabbMinModel_;}
const pcl::PointXYZ & aabbMaxModel() const {return aabbMaxModel_;}
@@ -115,14 +115,10 @@ private:
private:
// Vertex buffer of the point cloud geometry.
GLuint vertex_buffers_;
GLuint textures_;
std::vector<GLuint> polygons_;
std::vector<GLuint> polygonsLowRes_;
std::vector<GLuint> polygonLines_;
std::vector<GLuint> polygonLinesLowRes_;
std::vector<GLuint> verticesLowRes_;
std::vector<GLuint> verticesLowLowRes_;
GLuint vertex_buffer_;
GLuint texture_;
std::vector<GLuint> index_buffers_;
std::vector<int> index_buffers_count_;
int nPoints_;
rtabmap::Transform pose_;
glm::mat4 poseGl_;

View File

@@ -102,7 +102,7 @@ Scene::Scene() :
screenHeight_(0),
doubleTapOn_(false)
{
depthTextures_[0] = depthTextures_[1] = 0;
depthTexture_ = 0;
gesture_camera_ = new tango_gl::GestureCamera();
gesture_camera_->SetCameraType(
tango_gl::GestureCamera::kThirdPersonFollow);
@@ -179,8 +179,8 @@ void Scene::DeleteResources() {
fboId_ = 0;
glDeleteRenderbuffers(1, &rboId_);
rboId_ = 0;
glDeleteTextures(2, depthTextures_);
depthTextures_[0] = depthTextures_[1] = 0;
glDeleteTextures(1, &depthTexture_);
depthTexture_ = 0;
}
clear();
@@ -234,8 +234,8 @@ void Scene::SetupViewPort(int w, int h) {
fboId_ = 0;
glDeleteRenderbuffers(1, &rboId_);
rboId_ = 0;
glDeleteTextures(2, depthTextures_);
depthTextures_[0] = depthTextures_[1] = 0;
glDeleteTextures(1, &depthTexture_);
depthTexture_ = 0;
}
GLint originid = 0;
@@ -247,16 +247,8 @@ void Scene::SetupViewPort(int w, int h) {
glBindFramebuffer(GL_FRAMEBUFFER, fboId_);
// Create depth texture
glGenTextures(2, depthTextures_);
glBindTexture(GL_TEXTURE_2D, depthTextures_[0]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 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_MIN_FILTER, GL_NEAREST);
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, depthTextures_[1]);
glGenTextures(1, &depthTexture_);
glBindTexture(GL_TEXTURE_2D, depthTexture_);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 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);
@@ -270,7 +262,7 @@ void Scene::SetupViewPort(int w, int h) {
glBindRenderbuffer(GL_RENDERBUFFER, 0);
// Set the texture to be at the color attachment point of the FBO (we pack depth 32 bits in color)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, depthTextures_[0], 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);
@@ -349,8 +341,9 @@ std::vector<glm::vec4> computeFrustumPlanes(const glm::mat4 & mat, bool normaliz
/**
* Tells whether or not b is intersecting f.
* http://www.txutxi.com/?p=584
* @param f Viewing frustum.
* @param b An axis aligned bounding box.
* @param planes Viewing frustum.
* @param boxMin The axis aligned bounding box min.
* @param boxMax The axis aligned bounding box max.
* @return True if b intersects f, false otherwise.
*/
bool intersectFrustumAABB(
@@ -389,7 +382,8 @@ bool intersectFrustumAABB(
}
//Should only be called in OpenGL thread!
int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat4 arProjectionMatrix, const rtabmap::Mesh & occlusionMesh, bool mapping) {
int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat4 arProjectionMatrix, const rtabmap::Mesh & occlusionMesh, bool mapping)
{
UASSERT(gesture_camera_ != 0);
if(currentPose_ == 0)
@@ -428,7 +422,7 @@ int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat
if(renderBackgroundCamera)
{
if(projectionMatrix[0][0] > arProjectionMatrix[0][0]-0.2)
if(projectionMatrix[0][0] > arProjectionMatrix[0][0]-0.3)
{
projectionMatrix = arProjectionMatrix;
viewMatrix = arViewMatrix;
@@ -486,9 +480,15 @@ int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat
glDisable(GL_CULL_FACE);
}
UTimer timer;
bool onlineBlending =
(!meshRendering_ &&
occlusionMesh.cloud.get() &&
occlusionMesh.cloud->size()) ||
(blending_ &&
gesture_camera_->GetCameraType()!=tango_gl::GestureCamera::kTopOrtho &&
mapRendering_ && meshRendering_ &&
(cloudsToDraw.size() > 1 || (renderBackgroundCamera && wireFrame_)));
bool onlineBlending = (!meshRendering_ && occlusionMesh.cloud.get() && occlusionMesh.cloud->size()) || (blending_ && gesture_camera_->GetCameraType()!=tango_gl::GestureCamera::kTopOrtho && mapRendering_ && meshRendering_);
if(onlineBlending && fboId_)
{
GLint originid = 0;
@@ -511,10 +511,6 @@ int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat
(*iter)->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_, false, false, distanceToCameraSqr, 0, 0, 0, 0, 0, true);
}
glBindTexture(GL_TEXTURE_2D, depthTextures_[1]);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, screenWidth_, screenHeight_);
glBindTexture(GL_TEXTURE_2D, 0);
if(!meshRendering_ && occlusionMesh.cloud.get() && occlusionMesh.cloud->size())
{
PointCloudDrawable drawable(occlusionMesh);
@@ -559,7 +555,7 @@ int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat
glClearColor(r_, g_, b_, 1.0f);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
if(renderBackgroundCamera && !onlineBlending)
if(renderBackgroundCamera && (!onlineBlending || !meshRendering_))
{
background_renderer_->Draw(uvsTransformed, 0, screenWidth_, screenHeight_, false);
@@ -594,6 +590,10 @@ int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat
{
trace_->Render(projectionMatrix, viewMatrix);
}
else
{
trace_->ClearVertexArray();
}
}
if(gridVisible_ && !renderBackgroundCamera)
@@ -629,14 +629,14 @@ int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat
cloud->getPose().z() - openglCamera.z());
float distanceToCameraSqr = cloudToCamera[0]*cloudToCamera[0] + cloudToCamera[1]*cloudToCamera[1] + cloudToCamera[2]*cloudToCamera[2];
cloud->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_, meshRenderingTexture_, lighting_, distanceToCameraSqr, onlineBlending?depthTextures_[0]:0, screenWidth_, screenHeight_, gesture_camera_->getNearClipPlane(), gesture_camera_->getFarClipPlane(), false, wireFrame_);
cloud->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_, meshRenderingTexture_, lighting_, distanceToCameraSqr, onlineBlending?depthTexture_:0, screenWidth_, screenHeight_, gesture_camera_->getNearClipPlane(), gesture_camera_->getFarClipPlane(), false, wireFrame_);
}
if(onlineBlending)
{
if(renderBackgroundCamera)
if(renderBackgroundCamera && meshRendering_)
{
background_renderer_->Draw(uvsTransformed, depthTextures_[1], screenWidth_, screenHeight_, meshRendering_?mapping:false);
background_renderer_->Draw(uvsTransformed, depthTexture_, screenWidth_, screenHeight_, mapping);
}
glDisable (GL_BLEND);

View File

@@ -208,7 +208,7 @@ class Scene {
float b_;
GLuint fboId_;
GLuint rboId_;
GLuint depthTextures_[2]; // 0=objects+occlusion 1=objects only
GLuint depthTexture_; // 0=objects+occlusion
GLsizei screenWidth_;
GLsizei screenHeight_;
bool doubleTapOn_;

View File

@@ -183,7 +183,7 @@ void GestureCamera::SetCameraType(CameraType camera_index) {
case kFirstPerson:
SetOrthoMode(false);
SetFieldOfView(kLowestFov);
SetNearFarClipPlanes(0.1, 50);
SetNearFarClipPlanes(0.25, 25);
SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
cam_cur_dist_ = 0.0f;

View File

@@ -19,7 +19,7 @@
<string name="light_off">Lighting</string>
<string name="wireframe">Wireframe</string>
<string name="close_visualization">Close Visualization</string>
<string name="save_to_file">Export to File&#8230;</string>
<string name="save_to_file">Export OBJ/PLY&#8230;</string>
<string name="share_to_sketchfab">Share to Sketchfab&#8230;</string>
<string name="start">Start</string>
<string name="nodes">"Nodes (WM): "</string>
@@ -80,7 +80,7 @@
<string name="pref_default_fisheye">false</string>
<string name="pref_key_camera_driver">pref_key_camera_driver</string>
<string name="pref_default_camera_driver">0</string>
<string name="pref_default_camera_driver">-1</string>
<string name="pref_key_depth_from_motion">pref_key_depth_from_motion</string>
<string name="pref_default_depth_from_motion">false</string>
<string name="pref_key_arcore_localization_filtering_speed">pref_key_arcore_localization_filtering_speed</string>
@@ -108,7 +108,7 @@
<string name="pref_key_features_type">pref_key_features_type</string>
<string name="pref_default_features_type">6</string>
<string name="pref_key_optimizer">pref_key_optimizer</string>
<string name="pref_default_optimizer">1</string>
<string name="pref_default_optimizer">2</string>
<string name="pref_key_optimize_end">pref_key_optimize_end</string>
<string name="pref_default_optimize_end">true</string>
<string name="pref_key_marker_detection">pref_key_marker_detection</string>
@@ -381,12 +381,14 @@
<string name="pref_summary_db_in_memory">The database is kept in RAM for fast access. Set to false to reduce RAM used at the cost of slower access. This parameter is applied on reset or when a database is opened.</string>
<string-array name="pref_camera_driver_keys">
<item>"Auto"</item>
<item>"Google Tango NDK"</item>
<item>"ARCore NDK"</item>
<item>"AREngine NDK"</item>
<item>"ARCore Java"</item>
</string-array>
<string-array name="pref_camera_driver_values">
<item>"-1"</item>
<item>"0"</item>
<item>"1"</item>
<item>"2"</item>

View File

@@ -688,7 +688,7 @@ public class ARCoreSharedCamera {
if(mToast!=null && previousAnchorPose != null)
{
String msg = "Tracking lost! If you are mapping, you will need to relocalize before continuing.";
if(!mToast.getView().isShown())
if(mToast.getView() == null || !mToast.getView().isShown())
{
mToast.makeText(mActivity.getApplicationContext(),
msg, Toast.LENGTH_LONG).show();
@@ -736,7 +736,7 @@ public class ARCoreSharedCamera {
+ "because of high speed detected (%f m/s) causing a jump! You can change "
+ "ARCore localization filtering speed in Settings->Mapping if you are "
+ "indeed moving as fast.", speed);
if(!mToast.getView().isShown())
if(mToast.getView() == null || !mToast.getView().isShown())
{
mToast.makeText(mActivity.getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}

View File

@@ -2,6 +2,7 @@ package com.introlab.rtabmap;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -25,6 +26,8 @@ import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnShowListener;
@@ -35,6 +38,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.Cursor;
import android.hardware.Camera;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
@@ -46,6 +50,7 @@ import android.hardware.display.DisplayManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
@@ -56,6 +61,8 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.provider.OpenableColumns;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.FileProvider;
import android.text.InputType;
@@ -118,7 +125,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
public static final String RTABMAP_TMP_DB = "rtabmap.tmp.db";
public static final String RTABMAP_TMP_DIR = "tmp";
public static final String RTABMAP_TMP_FILENAME = "map";
public static final String RTABMAP_SDCARD_PATH = "/sdcard/";
public static final String RTABMAP_SDCARD_PATH = "/Internal storage/";
public static final String RTABMAP_EXPORT_DIR = "Export/";
public static final String RTABMAP_AUTH_TOKEN_KEY = "com.introlab.rtabmap.AUTH_TOKEN";
@@ -257,6 +264,8 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
ARCoreSharedCamera mArCoreCamera = null;
int mCameraDriver = 0;
private String mIntentDbToOpen = null;
//Tango Service connection.
boolean mCameraServiceConnectionUsed = false;
ServiceConnection mCameraServiceConnection = new ServiceConnection() {
@@ -495,9 +504,28 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
mTotalLoopClosures = 0;
mLastFastMovementNotificationStamp = System.currentTimeMillis()/1000;
if(Environment.getExternalStorageState().compareTo(Environment.MEDIA_MOUNTED)==0)
int targetSdkVersion= 0;
try {
ApplicationInfo app = this.getPackageManager().getApplicationInfo("com.introlab.rtabmap", 0);
targetSdkVersion = app.targetSdkVersion;
} catch (NameNotFoundException e) {
e.printStackTrace();
}
if(Environment.getExternalStorageState().compareTo(Environment.MEDIA_MOUNTED)==0 &&
(targetSdkVersion < 30 || getActivity().getExternalFilesDirs(null).length >=1))
{
File extStore = Environment.getExternalStorageDirectory();
File extStore;
if(targetSdkVersion < 30)
{
extStore = Environment.getExternalStorageDirectory();
}
else // >= android30
{
extStore = getActivity().getExternalFilesDirs(null)[0];
}
mWorkingDirectory = extStore.getAbsolutePath() + "/" + getString(R.string.app_name) + "/";
extStore = new File(mWorkingDirectory);
extStore.mkdirs();
@@ -507,7 +535,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
{
// show warning that data cannot be saved!
mToast.makeText(getApplicationContext(),
String.format("Failed to get external storage path (SD-CARD, state=%s). Saving disabled.",
String.format("Failed to get external storage path (state=%s). Saving disabled.",
Environment.getExternalStorageState()), mToast.LENGTH_LONG).show();
}
@@ -574,33 +602,141 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
DISABLE_LOG = !( 0 != ( getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE ) );
if (!PermissionHelper.hasPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
PermissionHelper.requestPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
else
{
postCreate();
}
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String cameraDriverStr = sharedPref.getString(getString(R.string.pref_key_camera_driver), getString(R.string.pref_default_camera_driver));
mCameraDriver = Integer.parseInt(cameraDriverStr);
isArCoreAvailable();
isArEngineAvailable();
if (!PermissionHelper.hasPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
PermissionHelper.requestPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
else
{
// Get intent, action and MIME type
Intent intent = getIntent();
String action = intent.getAction();
String type = intent.getType();
if (Intent.ACTION_SEND.equals(action) && type != null) {
if ("application/octet-stream".equals(type)) {
Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (imageUri != null) {
String fileName = getFileName(imageUri);
Log.i(TAG, "Intent received: " + imageUri.getPath() + " Name:" + fileName);
if(fileName.endsWith(".db"))
{
File file = new File(mWorkingDirectory+fileName);
if(file.exists())
{
mToast.makeText(this, fileName + " already exists in RTAB-Map's library! Cannot be copied.", mToast.LENGTH_LONG).show();
}
else
{
copy(imageUri, file);
mIntentDbToOpen = fileName;
}
}
}
}
} else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
if (type.startsWith("application/")) {
ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
if (imageUris != null) {
boolean added = false;
for(Uri imageUri: imageUris)
{
String fileName = getFileName(imageUri);
Log.i(TAG, "Intent received: " + imageUri.getPath() + " Name:" + fileName);
if(fileName.endsWith(".db"))
{
File file = new File(mWorkingDirectory+"/"+getFileName(imageUri));
if(!file.exists())
{
copy(imageUri, file);
added = true;
}
else
{
Log.e(TAG, fileName + " already exists in RTAB-Map's library! Cannot be copied.");
}
}
}
if(added)
{
openDatabase();
}
}
}
}
postCreate();
}
}
public void copy(File src, File dst) throws IOException {
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
public void copy(Uri uri, File file)
{
InputStream in;
try {
in = getApplicationContext().getContentResolver().openInputStream(uri);
OutputStream out = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
public String getFileName(Uri uri) {
String result = null;
if (uri.getScheme().equals("content")) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
} finally {
cursor.close();
}
}
if (result == null) {
result = uri.getPath();
int cut = result.lastIndexOf('/');
if (cut != -1) {
result = result.substring(cut + 1);
}
}
return result;
}
// Should be called only if read/write permissions are granted!
private void postCreate()
{
Log.i(TAG, "postCreate()");
String tmpDatabase = mWorkingDirectory+RTABMAP_TMP_DB;
(new File(tmpDatabase)).delete();
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
boolean databaseInMemory = sharedPref.getBoolean(getString(R.string.pref_key_db_in_memory), Boolean.parseBoolean(getString(R.string.pref_default_db_in_memory)));
RTABMapLib.openDatabase(nativeApplication, tmpDatabase, databaseInMemory, false);
final String[] files = Util.loadFileList(mWorkingDirectory, true);
if(files.length == 0)
{
@@ -613,6 +749,17 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
Log.i(TAG, String.format("updateCameraDriverSettings() mCameraDriver=%d RTABMapLib.isBuiltWith(%d)=%d", mCameraDriver, mCameraDriver, RTABMapLib.isBuiltWith(nativeApplication, mCameraDriver)?1:0));
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String cameraDriverStr = sharedPref.getString(getString(R.string.pref_key_camera_driver), getString(R.string.pref_default_camera_driver));
mCameraDriver = Integer.parseInt(cameraDriverStr);
if(mCameraDriver == -1)
{
// Prioritize tango if available
mCameraDriver = 0;
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString(getString(R.string.pref_key_camera_driver), "0");
editor.commit();
}
if(mCameraDriver == 0 && (!CheckTangoCoreVersion(MIN_TANGO_CORE_VERSION) || !RTABMapLib.isBuiltWith(nativeApplication, 0)))
{
@@ -1167,7 +1314,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
final boolean depthFromMotion = sharedPref.getBoolean(getString(R.string.pref_key_depth_from_motion), Boolean.parseBoolean(getString(R.string.pref_default_depth_from_motion)));
mCameraDriver = Integer.parseInt(cameraDriverStr);
if(!DISABLE_LOG) Log.i(TAG, String.format("startCamera() driver=%d", mCameraDriver));
Log.i(TAG, String.format("startCamera() driver=%d", mCameraDriver));
if(mCameraDriver == 0) // Tango
{
// Check if the Tango Core is out dated.
@@ -1992,6 +2139,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
final int loopDetected = RTABMapLib.postProcessing(nativeApplication, -1);
runOnUiThread(new Runnable() {
public void run() {
updateState(State.STATE_IDLE);
if(mExportProgressDialog.isShowing())
{
mExportProgressDialog.dismiss();
@@ -2024,8 +2172,6 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
mProgressDialog.dismiss();
mToast.makeText(getActivity(), String.format("Optimization canceled"), mToast.LENGTH_LONG).show();
}
updateState(State.STATE_IDLE);
}
});
}
@@ -2144,7 +2290,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
mButtonCloseVisualization.setVisibility(mHudVisible && mState != State.STATE_VISUALIZING_CAMERA?View.VISIBLE:View.INVISIBLE);
mButtonCloseVisualization.setEnabled(true);
mButtonSaveOnDevice.setVisibility(mHudVisible && mState != State.STATE_VISUALIZING_CAMERA?View.VISIBLE:View.INVISIBLE);
mButtonShareOnSketchfab.setVisibility(mHudVisible && mState != State.STATE_VISUALIZING_CAMERA?View.VISIBLE:View.INVISIBLE);
//mButtonShareOnSketchfab.setVisibility(mHudVisible && mState != State.STATE_VISUALIZING_CAMERA?View.VISIBLE:View.INVISIBLE);
mButtonLibrary.setVisibility(View.INVISIBLE);
mButtonNewScan.setVisibility(View.INVISIBLE);
mItemSave.setEnabled(mState != State.STATE_VISUALIZING_CAMERA);
@@ -2217,6 +2363,12 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
{
mGLView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}
if(mState == State.STATE_WELCOME && mIntentDbToOpen != null)
{
openDatabase(mIntentDbToOpen, false);
mIntentDbToOpen = null;
}
}
private void startMapping() {
@@ -2626,7 +2778,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity());
boolean databaseInMemory = sharedPref.getBoolean(getString(R.string.pref_key_db_in_memory), Boolean.parseBoolean(getString(R.string.pref_default_db_in_memory)));
String tmpDatabase = mWorkingDirectory+RTABMAP_TMP_DB;
RTABMapLib.openDatabase(nativeApplication, tmpDatabase, databaseInMemory, false);
RTABMapLib.openDatabase(nativeApplication, tmpDatabase, databaseInMemory, false, true);
mItemLocalizationMode.setEnabled(!mItemDataRecorderMode.isChecked());
@@ -2780,16 +2932,110 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
mOpenedDatabasePath = "";
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
boolean databaseInMemory = sharedPref.getBoolean(getString(R.string.pref_key_db_in_memory), Boolean.parseBoolean(getString(R.string.pref_default_db_in_memory)));
String tmpDatabase = mWorkingDirectory+RTABMAP_TMP_DB;
RTABMapLib.openDatabase(nativeApplication, tmpDatabase, databaseInMemory, false);
final String tmpDatabase = mWorkingDirectory+RTABMAP_TMP_DB;
File newFile = new File(tmpDatabase);
final int fileSizeMB = (int)newFile.length()/(1024 * 1024);
if(!(mState == State.STATE_CAMERA || mState ==State.STATE_MAPPING) &&
newFile.exists() &&
fileSizeMB>1) // >1MB
{
AlertDialog d2 = new AlertDialog.Builder(getActivity())
.setCancelable(false)
.setTitle("Recovery")
.setMessage(String.format("The previous session (%d MB) was not correctly saved, do you want to recover it?", fileSizeMB))
.setNegativeButton("Ignore", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
(new File(tmpDatabase)).delete();
newScan();
}
})
.setNeutralButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do nothing
}
})
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
final String fileName = new SimpleDateFormat("yyMMdd-HHmmss").format(new Date()) + ".db";
final String outputDbPath = mWorkingDirectory + fileName;
mExportProgressDialog.setTitle("Recovering");
mExportProgressDialog.setMessage(String.format("Please wait while recovering data..."));
mExportProgressDialog.setProgress(0);
final State previousState = mState;
mExportProgressDialog.show();
updateState(State.STATE_PROCESSING);
Thread exportThread = new Thread(new Runnable() {
public void run() {
final long startTime = System.currentTimeMillis()/1000;
final boolean success = RTABMapLib.recover(
nativeApplication,
tmpDatabase,
outputDbPath);
runOnUiThread(new Runnable() {
public void run() {
if(mExportProgressDialog.isShowing())
{
if(success)
{
AlertDialog d2 = new AlertDialog.Builder(getActivity())
.setCancelable(false)
.setTitle("Database saved!")
.setMessage(String.format("Database \"%s\" (%d MB) successfully saved!", fileName, fileSizeMB))
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
openDatabase(fileName, false);
}
})
.create();
d2.setCanceledOnTouchOutside(true);
d2.show();
}
else
{
updateState(previousState);
mToast.makeText(getActivity(), String.format("Recovery failed!"), mToast.LENGTH_LONG).show();
}
mExportProgressDialog.dismiss();
}
else
{
mToast.makeText(getActivity(), String.format("Recovery canceled"), mToast.LENGTH_LONG).show();
updateState(previousState);
}
}
});
}
});
exportThread.start();
refreshSystemMediaScanDataBase(getActivity(), outputDbPath);
}
})
.create();
d2.setCanceledOnTouchOutside(false);
d2.show();
}
else
{
RTABMapLib.openDatabase(nativeApplication, tmpDatabase, databaseInMemory, false, true);
if(!(mState == State.STATE_CAMERA || mState ==State.STATE_MAPPING))
{
setCamera(1);
setCamera(0);
startCamera(String.format("Hold Tight! Initializing Camera Service...\n"
+ "Tip: If the camera is still drifting just after the mapping has started, do \"Reset\"."));
}
}
}
private void openDatabase()
{
@@ -3215,7 +3461,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
context.sendBroadcast(mediaScanIntent);
}
private void saveDatabase(String fileName)
private void saveDatabase(final String fileName)
{
final String newDatabasePath = mWorkingDirectory + fileName + ".db";
final String newDatabasePathHuman = mWorkingDirectoryHuman + fileName + ".db";
@@ -3280,7 +3526,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
AlertDialog d2 = new AlertDialog.Builder(getActivity())
.setCancelable(false)
.setTitle("Database saved!")
.setMessage(String.format("Database \"%s\" (%d MB) successfully saved on the SD-CARD!", newDatabasePathHuman, fileSizeMB))
.setMessage(String.format("Database \"%s\" (%d MB) successfully saved!", newDatabasePathHuman, fileSizeMB))
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
resetNoTouchTimer(true);
@@ -3334,31 +3580,8 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
dialog.dismiss();
if(!fileName.isEmpty())
{
File newFile = new File(mWorkingDirectory + RTABMAP_EXPORT_DIR + fileName + ".zip");
if(newFile.exists())
{
AlertDialog ad = new AlertDialog.Builder(getActivity())
.setCancelable(false)
.setTitle("File Already Exists")
.setMessage("Do you want to overwrite the existing file?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
writeExportedFiles(fileName);
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
saveOnDevice();
}
}).create();
ad.setCanceledOnTouchOutside(false);
ad.show();
}
else
{
writeExportedFiles(fileName);
}
}
}
});
AlertDialog alertToShow = builder.create();
@@ -3371,7 +3594,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
{
Log.i(TAG, String.format("Write exported mesh to \"%s\"", fileName));
mProgressDialog.setTitle("Saving to sd-card");
mProgressDialog.setTitle("Exporting");
mProgressDialog.setMessage(String.format("Compressing the files..."));
mProgressDialog.show();
@@ -3424,7 +3647,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
final String msg = e.getMessage();
runOnUiThread(new Runnable() {
public void run() {
mToast.makeText(getActivity(), String.format("Exporting mesh \"%s\" failed! Error=%s", pathHuman, msg), mToast.LENGTH_LONG).show();
mToast.makeText(getActivity(), String.format("Exporting mesh \"%s\" failed! Error=%s", fileName, msg), mToast.LENGTH_LONG).show();
}
});
}
@@ -3443,13 +3666,14 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
AlertDialog d = new AlertDialog.Builder(getActivity())
.setCancelable(false)
.setTitle("Mesh Saved!")
.setMessage(String.format("Mesh \"%s\" (%d MB) successfully exported on the SD-CARD! Share it?", pathHuman, fileSizeMB))
.setMessage(String.format("Mesh \"%s\" (%d MB) successfully exported! Share it?", pathHuman, fileSizeMB))
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Send to...
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(f));
shareIntent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(getActivity(), getActivity().getApplicationContext().getPackageName() + ".provider", f));
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.setType("application/zip");
startActivity(Intent.createChooser(shareIntent, "Sharing..."));
@@ -3471,7 +3695,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
runOnUiThread(new Runnable() {
public void run() {
mProgressDialog.dismiss();
mToast.makeText(getActivity(), String.format("Exporting mesh \"%s\" failed! No files found in tmp directory!? Last export may have failed or have been canceled.", pathHuman), mToast.LENGTH_LONG).show();
mToast.makeText(getActivity(), String.format("Exporting mesh \"%s\" failed! No files found in tmp directory!? Last export may have failed or have been canceled.", fileName), mToast.LENGTH_LONG).show();
resetNoTouchTimer(true);
}
});
@@ -3498,8 +3722,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
Thread openThread = new Thread(new Runnable() {
public void run() {
final String tmpDatabase = mWorkingDirectory+RTABMAP_TMP_DB;
final int status = RTABMapLib.openDatabase2(nativeApplication, mOpenedDatabasePath, tmpDatabase, databaseInMemory, optimize);
final int status = RTABMapLib.openDatabase(nativeApplication, mOpenedDatabasePath, databaseInMemory, optimize, false);
runOnUiThread(new Runnable() {
public void run() {
@@ -3578,20 +3801,6 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
openThread.start();
}
public void copy(File src, File dst) throws IOException {
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
private void shareToSketchfab()
{
if (!PermissionHelper.hasPermission(this, Manifest.permission.INTERNET)) {

View File

@@ -34,8 +34,9 @@ public class RTABMapLib
public static native void setScreenRotation(long nativeApplication, int displayRotation, int cameraRotation);
public static native int openDatabase(long nativeApplication, String databasePath, boolean databaseInMemory, boolean optimize);
public static native int openDatabase2(long nativeApplication, String databaseSource, String databasePath, boolean databaseInMemory, boolean optimize);
public static native int openDatabase(long nativeApplication, String databasePath, boolean databaseInMemory, boolean optimize, boolean clearDatabase);
public static native boolean recover(long nativeApplication, String from, String to);
public static native boolean isBuiltWith(long nativeApplication, int cameraDriver);
public static native boolean startCamera(long nativeApplication, IBinder binder, Context context, Activity activity, int driver);

View File

@@ -7,7 +7,11 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@@ -55,7 +59,7 @@ public class Util {
}
}
public static String[] loadFileList(String directory, final boolean databasesOnly) {
public static String[] loadFileList(final String directory, final boolean databasesOnly) {
File path = new File(directory);
String fileList[];
try {
@@ -83,6 +87,25 @@ public class Util {
};
fileList = path.list(filter);
Arrays.sort(fileList);
List<String> fileListt = new ArrayList<String>(Arrays.asList(fileList));
Collections.sort(fileListt, new Comparator<String>() {
@Override
public int compare(String filename1, String filename2) {
File file1 = new File(directory+"/"+filename1);
File file2 = new File(directory+"/"+filename2);
long k = file1.lastModified() - file2.lastModified();
if(k > 0){
return -1;
}else if(k == 0){
return 0;
}else{
return 1;
}
}
});
fileListt.toArray(fileList);
}
else {
fileList = new String[0];

View File

@@ -979,9 +979,10 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_CXX_LIBRARY = "libc++";
CLANG_USE_OPTIMIZATION_PROFILE = NO;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 7;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 3RRB6NV8U9;
EXCLUDED_ARCHS = "";
@@ -1006,7 +1007,7 @@
"$(PROJECT_DIR)/RTABMapApp/Libraries/lib",
"$(PROJECT_DIR)/RTABMapApp/Libraries/share/OpenCV/3rdparty/lib",
);
MARKETING_VERSION = 0.20.12;
MARKETING_VERSION = 0.20.19;
OTHER_CFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = com.introlab.rtabmap;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1038,7 +1039,7 @@
CLANG_USE_OPTIMIZATION_PROFILE = NO;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 7;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 3RRB6NV8U9;
FRAMEWORK_SEARCH_PATHS = (
@@ -1063,7 +1064,7 @@
"$(PROJECT_DIR)/RTABMapApp/Libraries/lib",
"$(PROJECT_DIR)/RTABMapApp/Libraries/share/OpenCV/3rdparty/lib",
);
MARKETING_VERSION = 0.20.12;
MARKETING_VERSION = 0.20.19;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = com.introlab.rtabmap;

View File

@@ -39,6 +39,7 @@
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUFrameCaptureMode = "2"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">

View File

@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19455" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19454"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>

View File

@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="zah-iI-EPt">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19455" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="zah-iI-EPt">
<device id="retina3_5" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19454"/>
<capability name="Image references" minToolsVersion="12.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>

View File

@@ -55,9 +55,11 @@ cd $pwd
# FLANN
echo "wget flann..."
curl -L http://www.cs.ubc.ca/research/flann/uploads/FLANN/flann-1.8.4-src.zip -o flann-1.8.4-src.zip
unzip -qq flann-1.8.4-src.zip
cd flann-1.8.4-src
git clone https://github.com/flann-lib/flann.git
cd flann
git checkout 1.8.4
curl -L https://gist.githubusercontent.com/matlabbe/c858ba36fb85d5e44d8667dfb3543e12/raw/8fc40aa9bc3267604869444020476a49f14ab424/flann_ios.patch -o flann_ios.patch
git apply flann_ios.patch
mkdir build
cd build
# comment "add_subdirectory( test )" in top CMakeLists.txt
@@ -66,7 +68,7 @@ cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_O
cmake --build . --config Release -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
cmake --build . --config Release --target install -- CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED="NO" CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO"
cd $pwd
#rm -r flann-1.8.4-src.zip flann-1.8.4-src
#rm -r flann
# GTSAM
git clone https://bitbucket.org/gtborg/gtsam.git
@@ -134,6 +136,8 @@ cd $pwd
git clone https://github.com/opencv/opencv.git
cd opencv
git checkout tags/3.4.2
curl -L https://gist.githubusercontent.com/matlabbe/fdc3ab4854f3a68fbde7277f543b4e5b/raw/f340839c09165056d3845645df24b76507542fd2/opencv_ios.patch -o opencv_ios.patch
git apply opencv_ios.patch
mkdir build
cd build
# add "add_definitions(-DPNG_ARM_NEON_OPT=0)" in 3rdparty/libpng/CMakeLists.txt
@@ -145,6 +149,10 @@ cd $pwd
mkdir rtabmap
cd rtabmap
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 -DCMAKE_C_FLAGS=-fembed-bitcode -DCMAKE_CXX_FLAGS=-fembed-bitcode -DCMAKE_INSTALL_PREFIX=$prefix -DCMAKE_FIND_ROOT_PATH=$prefix -DWITH_QT=OFF -DBUILD_APP=OFF -DBUILD_TOOLS=OFF -DWITH_TORO=OFF -DWITH_VERTIGO=OFF -DWITH_MADGWICK=OFF -DWITH_ORB_OCTREE=OFF -DBUILD_EXAMPLES=OFF ../../../../..
cmake -DANDROID_PREBUILD=ON ../../../../..
cmake --build . --config Release
mkdir ios
cd ios
cmake -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_OSX_SYSROOT=$sysroot -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_DEPLOYMENT_TARGET=11.0 -DCMAKE_C_FLAGS=-fembed-bitcode -DCMAKE_CXX_FLAGS=-fembed-bitcode -DCMAKE_INSTALL_PREFIX=$prefix -DCMAKE_FIND_ROOT_PATH=$prefix -DWITH_QT=OFF -DBUILD_APP=OFF -DBUILD_TOOLS=OFF -DWITH_TORO=OFF -DWITH_VERTIGO=OFF -DWITH_MADGWICK=OFF -DWITH_ORB_OCTREE=OFF -DBUILD_EXAMPLES=OFF ../../../../../..
cmake --build . --config Release
cmake --build . --config Release --target install

View File

@@ -69,24 +69,11 @@ void setScreenRotationNative(const void *object, int displayRotation)
}
}
int openDatabaseNative(const void *object, const char * databasePath, bool databaseInMemory, bool optimize)
int openDatabaseNative(const void *object, const char * databasePath, bool databaseInMemory, bool optimize, bool clearDatabase)
{
if(object)
{
return native(object)->openDatabase(databasePath, databaseInMemory, optimize);
}
else
{
UERROR("object is null!");
return -1;
}
}
int openDatabase2Native(const void *object, const char * databaseSource, const char * databasePath, bool databaseInMemory, bool optimize)
{
if(object)
{
return native(object)->openDatabase(databasePath, databaseInMemory, optimize, databaseSource);
return native(object)->openDatabase(databasePath, databaseInMemory, optimize, clearDatabase);
}
else
{
@@ -107,6 +94,31 @@ void saveNative(const void *object, const char * databasePath)
}
}
bool recoverNative(const void *object, const char * from, const char * to)
{
if(object)
{
return native(object)->recover(from, to);
}
else
{
UERROR("object is null!");
}
return false;
}
void cancelProcessingNative(const void *object)
{
if(object)
{
native(object)->cancelProcessing();
}
else
{
UERROR("object is null!");
}
}
int postProcessingNative(const void *object, int approach)
{
if(object)

View File

@@ -32,9 +32,10 @@ void setupCallbacksNative(const void *object, void * classPtr,
float, float, float, float, float, float));
void destroyNativeApplication(const void *object);
void setScreenRotationNative(const void *object, int displayRotation);
int openDatabaseNative(const void *object, const char * databasePath, bool databaseInMemory, bool optimize);
int openDatabase2Native(const void *object, const char * databaseSource, const char * databasePath, bool databaseInMemory, bool optimize);
int openDatabaseNative(const void *object, const char * databasePath, bool databaseInMemory, bool optimize, bool clearDatabase);
void saveNative(const void *object, const char * databasePath);
bool recoverNative(const void *object, const char * from, const char * to);
void cancelProcessingNative(const void * object);
int postProcessingNative(const void *object, int approach);
bool exportMeshNative(
const void *object,

View File

@@ -113,17 +113,9 @@ class RTABMap {
setupGraphicNative(native_rtabmap, Int32(size.width), Int32(size.height));
}
func openDatabase(databasePath:String, databaseInMemory:Bool, optimize:Bool) -> Int {
func openDatabase(databasePath:String, databaseInMemory:Bool, optimize:Bool, clearDatabase: Bool) -> Int {
databasePath.utf8CString.withUnsafeBufferPointer { buffer -> Int in
return Int(openDatabaseNative(native_rtabmap, buffer.baseAddress, databaseInMemory, optimize))
}
}
func openDatabase(databaseSource:String, databasePath:String, databaseInMemory:Bool, optimize:Bool) -> Int {
databasePath.utf8CString.withUnsafeBufferPointer { buffer -> Int in
databaseSource.utf8CString.withUnsafeBufferPointer { bufferSource -> Int in
return Int(openDatabase2Native(native_rtabmap, bufferSource.baseAddress, buffer.baseAddress, databaseInMemory, optimize))
}
return Int(openDatabaseNative(native_rtabmap, buffer.baseAddress, databaseInMemory, optimize, clearDatabase))
}
}
@@ -133,6 +125,18 @@ class RTABMap {
}
}
func recover(from: String, to: String) -> Bool {
from.utf8CString.withUnsafeBufferPointer { bufferFrom -> Bool in
to.utf8CString.withUnsafeBufferPointer { bufferTo -> Bool in
return recoverNative(native_rtabmap, bufferFrom.baseAddress, bufferTo.baseAddress)
}
}
}
func cancelProcessing() {
cancelProcessingNative(native_rtabmap);
}
func postProcessing(approach: Int) -> Int {
return Int(postProcessingNative(native_rtabmap, Int32(approach)))
}
@@ -486,7 +490,7 @@ func getPreviewImage(databasePath: String) -> UIImage?
let bitmap = CIImage(bitmapData: data, bytesPerRow: Int(image.width*image.channels), size: CGSize(width: Int(image.width), height: Int(image.height)), format: CIFormat.BGRA8, colorSpace: nil)
return UIImage(ciImage: bitmap)
}
return nil
return UIImage(named: "RTAB-Map1024")
}
return imageOut
}

View File

@@ -8,6 +8,7 @@
import GLKit
import ARKit
import Zip
import StoreKit
extension Array {
func size() -> Int {
@@ -41,6 +42,8 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
private var mMaxFeatures: Int = 0
private var mLoopThr = 0.11
private var mReviewRequested = false
// UI states
private enum State {
case STATE_WELCOME, // Camera/Motion off - showing only buttons open and start new scan
@@ -112,6 +115,7 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
@IBOutlet weak var toastLabel: UILabel!
let RTABMAP_TMP_DB = "rtabmap.tmp.db"
let RTABMAP_RECOVERY_DB = "rtabmap.tmp.recovery.db"
let RTABMAP_EXPORT_DIR = "Export"
func getDocumentDirectory() -> URL {
@@ -1340,6 +1344,7 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
rtabmap!.setMappingParameter(key: "Vis/FeatureType", value: defaults.string(forKey: "FeatureType")!);
rtabmap!.setMappingParameter(key: "Mem/NotLinkedNodesKept", value: defaults.bool(forKey: "SaveAllFramesInDatabase") ? "true" : "false");
rtabmap!.setMappingParameter(key: "RGBD/OptimizeFromGraphEnd", value: defaults.bool(forKey: "OptimizationfromGraphEnd") ? "true" : "false");
rtabmap!.setMappingParameter(key: "RGBD/MaxOdomCacheSize", value: defaults.string(forKey: "MaximumOdometryCacheSize")!);
rtabmap!.setMappingParameter(key: "Optimizer/Strategy", value: defaults.string(forKey: "GraphOptimizer")!);
rtabmap!.setMappingParameter(key: "RGBD/ProximityBySpace", value: defaults.string(forKey: "ProximityDetection")!);
@@ -1413,12 +1418,19 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
present(alertController, animated: true)
setGLCamera(type: 1);
setGLCamera(type: 0);
startCamera();
}
func newScan()
{
print("databases.size() = \(databases.size())")
if(databases.count >= 5 && !mReviewRequested && self.depthSupported)
{
SKStoreReviewController.requestReviewInCurrentScene()
mReviewRequested = true
}
if(mState == State.STATE_VISUALIZING)
{
closeVisualization()
@@ -1426,17 +1438,123 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
mMapNodes = 0;
self.openedDatabasePath = nil
let tmpDatabase = self.getTmpDirectory().appendingPathComponent(self.RTABMAP_TMP_DB)
let tmpDatabase = self.getDocumentDirectory().appendingPathComponent(self.RTABMAP_TMP_DB)
let inMemory = UserDefaults.standard.bool(forKey: "DatabaseInMemory")
self.rtabmap!.openDatabase(databasePath: tmpDatabase.path, databaseInMemory: inMemory, optimize: false)
if(!(self.mState == State.STATE_CAMERA || self.mState == State.STATE_MAPPING) &&
FileManager.default.fileExists(atPath: tmpDatabase.path) &&
tmpDatabase.fileSize > 1024*1024) // > 1MB
{
dismiss(animated: true, completion: {
let msg = "The previous session (\(tmpDatabase.fileSizeString)) was not correctly saved, do you want to recover it?"
let alert = UIAlertController(title: "Recovery", message: msg, preferredStyle: .alert)
let alertActionNo = UIAlertAction(title: "Ignore", style: .destructive) {
(UIAlertAction) -> Void in
do {
try FileManager.default.removeItem(at: tmpDatabase)
}
catch {
print("Could not clear tmp database: \(error)")
}
self.newScan()
}
alert.addAction(alertActionNo)
let alertActionCancel = UIAlertAction(title: "Cancel", style: .cancel) {
(UIAlertAction) -> Void in
// do nothing
}
alert.addAction(alertActionCancel)
let alertActionYes = UIAlertAction(title: "Yes", style: .default) {
(UIAlertAction2) -> Void in
let fileName = Date().getFormattedDate(format: "yyMMdd-HHmmss") + ".db"
let outputDbPath = self.getDocumentDirectory().appendingPathComponent(fileName).path
var indicator: UIActivityIndicatorView?
let alertView = UIAlertController(title: "Recovering", message: "Please wait while recovering data...", preferredStyle: .alert)
let alertViewActionCancel = UIAlertAction(title: "Cancel", style: .cancel) {
(UIAlertAction) -> Void in
self.dismiss(animated: true, completion: {
self.progressView = nil
indicator = UIActivityIndicatorView(style: .large)
indicator?.frame = CGRect(x: 0.0, y: 0.0, width: 60.0, height: 60.0)
indicator?.center = self.view.center
self.view.addSubview(indicator!)
indicator?.bringSubviewToFront(self.view)
indicator?.startAnimating()
self.rtabmap!.cancelProcessing();
})
}
alertView.addAction(alertViewActionCancel)
let previousState = self.mState
self.updateState(state: .STATE_PROCESSING);
self.present(alertView, animated: true, completion: {
// Add your progressbar after alert is shown (and measured)
let margin:CGFloat = 8.0
let rect = CGRect(x: margin, y: 84.0, width: alertView.view.frame.width - margin * 2.0 , height: 2.0)
self.progressView = UIProgressView(frame: rect)
self.progressView!.progress = 0
self.progressView!.tintColor = self.view.tintColor
alertView.view.addSubview(self.progressView!)
var success : Bool = false
DispatchQueue.background(background: {
success = self.rtabmap!.recover(from: tmpDatabase.path, to: outputDbPath)
}, completion:{
if(indicator != nil)
{
indicator!.stopAnimating()
indicator!.removeFromSuperview()
}
if self.progressView != nil
{
self.dismiss(animated: self.openedDatabasePath == nil, completion: {
if(success)
{
let alertSaved = UIAlertController(title: "Database saved!", message: String(format: "Database \"%@\" successfully recovered!", fileName), preferredStyle: .alert)
let yes = UIAlertAction(title: "OK", style: .default) {
(UIAlertAction) -> Void in
self.openDatabase(fileUrl: URL(fileURLWithPath: outputDbPath))
}
alertSaved.addAction(yes)
self.present(alertSaved, animated: true, completion: nil)
}
else
{
self.updateState(state: previousState);
self.showToast(message: "Recovery failed!", seconds: 4)
}
})
}
else
{
self.showToast(message: "Recovery canceled", seconds: 2)
self.updateState(state: previousState);
}
})
})
}
alert.addAction(alertActionYes)
self.present(alert, animated: true, completion: nil)
})
}
else
{
self.rtabmap!.openDatabase(databasePath: tmpDatabase.path, databaseInMemory: inMemory, optimize: false, clearDatabase: true)
if(!(self.mState == State.STATE_CAMERA || self.mState == State.STATE_MAPPING))
{
self.setGLCamera(type: 1);
self.setGLCamera(type: 0);
self.startCamera();
}
}
}
func save()
{
@@ -1518,12 +1636,19 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
self.openedDatabasePath = URL(fileURLWithPath: filePath)
let alert = UIAlertController(title: "Database saved!", message: String(format: "Database \"%@\" successfully saved on the SD-CARD!", fileName), preferredStyle: .alert)
let alert = UIAlertController(title: "Database saved!", message: String(format: "Database \"%@\" successfully saved!", fileName), preferredStyle: .alert)
let yes = UIAlertAction(title: "OK", style: .default) {
(UIAlertAction) -> Void in
}
alert.addAction(yes)
self.present(alert, animated: true, completion: nil)
do {
let tmpDatabase = self.getDocumentDirectory().appendingPathComponent(self.RTABMAP_TMP_DB)
try FileManager.default.removeItem(at: tmpDatabase)
}
catch {
print("Could not clear tmp database: \(error)")
}
self.updateDatabases()
self.updateState(state: previousState)
})
@@ -1559,6 +1684,8 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
indicator?.bringSubviewToFront(self.view)
indicator?.startAnimating()
self.rtabmap!.cancelProcessing()
})
}))
@@ -1663,6 +1790,7 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
alertView.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { _ in
self.dismiss(animated: true)
self.progressView = nil
self.rtabmap!.cancelProcessing()
}))
let previousState = mState
@@ -1799,7 +1927,6 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
stopMapping(ignoreSaving: true)
}
let tmpDatabase = self.getTmpDirectory().appendingPathComponent(self.RTABMAP_TMP_DB)
openedDatabasePath = fileUrl;
let fileName: String = self.openedDatabasePath!.lastPathComponent
@@ -1811,7 +1938,7 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
updateState(state: .STATE_PROCESSING);
var status = 0
DispatchQueue.background(background: {
status = self.rtabmap!.openDatabase(databaseSource: self.openedDatabasePath!.path, databasePath: tmpDatabase.path, databaseInMemory: true, optimize: false)
status = self.rtabmap!.openDatabase(databasePath: self.openedDatabasePath!.path, databaseInMemory: true, optimize: false, clearDatabase: false)
}, completion:{
// main thread
if(status == -1) {
@@ -1973,6 +2100,7 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
alertView.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { _ in
self.dismiss(animated: true)
self.progressView = nil
self.rtabmap!.cancelProcessing()
}))
let previousState = mState;
@@ -2072,7 +2200,7 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
}
.sorted(by: { $0.1 > $1.1 }) // sort descending modification dates
.map { $0.0 } // extract file names
databases = data.filter{ $0.pathExtension == "db" }
databases = data.filter{ $0.pathExtension == "db" && $0.lastPathComponent != RTABMAP_TMP_DB && $0.lastPathComponent != RTABMAP_RECOVERY_DB }
} catch {
print("Error while enumerating files : \(error.localizedDescription)")
@@ -2210,6 +2338,14 @@ extension Date {
dateformat.dateFormat = format
return dateformat.string(from: self)
}
var millisecondsSince1970:Int64 {
Int64((self.timeIntervalSince1970 * 1000.0).rounded())
}
init(milliseconds:Int64) {
self = Date(timeIntervalSince1970: TimeInterval(milliseconds) / 1000)
}
}
extension DispatchQueue {
@@ -2322,3 +2458,11 @@ extension UserDefaults {
setDefaultsFromSettingsBundle()
}
}
extension SKStoreReviewController {
public static func requestReviewInCurrentScene() {
if let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
requestReview(in: scene)
}
}
}

View File

@@ -13,7 +13,7 @@
<string>
======= RTAB-Map =======
RTAB-Map - https://github.com/introlab/rtabmap
Copyright (c) 2010-2021, Mathieu Labbe - IntRoLab - Universite de Sherbrooke, all rights reserved.
Copyright (c) 2010-2022, Mathieu Labbe - IntRoLab - Universite de Sherbrooke, all rights reserved.
Copyright (c) XXX, contributors, all rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@@ -552,6 +552,50 @@
<key>DefaultValue</key>
<true/>
</dict>
<dict>
<key>Type</key>
<string>PSGroupSpecifier</string>
<key>FooterText</key>
<string>Used only in localization mode (when clicking First-P. View during visualization). This is used to get smoother localizations and to verify localization transforms (when Max Optimization Error is not disabled) to make sure we don't teleport to a location very similar to one we previously localized on.</string>
</dict>
<dict>
<key>Type</key>
<string>PSMultiValueSpecifier</string>
<key>Title</key>
<string>Maximum odometry cache size</string>
<key>Key</key>
<string>MaximumOdometryCacheSize</string>
<key>DefaultValue</key>
<string>10</string>
<key>Titles</key>
<array>
<string>500</string>
<string>200</string>
<string>100</string>
<string>75</string>
<string>50</string>
<string>40</string>
<string>30</string>
<string>20</string>
<string>10</string>
<string>5</string>
<string>Disabled</string>
</array>
<key>Values</key>
<array>
<string>500</string>
<string>200</string>
<string>100</string>
<string>75</string>
<string>50</string>
<string>40</string>
<string>30</string>
<string>20</string>
<string>10</string>
<string>5</string>
<string>0</string>
</array>
</dict>
<dict>
<key>Type</key>
<string>PSGroupSpecifier</string>

View File

@@ -14,7 +14,7 @@
</dict>
<dict>
<key>DefaultValue</key>
<integer>2</integer>
<integer>1</integer>
<key>Key</key>
<string>PointCloudDensity</string>
<key>Title</key>
@@ -454,7 +454,7 @@
</dict>
<dict>
<key>FooterText</key>
<string>Copyright (c) 2010-2021, Mathieu Labbe - IntRoLab - Université de Sherbrooke. All rights reserved.</string>
<string>Copyright (c) 2010-2022, Mathieu Labbe - IntRoLab - Université de Sherbrooke. All rights reserved.</string>
<key>Title</key>
<string>About</string>
<key>Type</key>
@@ -462,7 +462,7 @@
</dict>
<dict>
<key>DefaultValue</key>
<string>0.20.12</string>
<string>0.20.19</string>
<key>Key</key>
<string>Version</string>
<key>Title</key>

View File

@@ -4,6 +4,7 @@ SET(SRC_FILES
)
SET(INCLUDE_DIRS
${PROJECT_BINARY_DIR}/corelib/include
${PROJECT_SOURCE_DIR}/utilite/include
${PROJECT_SOURCE_DIR}/corelib/include
${PROJECT_SOURCE_DIR}/guilib/include
@@ -135,6 +136,24 @@ IF(BUILD_AS_BUNDLE AND (APPLE OR WIN32))
ENDIF(WIN32)
ENDIF(k4a_FOUND)
IF(Torch_FOUND)
# Install needed cudnn_ops_infer64_8.dll and cudnn_cnn_infer64_8.dll
# TODO: should be a more general way to include them if version is different
IF(WIN32 AND CUDA_FOUND)
find_file(CUDNN_OPS_DLL NAMES cudnn_ops_infer64_8.dll)
find_file(CUDNN_CNN_DLL NAMES cudnn_cnn_infer64_8.dll)
IF(CUDNN_OPS_DLL AND CUDNN_CNN_DLL)
MESSAGE(STATUS "Found ${CUDNN_OPS_DLL}")
MESSAGE(STATUS "Found ${CUDNN_CNN_DLL}")
INSTALL(FILES ${CUDNN_OPS_DLL} ${CUDNN_CNN_DLL}
DESTINATION ${plugin_dest_dir}
COMPONENT runtime)
ELSE()
MESSAGE(AUTHOR_WARNING "Using Torch with CUDA, but cudnn_ops_infer64_8.dll and cudnn_cnn_infer64_8.dll are not found on the PATH, so it won't be added to package.")
ENDIF()
ENDIF(WIN32 AND CUDA_FOUND)
ENDIF(Torch_FOUND)
# Install needed Qt plugins by copying directories from the qt installation
# One can cull what gets copied by using 'REGEX "..." EXCLUDE'
# Exclude debug libraries

View File

@@ -38,10 +38,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vtkObject.h>
#ifdef RTABMAP_PYTHON
#include "rtabmap/core/PythonInterface.h"
#endif
using namespace rtabmap;
int main(int argc, char* argv[])
@@ -54,10 +50,6 @@ int main(int argc, char* argv[])
CoInitialize(nullptr);
#endif
#ifdef RTABMAP_PYTHON
PythonInterface python; // Make sure we initialize python in main thread
#endif
#if VTK_MAJOR_VERSION >= 8
vtkObject::GlobalWarningDisplayOff();
#endif

View File

@@ -1,22 +0,0 @@
## 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.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

View File

@@ -1,19 +0,0 @@
#!/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

View File

@@ -1,42 +0,0 @@
#!/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

View File

@@ -1,16 +0,0 @@
#!/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

View File

@@ -1,13 +0,0 @@
#!/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

View File

@@ -1,31 +0,0 @@
#!/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

View File

@@ -1,15 +0,0 @@
#!/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

View File

@@ -1,38 +0,0 @@
#!/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

View File

@@ -1,32 +0,0 @@
#!/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

View File

@@ -1,15 +0,0 @@
#!/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

View File

@@ -1,38 +0,0 @@
#!/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

View File

@@ -1,19 +0,0 @@
#!/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

View File

@@ -0,0 +1,106 @@
## Multi-Session Visual SLAM for Illumination Invariant Re-Localization in Indoor Environments
* Paper: https://doi.org/10.3389/frobt.2022.801886
* 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/2022-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/2022-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/2022-IlluminationInvariant/images/fig_merged_percentage.jpg)
![All sessions](https://github.com/introlab/rtabmap/raw/master/archive/2022-IlluminationInvariant/images/fig_map_merged_999.jpg)
## Dataset
We provide two formats: the first one is more general and the second one is used to produce the results in this paper with RTAB-Map. Please open issue if the links are outdated.
* [Images](https://usherbrooke-my.sharepoint.com/:u:/g/personal/labm2414_usherbrooke_ca/EV8F4PZUxOxLhwAyEehlzKwBjF-9xNuxR32Q4mUjx5u-rA?e=eCJ3TW):
* `rgb`: folder containing *.jpg color camera images
* `depth`: folder containing *.png 16bits mm depth images
* `calib`: folder containing calibration for each color image. Each calibration contains also the transform between `device` and `camera` frames as `local_transform`.
* `device_poses.txt`: VIO poses of each image in `device` frame
* `camera_poses.txt`: VIO poses of each image in `camera` frame
* [RTAB-Map Databases](https://usherbrooke-my.sharepoint.com/:u:/g/personal/labm2414_usherbrooke_ca/EU5fb0jEKzlGhPK3OWjMGLUBnDo1BRAoZwtB2czyeVLE_A?e=Y0JyXY)
## How reproduce results shown in the paper
1. RTAB-Map should be built from source with those dependencies (don't need to "install" it, we will launch it from build directory in the scripts below to avoid conflicting with another rtabmap already installed):
* Use Ubuntu 20.04+ to avoid any python2/python3 conflicts.
* OpenCV built with **xfeatures2d** and **nonfree** modules
* [torchlib c++](https://pytorch.org/get-started/locally/) (tested on v1.10.2) to enable [SuperPoint](https://github.com/magicleap/SuperPointPretrainedNetwork)
* Git clone [SuperGlue](https://github.com/magicleap/SuperGluePretrainedNetwork) into scripts directory.
* Generate `superpoint_v1.pt` in the scripts directory (can also be downloaded from [here](https://github.com/KinglittleQ/SuperPoint_SLAM/blob/master/superpoint.pt) but may not be compatible with more recent pytorch versions):
```bash
cd rtabmap/archive/2022-IlluminationInvariant/scripts
wget https://github.com/magicleap/SuperPointPretrainedNetwork/raw/master/superpoint_v1.pth
wget https://raw.githubusercontent.com/magicleap/SuperPointPretrainedNetwork/master/demo_superpoint.py
python trace.py
```
2. Download databases of the dataset and extract them.
3. Adjust the path inside `rtabmap_latest.sh` script to match where you just built rtabmap with right dependencies.
4. Run `run_all.sh DATABASES_PATH OUTPUT_PATH`, this script will do the following steps (warning, this could take hours to do...):
* Recreate the map databases for each feature type
* Create the merged databases
* Run localization databases over all map/merged databases
* Run consecutive localization experiment
5. Export statistics with `export_stats.sh` script.
6. Use the MatLab/Octave scripts in this folder to show results you want. Set `dataDir` to directory containing the exported statistics.
```
sudo apt install install octave liboctave-dev
# In octave:
pkg install -forge control signal
```
### Docker
1. Create the docker image:
```
cd rtabmap
docker build -t rtabmap_frontiers -f docker/frontiers2022/Dockerfile .
```
2. Assuming you extracted the databases of the dataset in `~/Downloads/Illumination_invariant_databases`, create an output directory for results:
```
mkdir ~/Downloads/Illumination_invariant_databases/results
```
3. Run script:
```
docker run --gpus all -it --rm --ipc=host --runtime=nvidia \
--user $(id -u):$(id -g) \
-w=/workspace/scripts \
-v ~/Downloads/Illumination_invariant_databases:/workspace/databases \
-v ~/Downloads/Illumination_invariant_databases/results:/workspace/results \
rtabmap_frontiers /workspace/scripts/run_all.sh /workspace/databases /workspace/results
```
4. Export statistics:
```
docker run --gpus all -it --rm --ipc=host --runtime=nvidia \
--env="DISPLAY=$DISPLAY" \
--env="QT_X11_NO_MITSHM=1" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
--env="XAUTHORITY=$XAUTH" \
--volume="$XAUTH:$XAUTH" \
--user $(id -u):$(id -g) \
-w=/workspace/results \
-v ~/Downloads/Illumination_invariant_databases/results:/workspace/results \
rtabmap_frontiers /workspace/scripts/export_stats.sh /workspace/results
```

View File

Before

Width:  |  Height:  |  Size: 224 KiB

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

View File

Before

Width:  |  Height:  |  Size: 253 KiB

After

Width:  |  Height:  |  Size: 253 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB

View File

@@ -2,24 +2,35 @@
clear all
close all
# sudo apt install octave-signal
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
# Use with files generated by export_stats.sh
dataDir = 'SET_PATH_TO_RESULTS_DIR';
resultsToShow = 1; % 1=single 2=Consecutive
skipFrameDir = '0';
prefix = 'Stat';
RAMaddOverhead = 1;
RAMaddOverhead = 0;
% 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
statNames = {'Loop/Odom_correction_norm/m', 'Loop/Visual_inliers/', 'Inliers_ratio_%', 'Timing/Total/ms', 'Memory/RAM_usage/MB', 'Memory/RAM_estimated/MB', 'Keypoint/Current_frame/words', 'Loop/Map_id/', 'Memory/Local_graph_size/', 'Keypoint/Dictionary_size/words', 'Loop/Distance_since_last_loc/'}; % 'Odometry_average'
datasets = [ 0 1 6 7 9 14 11 111 ]; % 0 1 6 7 9 12 14 11
sep = [0, 1000, 3000, 5000, 7000, 9000, 12000];
sepName = {'16:51', '17:31', '17:58', '18:30', '18:59', '19:42'};
if resultsToShow == 2
sep = [0, 1000, 3000, 5000, 7000, 9000];
sepName = {'17:27', '17:54', '18:27', '18:56', '19:35'};
prefix = 'Consecutive';
statNames = {'Loop/Distance_since_last_loc/', 'Distance_since_last_loc_under_50cm'};
endif
MapsN = length(sepName);
allCumResults = {};
allMaxResults = {};
@@ -35,13 +46,15 @@ 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 = dlmread([dataDir '/' prefix num2str(datasets(d)) '-' 'Loop-Visual_inliers-' '.txt'], '\t', 1, 0, "emptyvalue", 0);
dataWords = dlmread([dataDir '/' 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);
data = dlmread([dataDir '/' prefix num2str(datasets(d)) '-' 'Memory-Distance_travelled-m' '.txt'], '\t', 1, 0, "emptyvalue", 0);
elseif strcmp(statName, 'Distance_since_last_loc_under_50cm')
data = dlmread([dataDir '/' prefix num2str(datasets(d)) '-' 'Loop-Distance_since_last_loc-' '.txt'], '\t', 1, 0, "emptyvalue", 0);
else
data = dlmread([skipFrameDir '/' prefix num2str(datasets(d)) '-' statName '.txt'], '\t', 1, 0, "emptyvalue", 0);
data = dlmread([dataDir '/' prefix num2str(datasets(d)) '-' statName '.txt'], '\t', 1, 0, "emptyvalue", 0);
endif
sessions = size(data,2)-1;
@@ -69,7 +82,7 @@ for i = 1:sessions
if datasets(d) == 7
%% 135 MB overhead for BRISK kernel
y = y + 135;
elseif datasets(d) == 11
elseif datasets(d) == 11 || datasets(d) == 111
%% 645 MB (library cuda) + 800 MB (network) for SuperPoint
y = y + 645+800;
elseif datasets(d) == 13 || datasets(d) == 14
@@ -81,6 +94,12 @@ for i = 1:sessions
if strcmp(statName, 'Loop-Map_id-')
nonzeros = y;
end
if strcmp(statName, 'Distance_since_last_loc_under_50cm')
y(y>0.55) = 0;
y(isnan(y)) = 0;
y(y>0) = 1;
nonzeros = y;
end
if length(nonzeros) > 0
avgValue = sum(nonzeros)/length(nonzeros);
avgResultsTmp(i,j) = avgValue;
@@ -103,7 +122,7 @@ for d=1:length(datasets)
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)));
cumResults(end,d+1) = sum(sum(absResults{1,d}(1:MapsN,1:MapsN).*eye(MapsN,MapsN))) / sum(sum(totalResults{1,d}(1:MapsN,1:MapsN).*eye(MapsN,MapsN)));
end
cumResults(2:end-1,1) = 1:sessions;
@@ -123,7 +142,7 @@ for d=1:length(datasets)
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)));
cumMaxResults(end,d+1) = max(max(maxResults{1,d}(1:MapsN,1:MapsN).*eye(MapsN,MapsN)));
end
cumMaxResults(2:end-1,1) = 1:sessions;
@@ -133,3 +152,18 @@ allMaxResults{2,s} = cumMaxResults;
endfor % statNames
if resultsToShow == 2
disp('30min')
for d=1:length(datasets)
round(sum(absResults{1,d} .* eye(5,5)) / sum(totalResults{1,d} .*eye(5,5)) * 100)
endfor
disp('60min')
for d=1:length(datasets)
round(sum(absResults{1,d} .* [[0;0;0;0] eye(4,4) ; [0 0 0 0 0]]) / sum(totalResults{1,d} .*[[0;0;0;0] eye(4,4) ; [0 0 0 0 0]]) * 100)
endfor
disp('120min')
for d=1:length(datasets)
round(avgResults{1,d}(1,5) * 100)
endfor
endif

View File

@@ -4,16 +4,15 @@ 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
# Use with files generated by export_stats.sh
dataDir = 'SET_PATH_TO_RESULTS_DIR';
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
datasets = [0 1 6 7 9 14 11 111]; % 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'};
datasetsName{112} = 'SuperGlue'
sep = [0, 1000, 3000, 5000, 7000, 9000, 12000];
sepName = {'16:51', '17:31', '17:58', '18:30', '18:59', '19:42'};
@@ -41,13 +40,13 @@ globalc = [];
for d=1:length(datasets)
data = dlmread([skipFrameDir '/' datasetPrefix num2str(datasets(d)) '-Loop-Map_id-' '.txt'], '\t', 1, 0, "emptyvalue", NaN);
data = dlmread([dataDir '/' datasetPrefix num2str(datasets(d)) '-Loop-Map_id-' '.txt'], '\t', 1, 0, "emptyvalue", NaN);
curvesBeg = 2;
curvesEnd = size(data,2)-4;
curvesEnd = size(data,2)-5; % -4 for '0', -5 for '1'
if resultsToShow == 2
curvesBeg = 8;
curvesBeg = 8; % 2 if only 4 merged_reduced in stats, 8 to skip first 6
curvesEnd = size(data,2);
elseif resultsToShow == 3
curvesEnd = size(data,2);
@@ -198,7 +197,24 @@ for d=1:length(datasets)
data=percentResults{1,d}*100;
data(isnan(data)) = 0;
hAxes = gca;
imagesc( hAxes, data, [0, 100])
% Upscaling the image to reduce anti-aliasing effect in pfd viewers
scale = 50;
tickXStep = zeros(1, size(data, 2));
tickYStep = zeros(1, size(data, 1));
dataUp = upsample(upsample(data',scale)',scale);
for x=0:size(data, 2)-1
for y=1:scale-1
dataUp(:,(x*scale+1)+y) = dataUp(:,x*scale+1);
endfor
tickXStep(1,x+1) = scale/2 + scale*x;
endfor
for x=0:size(data, 1)-1
for y=1:scale-1
dataUp((x*scale+1)+y,:) = dataUp(x*scale+1,:);
endfor
tickYStep(1,x+1) = scale/2 + scale*x;
endfor
imagesc( hAxes, dataUp, [0, 100])
%title({"",datasetsName{datasets(d)+1}})
colors = [ones(100,1) [1:100]'*0.01 [1:100]'*0];
colors(1,:) = 1;
@@ -211,12 +227,14 @@ for d=1:length(datasets)
ylabel("Map")
endif
xlabel([datasetsName{datasets(d)+1} " Localization"])
set (gca, "xaxislocation", "top");
set(gca, "xaxislocation", "top");
set(gca, 'XTick', tickXStep)
set(gca, 'XTickLabel', sepName, 'fontsize',7)
set(gca, 'YTick', tickYStep)
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)
set(gca, 'YTickLabel', {'1+6', '1+3+5', '2+4+6', '1+2+3+4+5+6', '1-2-3-4-5-6', 'not set'}, 'fontsize',7)
else
set(gca, 'YTickLabel', {'16:46', '17:27', '17:54', '18:27', '18:56', '19:35'}, 'fontsize',7)
endif

View File

@@ -0,0 +1,109 @@
clear all
close all
# sudo apt install octave-signal
pkg load signal
# Use with files generated by export_stats.sh
dataDir = 'SET_PATH_TO_RESULTS_DIR';
prefix = 'Stat';
dataset = 6
sep = [0, 1000, 3000, 5000, 7000, 9000, 12000];
sepName = {'16:51', '17:31', '17:58', '18:30', '18:59', '19:42'};
statName = strrep('Loop/Distance_since_last_loc/','/','-');
data = dlmread([dataDir '/' prefix num2str(dataset) '-' statName '.txt'], '\t', 1, 0, "emptyvalue", 0);
sessions = size(data,2)-1
j = 1 % session #
x3 = data(:,1);
y3 = data(:,11);
y3 = y3(x3>=sep(j) & x3<=sep(j+1), :);
x3 = x3(x3>=sep(j) & x3<=sep(j+1), :);
max = 0;
for i=2:length(y3)
if isfinite(y3(i)) && isfinite(y3(i-1)) && (x3(i) - x3(i-1) < 1.5)
v = y3(i);
if v>max
max = v
endif
endif
endfor
xb = max/2:max:5;
[nn3, xx3] = hist (y3, xb);
nn3 = nn3/length(x3);
nn3(nn3==0) = NaN;
for j=1:6
x{j} = data(:,1);
y{j} = data(:,2);
y{j} = y{j}(x{j}>=sep(j) & x{j}<=sep(j+1), :);
x{j} = x{j}(x{j}>=sep(j) & x{j}<=sep(j+1), :);
[nn{j}, xx{j}] = hist (y{j}, xb);
%nn{j} = nn{j}/length(x{j});
%nn{j} = nn{j}/sum(nn{j});
for k=length(nn{j}):-1:1
if nn{j}(k) != 0
break;
else
nn{j}(k) = NaN;
endif
endfor
endfor
j = 6 % session #
x4 = data(:,1);
y4 = data(:,12);
y4 = y4(x4>=sep(j) & x4<=sep(j+1), :);
x4 = x4(x4>=sep(j) & x4<=sep(j+1), :);
[nn4, xx4] = hist (y4, xb);
nn4 = nn4/length(x4);
nn4(nn4==0) = NaN;
figure
hold on
%plot(x1,y1, '.-');
%plot(x2-x2(1),y2, '.-');
plot(x3-x3(1),y3, '.-');
%plot(x4-x4(1),y4, '.-');
%legend('Map1 -> LocA', 'Map1 -> LocF', 'Map1+2+3+4+5+6 -> LocF', 'Map1-2-3-4-5-6 -> LocF')
legend('Map1+2+3+4+5+6 -> LocA')
xlabel('Time')
ylabel('m')
title('Distance since last loc')
figure
hold on
%plot(x1,y1, '.-');
%plot(x2-x2(1),y2, '.-');
plot(x{6}-x{6}(1),y{6}, '.-');
%plot(x4-x4(1),y4, '.-');
%legend('Map1 -> LocA', 'Map1 -> LocF', 'Map1+2+3+4+5+6 -> LocF', 'Map1-2-3-4-5-6 -> LocF')
legend('Map1 -> LocF')
xlabel('Time')
ylabel('m')
title('Distance since last loc')
figure
hold on
for j=1:6
plot(xx{j},nn{j}, '-', 'linewidth', 3)
endfor
%plot(xx3,nn3, '.-', 'linewidth', 3)
%plot(xx4,nn4, '.-', 'linewidth', 3)
%legend('Loc-F', 'Loc-E', 'Loc-D', 'Loc-C', 'Loc-B', 'Loc-A')
legend('A-16:51', 'B-17:31', 'C-17:58', 'D-18:30', 'E-18:59', 'F-19:42', 'Map1+2+3+4+5+6 -> LocF', 'Map1-2-3-4-5-6 -> LocF')
%h = get(gca,'Children');
%set(gca,'Children',[h(6) h(5) h(4) h(3) h(2) h(1)])
%set(gca, 'YScale', 'log')
xlabel(['Distance not localized (m) Step ' num2str(max) ' m'])
ylabel('Re-Localization Probability on Map 1 (16:46)')

View File

@@ -0,0 +1,19 @@
#!/bin/bash
if [ $# -lt 1 ]
then
echo "No arguments supplied. It should be the data directory (where the reprocessed map databases are saved)."
exit
fi
DATA=$1
DETECTOR=(0 1 6 7 9 14 11 111)
source rtabmap_latest.bash
for d in "${DETECTOR[@]}"
do
rtabmap-report --export --export_prefix "Stat$d" --loc 32 Loop/Odom_correction_norm/m Loop/Visual_inliers/ Timing/Total/ms Timing/Proximity_by_space_visual/ms Timing/Likelihood_computation/ms Timing/Posterior_computation/ms TimingMem/Keypoints_detection/ms TimingMem/Descriptors_extraction/ms TimingMem/Add_new_words/ms Loop/Map_id/ Keypoint/Current_frame/words Memory/RAM_usage/MB Memory/RAM_estimated/MB Memory/Distance_travelled/m Loop/Distance_since_last_loc/ Memory/Local_graph_size/ Keypoint/Dictionary_size/words "$DATA/$d/loc"
rtabmap-report --export --export_prefix "Consecutive$d" --loc 32 Loop/Map_id/ Loop/Distance_since_last_loc/ "$DATA/$d/consecutive_loc"
done

View File

@@ -0,0 +1,41 @@
#!/bin/bash
if [ $# -lt 3 ]
then
echo "No arguments supplied. They should be 3: 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), the input directory (original maps) and the output data directory (where reprocessed map databases will be saved)."
exit
fi
TYPE=$1
INPUT=$2
OUTPUT=$3
source rtabmap_latest.bash
[ ! -d "$OUTPUT" ] && mkdir $OUTPUT
[ ! -d "$OUTPUT/$TYPE" ] && mkdir $OUTPUT/$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"
fi
if [ $TYPE -eq 111 ]
then
PARAMS="--Vis/CorNNType 6 --SuperGlue/Path SuperGluePretrainedNetwork/rtabmap_superglue.py --Reg/RepeatOnce false --Vis/CorGuessWinSize 0 $PARAMS --Kp/DetectorStrategy 11 --Vis/FeatureType 11"
fi
echo $PARAMS
for db in "${DATABASES[@]}"
do
rtabmap-reprocess --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 0 --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_v1.pt --Rtabmap/PublishRAMUsage true --ORB/EdgeThreshold 19 --ORB/ScaleFactor 2 --ORB/NLevels 3 --Db/TargetVersion "" --Icp/CorrespondenceRatio 0.1 --RGBD/MaxOdomCacheSize 0 --uwarn $PARAMS $INPUT/$db $OUTPUT/$TYPE/$db
rtabmap-detectMoreLoopClosures --uwarn $OUTPUT/$TYPE/$db
done

View File

@@ -0,0 +1,18 @@
#!/bin/bash
if [ $# -lt 2 ]
then
echo "No arguments supplied. They should be 2: the input directory (original maps) and the output data directory (where reprocessed map databases will be saved)."
exit
fi
INPUT=$1
OUTPUT=$2
DETECTOR=(0 1 6 7 9 14 11 111)
for d in "${DETECTOR[@]}"
do
./reprocess_maps.sh $d $INPUT $OUTPUT
./run_merge.sh $d $OUTPUT
done

View File

@@ -0,0 +1,5 @@
#!/bin/bash
export PATH=~/workspace/rtabmap/build/bin:$PATH
export LD_LIBRARY_PATH=~/workspace/rtabmap/build/lib:$LD_LIBRARY_PATH

View File

@@ -0,0 +1,14 @@
#!/bin/bash
if [ $# -lt 2 ]
then
echo "No arguments supplied. They should be 2: the input directory (original maps) and the output data directory (where reprocessed map databases will be saved)."
exit
fi
INPUT=$1
OUTPUT=$2
./reprocess_maps_all.sh $INPUT $OUTPUT
./run_localization_single_all.sh $INPUT $OUTPUT
./run_consecutive_localization_all.sh $OUTPUT

View File

@@ -0,0 +1,25 @@
#!/bin/bash
if [ $# -lt 2 ]
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) and the data directory (where map databases have been reprocessed)."
exit
fi
TYPE=$1
DATA=$2
source rtabmap_latest.bash
SOURCE=('map_190321-164651.db' 'map_190321-172717.db' 'map_190321-175428.db' 'map_190321-182709.db' 'map_190321-185608.db')
TARGETS=($DATA/$TYPE'/map_190321-172717.db;'$DATA/$TYPE'/map_190321-175428.db;'$DATA/$TYPE'/map_190321-193556.db' $DATA/$TYPE'/map_190321-175428.db;'$DATA/$TYPE'/map_190321-182709.db;' $DATA/$TYPE'/map_190321-182709.db;'$DATA/$TYPE'/map_190321-185608.db' $DATA/$TYPE'/map_190321-185608.db;'$DATA/$TYPE'/map_190321-193556.db' $DATA/$TYPE'/map_190321-193556.db' )
[ ! -d "$DATA/$TYPE/consecutive_loc" ] && mkdir $DATA/$TYPE/consecutive_loc
for i in ${!SOURCE[@]}
do
db=${SOURCE[$i]}
loc_dbs=${TARGETS[$i]}
rtabmap-reprocess --Mem/IncrementalMemory false --RGBD/ProximityBySpace true --RGBD/ProximityMaxPaths 1 --Mem/LocalizationDataSaved true --Mem/BinDataKept false --RGBD/SavedLocalizationIgnored true --Kp/IncrementalFlann false --Vis/MinInliers 20 --Rtabmap/PublishRAMUsage true --RGBD/ProximityOdomGuess false --uwarn "$DATA/$TYPE/$db;$loc_dbs" $DATA/$TYPE/consecutive_loc/loc_$db
done

View File

@@ -0,0 +1,16 @@
#!/bin/bash
if [ $# -lt 1 ]
then
echo "No arguments supplied. It should be the data directory (where the reprocessed map databases will be saved)."
exit
fi
DATA=$1
DETECTOR=(0 1 6 7 9 14 11 111)
for d in "${DETECTOR[@]}"
do
./run_consecutive_localization.sh $d $DATA
done

View File

@@ -0,0 +1,33 @@
#!/bin/bash
if [ $# -lt 3 ]
then
echo "No arguments supplied. They should be 3: 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), the input directory (original maps) and the output data directory (where reprocessed map databases will be saved)."
exit
fi
TYPE=$1
INPUT=$2
OUTPUT=$3
source rtabmap_latest.bash
# 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="$INPUT/loc_190321-165128.db;$INPUT/loc_190321-173134.db;$INPUT/loc_190321-175823.db;$INPUT/loc_190321-183051.db;$INPUT/loc_190321-185950.db;$INPUT/loc_190321-194226.db"
[ ! -d "$OUTPUT/$TYPE/loc" ] && mkdir $OUTPUT/$TYPE/accuracy
db=merged_123456.db
rtabmap-reprocess --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 "$OUTPUT/$TYPE/$db;$LOCALIZATION_DATABASES" $OUTPUT/$TYPE/accuracy/ProxOff_DoubleRegOn_BaOn_$db
rtabmap-reprocess --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 "$OUTPUT/$TYPE/$db;$LOCALIZATION_DATABASES" $OUTPUT/$TYPE/accuracy/ProxOff_DoubleRegOff_BaOn_$db
rtabmap-reprocess --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 "$OUTPUT/$TYPE/$db;$LOCALIZATION_DATABASES" $OUTPUT/$TYPE/accuracy/ProxOff_DoubleRegOn_BaOff_$db
rtabmap-reprocess --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 "$OUTPUT/$TYPE/$db;$LOCALIZATION_DATABASES" $OUTPUT/$TYPE/accuracy/ProxOff_DoubleRegOff_BaOff_$db
rtabmap-reprocess --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 "$OUTPUT/$TYPE/$db;$LOCALIZATION_DATABASES" $OUTPUT/$TYPE/accuracy/ProxOn_DoubleRegOn_BaOn_$db
rtabmap-reprocess --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 "$OUTPUT/$TYPE/$db;$LOCALIZATION_DATABASES" $OUTPUT/$TYPE/accuracy/ProxOn_DoubleRegOn_BaOff_$db

View File

@@ -0,0 +1,28 @@
#!/bin/bash
if [ $# -lt 3 ]
then
echo "No arguments supplied. They should be 3: 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), the input directory (original maps) and the output data directory (where reprocessed map databases will be saved)."
exit
fi
TYPE=$1
INPUT=$2
OUTPUT=$3
source rtabmap_latest.bash
# '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_123456.db' 'merged_135.db' 'merged_246.db' 'merged_16.db' 'merged_123456_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_123456.db' 'merged_135.db' 'merged_246.db' 'merged_16.db' 'merged_123456_reduced.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="$INPUT/loc_190321-165128.db;$INPUT/loc_190321-173134.db;$INPUT/loc_190321-175823.db;$INPUT/loc_190321-183051.db;$INPUT/loc_190321-185950.db;$INPUT/loc_190321-194226.db"
[ ! -d "$OUTPUT/$TYPE/loc" ] && mkdir $OUTPUT/$TYPE/loc
echo $PARAMS
for db in "${DATABASES[@]}"
do
rtabmap-reprocess -loc_null --Mem/IncrementalMemory false --RGBD/ProximityBySpace true --RGBD/ProximityMaxPaths 1 --Mem/LocalizationDataSaved true --Mem/BinDataKept false --RGBD/SavedLocalizationIgnored true --Kp/IncrementalFlann false --Vis/MinInliers 20 --Rtabmap/PublishRAMUsage true --RGBD/ProximityOdomGuess false --uwarn "$OUTPUT/$TYPE/$db;$LOCALIZATION_DATABASES" $OUTPUT/$TYPE/loc/loc_$db
done

View File

@@ -0,0 +1,17 @@
#!/bin/bash
if [ $# -lt 2 ]
then
echo "No arguments supplied. They should be 2: the input directory (original maps) and the output data directory (where reprocessed map databases will be saved)."
exit
fi
INPUT=$1
OUTPUT=$2
DETECTOR=(0 1 6 7 9 14 11 111)
for d in "${DETECTOR[@]}"
do
./run_localization_single.sh $d $INPUT $OUTPUT
done

View File

@@ -0,0 +1,34 @@
#!/bin/bash
if [ $# -lt 2 ]
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) and the data directory (where map databases have been reprocessed)."
exit
fi
TYPE=$1
DATA=$2
MIN_INLIERS=20 #20 40 60 80
source rtabmap_latest.bash
DATABASES="$DATA/$TYPE/map_190321-164651.db;$DATA/$TYPE/map_190321-172717.db;$DATA/$TYPE/map_190321-175428.db;$DATA/$TYPE/map_190321-182709.db;$DATA/$TYPE/map_190321-185608.db;$DATA/$TYPE/map_190321-193556.db"
# To compute "Ground truth"
rtabmap-reprocess --uwarn "$DATABASES" $DATA/$TYPE/merged_123456.db
cp $DATA/$TYPE/merged_123456.db $DATA/$TYPE/merged_123456_gt.db
rtabmap-detectMoreLoopClosures -r 0.5 -i 5 $DATA/$TYPE/merged_123456_gt.db
rtabmap-reprocess --uwarn -gt $DATA/$TYPE/merged_123456_gt.db $DATA/$TYPE/merged_123456.db
rtabmap-reprocess --uwarn "$DATA/$TYPE/map_190321-164651.db;$DATA/$TYPE/map_190321-193556.db" $DATA/$TYPE/merged_16.db
rtabmap-reprocess --uwarn "$DATA/$TYPE/map_190321-164651.db;$DATA/$TYPE/map_190321-175428.db;$DATA/$TYPE/map_190321-185608.db" $DATA/$TYPE/merged_135.db
rtabmap-reprocess --uwarn "$DATA/$TYPE/map_190321-172717.db;$DATA/$TYPE/map_190321-182709.db;$DATA/$TYPE/map_190321-193556.db" $DATA/$TYPE/merged_246.db
# Reduced graph
rtabmap-reprocess --uwarn -gt --Mem/ReduceGraph true --Vis/MinInliers $MIN_INLIERS $DATA/$TYPE/merged_123456_gt.db $DATA/$TYPE/merged_123456_reduced.db

View File

@@ -0,0 +1,9 @@
import torch
import torchvision
from demo_superpoint import SuperPointNet
model = SuperPointNet()
model.load_state_dict(torch.load("superpoint_v1.pth"))
model.eval()
example = torch.rand(1, 1, 640, 480)
traced_script_module = torch.jit.trace(model, example)
traced_script_module.save("superpoint_v1.pt")

View File

@@ -0,0 +1,20 @@
#!/bin/bash
if [ $# -lt 2 ]
then
echo "No arguments supplied. They should be 2: the input directory (original maps) and the output data directory (where reprocessed map databases will be saved)."
exit
fi
INPUT=$1
OUTPUT=$2
DETECTOR=(0 1 6 7 9 14 11 111)
source rtabmap_latest.bash
for d in "${DETECTOR[@]}"
do
valgrind --tool=massif --time-unit=ms --detailed-freq=1 --max-snapshots=100 rtabmap-reprocess --Mem/IncrementalMemory false --Kp/IncrementalFlann false "${OUTPUT}/${d}/map_190321-164651.db;${INPUT}/loc_190321-165128.db" output.db
rm output.db
done

View File

@@ -0,0 +1,108 @@
##close all
##clear all
%% Use Export Poses in TORO format, then copy columns
load vertexes.txt;
load edges.txt;
set(0,'defaultAxesFontName', 'Times')
set(0,'defaultTextFontName', 'Times')
%matlab indexes % rtabmap indexes
endMap1 = 201; % ID=206
endMap2 = 401; % ID=411
endMap3 = 604; % ID=621
endMap4 = 794; % ID=814
endMap5 = 968; % ID=990
endMap6 = 1201; % ID=1230
%% 3D
t = vertexes(:,1);
##figure
##plot3(vertexes(1:endMap1,2), vertexes(1:endMap1,3), vertexes(1:endMap1,1))
##hold on
##plot3(vertexes(endMap1+1:endMap2,2), vertexes(endMap1+1:endMap2,3), vertexes(endMap1+1:endMap2,1))
##plot3(vertexes(endMap2+1:endMap3,2), vertexes(endMap2+1:endMap3,3), vertexes(endMap2+1:endMap3,1))
##plot3(vertexes(endMap3+1:endMap4,2), vertexes(endMap3+1:endMap4,3), vertexes(endMap3+1:endMap4,1))
##plot3(vertexes(endMap4+1:endMap5,2), vertexes(endMap4+1:endMap5,3), vertexes(endMap4+1:endMap5,1))
##plot3(vertexes(endMap5+1:end,2), vertexes(endMap5+1:end,3), vertexes(endMap5+1:end,1))
mapIds = zeros(vertexes(end,1), 2); % matlab index to vertexes, map id
for i=1:size(vertexes,1)
mapIds(vertexes(i,1),1) = i;
if i <= endMap1
mapIds(vertexes(i,1),2) = 1;
elseif i<=endMap2
mapIds(vertexes(i,1),2) = 2;
elseif i<=endMap3
mapIds(vertexes(i,1),2) = 3;
elseif i<=endMap4
mapIds(vertexes(i,1),2) = 4;
elseif i<=endMap5
mapIds(vertexes(i,1),2) = 5;
else
mapIds(vertexes(i,1),2) = 6;
end
end
##interLoopClosures = 0;
##intraLoopClosures = 0;
##
##for i=1:size(edges, 1)
## if edges(i,2) > edges(i,1)+1
## x = [vertexes(mapIds(edges(i,1),1), 2) vertexes(mapIds(edges(i,2),1), 2)];
## y = [vertexes(mapIds(edges(i,1),1), 3) vertexes(mapIds(edges(i,2),1), 3)];
## t = [vertexes(mapIds(edges(i,1),1), 1) vertexes(mapIds(edges(i,2),1), 1)];
## if mapIds(edges(i,1),2) ~= mapIds(edges(i,2),2)
## plot3(x,y,t, 'g')
## interLoopClosures = interLoopClosures+1;
## else
## plot3(x,y,t, 'r')
## intraLoopClosures = intraLoopClosures + 1;
## end
## end
##end
##xlabel('x')
##ylabel('y')
##zlabel('Node indexes')
##
##interLoopClosures
##intraLoopClosures
%% 2D
figure
hold on
plot([-8 6], [vertexes(endMap1,1) vertexes(endMap1,1)], 'k:')
plot([-8 6], [vertexes(endMap2,1) vertexes(endMap2,1)], 'k:')
plot([-8 6], [vertexes(endMap3,1) vertexes(endMap3,1)], 'k:')
plot([-8 6], [vertexes(endMap4,1) vertexes(endMap4,1)], 'k:')
plot([-8 6], [vertexes(endMap5,1) vertexes(endMap5,1)], 'k:')
colors = {'r:', 'g:', 'c:', 'y:', 'm:', 'c'};
for i=1:size(edges, 1)
if edges(i,2) > edges(i,1)+1
y = [vertexes(mapIds(edges(i,1),1), 3) vertexes(mapIds(edges(i,2),1), 3)];
t = [vertexes(mapIds(edges(i,1),1), 1) vertexes(mapIds(edges(i,2),1), 1)];
mapId = mapIds(edges(i,1),2);
if mapId ~= mapIds(edges(i,2),2) && (mapId == 1 || mapIds(edges(i,2),2) == 1)
plot(y,t, 'r')
else
%plot(y,t, 'r')
end
end
end
curveColor = 'b'
plot(vertexes(1:endMap1,3), vertexes(1:endMap1,1), curveColor)
plot(vertexes(endMap1+1:endMap2,3), vertexes(endMap1+1:endMap2,1), curveColor)
plot(vertexes(endMap2+1:endMap3,3), vertexes(endMap2+1:endMap3,1), curveColor)
plot(vertexes(endMap3+1:endMap4,3), vertexes(endMap3+1:endMap4,1), curveColor)
plot(vertexes(endMap4+1:endMap5,3), vertexes(endMap4+1:endMap5,1), curveColor)
plot(vertexes(endMap5+1:end,3), vertexes(endMap5+1:end,1), 'k')
xlabel('y')
ylabel('Node indexes')

5
bin/.gitignore vendored
View File

@@ -1,5 +0,0 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore
!data

View File

@@ -1,4 +1,5 @@
#Pre-requisites: Look for csparse
MESSAGE(STATUS "RTAB-Map's cmake g2o find module used for convenience (for older g2o versions)")
FIND_PATH(CSPARSE_INCLUDE_DIR NAMES cs.h PATH_SUFFIXES suitesparse csparse EXTERNAL/suitesparse EXTERNAL/csparse g2o/EXTERNAL/suitesparse g2o/EXTERNAL/csparse
PATHS "C:\\Program Files\\g2o\\include\\EXTERNAL")
FIND_LIBRARY(CSPARSE_LIBRARY NAMES cxsparse g2o_ext_csparse
@@ -21,6 +22,10 @@ FIND_FILE(G2O_CONFIG_FILE g2o/config.h
PATHS ${G2O_INCLUDE_DIR}
NO_DEFAULT_PATH)
FIND_FILE(G2O_FACTORY_FILE g2o/core/factory.h
PATHS ${G2O_INCLUDE_DIR}
NO_DEFAULT_PATH)
#ifdef G2O_NUMBER_FORMAT_STR
#define G2O_CPP11 // we assume that if G2O_NUMBER_FORMAT_STR is defined, this is the new g2o code with c++11 interface
#endif
@@ -83,7 +88,7 @@ ENDIF(G2O_SOLVER_CHOLMOD OR G2O_SOLVER_CSPARSE OR G2O_SOLVER_DENSE OR G2O_SOLVER
# G2O itself declared found if we found the core libraries and at least one solver
SET(G2O_FOUND "NO")
IF(G2O_STUFF_LIBRARY AND G2O_CORE_LIBRARY AND G2O_INCLUDE_DIR AND G2O_CONFIG_FILE AND G2O_SOLVERS_FOUND)
IF(G2O_STUFF_LIBRARY AND G2O_CORE_LIBRARY AND G2O_INCLUDE_DIR AND G2O_CONFIG_FILE AND G2O_FACTORY_FILE AND G2O_SOLVERS_FOUND)
SET(G2O_INCLUDE_DIRS ${G2O_INCLUDE_DIR})
SET(G2O_LIBRARIES
${G2O_CORE_LIBRARY}
@@ -120,8 +125,16 @@ IF(G2O_STUFF_LIBRARY AND G2O_CORE_LIBRARY AND G2O_INCLUDE_DIR AND G2O_CONFIG_FIL
SET(G2O_CPP11 0)
ELSE()
MESSAGE(WARNING "Latest g2o version detected with c++11 interface (config file: ${G2O_CONFIG_FILE}). Make sure g2o is built with \"-DBUILD_WITH_MARCH_NATIVE=OFF\" to avoid segmentation faults caused by Eigen.")
FILE(READ ${G2O_FACTORY_FILE} TMPTXT)
STRING(FIND "${TMPTXT}" "shared_ptr" matchres)
IF(${matchres} EQUAL -1)
MESSAGE(STATUS "Old g2o factory version detected without shared ptr (factory file: ${G2O_FACTORY_FILE}).")
SET(G2O_CPP11 2)
ELSE()
MESSAGE(STATUS "Latest g2o factory version detected with shared ptr (factory file: ${G2O_FACTORY_FILE}).")
SET(G2O_CPP11 1)
ENDIF()
ENDIF()
SET(G2O_FOUND "YES")
ENDIF(G2O_STUFF_LIBRARY AND G2O_CORE_LIBRARY AND G2O_INCLUDE_DIR AND G2O_CONFIG_FILE AND G2O_SOLVERS_FOUND)
ENDIF(G2O_STUFF_LIBRARY AND G2O_CORE_LIBRARY AND G2O_INCLUDE_DIR AND G2O_CONFIG_FILE AND G2O_FACTORY_FILE AND G2O_SOLVERS_FOUND)

View File

@@ -1 +0,0 @@
/Version.h

View File

@@ -167,7 +167,7 @@ public:
void loadNodeData(Signature * signature, bool images = true, bool scan = true, bool userData = true, bool occupancyGrid = true) const;
void loadNodeData(std::list<Signature *> & signatures, bool images = true, bool scan = true, bool userData = true, bool occupancyGrid = true) const;
void getNodeData(int signatureId, SensorData & data, bool images = true, bool scan = true, bool userData = true, bool occupancyGrid = true) const;
bool getCalibration(int signatureId, std::vector<CameraModel> & models, StereoCameraModel & stereoModel) const;
bool getCalibration(int signatureId, std::vector<CameraModel> & models, std::vector<StereoCameraModel> & stereoModels) const;
bool getLaserScanInfo(int signatureId, LaserScan & info) const;
bool getNodeInfo(int signatureId, Transform & pose, int & mapId, int & weight, std::string & label, double & stamp, Transform & groundTruthPose, std::vector<float> & velocity, GPS & gps, EnvSensors & sensors) const;
void loadLinks(int signatureId, std::multimap<int, Link> & links, Link::Type type = Link::kUndef) const;
@@ -272,7 +272,7 @@ protected:
virtual void loadLinksQuery(int signatureId, std::multimap<int, Link> & links, Link::Type type = Link::kUndef) const = 0;
virtual void loadNodeDataQuery(std::list<Signature *> & signatures, bool images=true, bool scan=true, bool userData=true, bool occupancyGrid=true) const = 0;
virtual bool getCalibrationQuery(int signatureId, std::vector<CameraModel> & models, StereoCameraModel & stereoModel) const = 0;
virtual bool getCalibrationQuery(int signatureId, std::vector<CameraModel> & models, std::vector<StereoCameraModel> & stereoModels) const = 0;
virtual bool getLaserScanInfoQuery(int signatureId, LaserScan & info) const = 0;
virtual bool getNodeInfoQuery(int signatureId, Transform & pose, int & mapId, int & weight, std::string & label, double & stamp, Transform & groundTruthPose, std::vector<float> & velocity, GPS & gps, EnvSensors & sensors) const = 0;
virtual void getLastNodeIdsQuery(std::set<int> & ids) const = 0;

View File

@@ -137,7 +137,7 @@ protected:
virtual void loadLinksQuery(int signatureId, std::multimap<int, Link> & links, Link::Type type = Link::kUndef) const;
virtual void loadNodeDataQuery(std::list<Signature *> & signatures, bool images=true, bool scan=true, bool userData=true, bool occupancyGrid=true) const;
virtual bool getCalibrationQuery(int signatureId, std::vector<CameraModel> & models, StereoCameraModel & stereoModel) const;
virtual bool getCalibrationQuery(int signatureId, std::vector<CameraModel> & models, std::vector<StereoCameraModel> & stereoModels) const;
virtual bool getLaserScanInfoQuery(int signatureId, LaserScan & info) const;
virtual bool getNodeInfoQuery(int signatureId, Transform & pose, int & mapId, int & weight, std::string & label, double & stamp, Transform & groundTruthPose, std::vector<float> & velocity, GPS & gps, EnvSensors & sensors) const;
virtual void getLastNodeIdsQuery(std::set<int> & ids) const;

View File

@@ -54,7 +54,8 @@ public:
int cameraIndex = -1,
int stopId = 0,
bool intermediateNodesIgnored = false,
bool landmarksIgnored = false);
bool landmarksIgnored = false,
bool featuresIgnored = false);
DBReader(const std::list<std::string> & databasePaths,
float frameRate = 0.0f, // -1 = use Database stamps, 0 = inf
bool odometryIgnored = false,
@@ -64,7 +65,8 @@ public:
int cameraIndex = -1,
int stopId = 0,
bool intermediateNodesIgnored = false,
bool landmarksIgnored = false);
bool landmarksIgnored = false,
bool featuresIgnored = false);
virtual ~DBReader();
virtual bool init(
@@ -91,6 +93,7 @@ private:
int _cameraIndex;
bool _intermediateNodesIgnored;
bool _landmarksIgnored;
bool _featuresIgnored;
DBDriver * _dbDriver;
UTimer _timer;

View File

@@ -125,7 +125,8 @@ void RTABMAP_EXP computeMaxGraphErrors(
float & maxLinearError,
float & maxAngularError,
const Link ** maxLinearErrorLink = 0,
const Link ** maxAngularErrorLink = 0);
const Link ** maxAngularErrorLink = 0,
bool for3DoF = false);
std::vector<double> RTABMAP_EXP getMaxOdomInf(const std::multimap<int, Link> & links);
@@ -133,7 +134,8 @@ std::multimap<int, Link>::iterator RTABMAP_EXP findLink(
std::multimap<int, Link> & links,
int from,
int to,
bool checkBothWays = true);
bool checkBothWays = true,
Link::Type type = Link::kUndef);
std::multimap<int, int>::iterator RTABMAP_EXP findLink(
std::multimap<int, int> & links,
int from,
@@ -157,14 +159,14 @@ std::list<Link> RTABMAP_EXP findLinks(
std::multimap<int, Link> RTABMAP_EXP filterDuplicateLinks(
const std::multimap<int, Link> & links);
/**
* Return links not of type "filteredType". If inverted=true, return links of of type "filteredType".
* Return links not of type "filteredType". If inverted=true, return links of type "filteredType".
*/
std::multimap<int, Link> RTABMAP_EXP filterLinks(
const std::multimap<int, Link> & links,
Link::Type filteredType,
bool inverted = false);
/**
* Return links not of type "filteredType". If inverted=true, return links of of type "filteredType".
* Return links not of type "filteredType". If inverted=true, return links of type "filteredType".
*/
std::map<int, Link> RTABMAP_EXP filterLinks(
const std::map<int, Link> & links,
@@ -265,54 +267,58 @@ std::list<std::pair<int, Transform> > RTABMAP_EXP computePath(
float angularVelocity = 0.0f); // rad/sec
/**
* Get the nearest node of the target pose
* Find the nearest node of the target pose
* @param nodes the nodes to search for
* @param targetPose the target pose to search around
* @param distance squared distance of the nearest node found (optional)
* @return the node id.
*/
int RTABMAP_EXP findNearestNode(
const std::map<int, rtabmap::Transform> & nodes,
const std::map<int, rtabmap::Transform> & poses,
const rtabmap::Transform & targetPose,
float * distance = 0);
/**
* Get K nearest nodes of the target pose
* @param nodes the nodes to search for
* @param targetPose the target pose to search around
* @param k number of nearest neighbors to search for
* @return the node ids with squared distance to target pose.
*/
std::map<int, float> RTABMAP_EXP findNearestNodes(
const std::map<int, rtabmap::Transform> & nodes,
const rtabmap::Transform & targetPose,
int k);
/**
* Get nodes near the query
* Find the nearest nodes of the query pose or node
* @param nodeId the query id
* @param nodes the nodes to search for
* @param radius radius to search for (m)
* @param radius radius to search for (m), if 0, k should be > 0.
* @param k max nearest neighbors (0=all inside the radius)
* @return the nodes with squared distance to query node.
*/
std::map<int, float> RTABMAP_EXP getNodesInRadius(
std::map<int, float> RTABMAP_EXP findNearestNodes(
int nodeId,
const std::map<int, Transform> & nodes,
float radius);
std::map<int, float> RTABMAP_EXP getNodesInRadius(
const std::map<int, Transform> & poses,
float radius,
float angle = 0.0f,
int k=0);
std::map<int, float> RTABMAP_EXP findNearestNodes(
const Transform & targetPose,
const std::map<int, Transform> & nodes,
float radius);
std::map<int, Transform> RTABMAP_EXP getPosesInRadius(
const std::map<int, Transform> & poses,
float radius,
float angle = 0.0f,
int k=0);
std::map<int, Transform> RTABMAP_EXP findNearestPoses(
int nodeId,
const std::map<int, Transform> & nodes,
const std::map<int, Transform> & poses,
float radius,
float angle = 0.0f);
std::map<int, Transform> RTABMAP_EXP getPosesInRadius(
float angle = 0.0f,
int k=0);
std::map<int, Transform> RTABMAP_EXP findNearestPoses(
const Transform & targetPose,
const std::map<int, Transform> & nodes,
const std::map<int, Transform> & poses,
float radius,
float angle = 0.0f);
float angle = 0.0f,
int k=0);
// typedef hack to avoid error with RTABMAP_DEPRECATED
typedef std::map<int, float> _mapIntFloat;
typedef std::map<int, Transform> _mapIntTransform;
RTABMAP_DEPRECATED(_mapIntFloat RTABMAP_EXP findNearestNodes(const std::map<int, rtabmap::Transform> & nodes, const rtabmap::Transform & targetPose, int k), "Use new findNearestNodes() interface with radius=0, angle=0.");
RTABMAP_DEPRECATED(_mapIntFloat RTABMAP_EXP getNodesInRadius(int nodeId, const std::map<int, Transform> & nodes, float radius), "Renamed to findNearestNodes()");
RTABMAP_DEPRECATED(_mapIntFloat RTABMAP_EXP getNodesInRadius(const Transform & targetPose, const std::map<int, Transform> & nodes, float radius), "Renamed to findNearestNodes()");
RTABMAP_DEPRECATED(_mapIntTransform RTABMAP_EXP getPosesInRadius(int nodeId, const std::map<int, Transform> & nodes, float radius, float angle = 0.0f), "Renamed to findNearestNodes()");
RTABMAP_DEPRECATED(_mapIntTransform RTABMAP_EXP getPosesInRadius(const Transform & targetPose, const std::map<int, Transform> & nodes, float radius, float angle = 0.0f), "Renamed to findNearestNodes()");
float RTABMAP_EXP computePathLength(
const std::vector<std::pair<int, Transform> > & path,

View File

@@ -68,7 +68,13 @@ public:
const CameraModel & model,
const cv::Mat & depth = cv::Mat(),
float * estimatedMarkerLength = 0,
cv::Mat * imageWithDetections = 0), "Use the other constructor, in which the returned map contains the length of each marker detected.");
cv::Mat * imageWithDetections = 0), "Use the other detect(), in which the returned map contains the length of each marker detected.");
std::map<int, MarkerInfo> detect(const cv::Mat & image,
const std::vector<CameraModel> & models,
const cv::Mat & depth = cv::Mat(),
const std::map<int, float> & markerLengths = std::map<int, float>(),
cv::Mat * imageWithDetections = 0);
std::map<int, MarkerInfo> detect(const cv::Mat & image,
const CameraModel & model,

View File

@@ -55,6 +55,7 @@ class Statistics;
class Registration;
class RegistrationInfo;
class RegistrationIcp;
class RegistrationVis;
class Stereo;
class OccupancyGrid;
class MarkerDetector;
@@ -205,7 +206,7 @@ public:
std::vector<GlobalDescriptor> & globalDescriptors) const;
void getNodeCalibration(int nodeId,
std::vector<CameraModel> & models,
StereoCameraModel & stereoModel) const;
std::vector<StereoCameraModel> & stereoModels) const;
std::set<int> getAllSignatureIds(bool ignoreChildren = true) const;
bool memoryChanged() const {return _memoryChanged;}
bool isIncremental() const {return _incrementalMemory;}
@@ -228,6 +229,14 @@ public:
unsigned long getMemoryUsed() const; //Bytes
void generateGraph(const std::string & fileName, const std::set<int> & ids = std::set<int>());
int cleanupLocalGrids(
const std::map<int, Transform> & poses,
const cv::Mat & map,
float xMin,
float yMin,
float cellSize,
int cropRadius = 1,
bool filterScans = false);
//keypoint stuff
const VWDictionary * getVWDictionary() const;
@@ -312,8 +321,10 @@ private:
float _laserScanVoxelSize;
int _laserScanNormalK;
float _laserScanNormalRadius;
float _laserScanGroundNormalsUp;
bool _reextractLoopClosureFeatures;
bool _localBundleOnLoopClosure;
bool _invertedReg;
float _rehearsalMaxDistance;
float _rehearsalMaxAngle;
bool _rehearsalWeightIgnoredWhileMoving;
@@ -338,7 +349,7 @@ private:
bool _allNodesInWM;
GPS _gpsOrigin;
std::vector<CameraModel> _rectCameraModels;
StereoCameraModel _rectStereoCameraModel;
std::vector<StereoCameraModel> _rectStereoCameraModels;
std::vector<double> _odomMaxInf;
std::map<int, Signature *> _signatures; // TODO : check if a signature is already added? although it is not supposed to occur...
@@ -358,6 +369,7 @@ private:
Registration * _registrationPipeline;
RegistrationIcp * _registrationIcpMulti;
RegistrationVis * _registrationVis;
OccupancyGrid * _occupancy;

View File

@@ -58,7 +58,7 @@ public:
float getCellSize() const {return cellSize_;}
void setCloudAssembling(bool enabled);
float getMinMapSize() const {return minMapSize_;}
bool isGridFromDepth() const {return occupancyFromDepth_;}
bool isGridFromDepth() const {return occupancySensor_;}
bool isFullUpdate() const {return fullUpdate_;}
float getUpdateError() const {return updateError_;}
bool isMapFrameProjection() const {return projMapFrame_;}
@@ -81,7 +81,7 @@ public:
cv::Mat & groundCells,
cv::Mat & obstacleCells,
cv::Mat & emptyCells,
cv::Point3f & viewPoint) const;
cv::Point3f & viewPoint);
void createLocalMap(
const LaserScan & cloud,
@@ -118,10 +118,11 @@ private:
int scanDecimation_;
float cellSize_;
bool preVoxelFiltering_;
bool occupancyFromDepth_;
int occupancySensor_;
bool projMapFrame_;
float maxObstacleHeight_;
int normalKSearch_;
float groundNormalsUp_;
float maxGroundAngle_;
float clusterRadius_;
int minClusterSize_;

View File

@@ -74,6 +74,8 @@ public:
void expandNode();
bool createChild(unsigned int i);
void updateOccupancyTypeChildren();
private:
int nodeRefId_;
int type_; // -1=undefined, 0=empty, 100=obstacle, 1=ground

View File

@@ -54,7 +54,9 @@ public:
kTypeLOAM = 7,
kTypeMSCKF = 8,
kTypeVINS = 9,
kTypeOpenVINS = 10
kTypeOpenVINS = 10,
kTypeFLOAM = 11,
kTypeOpen3D = 12
};
public:
@@ -120,7 +122,7 @@ private:
std::vector<ParticleFilter *> particleFilters_;
cv::KalmanFilter kalmanFilter_;
StereoCameraModel stereoModel_;
std::vector<StereoCameraModel> stereoModels_;
std::vector<CameraModel> models_;
std::map<double, Transform> imus_;

View File

@@ -103,7 +103,7 @@ public:
int localBundleConstraints;
float localBundleTime;
std::map<int, Transform> localBundlePoses;
std::map<int, CameraModel> localBundleModels;
std::map<int, std::vector<CameraModel> > localBundleModels;
bool keyFrameAdded;
float timeEstimation;
float timeParticleFiltering;

View File

@@ -41,14 +41,18 @@ namespace rtabmap {
class FeatureBA
{
public:
FeatureBA(const cv::KeyPoint & kptIn, const float & depthIn = 0.0f, const cv::Mat & descriptorIn = cv::Mat()):
FeatureBA(const cv::KeyPoint & kptIn, const float & depthIn = 0.0f, const cv::Mat & descriptorIn = cv::Mat(), int cameraIndexIn = 0):
kpt(kptIn),
depth(depthIn),
descriptor(descriptorIn)
{}
descriptor(descriptorIn),
cameraIndex(cameraIndexIn)
{
//UDEBUG("kpt=(%f,%f) depth=%f, camIndex=%d", kpt.pt.x, kpt.pt.y, depth, cameraIndex);
}
cv::KeyPoint kpt;
float depth;
cv::Mat descriptor;
int cameraIndex;
};
////////////////////////////////////////////
@@ -75,7 +79,8 @@ public:
const std::map<int, Transform> & posesIn,
const std::multimap<int, Link> & linksIn,
std::map<int, Transform> & posesOut,
std::multimap<int, Link> & linksOut) const;
std::multimap<int, Link> & linksOut,
bool adjustPosesWithConstraints = true) const;
public:
virtual ~Optimizer() {}
@@ -133,7 +138,7 @@ public:
int rootId, // if negative, all other poses are fixed
const std::map<int, Transform> & poses,
const std::multimap<int, Link> & links,
const std::map<int, CameraModel> & models, // in case of stereo, Tx should be set
const std::map<int, std::vector<CameraModel> > & models, // in case of stereo, Tx should be set
std::map<int, cv::Point3f> & points3DMap,
const std::map<int, std::map<int, FeatureBA> > & wordReferences, // <ID words, IDs frames + keypoint/depth/descriptor>
std::set<int> * outliers = 0);

View File

@@ -36,8 +36,8 @@ 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::PointXYZRGB> & cloud, const std::vector<int> & cameraIds = std::vector<int>(), bool binary = false, const std::vector<float> & intensities = std::vector<float>());
int savePDALFile(const std::string & filePath, const pcl::PointCloud<pcl::PointXYZRGBNormal> & cloud, const std::vector<int> & cameraIds = std::vector<int>(), bool binary = false, const std::vector<float> & intensities = std::vector<float>());
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);

View File

@@ -202,7 +202,7 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(Mem, ImageKept, bool, false, "Keep raw images in RAM.");
RTABMAP_PARAM(Mem, BinDataKept, bool, true, "Keep binary data in db.");
RTABMAP_PARAM(Mem, RawDescriptorsKept, bool, true, "Raw descriptors kept in memory.");
RTABMAP_PARAM(Mem, MapLabelsAdded, bool, true, "Create map labels. The first node of a map will be labelled as \"map#\" where # is the map ID.");
RTABMAP_PARAM(Mem, MapLabelsAdded, bool, true, "Create map labels. The first node of a map will be labeled as \"map#\" where # is the map ID.");
RTABMAP_PARAM(Mem, SaveDepth16Format, bool, false, "Save depth image into 16 bits format to reduce memory used. Warning: values over ~65 meters are ignored (maximum 65535 millimeters).");
RTABMAP_PARAM(Mem, NotLinkedNodesKept, bool, true, "Keep not linked nodes in db (rehearsed nodes and deleted nodes).");
RTABMAP_PARAM(Mem, IntermediateNodeDataKept, bool, false, "Keep intermediate node data in db.");
@@ -368,12 +368,13 @@ class RTABMAP_EXP Parameters
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, 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. Raw features are not saved in database.");
RTABMAP_PARAM(RGBD, LocalBundleOnLoopClosure, bool, false, "Do local bundle adjustment with neighborhood of the loop closure.");
RTABMAP_PARAM(RGBD, InvertedReg, bool, false, "On loop closure, do registration from the target to reference instead of reference to target.");
RTABMAP_PARAM(RGBD, CreateOccupancyGrid, bool, false, "Create local occupancy grid maps. See \"Grid\" group for parameters.");
RTABMAP_PARAM(RGBD, MarkerDetection, bool, false, "Detect static markers to be added as landmarks for graph optimization. If input data have already landmarks, this will be ignored. See \"Marker\" group for parameters.");
RTABMAP_PARAM(RGBD, LoopCovLimited, bool, false, "Limit covariance of non-neighbor links to minimum covariance of neighbor links. In other words, if covariance of a loop closure link is smaller than the minimum covariance of odometry links, its covariance is set to minimum covariance of odometry links.");
RTABMAP_PARAM(RGBD, MaxOdomCacheSize, int, 0, uFormat("Maximum odometry cache size. Used only in localization mode (when %s=false) and when %s!=0. This is used to verify localization transforms to make sure we don't teleport to a location very similar to one we previously localized on. When the cache is full, the whole cache is cleared and the next localization is automatically accepted without verification. Set 0 to disable caching.", kMemIncrementalMemory().c_str(), kRGBDOptimizeMaxError().c_str()));
RTABMAP_PARAM(RGBD, MaxOdomCacheSize, int, 10, uFormat("Maximum odometry cache size. Used only in localization mode (when %s=false). This is used to get smoother localizations and to verify localization transforms (when %s!=0) to make sure we don't teleport to a location very similar to one we previously localized on. Set 0 to disable caching.", kMemIncrementalMemory().c_str(), kRGBDOptimizeMaxError().c_str()));
// Local/Proximity loop closure detection
RTABMAP_PARAM(RGBD, ProximityByTime, bool, false, "Detection over all locations in STM.");
@@ -385,7 +386,8 @@ class RTABMAP_EXP Parameters
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 one-to-one proximity detection.");
RTABMAP_PARAM(RGBD, ProximityOdomGuess, bool, false, "Use odometry as motion guess for one-to-one proximity detection.");
RTABMAP_PARAM(RGBD, ProximityGlobalScanMap, bool, false, uFormat("Create a global assembled map from laser scans for one-to-many proximity detection, replacing the original one-to-many proximity detection (i.e., detection against local paths). Only used in localization mode (%s=false), otherwise original one-to-many proximity detection is done. Note also that if graph is modified (i.e., memory management is enabled or robot jumps from one disjoint session to another in same database), the global scan map is cleared and one-to-many proximity detection is reverted to original approach.", kMemIncrementalMemory().c_str(), kRGBDProximityPathRawPosesUsed().c_str()));
RTABMAP_PARAM(RGBD, ProximityGlobalScanMap, bool, false, uFormat("Create a global assembled map from laser scans for one-to-many proximity detection, replacing the original one-to-many proximity detection (i.e., detection against local paths). Only used in localization mode (%s=false), otherwise original one-to-many proximity detection is done. Note also that if graph is modified (i.e., memory management is enabled or robot jumps from one disjoint session to another in same database), the global scan map is cleared and one-to-many proximity detection is reverted to original approach.", kMemIncrementalMemory().c_str()));
RTABMAP_PARAM(RGBD, ProximityMergedScanCovFactor, double, 100.0, uFormat("Covariance factor for one-to-many proximity detection (when %s>0 and scans are used).", kRGBDProximityPathMaxNeighbors().c_str()));
// Graph optimization
#ifdef RTABMAP_GTSAM
@@ -432,7 +434,7 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(GTSAM, Optimizer, int, 1, "0=Levenberg 1=GaussNewton 2=Dogleg");
// Odometry
RTABMAP_PARAM(Odom, Strategy, int, 0, "0=Frame-to-Map (F2M) 1=Frame-to-Frame (F2F) 2=Fovis 3=viso2 4=DVO-SLAM 5=ORB_SLAM2 6=OKVIS 7=LOAM 8=MSCKF_VIO 9=VINS-Fusion");
RTABMAP_PARAM(Odom, Strategy, int, 0, "0=Frame-to-Map (F2M) 1=Frame-to-Frame (F2F) 2=Fovis 3=viso2 4=DVO-SLAM 5=ORB_SLAM2 6=OKVIS 7=LOAM 8=MSCKF_VIO 9=VINS-Fusion 10=OpenVINS 11=FLOAM 12=Open3D");
RTABMAP_PARAM(Odom, ResetCountdown, int, 0, "Automatically reset odometry after X consecutive images on which odometry cannot be computed (value=0 disables auto-reset).");
RTABMAP_PARAM(Odom, Holonomic, bool, true, "If the robot is holonomic (strafing commands can be issued). If not, y value will be estimated from x and yaw values (y=x*tan(yaw)).");
RTABMAP_PARAM(Odom, FillInfoData, bool, true, "Fill info with data (inliers/outliers features).");
@@ -535,6 +537,7 @@ class RTABMAP_EXP Parameters
// Odometry LOAM
RTABMAP_PARAM(OdomLOAM, Sensor, int, 2, "Velodyne sensor: 0=VLP-16, 1=HDL-32, 2=HDL-64E");
RTABMAP_PARAM(OdomLOAM, ScanPeriod, float, 0.1, "Scan period (s)");
RTABMAP_PARAM(OdomLOAM, Resolution, float, 0.2, "Map resolution");
RTABMAP_PARAM(OdomLOAM, LinVar, float, 0.01, "Linear output variance.");
RTABMAP_PARAM(OdomLOAM, AngVar, float, 0.01, "Angular output variance.");
RTABMAP_PARAM(OdomLOAM, LocalMapping, bool, true, "Local mapping. It adds more time to compute odometry, but accuracy is significantly improved.");
@@ -571,6 +574,10 @@ class RTABMAP_EXP Parameters
// Odometry VINS
RTABMAP_PARAM_STR(OdomVINS, ConfigPath, "", "Path of VINS config file.");
// Odometry Open3D
RTABMAP_PARAM(OdomOpen3D, MaxDepth, float, 3.0, "Maximum depth.");
RTABMAP_PARAM(OdomOpen3D, Method, int, 0, "Registration method: 0=PointToPlane, 1=Intensity, 2=Hybrid.");
// Common registration parameters
RTABMAP_PARAM(Reg, RepeatOnce, bool, true, "Do a second registration with the output of the first registration as guess. Only done if no guess was provided for the first registration (like on loop closure). It can be useful if the registration approach used can use a guess to get better matches.");
RTABMAP_PARAM(Reg, Strategy, int, 0, "0=Vis, 1=Icp, 2=VisIcp");
@@ -588,6 +595,7 @@ class RTABMAP_EXP Parameters
#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()));
#endif
RTABMAP_PARAM(Vis, PnPMaxVariance, float, 0.0, uFormat("[%s = 1] Max linear variance between 3D point correspondences after PnP. 0 means disabled.", kVisEstimationType().c_str()));
RTABMAP_PARAM(Vis, EpipolarGeometryVar, float, 0.1, uFormat("[%s = 2] Epipolar geometry maximum variance to accept the transformation.", kVisEstimationType().c_str()));
RTABMAP_PARAM(Vis, MinInliers, int, 20, "Minimum feature correspondences to compute/accept the transformation.");
@@ -664,7 +672,7 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(Icp, PointToPlane, bool, false, "Use point to plane ICP.");
#endif
RTABMAP_PARAM(Icp, PointToPlaneK, int, 5, "Number of neighbors to compute normals for point to plane if the cloud doesn't have already normals.");
RTABMAP_PARAM(Icp, PointToPlaneRadius, float, 1.0, "Search radius to compute normals for point to plane if the cloud doesn't have already normals.");
RTABMAP_PARAM(Icp, PointToPlaneRadius, float, 0.0, "Search radius to compute normals for point to plane if the cloud doesn't have already normals.");
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, 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()));
@@ -722,15 +730,15 @@ class RTABMAP_EXP Parameters
#endif
// Occupancy Grid
RTABMAP_PARAM(Grid, FromDepth, bool, true, "Create occupancy grid from depth image(s), otherwise it is created from laser scan.");
RTABMAP_PARAM(Grid, Sensor, int, 1, "Create occupancy grid from selected sensor: 0=laser scan, 1=depth image(s) or 2=both laser scan and depth image(s).");
RTABMAP_PARAM(Grid, DepthDecimation, unsigned int, 4, uFormat("[%s=true] Decimation of the depth image before creating cloud.", kGridDepthDecimation().c_str()));
RTABMAP_PARAM(Grid, RangeMin, float, 0.0, "Minimum range from sensor.");
RTABMAP_PARAM(Grid, RangeMax, float, 5.0, "Maximum range from sensor. 0=inf.");
RTABMAP_PARAM_STR(Grid, DepthRoiRatios, "0.0 0.0 0.0 0.0", uFormat("[%s=true] Region of interest ratios [left, right, top, bottom].", kGridFromDepth().c_str()));
RTABMAP_PARAM_STR(Grid, DepthRoiRatios, "0.0 0.0 0.0 0.0", uFormat("[%s>=1] Region of interest ratios [left, right, top, bottom].", kGridSensor().c_str()));
RTABMAP_PARAM(Grid, FootprintLength, float, 0.0, "Footprint length used to filter points over the footprint of the robot.");
RTABMAP_PARAM(Grid, FootprintWidth, float, 0.0, "Footprint width used to filter points over the footprint of the robot. Footprint length should be set.");
RTABMAP_PARAM(Grid, FootprintHeight, float, 0.0, "Footprint height used to filter points over the footprint of the robot. Footprint length and width should be set.");
RTABMAP_PARAM(Grid, ScanDecimation, int, 1, uFormat("[%s=false] Decimation of the laser scan before creating cloud.", kGridFromDepth().c_str()));
RTABMAP_PARAM(Grid, ScanDecimation, int, 1, uFormat("[%s=0 or 2] Decimation of the laser scan before creating cloud.", kGridSensor().c_str()));
RTABMAP_PARAM(Grid, CellSize, float, 0.05, "Resolution of the occupancy grid.");
RTABMAP_PARAM(Grid, PreVoxelFiltering, bool, true, uFormat("Input cloud is downsampled by voxel filter (voxel size is \"%s\") before doing segmentation of obstacles and ground.", kGridCellSize().c_str()));
RTABMAP_PARAM(Grid, MapFrameProjection, bool, false, "Projection in map frame. On a 3D terrain and a fixed local camera transform (the cloud is created relative to ground), you may want to disable this to do the projection in robot frame instead.");
@@ -744,9 +752,9 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(Grid, MinClusterSize, int, 10, uFormat("[%s=true] Minimum cluster size to project the points.", kGridNormalsSegmentation().c_str()));
RTABMAP_PARAM(Grid, FlatObstacleDetected, bool, true, uFormat("[%s=true] Flat obstacles detected.", kGridNormalsSegmentation().c_str()));
#ifdef RTABMAP_OCTOMAP
RTABMAP_PARAM(Grid, 3D, bool, true, uFormat("A 3D occupancy grid is required if you want an OctoMap (3D ray tracing). Set to false if you want only a 2D map, the cloud will be projected on xy plane. A 2D map can be still generated if checked, but it requires more memory and time to generate it. Ignored if laser scan is 2D and \"%s\" is false.", kGridFromDepth().c_str()));
RTABMAP_PARAM(Grid, 3D, bool, true, uFormat("A 3D occupancy grid is required if you want an OctoMap (3D ray tracing). Set to false if you want only a 2D map, the cloud will be projected on xy plane. A 2D map can be still generated if checked, but it requires more memory and time to generate it. Ignored if laser scan is 2D and \"%s\" is 0.", kGridSensor().c_str()));
#else
RTABMAP_PARAM(Grid, 3D, bool, false, uFormat("A 3D occupancy grid is required if you want an OctoMap (3D ray tracing). Set to false if you want only a 2D map, the cloud will be projected on xy plane. A 2D map can be still generated if checked, but it requires more memory and time to generate it. Ignored if laser scan is 2D and \"%s\" is false.", kGridFromDepth().c_str()));
RTABMAP_PARAM(Grid, 3D, bool, false, uFormat("A 3D occupancy grid is required if you want an OctoMap (3D ray tracing). Set to false if you want only a 2D map, the cloud will be projected on xy plane. A 2D map can be still generated if checked, but it requires more memory and time to generate it. Ignored if laser scan is 2D and \"%s\" is 0.", kGridSensor().c_str()));
#endif
RTABMAP_PARAM(Grid, GroundIsObstacle, bool, false, uFormat("[%s=true] Ground segmentation (%s) is ignored, all points are obstacles. Use this only if you want an OctoMap with ground identified as an obstacle (e.g., with an UAV).", kGrid3D().c_str(), kGridNormalsSegmentation().c_str()));
RTABMAP_PARAM(Grid, NoiseFilteringRadius, float, 0.0, "Noise filtering radius (0=disabled). Done after segmentation.");
@@ -776,6 +784,9 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(Marker, CornerRefinementMethod, int, 0, "Corner refinement method (0: None, 1: Subpixel, 2:contour, 3: AprilTag2). For OpenCV <3.3.0, this is \"doCornerRefinement\" parameter: set 0 for false and 1 for true.");
RTABMAP_PARAM(Marker, MaxRange, float, 0.0, "Maximum range in which markers will be detected. <=0 for unlimited range.");
RTABMAP_PARAM(Marker, MinRange, float, 0.0, "Miniminum range in which markers will be detected. <=0 for unlimited range.");
RTABMAP_PARAM_STR(Marker, Priors, "", "World prior locations of the markers. The map will be transformed in marker's world frame when a tag is detected. Format is the marker's ID followed by its position (angles in rad), markers are separated by vertical line (\"id1 x y z roll pitch yaw|id2 x y z roll pitch yaw\"). Example: \"1 0 0 1 0 0 0|2 1 0 1 0 0 1.57\" (marker 2 is 1 meter forward than marker 1 with 90 deg yaw rotation).");
RTABMAP_PARAM(Marker, PriorsVarianceLinear, float, 0.001, "Linear variance to set on marker priors.");
RTABMAP_PARAM(Marker, PriorsVarianceAngular, float, 0.001, "Angular variance to set on marker priors.");
RTABMAP_PARAM(ImuFilter, MadgwickGain, double, 0.1, "Gain of the filter. Higher values lead to faster convergence but more noise. Lower values lead to slower convergence but smoother signal, belongs in [0, 1].");
RTABMAP_PARAM(ImuFilter, MadgwickZeta, double, 0.0, "Gyro drift gain (approx. rad/s), belongs in [-1, 1].");
@@ -829,7 +840,11 @@ public:
static bool isFeatureParameter(const std::string & param);
static ParametersMap getDefaultOdometryParameters(bool stereo = false, bool vis = true, bool icp = false);
static ParametersMap getDefaultParameters(const std::string & group);
static ParametersMap filterParameters(const ParametersMap & parameters, const std::string & group);
/**
* If remove=false: keep only parameters of the specified group.
* If remove=true: remove parameters of the specified group.
*/
static ParametersMap filterParameters(const ParametersMap & parameters, const std::string & group, bool remove = false);
static void readINI(const std::string & configFile, ParametersMap & parameters, bool modifiedOnly = false);
static void writeINI(const std::string & configFile, const ParametersMap & parameters);

View File

@@ -45,7 +45,8 @@ public:
kTypeIcp = 1,
kTypeVisIcp = 2
};
static double COVARIANCE_EPSILON;
static double COVARIANCE_LINEAR_EPSILON;
static double COVARIANCE_ANGULAR_EPSILON;
public:
static Registration * create(const ParametersMap & parameters);

View File

@@ -82,6 +82,7 @@ private:
float _PnPReprojError;
int _PnPFlags;
int _PnPRefineIterations;
float _PnPMaxVar;
int _correspondencesApproach;
int _flowWinSize;
int _flowIterations;

View File

@@ -49,6 +49,7 @@ class Memory;
class BayesFilter;
class Signature;
class Optimizer;
class PythonInterface;
class RTABMAP_EXP Rtabmap
{
@@ -196,8 +197,8 @@ public:
bool withGrid = false,
bool withWords = true,
bool withGlobalDescriptors = true) const;
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(const Transform & pose, float radius, int k=0, std::map<int, float> * distsSqr=0); // If radius=0 and k=0, RGBD/LocalRadius is used. Can return landmarks.
std::map<int, Transform> getNodesInRadius(int nodeId, float radius, int k=0, std::map<int, float> * distsSqr=0); // If nodeId==0, return poses around latest node. If radius=0 and k=0, RGBD/LocalRadius is used. Can return landmarks and use landmark id (negative) as request.
int detectMoreLoopClosures(
float clusterRadiusMax = 0.5f,
float clusterAngle = M_PI/6.0f,
@@ -206,6 +207,19 @@ public:
bool interSession = true,
const ProgressState * state = 0,
float clusterRadiusMin = 0.0f);
bool globalBundleAdjustment(
int optimizerType = 1 /*g2o*/,
bool rematchFeatures = true,
int iterations = 0,
float pixelVariance = 0.0f);
int cleanupLocalGrids(
const std::map<int, Transform> & mapPoses,
const cv::Mat & map,
float xMin,
float yMin,
float cellSize,
int cropRadius = 1,
bool filterScans = false);
int refineLinks();
bool addLink(const Link & link);
cv::Mat getInformation(const cv::Mat & covariance) const;
@@ -294,6 +308,7 @@ private:
bool _proximityRawPosesUsed;
float _proximityAngle;
bool _proximityOdomGuess;
double _proximityMergedScanCovFactor;
std::string _databasePath;
bool _optimizeFromGraphEnd;
float _optimizationMaxError;
@@ -309,6 +324,8 @@ private:
bool _loopGPS;
int _maxOdomCacheSize;
bool _createGlobalScanMap;
float _markerPriorsLinearVariance;
float _markerPriorsAngularVariance;
std::pair<int, float> _loopClosureHypothesis;
std::pair<int, float> _highestHypothesis;
@@ -348,8 +365,8 @@ private:
std::map<int, Transform> _globalScanMapPoses;
std::map<int, Transform> _odomCachePoses; // used in localization mode to reject loop closures
std::multimap<int, Link> _odomCacheConstraints; // used in localization mode to reject loop closures
std::map<int, Transform> _odomCacheAddLink; // used in localization mode when adding external link
std::vector<float> _odomCorrectionAcc;
std::map<int, Transform> _markerPriors;
// Planning stuff
int _pathStatus;
@@ -361,6 +378,10 @@ private:
int _pathStuckCount;
float _pathStuckDistance;
#ifdef RTABMAP_PYTHON
PythonInterface * _python;
#endif
};
} // namespace rtabmap

View File

@@ -73,7 +73,8 @@ public:
kCmdResume,
kCmdGoal, // params: [string] label or [int] location ID
kCmdCancelGoal,
kCmdLabel // params: [string] label, [int] location ID
kCmdLabel, // params: [string] label, [int] location ID
kCmdRemoveLabel // params: [string] label
};
public:
RtabmapEventCmd(Cmd cmd, const ParametersMap & parameters = ParametersMap()) :

View File

@@ -68,7 +68,8 @@ public:
kStateTriggeringMap,
kStateSettingGoal,
kStateCancellingGoal,
kStateLabelling
kStateLabelling,
kStateRemovingLabel
};
public:

View File

@@ -126,6 +126,25 @@ public:
double stamp = 0.0,
const cv::Mat & userData = cv::Mat());
// Multi-cameras stereo constructor
SensorData(
const cv::Mat & rgb,
const cv::Mat & depth,
const std::vector<StereoCameraModel> & cameraModels,
int id = 0,
double stamp = 0.0,
const cv::Mat & userData = cv::Mat());
// Multi-cameras stereo constructor + laser scan
SensorData(
const LaserScan & laserScan,
const cv::Mat & rgb,
const cv::Mat & depth,
const std::vector<StereoCameraModel> & cameraModels,
int id = 0,
double stamp = 0.0,
const cv::Mat & userData = cv::Mat());
// IMU constructor
SensorData(
const IMU & imu,
@@ -143,8 +162,8 @@ public:
_depthOrRightCompressed.empty() &&
_laserScanRaw.isEmpty() &&
_laserScanCompressed.isEmpty() &&
_cameraModels.size() == 0 &&
!_stereoCameraModel.isValidForProjection() &&
_cameraModels.empty() &&
_stereoCameraModels.empty() &&
_userDataRaw.empty() &&
_userDataCompressed.empty() &&
_keypoints.size() == 0 &&
@@ -173,6 +192,7 @@ public:
void setRGBDImage(const cv::Mat & rgb, const cv::Mat & depth, const CameraModel & model, bool clearPreviousData = true);
void setRGBDImage(const cv::Mat & rgb, const cv::Mat & depth, const std::vector<CameraModel> & models, bool clearPreviousData = true);
void setStereoImage(const cv::Mat & left, const cv::Mat & right, const StereoCameraModel & stereoCameraModel, bool clearPreviousData = true);
void setStereoImage(const cv::Mat & left, const cv::Mat & right, const std::vector<StereoCameraModel> & stereoCameraModels, bool clearPreviousData = true);
/**
* Set laser scan data. Detect automatically if raw or compressed.
@@ -183,7 +203,8 @@ public:
void setCameraModel(const CameraModel & model) {_cameraModels.clear(); _cameraModels.push_back(model);}
void setCameraModels(const std::vector<CameraModel> & models) {_cameraModels = models;}
void setStereoCameraModel(const StereoCameraModel & stereoCameraModel) {_stereoCameraModel = stereoCameraModel;}
void setStereoCameraModel(const StereoCameraModel & stereoCameraModel) {_stereoCameraModels.clear(); _stereoCameraModels.push_back(stereoCameraModel);}
void setStereoCameraModels(const std::vector<StereoCameraModel> & stereoCameraModels) {_stereoCameraModels = stereoCameraModels;}
//for convenience
cv::Mat depthRaw() const {return _depthOrRightRaw.type()!=CV_8UC1?_depthOrRightRaw:cv::Mat();}
@@ -213,7 +234,7 @@ public:
cv::Mat * emptyCellsRaw = 0) const;
const std::vector<CameraModel> & cameraModels() const {return _cameraModels;}
const StereoCameraModel & stereoCameraModel() const {return _stereoCameraModel;}
const std::vector<StereoCameraModel> & stereoCameraModels() const {return _stereoCameraModels;}
/**
* Set user data. Detect automatically if raw or compressed. If raw, the data is
@@ -302,7 +323,7 @@ private:
LaserScan _laserScanRaw;
std::vector<CameraModel> _cameraModels;
StereoCameraModel _stereoCameraModel;
std::vector<StereoCameraModel> _stereoCameraModels;
// user data
cv::Mat _userDataCompressed; // compressed data

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